mcpgen
Health Pass
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 14 GitHub stars
Code Pass
- Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Turn any OpenAPI spec or Postman collection into an ownable Python MCP server in 30 seconds
Point mcpgen at an OpenAPI spec or Postman collection. Get back a complete Python MCP server you own — no runtime dependency on mcpgen, no proxy, no lock-in. Read it. Modify it. Ship it.
Install
pip install mcpgen-cli
Quickstart
# From a URL
mcpgen https://petstore3.swagger.io/api/v3/openapi.json
# From a local OpenAPI file (JSON or YAML)
mcpgen stripe.yaml
# From a Postman collection
mcpgen postman_collection.json
# Preview without writing anything
mcpgen openapi.json --dry-run
# Custom output directory and server name
mcpgen openapi.json --output ~/my-mcp-servers --name "My API"
That's it. mcpgen reads your spec and writes a Python MCP server to disk.
What you get
A self-contained directory with source code you own:
stripe_api_mcp/
├── server.py ← the MCP server (read it, edit it, it's yours)
└── requirements.txt ← httpx, mcp
Run it immediately:
cd stripe_api_mcp
pip install -r requirements.txt
export STRIPE_API_TOKEN="sk_live_..."
python server.py
The generated server.py looks like this:
#!/usr/bin/env python3
"""
Stripe API MCP Server
Generated by mcpgen — https://github.com/JnanaSrota/mcpgen
This file is yours. Modify it freely.
"""
import os, asyncio, httpx
from mcp.server import Server
from mcp.server.stdio import stdio_server
from mcp import types
BASE_URL = "https://api.stripe.com"
AUTH_TOKEN = os.environ.get("STRIPE_API_TOKEN", "")
app = Server("stripe-api")
@app.call_tool()
async def _handle_get_customers(name: str, arguments: dict):
if name != "get_customers":
raise ValueError(f"Unknown tool: {name}")
url = BASE_URL + "/v1/customers"
query_params = {}
if "limit" in arguments:
query_params["limit"] = arguments["limit"]
async with httpx.AsyncClient(timeout=30.0) as client:
response = await client.get(url, params=query_params,
headers={"Authorization": f"Bearer {AUTH_TOKEN}"})
response.raise_for_status()
return [types.TextContent(type="text", text=response.text)]
# ... one function per API endpoint
@app.list_tools()
async def list_tools(): ...
if __name__ == "__main__":
asyncio.run(stdio_server(app))
No black box. No dependencies at runtime. Just Python.
Add to Claude Desktop
mcpgen prints the exact config snippet to paste into your claude_desktop_config.json:
{
"mcpServers": {
"stripe-api-mcp": {
"command": "python",
"args": ["/path/to/stripe_api_mcp/server.py"],
"env": { "STRIPE_API_TOKEN": "your-key-here" }
}
}
}
Config file location:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
Why source code instead of a proxy?
Most API-to-MCP tools are runtime proxies — they sit between Claude and your API forever, and you depend on them to stay running.
mcpgen generates source code you own. The output is a plain Python file. You can:
- Read every line of what's happening
- Modify auth logic, add retries, adjust error handling
- Deploy it anywhere without any dependency on
mcpgen - Commit it to your own repo, version it, review it in PRs
mcpgen is a build tool. Needed once, at generation time. Never at runtime.
Supported inputs
| Format | Example |
|---|---|
| OpenAPI 3.x JSON | mcpgen openapi.json |
| OpenAPI 3.x YAML | mcpgen api.yaml |
| URL pointing to OpenAPI spec | mcpgen https://api.example.com/openapi.json |
| Postman Collection v2.1 | mcpgen collection.json |
Tested with:
- Petstore — 19 endpoints → 19 tools
- GitHub REST API (subset)
- Stripe API (subset)
- Any valid OpenAPI 3.x spec
Auth support
mcpgen auto-detects your API's auth scheme from the spec:
| Scheme | OpenAPI declaration | Generated env var |
|---|---|---|
| Bearer token | type: http, scheme: bearer |
YOUR_API_TOKEN |
| API Key | type: apiKey |
YOUR_API_API_KEY |
| Basic Auth | type: http, scheme: basic |
YOUR_API_CREDENTIALS |
| None | No securitySchemes |
— |
OAuth2 flows are approximated as bearer token — you supply the token manually.
CLI reference
Usage: mcpgen [OPTIONS] INPUT
Turn any API into an MCP server in 30 seconds.
Arguments:
INPUT OpenAPI JSON/YAML file, Postman collection, or URL [required]
Options:
-o, --output PATH Output directory (default: current directory)
-n, --name TEXT Override the generated server name
--dry-run Print generated code without writing files
--no-color Disable colored output
-v, --version Show version and exit
--help Show this message and exit
Roadmap
- TypeScript output (
--lang ts) using@modelcontextprotocol/sdk - Swagger 2.x support (auto-detected, separate parser)
- Auto-detect OpenAPI URL from base domain (
/.well-known/openapi.json,/api-docs, etc.) -
--update-claude-configflag to patchclaude_desktop_config.jsonautomatically - Recursive
$refresolution for deeply nested schemas
PRs welcome. See CONTRIBUTING.md.
Contributing
git clone https://github.com/JnanaSrota/mcpgen
cd mcpgen
pip install -e ".[dev]"
pytest tests/ -v
The codebase has three clean layers:
Input (file / URL)
↓
loader.py ← detects format, routes to correct parser
↓
openapi.py / postman.py ← parse to MCPSpec (internal IR)
↓
generator/python.py ← renders Jinja2 templates → server.py
To add a new input format: write a parser that returns MCPSpec. Nothing else changes.
To add a new output language: write a generator that consumes MCPSpec. Nothing else changes.
License
MIT — the generated code is yours to do whatever you want with.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found