Skip to main content

openapi-mcp-hub

Turn any OpenAPI spec — or a live PostgreSQL / MySQL database — into production-ready MCP endpoints. One process. One port. Zero code.

CI License: MIT Python 3.10+ 中文文档

demo

Install: pip install openapi-mcp-hub or uvx openapi-mcp-hub · Python 3.10+ · MIT

POST an openapi.json to the gateway and you instantly get an MCP endpoint any agent can call:

POST /services        →   http://your-gateway:20033/mcp/{service-name}

No wrapper code. No per-spec deployment. No port sprawl. Register as many services as you like — REST APIs or read-only databases — all behind a single port, hot-loaded the moment they register.

🇨🇳 中文文档看这里 · 📖 Full usage guide: USAGE.md (中文)


Why

  • OpenAPI/Swagger is the de-facto standard for describing REST APIs — most internal services already have a spec.
  • MCP (Model Context Protocol) is how agents consume tools — Claude Code and friends speak it natively over Streamable HTTP.
  • Hand-writing MCP wrappers for every endpoint is repetitive and drifts out of sync. Running one MCP server per spec means port sprawl and linear ops cost.

openapi-mcp-hub is a gateway: one resident process, one port, path-level multi-tenancy (/mcp/{service}). Registration takes effect immediately — no restarts.

Public 2026 MCP ecosystem reports keep finding the same pain: only ~8.5% of MCP servers use OAuth, and tool-poisoning / rug-pull changes go unnoticed until an agent misbehaves. That is why this gateway treats data-plane auth and tool-change visibility as first-class features, not enterprise add-ons.

             ┌──────────── admin plane (admin token) ─────────────┐
             │  POST /services            register (REST or DB)   │
             │  GET  /services            list / inspect          │
             │  POST /services/preview    dry-run registration    │
             └────────────────────┬───────────────────────────────┘
                                  ▼
   Agents ── MCP (streamable HTTP / SSE) ──▶  openapi-mcp-hub gateway  ── HTTP ──▶  your APIs
   Claude Code, Cursor, custom clients        single port :20033   ── SQL ──▶  PostgreSQL / MySQL 8+
                                             per-service api_key

Quickstart — 60 seconds

git clone https://github.com/zhangjk1207/openapi-mcp-hub && cd openapi-mcp-hub
docker compose up -d       # gateway + PostgreSQL + demo API, auto-registers a petstore service

Open http://localhost:20033 and paste the demo admin token: demo-admin-token — the console shows a ready-to-use petstore service (fixed demo key, listed below).

Try the agent-callable endpoint right away:

curl -X POST http://localhost:20033/mcp/petstore \
  -H "X-Api-Key: psk-demo-petstore-key" -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_pets","arguments":{"limit":3}}}'

And in Claude Code:

claude mcp add --transport http petstore http://localhost:20033/mcp/petstore \
  --header "X-Api-Key: psk-demo-petstore-key"

The demo mode (OPENAPI_MCP_HUB_DEMO=1 in docker-compose.yml) uses a fixed, publicly-documented key for a friction-free tour. Turn it off (and change OPENAPI_MCP_HUB_ADMIN_TOKEN) before any real use — real registrations always mint a fresh one-time key.

Register your own API

ADMIN_TOKEN=demo-admin-token

# spec_text receives the raw file content (JSON or YAML)
jq -n --rawfile s your-openapi.json '{name:"my-api", base_url:"https://api.example.com", spec_text:$s}' | \
  curl -X POST http://localhost:20033/services \
    -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" -d @-

Connect it to Claude Code (the response includes a ready-to-run command):

claude mcp add --transport http my-api http://localhost:20033/mcp/my-api \
  --header 'X-Api-Key: psk-xxxx'

That's it — your API's operations are now agent-callable tools.

Register a database instead of an API

No REST spec needed. Point the gateway at a database (via an environment variable name — the DSN itself never touches disk):

export WORKFLOW_DB_URL='postgresql://ro_user:pass@db.internal.example:5432/workflow'
curl -X POST http://localhost:20033/services \
  -H "Authorization: Bearer $ADMIN_TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"workflow-db","db":{"url_env":"WORKFLOW_DB_URL"}}'

You get three tools the agent can use blind: list_tables, describe_table (schema + comments embedded), and query (SELECT-only).

Read-only is enforced in six layers

Layer What it does
Lexical whitelist First token must be SELECT/WITH/EXPLAIN; comments blocked; string literals respected
READ ONLY transactions Server-enforced — writes fail even if they slip past the lexer (PG / MySQL 8+)
Outer LIMIT wrap SELECT * FROM (your SQL) sub LIMIT max_rows+1 — result size capped regardless
Statement timeout statement_timeout (PG) / max_execution_time (MySQL) per pool
Isolated pool Separate connection pool per service, minsize=1, maxsize=5
Table filtering include_tables / exclude_tables at introspection time

Credentials are referenced by env var name only — nothing sensitive is persisted or logged. SQL digests land in the in-memory call log for auditing.

Features

Sources OpenAPI 3.0/3.1, Swagger 2.0 (auto-normalized), spec URL with SSRF allowlist, JSON/YAML upload, PostgreSQL, MySQL 8+
Transport Streamable HTTP + legacy SSE (/mcp/{name}/sse) on one port
Multi-tenant security Per-service api_key (shown once, stored hashed, rotatable), admin token for the management plane
MCP data-plane auth Static key or JWT as an OAuth 2.1 resource server: external IdP (RS256/ES256 + JWKS + issuer/audience checks, RFC 9728 discovery, WWW-Authenticate on 401) or built-in issuance (HS256, short-TTL, aud bound to the service)
Tool-poisoning visibility Every update/refresh returns a tool-set diff (added / removed / description_changed / input_schema_changed) plus a human-review warning when descriptions change — descriptions are the LLM's instruction surface
Target API auth Bearer / API key / Basic / OAuth2 client_credentials — token fetched, cached & auto-refreshed by the gateway (one 401 retry); credentials referenced by env var name only, token_url allowlist-checked at registration
Hot registration Register / update / delete without restarts; failures roll back atomically; spec_url sources re-pull via refresh (key preserved)
Filtering Path include/exclude globs, tool whitelist, max_tools cap, response templates
Persistence JSON file or PostgreSQL backend, automatic one-way migration
Console Single-file admin UI, zero build chain, zero external assets — works in air-gapped intranets
Observability Health probes, in-memory ring call log (last 20/service), call stats (ok-rate / p50 / p95 / top tools), structured error codes (-32000/-32602/-32002)

Comparison

openapi-mcp-hub one-MCP-server-per-spec general API gateways + MCP plugin
New service POST a spec, ~1s Write & deploy a wrapper Plugin config + reload
Ports 1 N 1 (heavyweight)
Database → MCP Built-in, read-only enforced Separate project Rarely
Air-gapped console Yes, single HTML file — Usually needs internet
MCP data-plane auth (OAuth 2.1 resource server) Built-in, free — Kong AI Gateway: RBAC/OIDC requires the paid Enterprise tier; Zuplo: SaaS
Tool-poisoning visibility Tool-set diff + review warning on every update/refresh — Rarely
Runtime deps FastAPI + mcp SDK (~10 packages) varies Full gateway stack

Security posture

Everything below ships in the free, self-hosted, single-binary build:

Layer Mechanism
Management plane OPENAPI_MCP_HUB_ADMIN_TOKEN (env only); all admin routes require it
Data plane (static mode) Per-service X-Api-Key, shown once, stored as SHA-256 hash, rotatable via rotate-key
Data plane (JWT mode) Authorization: Bearer — external IdP: RS256/ES256 via JWKS (cached 300s, kid rotation aware), iss/aud enforced, algorithms whitelisted (no alg-confusion); built-in: HS256 with OPENAPI_MCP_HUB_JWT_SECRET (env only, never persisted), TTL ≤ 24h, aud bound to the service name. RFC 9728 metadata at /.well-known/oauth-protected-resource/mcp/{name} so spec-native clients (e.g. Claude Code) can discover your IdP
SSRF Three layers: registration-time host allowlist, per-hop re-check on redirects, response timeouts
Secrets at rest Target-API credentials referenced by env var names only — nothing sensitive is persisted
Database tools Six-layer read-only (see above)
Tool poisoning tool_changes diff + human-review warning whenever tool descriptions change on update/refresh

JWT mode in three commands (built-in issuance):

export OPENAPI_MCP_HUB_JWT_SECRET="$(openssl rand -hex 32)"
# register with authn={"mode":"jwt"} (see USAGE.md for external-IdP mode)
curl -X POST $GW/services -H "Authorization: Bearer $ADMIN" -d '{"name":"crm","spec_url":"...","base_url":"...","authn":{"mode":"jwt"}}'
curl -X POST $GW/services/crm/token -H "Authorization: Bearer $ADMIN" -d '{"ttl_s":3600}'
# → use the returned token as: Authorization: Bearer <token>

Console screenshots

Real console, not mockups — REST and database sources in one table, generated tool sets, health probes and key rotation, all from a single static page: no build chain, no external assets, works air-gapped.

Services — REST and database sources side by side, /mcp/{name} per row:

Services list

Service detail — endpoint, generated tools with descriptions, health probe, key rotation:

Service detail

Register a REST API — spec upload / paste, path filters, target auth by env var name:

Register a REST API

Register a database — DSN referenced by env var name only, read-only tool trio generated:

Register a database

Roadmap

  • v0.4.0 — JWT data-plane auth (OAuth 2.1 resource server, RFC 9728) · tool-poisoning drift diff on update/refresh
  • v0.3.0 — OAuth2 client_credentials target auth · spec refresh endpoint · call stats · console auth fix
  • M5-1 — Database → MCP (PostgreSQL + MySQL 8, six-layer read-only)
  • M5-2 — per-table tool mode, sensitive-column masking
  • M5-3 — write operations (opt-in, statement allowlist)
  • Metrics endpoint (Prometheus) & key expiry
  • Per-tenant quotas / rate limiting
  • Per-service circuit breaking

Not implemented today — do not plan around these: circuit breaking, per-tenant rate limiting or quotas, HA / multi-replica coordination, Prometheus metrics, database write operations, per-table database tools, API-key expiry. Safety isolation today is per-service httpx client + independent timeout + connection-pool cap + the SSRF allowlist, all inside a single process.

Development

pip install -e ".[dev]"
pytest tests/ -q          # 178 pass; 22 opt-in integration tests skip without PG/MySQL DSNs

License

MIT

Metadata

Release files for openapi-mcp-hub 0.4.1

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

Source distribution (sdist)

Source distribution for openapi-mcp-hub 0.4.1
File Size Uploaded Provenance Actions
openapi_mcp_hub-0.4.1.tar.gz 115.7 kB With provenance Details for openapi_mcp_hub-0.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for openapi-mcp-hub 0.4.1
File Interpreter ABI Platform Actions
openapi_mcp_hub-0.4.1-py3-none-any.whl Python 3 none any Details for openapi_mcp_hub-0.4.1-py3-none-any.whl

Total release size: 200.0 kB

Release files / openapi_mcp_hub-0.4.1.tar.gz

Download URL openapi_mcp_hub-0.4.1.tar.gz
Size 115.7 kB
Tags Source
SHA-256 checksum
How to use checksums
85260ba200c9f61ec4c7a30610c4b309b105a7eb6b18b67c1f4794d82942e8e4
BLAKE2b-256 checksum
How to use checksums
119595e975f39994996845f89100633118fe8cb99332905d1f13cd997e1181fb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Release files / openapi_mcp_hub-0.4.1-py3-none-any.whl

Download URL openapi_mcp_hub-0.4.1-py3-none-any.whl
Size 84.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b68fc1e2c1ab92ded1698a26eed0f02d90cd101f99af806850dd8d931d3a751
BLAKE2b-256 checksum
How to use checksums
d698f2bd6349e642ec68e0b1523f2b5166ba41f5b36ac2047cc02b2055885a69
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

Security for openapi-mcp-hub 0.4.1

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.

Full provenance

Both files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for openapi_mcp_hub-0.4.1.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 26, 2026.

Transparency log

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.4.1 This release

2 release files Full 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