Skip to main content

api2mcp logo

api2mcp

Turn any OpenAPI spec into a working MCP server. One command.

License: MIT Python 3.10+ PyPI GitHub stars

api2mcp https://petstore3.swagger.io/api/v3/openapi.json

That's it. You now have a runnable MCP server exposing every endpoint in that API as a tool an LLM agent can call — typed arguments, docstrings, auth wiring, all generated.

api2mcp terminal demo


The problem

Want Claude (or any MCP-compatible agent) to use Stripe, GitHub, your internal REST API, whatever? Right now that means hand-writing an MCP server: read the docs, define a tool per endpoint, map params, wire up auth, keep it in sync when the API changes.

Almost every API already publishes an OpenAPI/Swagger spec describing exactly that shape. api2mcp reads it and generates the server for you.

Install

pip install spec2mcp

(The PyPI package is named spec2mcp — api2mcp was already taken. The CLI command and import name are still api2mcp.)

Usage

api2mcp <spec-url-or-file> [-o output-dir]

Works with a spec URL, a local .json file, or a local .yaml/.yml file.

Example

$ api2mcp https://petstore3.swagger.io/api/v3/openapi.json -o ./petstore-mcp
Fetching spec from https://petstore3.swagger.io/api/v3/openapi.json ...
Generated 19 tools for 'Swagger Petstore - OpenAPI 3.0'
-> petstore-mcp/server.py
-> petstore-mcp/README.md

Run it:
  cd petstore-mcp && pip install "mcp[cli]" requests && python server.py

Run the generated server, then point any MCP client at it — Claude Desktop, Claude Code, or your own agent — and every endpoint (findPetsByStatus, addPet, deletePet, …) is now a callable tool.

Point Claude Desktop / Claude Code at it

Add to your MCP client config (e.g. claude_desktop_config.json):

{
  "mcpServers": {
    "petstore": {
      "command": "python",
      "args": ["/absolute/path/to/petstore-mcp/server.py"],
      "env": {
        "API_BASE_URL": "https://petstore3.swagger.io/api/v3",
        "API_KEY": "your-key-if-needed"
      }
    }
  }
}

Auth

Set env vars before running the generated server:

  • API_BASE_URL — overrides the base URL detected from the spec
  • API_KEY — sent as Authorization: Bearer <API_KEY> on every request

Use it as a library instead of the CLI

from api2mcp import parse_spec, write_server

spec = parse_spec("https://petstore3.swagger.io/api/v3/openapi.json")
write_server(spec, "./out")

What gets generated

For every operation in the spec, one @mcp.tool()-decorated function:

@mcp.tool()
def findpetsbystatus(status: str = "") -> dict:
    """Finds Pets by status."""
    ...
    resp = requests.request("GET", url, params=params, json=json_body, headers=_headers(), timeout=30)
    resp.raise_for_status()
    return resp.json()
  • Path, query, and JSON body params become typed Python arguments (required params ordered before optional ones, so it's always valid Python)
  • The summary/description from the spec becomes the tool's docstring — that's what the LLM sees when deciding whether to call it
  • A README.md listing every generated tool ships alongside server.py

The output is plain, readable code — not a black box. Generate it, read it, edit it by hand if you need something custom.

How it works

flowchart LR
    A["OpenAPI spec\n(URL or file)"] --> B["parser.py\nflatten paths → Operations"]
    B --> C["generator.py\nJinja2 template"]
    C --> D["server.py\none @mcp.tool()\nper endpoint"]
    D --> E["MCP client\n(Claude Desktop / Claude Code)"]
    E -->|calls tool| F["your API"]
    F -->|response| E
  1. Parse (api2mcp/parser.py) — loads the spec (JSON or YAML, URL or file), walks paths, flattens each operation's parameters and request body into a simple typed Operation model.
  2. Generate (api2mcp/generator.py + templates/server.py.j2) — renders a Jinja2 template into a single-file MCP server using the official mcp Python SDK.
  3. Run — the generated server is a normal Python script; mcp.run() speaks the MCP protocol over stdio.

No LLM calls involved in generation — it's pure codegen from the spec's structure, so it's fast, free, and deterministic.

Development

git clone https://github.com/azamoviich/api2mcp
cd api2mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,serve]"
pytest

Limitations (v1)

  • No OAuth2 flows — only static bearer token auth via API_KEY
  • $ref resolution for request bodies is shallow (one level)
  • No pagination helpers — generated tools return raw responses as-is

Contributions welcome for any of the above.

License

MIT — see LICENSE.

Metadata

Release files for spec2mcp 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for spec2mcp 0.2.0
File Size Uploaded Provenance Actions
spec2mcp-0.2.0.tar.gz 262.5 kB Without provenance Details for spec2mcp-0.2.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for spec2mcp 0.2.0
File Interpreter ABI Platform Actions
spec2mcp-0.2.0-py3-none-any.whl Python 3 none any Details for spec2mcp-0.2.0-py3-none-any.whl

Total release size: 272.5 kB

Release files / spec2mcp-0.2.0.tar.gz

Download URL spec2mcp-0.2.0.tar.gz
Size 262.5 kB
Tags Source
SHA-256 checksum
How to use checksums
7866da6007a2ca8a06cd99fd6f8d93350a6a6914f8627fe4d7e7c5599cb0275d
BLAKE2b-256 checksum
How to use checksums
f25263479b6310f21d0f19f5810c402b5777047163fbd9e6b8831cac3a25f6fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Release files / spec2mcp-0.2.0-py3-none-any.whl

Download URL spec2mcp-0.2.0-py3-none-any.whl
Size 9.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b82733b6611a515e784999575271756fe78b7960e76b3417a9a64a0e67638f92
BLAKE2b-256 checksum
How to use checksums
cf83504fdc4ed04075fad1dd0853de7e93e90386b0e3872751c40d893455b4af
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.6

Security for spec2mcp 0.2.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page