CLI tool
harsha-iiiv/openapi-mcp-generator avatar
harsha-iiiv/openapi-mcp-generator

openapi-mcp-generator turns an OpenAPI spec into a proxying MCP server

A tool that converts OpenAPI specifications to MCP server

641 stars87 forksTypeScriptMIT

At a glance

What is it?
openapi-mcp-generator is a TypeScript CLI that reads an OpenAPI 3.0 specification and writes a Model Context Protocol server that validates input with Zod and forwards calls to the original REST API. It suits teams exposing an existing API to MCP clients without hand writing a server.
Who is it for?
Adopt openapi-mcp-generator when you already publish a documented REST API and want MCP clients, including AI agents, to call it, and you would rather review generated code once than maintain a hand written server. Do not adopt it for an API with no specification, since the input is the spec, or if you need a server that owns the business logic, because the output proxies to your API rather than replacing it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 26 days ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The output is a proxy, not a rewrite of your API

The generator's stated purpose is to automate the generation of MCP-compatible servers that proxy requests to existing REST APIs, so that AI agents and other MCP clients can interact with your API using your choice of transport. The word proxy carries the design. Your OpenAPI document is the input, the MCP server is the output, and the actual business logic stays where it already is, behind your REST API. That is a clearly different approach from writing an MCP server that reimplements the endpoint behaviour in TypeScript, and the difference shows up in what you have to maintain afterwards. With the generated server, an endpoint that changes in your API changes in the proxy as soon as the spec is regenerated. The feature list puts the proxy behaviour precisely: it proxies calls to your original REST API while validating request structure and security. So the generated code is a typed, validated adapter, not a second implementation. The audience is therefore a team that has a working API and wants it reachable from MCP clients, rather than a team building an API from scratch.

Zod schemas are generated from the spec so input is checked at runtime

The validation layer is what turns a thin proxy into something an agent can call safely. Zod schemas are generated automatically from the OpenAPI definitions for runtime input validation, which means the argument shapes the model produces are checked before a request leaves the server. The output is described as fully typed, maintainable TypeScript code, and the package is published as an ES module with a bin entry at ./bin/openapi-mcp-generator.js and type declarations at ./dist/index.d.ts. The runtime dependencies are narrow: @apidevtools/swagger-parser at version 10 for reading and dereferencing the specification, commander at 13 for the command line, and openapi-types at 12 for the type layer. The MCP SDK at 1.10.2 is a peer dependency rather than a direct one, which is the right arrangement for a generator, since the generated project pins its own copy. A few other peer dependencies are listed but truncated in the package manifest. The point worth holding on to is that the validation is derived from the same document that describes the endpoint, so a spec that is vague produces a schema that is vague, and the generator does not add knowledge your spec does not contain.

Four transports, and a decision about where the server runs

The transport choice is a first class part of the tool rather than an afterthought, and the CLI exposes it directly. The generator can emit a server that communicates over stdio, over SSE using Hono, over StreamableHTTP, or as a deployable Cloudflare Worker. That last option is the interesting one for a lot of teams, because it turns a generated MCP server into something you deploy to an edge runtime rather than something you run on a box. The CLI options table is where the details live. The transport mode is set with --transport and defaults to stdio, the port for web based transports defaults to 3000 and is set with --port, and the base URL for API requests comes from --base-url, which is required if the OpenAPI servers entry is missing or ambiguous and is otherwise auto-detected. At runtime the generated server reads API_BASE_URL from the environment, from a .env file, overriding the value baked in from the servers list, and the port resolves from --port, then the PORT environment variable, then 3000. That ordering is worth knowing, because a deployment that sets PORT in a platform that injects it will silently win over the flag.

Authentication options, and the hooks for the cases it cannot cover

The generator handles the common authentication schemes out of the box: API keys, Bearer tokens, Basic auth and OAuth2, supplied through environment variables. Two flags adjust that behaviour in ways that matter for different deployment styles. --oauth-creds-in-body sends OAuth2 client credentials in the token request body instead of the Basic Authorization header, which is what some token endpoints expect and others reject. --custom-auth generates an editable src/auth.ts hook, named applyCustomAuth, which is called before the built-in auth and can return true to skip it, so a bespoke scheme does not require forking the generator. --header-passthrough takes a comma-separated list of inbound header names to forward to the upstream API on the web and streamable-http transports, and the stated purpose is per-user API keys sent through MCP client headers. --insecure allows insecure HTTPS connections by skipping TLS certificate verification in the generated server. That flag exists, and it is the right thing for a laptop against a self signed endpoint, and it is also the wrong thing in production. The header passthrough feature deserves a second look from a security standpoint, since it forwards caller supplied headers to your upstream API, so the upstream must treat those headers as untrusted input.

Parsing controls that stop the generator from being a network hazard

Two options decide how much the generator is allowed to reach, and both default to the safe answer. --allow-external-refs is disabled by default, and the stated reason is to prevent SSRF during parsing, so by default a $ref pointing at an http or https URL is not resolved. That matters because a specification is often something you did not write, or did not vet, and a generator that follows remote references while parsing can be used to reach internal addresses. Turn it on only when you control the spec. The other is --default-include, which controls the default behaviour for x-mcp filtering and accepts true or false case-insensitively, with true meaning include by default and false meaning exclude by default. The x-mcp extension is a way for a spec to mark individual operations as exposed or hidden to MCP clients, and this flag decides what happens to operations that do not say. The default of true exposes everything, which is convenient and is a broad default, so if your API has endpoints you would rather not expose to an agent, flipping this to false is a one flag change with a large effect. --max-tool-name-length defaults to 64 because Claude Desktop caps tool names there, and longer names are truncated with a hash suffix so they stay unique.

Generating a project, and what the output directory contains

The generator writes a complete Node.js project rather than a single file, with tsconfig.json, package.json and an entry point, and the --force option controls whether existing files in the output directory are overwritten without confirmation. The scaffold is the point, because a usable MCP server needs a build step, a start script and a transport wiring, and generating that removes the most tedious part of the job. The npm installation is a single global command:

bash
npm install -g openapi-mcp-generator

The yarn and pnpm equivalents are noted in the documentation. The basic invocation points the tool at a specification and an output directory:

bash
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir

And the transport variants are the same command with a different flag, for a web server with SSE:

bash
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --transport=web --port=3000

or for StreamableHTTP, and for a Cloudflare Worker:

bash
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --transport=streamable-http --port=3000
bash
openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir --transport=cloudflare-worker

The project also ships built-in HTML test clients so you can exercise API interactions visually in a browser for the web based transports, and there are example projects in the repository for a pet store over SSE, a pet store over StreamableHTTP and a plain petstore MCP server. The package is published to npm under the name openapi-mcp-generator at version 4.1.0, with programmatic use also possible through getToolsFromOpenApi imported from the package.

Editorial conclusion

Adopt openapi-mcp-generator when you already publish a documented REST API and want MCP clients, including AI agents, to call it, and you would rather review generated code once than maintain a hand written server. Do not adopt it for an API with no specification, since the input is the spec, or if you need a server that owns the business logic, because the output proxies to your API rather than replacing it. Before you generate, check that the OpenAPI document has unambiguous servers entries or pass --base-url, decide whether x-mcp filtering should default to include or exclude operations, and read the generated auth.ts and the --insecure flag carefully before deploying the output.

Frequently asked questions

What does openapi-mcp-generator produce?

It generates a Model Context Protocol server from an OpenAPI 3.0 specification. The generated server proxies calls to your original REST API while validating request structure and security, using Zod schemas generated from the OpenAPI definitions.

How do I install and run openapi-mcp-generator?

Install it globally with `npm install -g openapi-mcp-generator`, then run it with `--input` pointing at the specification and `--output` at the target directory, for example `openapi-mcp-generator --input path/to/openapi.json --output path/to/output/dir`. The yarn and pnpm global equivalents are also documented.

Which transports can the generated MCP server use?

The --transport option accepts stdio, which is the default, web for SSE using Hono, streamable-http, and cloudflare-worker for a deployable Worker. The port for the web based transports defaults to 3000 and can be set with --port.

Does openapi-mcp-generator resolve external $ref references?

Not by default. The --allow-external-refs option is disabled by default specifically to prevent SSRF during parsing, so remote http and https references are only resolved when you enable it. The --default-include option controls x-mcp filtering and defaults to true, meaning operations are included unless they say otherwise.

Which authentication schemes does the generated server support?

API keys, Bearer tokens, Basic auth and OAuth2 are supported through environment variables. OAuth2 client credentials can be sent in the token request body with --oauth-creds-in-body, a custom scheme can be added through the generated src/auth.ts hook with --custom-auth, and --header-passthrough forwards named inbound headers to the upstream API.

Official sources

  1. harsha-iiiv/openapi-mcp-generator on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/harsha-iiiv-openapi-mcp-generator.svg)](https://hysenlabs.com/projects/harsha-iiiv-openapi-mcp-generator)

Was this useful?