Turn any OpenAPI specification into a Model Context Protocol (MCP) server with a single command.
Project description
OpenAPI MCP Gateway
Turn any OpenAPI specification into a Model Context Protocol (MCP) server with a single command.
openapi-mcp-gateway --spec https://petstore3.swagger.io/api/v3/openapi.json
# Server live at http://127.0.0.1:8000/api/mcp
- No code generation. Point it at a spec and every operation becomes an MCP tool.
- Multi-API. Run several OpenAPI services in one process, each on its own mount path.
- Auth built in. Bearer, API Key, and OAuth2 (with per-user delegation).
- Flexible transport. Streamable HTTP, SSE, or stdio.
Table of Contents
Installation
pip install openapi-mcp-gateway
Or with uv:
uv add openapi-mcp-gateway
Optional extras:
pip install "openapi-mcp-gateway[redis]" # Redis token store
Requires Python 3.11+.
Quick Start
1. Public API, No Auth
openapi-mcp-gateway --spec https://petstore3.swagger.io/api/v3/openapi.json --name petstore
Connect an MCP client to http://127.0.0.1:8000/petstore/mcp.
2. Bearer Token
export GITHUB_TOKEN="ghp_..."
openapi-mcp-gateway \
--spec https://raw.githubusercontent.com/github/rest-api-description/main/descriptions/api.github.com/api.github.com.json \
--name github \
--auth-type bearer \
--auth-token '${GITHUB_TOKEN}'
3. OAuth2 (Auto-Detected from Spec)
export ASANA_CLIENT_ID="..." ASANA_CLIENT_SECRET="..."
openapi-mcp-gateway \
--spec https://raw.githubusercontent.com/Asana/openapi/master/defs/asana_oas.yaml \
--name asana \
--auth-type oauth2 \
--auth-client-id '${ASANA_CLIENT_ID}' \
--auth-client-secret '${ASANA_CLIENT_SECRET}' \
--auth-scopes "openid,email,profile,users:read,workspaces:read"
4. Multiple APIs at Once
# servers.yml
host: "0.0.0.0"
port: 8000
servers:
- name: petstore
spec: https://petstore3.swagger.io/api/v3/openapi.json
- name: github
spec: ./openapi/github.json
auth:
type: bearer
token: ${GITHUB_TOKEN}
policy:
allow: ["GET /repos/*", "GET /users/*"]
openapi-mcp-gateway --config servers.yml
Runnable examples live in examples/. Each YAML lists its prerequisites at the top.
5. Local Desktop Client (stdio)
For Claude Desktop, IDE integrations, or any MCP client that prefers stdio:
{
"mcpServers": {
"petstore": {
"command": "openapi-mcp-gateway",
"args": ["--spec", "/abs/path/to/openapi.json", "--transport", "stdio"]
}
}
}
Authentication
| Type | Use Case | Required Fields |
|---|---|---|
none |
Public APIs | |
bearer |
Personal access tokens, API tokens | token |
api_key |
API key in X-API-Key header (override with auth.api_key_header) |
token |
oauth2 |
Per-user delegated access | client_id, client_secret |
All string fields support ${ENV_VAR} and ${ENV_VAR:-default} interpolation, resolved at request time:
auth:
type: bearer
token: ${GITHUB_TOKEN}
OAuth2 Details
authorizationUrl, tokenUrl, and scopes are read from the spec's securitySchemes. Override auth.authorization_url, auth.token_url, or auth.scopes when the spec is incomplete.
Configuration
Run openapi-mcp-gateway --help for the CLI reference. For YAML config, the Quick Start examples cover most setups; the full field reference:
Top-Level Fields
| Field | Type | Default | Description |
|---|---|---|---|
host |
string | 0.0.0.0 |
Bind address (0.0.0.0 = all interfaces). Clients on the same machine usually open http://localhost:{port} or http://127.0.0.1:{port}. |
port |
int | 8000 |
Bind port |
url |
string | (empty) | Public base URL for OAuth redirects and discovery. When unset: http://localhost:{port} if host is 0.0.0.0, otherwise http://{host}:{port}. Override when your registered redirect URI uses another host (tunnel, reverse proxy, etc.). |
transport |
string | streamable-http |
sse, streamable-http, or stdio |
store.type |
string | memory |
memory or redis |
store.redis_url |
string | redis://localhost:6379 |
Redis URL when store.type: redis |
logging.level |
string | INFO |
DEBUG, INFO, WARNING, ERROR, CRITICAL |
logging.format |
string | text |
text or json |
logging.file |
string | Mirror logs to this file | |
servers |
list | required | List of per-server config entries |
Per-Server Fields
| Field | Type | Default | Description |
|---|---|---|---|
name |
string | required | Unique identifier; mount path defaults to /{name} |
spec |
string | required | Path or URL to OpenAPI document (JSON or YAML) |
base_url |
string | from spec | Override the upstream base URL |
auth.* |
See Authentication | ||
policy.allow |
list | Only expose matching operations | |
policy.deny |
list | Exclude matching operations | |
timeout |
float | 90 |
HTTP timeout in seconds |
Filtering Operations
Use policy.allow and policy.deny with fnmatch syntax against operation IDs (getUsers, create*) or method + path (GET /users/*):
policy:
allow: ["GET /repos/*"]
deny: ["GET /repos/*/actions/secrets*"]
Or mark operations directly in the spec and enable marked_only:
# openapi.yml
paths:
/users:
get:
operationId: listUsers
x-mcp-integration:
expose:
tool: {}
# servers.yml
policy:
marked_only: true
Filters apply in order: marked_only, then allow, then deny.
Logging
Configure via the logging.* YAML keys or via CLI flags. -v and -q are shortcuts for DEBUG and WARNING.
Python API
Use the gateway as a library inside your own Python application:
from openapi_mcp_gateway import Gateway
gateway = Gateway()
gateway.add_server(
name="petstore",
spec="https://petstore3.swagger.io/api/v3/openapi.json",
)
gateway.add_server(
name="github",
spec="./github-openapi.json",
auth={"type": "bearer", "token": "${GITHUB_TOKEN}"},
policy={"allow": ["GET /repos/*"]},
)
gateway.run(port=8000)
Or mount into an existing FastAPI app:
from fastapi import FastAPI
from openapi_mcp_gateway import Gateway
app = FastAPI()
gateway = Gateway()
gateway.add_server(name="petstore", spec="petstore.json")
gateway.mount(app)
License
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file openapi_mcp_gateway-0.1.0.tar.gz.
File metadata
- Download URL: openapi_mcp_gateway-0.1.0.tar.gz
- Upload date:
- Size: 112.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
44a4f8456ca2c0fefb1f2b1c8014e314e5102b410f60a9849e52472e6ecdd6fb
|
|
| MD5 |
2f717514e3f09b21a6611d377a927f30
|
|
| BLAKE2b-256 |
5ad6f7c30b583c26b4527e2a019d85cf98212ef9f26c3dbd309c8fd3c2eca2f2
|
Provenance
The following attestation bundles were made for openapi_mcp_gateway-0.1.0.tar.gz:
Publisher:
release.yml on mroops0111/openapi-mcp-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_mcp_gateway-0.1.0.tar.gz -
Subject digest:
44a4f8456ca2c0fefb1f2b1c8014e314e5102b410f60a9849e52472e6ecdd6fb - Sigstore transparency entry: 1426098391
- Sigstore integration time:
-
Permalink:
mroops0111/openapi-mcp-gateway@89a49fb47f7054ab9474da3ada8a6f833a745881 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mroops0111
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@89a49fb47f7054ab9474da3ada8a6f833a745881 -
Trigger Event:
push
-
Statement type:
File details
Details for the file openapi_mcp_gateway-0.1.0-py3-none-any.whl.
File metadata
- Download URL: openapi_mcp_gateway-0.1.0-py3-none-any.whl
- Upload date:
- Size: 34.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
25ae54a219b747899e2e43a0bf4a96a89b72f0c9e9b52f68737cfcbb6538b4d0
|
|
| MD5 |
88c745bc993e13a3593841b23319ae62
|
|
| BLAKE2b-256 |
3985e1d3880a9510e826d83ad7ddb0542fed6f0ba3472f1636f8ffbef366ebd9
|
Provenance
The following attestation bundles were made for openapi_mcp_gateway-0.1.0-py3-none-any.whl:
Publisher:
release.yml on mroops0111/openapi-mcp-gateway
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
openapi_mcp_gateway-0.1.0-py3-none-any.whl -
Subject digest:
25ae54a219b747899e2e43a0bf4a96a89b72f0c9e9b52f68737cfcbb6538b4d0 - Sigstore transparency entry: 1426098512
- Sigstore integration time:
-
Permalink:
mroops0111/openapi-mcp-gateway@89a49fb47f7054ab9474da3ada8a6f833a745881 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/mroops0111
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@89a49fb47f7054ab9474da3ada8a6f833a745881 -
Trigger Event:
push
-
Statement type: