npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mcp-from-openapi

v2.7.0

Published

Production-ready library for converting OpenAPI specifications into MCP tool definitions

Readme

mcp-from-openapi

Convert OpenAPI specifications into MCP tool definitions with automatic parameter conflict resolution

npm version npm downloads CI coverage CodeQL License: Apache 2.0 TypeScript node

What This Solves

When converting OpenAPI specs to MCP tools, you hit parameter conflicts -- the same name appears in different locations (path, query, body). This library resolves them automatically and gives you an explicit mapper for building HTTP requests.

The Problem:

paths:
  /users/{id}:
    post:
      parameters:
        - name: id # path
          in: path
      requestBody:
        content:
          application/json:
            schema:
              properties:
                id: # body -- CONFLICT!
                  type: string

The Solution:

{
  inputSchema: {
    properties: {
      pathId: { type: "string" },    // Automatically renamed
      bodyId: { type: "string" }     // Automatically renamed
    }
  },
  mapper: [
    { inputKey: "pathId", type: "path", key: "id" },
    { inputKey: "bodyId", type: "body", key: "id" }
  ]
}

Now you know exactly how to build the HTTP request.

Features

  • Built-in Request Builder -- buildHttpRequest() applies the full OpenAPI serialization table (form/deepObject/pipeDelimited queries, label/matrix paths, multipart, binary, wholeBody) so you never hand-write request assembly
  • Client Compatibility Targets -- target: 'claude' | 'openai' | 'gemini' | 'strict' emits schemas each client actually accepts (inlined refs, closed objects, collapsed unions, demoted formats)
  • Context-Budget Reports -- analyzeToolSet() estimates the token bill per tool and warns at the thresholds where agent accuracy degrades
  • Overlays & Lint -- apply OpenAPI Overlay curation files at load time; lint() flags the spec gaps that hurt tool-calling accuracy
  • Curation-Grade Filtering -- Filter by tag, method, path glob (/admin/**), operationId, a readOnlyOnly safety switch, and x-mcp extension flags with root < path < operation precedence
  • Smart Parameter Handling -- Automatic conflict detection and resolution across path, query, header, cookie, and body; allOf bodies flatten, union and binary bodies map cleanly (wholeBody, binary markers)
  • Complete Schemas -- Input schema combines all parameters; output schema from responses (with oneOf unions); clean JSON Schema 2020-12 output (nullable unions, normalized examples)
  • MCP-Native Tools -- title and tool annotations (readOnly/destructive/idempotent hints) inferred from HTTP semantics, overridable via the x-mcp extension family; spec-compliant tool names (64-char cap, stable hash truncation, collision dedup); deterministic tool ordering for prompt-cache friendliness; toSdkTool() for one-line SDK registration
  • Security Resolution -- Framework-agnostic auth for Bearer, Basic, Digest, API Key, OAuth2, OpenID, mTLS, HMAC, AWS Sig V4; per-scheme includeSecurityInInput
  • SSRF Prevention -- Blocks internal IPs, localhost, and cloud metadata endpoints by default during $ref resolution; one-flag secureDefaults posture for untrusted specs
  • Multiple Input Sources -- Load from URL, file, YAML string, or JSON object
  • Rich Metadata -- Authentication, servers, tags, deprecation, external docs, x-frontmcp extension
  • Production Ready -- Full TypeScript support, validation, structured errors, 100% test coverage (enforced)
  • Runtime Agnostic -- Works on Node and V8 isolates (Cloudflare Workers) alike

Installation

npm install mcp-from-openapi
# or
yarn add mcp-from-openapi
# or
pnpm add mcp-from-openapi

Quick Start

import { OpenAPIToolGenerator } from "mcp-from-openapi";

// Load an OpenAPI spec
const generator = await OpenAPIToolGenerator.fromURL(
  "https://api.example.com/openapi.json",
);

// Generate MCP tools
const tools = await generator.generateTools();

// Each tool has everything you need
tools.forEach((tool) => {
  console.log(tool.name); // "createUser"
  console.log(tool.title); // "Create a user" (from summary/extensions)
  console.log(tool.annotations); // { readOnlyHint: false, destructiveHint: true, ... }
  console.log(tool.inputSchema); // Combined schema for all params
  console.log(tool.outputSchema); // Response schema
  console.log(tool.mapper); // How to build the HTTP request
  console.log(tool.metadata); // Auth, servers, tags, etc.
});

Building Requests

buildHttpRequest() turns a tool plus input values into a ready-to-send request — style/explode serialization, deepObject queries, multipart, binary, and wholeBody handled correctly:

import { buildHttpRequest } from "mcp-from-openapi";

const request = buildHttpRequest(tool, { id: "42", filter: { tag: "news" } });
// { url: 'https://api.example.com/users/42?filter[tag]=news',
//   method: 'GET', headers: {...}, body: undefined, ... }

await fetch(request.url, {
  method: request.method,
  headers: request.headers,
  body: request.body as BodyInit,
});

The mapper array stays public for anyone who needs custom request assembly — see Request Builder and Parameter Conflicts for its contract.

Serving with the Official MCP SDK

import { toSdkTool, buildHttpRequest } from "mcp-from-openapi";
import { fromJsonSchema } from "@modelcontextprotocol/server"; // SDK v2

for (const tool of await generator.generateTools({ target: "claude" })) {
  server.registerTool(...toSdkTool(tool, { fromJsonSchema }), async (input) => {
    const request = buildHttpRequest(tool, input);
    const response = await fetch(request.url, {
      method: request.method,
      headers: request.headers,
      body: request.body as BodyInit,
    });
    return { content: [{ type: "text", text: await response.text() }] };
  });
}

Documentation

| Document | Description | | ----------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- | | Getting Started | Loading specs, generating tools, building requests | | Configuration | LoadOptions, GenerateOptions, RefResolutionOptions | | Parameter Conflicts | How conflict detection and resolution works | | Request Builder | buildHttpRequest — full OpenAPI parameter serialization | | Client Targets | Per-client schema dialects (Claude, OpenAI, Gemini) | | Curation | Token budgets, overlays, lint, trimming, response hints | | Type Signatures | TypeScript call contracts for code-execution surfaces | | Modern MCP Fields | Tool _meta, icons, x-mcp-header, elicitation descriptors | | Arazzo Workflows | fromArazzo() — Arazzo 1.0 workflows as consolidated MCP tools | | Tested Examples | Runnable examples, each executed as an e2e test on every CI run | | Response Schemas | Output schemas, status codes, oneOf unions | | Annotations & Extensions | Tool title, annotation inference, x-mcp extension family | | Security | SecurityResolver, all auth types, custom resolvers | | SSRF Prevention | Ref resolution security, blocked IPs and hosts | | Format Resolution | Format-to-schema enrichment (uuid, date-time, email, int32, etc.) | | Naming Strategies | Custom tool naming and conflict resolvers | | SchemaBuilder | JSON Schema utility methods | | Error Handling | Error classes, context, and patterns | | x-frontmcp Extension | Custom OpenAPI extension for MCP annotations | | API Reference | Complete types, interfaces, and exports | | Examples | MCP server, Zod, filtering, security, and more | | Architecture | System overview, data flow, design patterns |

Requirements

  • Node.js >= 20.0.0
  • TypeScript >= 5.0 (for TypeScript users)
  • Peer dependency: zod@^4.0.0

Contributing

Contributions are welcome! Start with the contributing guide; this project follows the Contributor Covenant. Bug reports and feature requests go through the issue templates.

Security

Report vulnerabilities privately — see the security policy. When loading untrusted specs, use secureDefaults: true.

Related Projects

License

Apache 2.0