Skip to main content
Glama
Karlangas12

openapi-to-mcp

by Karlangas12

πŸ”Œ openapi-to-mcp

Turn any OpenAPI 3.x spec into a live MCP server. Point it at a spec (file or URL) and every endpoint becomes a validated tool your AI agent can call β€” no glue code, no per-API server to write.

CI npm tests node license

Quick start Β· How it maps Β· Config Β· Secure it Β· Limits Β· EspaΓ±ol

  OpenAPI 3.x spec                         your AI client
 (JSON / YAML, file or URL)               (Claude, Cursor)
          β”‚                                      β”‚
          β–Ό                                      β”‚  MCP / JSON-RPC (stdio)
 [ openapi-to-mcp ]  β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
          β”‚  GET /pets/{id} β†’ tool "get_pet_by_id"
          β–Ό  HTTP + your auth header
   the underlying REST API

Why

MCP lets an agent call tools, but someone has to write those tools. If the capability you want already exists as a REST API with an OpenAPI spec, writing a bespoke MCP server for it is busywork.

openapi-to-mcp reads the spec and does the mapping for you: each METHOD /path becomes a tool, each parameter and request body becomes a Zod-validated input, and every call is turned into an HTTP request with your auth header attached. The response comes back trimmed for an LLM context window.

Related MCP server: Swagger MCP

Quick start

No install needed β€” run it straight from npm:

npx @karlangas12/openapi-to-mcp --spec https://api.example.com/openapi.json \
  --auth-header "Authorization: Bearer YOUR_TOKEN"

See what tools a spec produces without starting a server:

npx @karlangas12/openapi-to-mcp --spec ./openapi.yaml --list

Claude Desktop β€” claude_desktop_config.json

{
  "mcpServers": {
    "petstore": {
      "command": "npx",
      "args": [
        "-y", "@karlangas12/openapi-to-mcp",
        "--spec", "https://petstore3.swagger.io/api/v3/openapi.json",
        "--auth-header", "Authorization: Bearer YOUR_TOKEN"
      ]
    }
  }
}

Cursor β€” .cursor/mcp.json

{
  "mcpServers": {
    "my-api": {
      "command": "npx",
      "args": [
        "-y", "@karlangas12/openapi-to-mcp",
        "--spec", "./openapi.yaml",
        "--base-url", "https://api.internal.company.com"
      ]
    }
  }
}

That's the whole integration. Restart the client and the API's endpoints show up as tools.

How it maps

OpenAPI

Becomes

operationId, or METHOD /path if absent

Tool name (get_pets_by_pet_id)

summary / description

Tool description

Path, query and header parameters

Tool input properties (path params are required)

requestBody (application/json)

A body input property

Every input schema

A Zod validator + a JSON Schema for tools/list

Local $ref (#/components/...)

Resolved inline

enum, minimum/maximum, required, nullable, oneOf/anyOf/allOf

Enforced on input

When the agent calls a tool, arguments are validated before any HTTP request goes out. Path params are substituted into the URL, query params are appended, header params and your static --auth-header values are sent, and a JSON body is serialized. A 4xx/5xx response comes back as an error result the model can read and react to β€” not a silent failure.

Configuration

openapi-to-mcp --spec <path|url> [options]

  -s, --spec <path|url>    OpenAPI 3.x spec (JSON or YAML, local or remote)
      --base-url <url>     API base URL (when the spec declares no "servers")
  -H, --auth-header <h>    Header to forward, "Name: value" (repeatable)
      --format <mode>      Response format: markdown (default) or json
  -n, --name <name>        MCP server name
      --list               Print the generated tools and exit
  -h, --help / -v, --version

Multiple headers:

npx @karlangas12/openapi-to-mcp --spec ./api.yaml \
  --auth-header "Authorization: Bearer XYZ" \
  --auth-header "X-Api-Version: 2024-01"

Export a standalone server (codegen)

npx @karlangas12/openapi-to-mcp codegen --spec ./api.yaml -o server.ts

Writes a single self-contained TypeScript file that embeds the spec and boots the server via this package β€” handy for committing a pinned server to a repo.

Pairing with mcp-shield-proxy

openapi-to-mcp talks to a third-party API on your behalf, with your credentials. If you want a policy, credential masking and an audit trail around that, wrap it with mcp-shield-proxy β€” they compose with one extra line:

{
  "mcpServers": {
    "petstore": {
      "command": "npx",
      "args": [
        "-y", "mcp-shield-proxy", "--",          // ← inspect, mask, audit
        "npx", "-y", "@karlangas12/openapi-to-mcp",
        "--spec", "https://api.example.com/openapi.json",
        "--auth-header", "Authorization: Bearer YOUR_TOKEN"
      ]
    }
  }
}

Now every generated tool call is policy-checked, credentials in the traffic are masked, and the whole session lands in a verifiable audit log.

Use as a library

import { loadSpec, buildTools, createMcpServer, startStdioServer } from '@karlangas12/openapi-to-mcp';

const doc = await loadSpec('./openapi.yaml');
const { tools, baseUrl } = buildTools(doc);

const server = createMcpServer({
  tools,
  baseUrl: baseUrl ?? 'https://api.example.com',
  headers: { Authorization: 'Bearer YOUR_TOKEN' },
  fetchFn: (url, init) => fetch(url, init as RequestInit),
});

startStdioServer(server);

The parser, the schema→Zod converter and the tool builder are all exported independently.

Honest limitations

  • stdio transport only. The MCP server speaks stdio, which covers Claude Desktop, Cursor and Claude Code. Native HTTP/SSE serving isn't implemented yet.

  • Local $ref only. References inside the document (#/components/...) are resolved. External refs (other files or URLs) are not β€” they raise a clear error rather than failing quietly.

  • application/json bodies. Request bodies are mapped for JSON content. multipart/form-data and application/x-www-form-urlencoded aren't mapped yet.

  • It's a mapper, not a gateway. It doesn't add retries, caching or rate limiting. Pair it with a proxy if you need those.

Performance

The spec is parsed once at startup; after that, each tool call is a schema validation plus one HTTP request. Parsing and tool generation for a typical spec is sub-millisecond β€” the latency you feel is the underlying API's, not this.

Testing

npm test          # 32 tests
npm run typecheck # strict TypeScript

Coverage includes JSON and YAML parsing, endpoint→tool conversion with Zod schemas, and a full tools/call round trip over JSON-RPC against a mocked HTTP backend (asserting the URL, method, headers and body that reach it).

License

MIT

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Automatically converts Swagger/OpenAPI specifications into MCP servers, enabling AI agents to interact with any REST API through natural language by exposing endpoints as AI-friendly tools.
    3
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Turns any OpenAPI specification into a fully working MCP server with a single command, enabling AI agents to call APIs without writing any glue code.
    3 npm
    MIT