mcp-openapix
MCP server that fronts any OpenAPI service behind four generic tools.
An agent finds operations in each deployment's OpenAPI document and calls them; the
server resolves the URL, obtains a bearer token, and builds the request. Discovery is
list_platforms, list_endpoints and describe_endpoint; execution is the generic
proxy call_endpoint.
example / us / items / prod
│ │ │ └── env ......... which deployment URL a call reaches
│ │ └───────── service ..... one backend, one OpenAPI spec
│ └─────────────── region ...... a geographic deployment
└───────────────────── platform .... the product or API family
Requirements
- Python 3.13+ and
uv - A
config.jsondescribing the deployments you hold credentials for
Quick start
Set up your config (see Configuration), then run the server:
# Run directly with uvx (no clone needed)
npx -y @modelcontextprotocol/inspector@latest uvx mcp-openapix
# Or run from source
npx -y @modelcontextprotocol/inspector@latest uv run mcp-openapix
Configuration
config.json MUST live at ~/.config/mcp-openapix/config.json
(%USERPROFILE%\.config\… on Windows). config.example.json is a full template.
{
"headers": { "accept": "application/json" },
"defaults": { "platform": "example", "region": "us", "service": "items", "env": "prod" },
"platforms": {
"example": {
"regions": {
"us": {
"services": {
"token_helper": "us",
"items": {
"desc": "Catalogue and inventory API",
"spec_path": "/swagger/v1/swagger.json",
"canonical_env": "prod",
"envs": {
"prod": { "url": "https://api.example.com/items" },
"dev": { "url": "https://api-dev.example.com/items" }
}
}
}
}
}
}
},
"token_helpers": {
"us": {
"command": "token-helper",
"args": ["issue"]
}
}
}
platforms
A hierarchy of platform → region → services → service → env. Each service declares:
| Field | Notes |
|---|---|
spec_path |
Required. The OpenAPI JSON endpoint relative to the service URL |
canonical_env |
Required when more than one env is configured — the env whose URL the spec is fetched from |
envs |
Required. One entry per deployment environment, each carrying a full base url |
desc |
Optional. A short description surfaced by list_platforms |
token_helper |
Optional. The token helper this level binds to |
The services object may also contain a token_helper default applying to all services
in that region. A service or environment can override it.
token_helpers
Named token helpers, in the same shape as an MCP server entry:
| Field | Required | Default | Notes |
|---|---|---|---|
command |
yes | — | Resolved on PATH; never run through a shell |
args |
no | [] |
Passed verbatim |
timeout |
no | 60 |
Seconds before the helper's process group is killed; at most 300 |
The config names a command and nothing else, so config.json holds no secrets.
The complete helper invocation and output contract is documented in
docs/token-protocol.md.
Which helper a call uses is resolved most-specific-first:
env.token_helper → service.token_helper → services.token_helper
→ region.token_helper → platform.token_helper → defaults.token_helper
If no level declares a helper, the deployment is unauthenticated. Omit
token_helper for public deployments.
headers
Constant headers added to every API call — for APIs that require a tenant, product or locale header:
"headers": { "accept": "application/json", "x-product": "example" }
defaults
Makes every tool argument optional: a call falls back to defaults.platform, .region,
.service, .env, .username and .token_helper when they are omitted.
Top-level options
| Field | Default | Notes |
|---|---|---|
truncate_threshold |
1024 |
Response bytes returned inline before truncating to a preview |
response_cache_ttl |
3600 |
Seconds a truncated body stays readable at its resource URI |
spec_refresh |
{"auto": true, "interval": 7} |
Background spec refresh; interval is days and MAY be fractional |
Tools
| Tool | Purpose |
|---|---|
list_platforms |
Every platform with its regions, services, and envs |
list_endpoints |
A service's operations, filtered by query, tag or method |
describe_endpoint |
One operation plus the transitive closure of the schemas it references |
call_endpoint |
Execute an operation, or a raw method + path absent from the spec |
Operation ids
Many OpenAPI documents omit operationId, so the server synthesizes one as "<METHOD> <path>":
POST /api/items
└─┬─┘ └───┬───┘
method path as the spec declares it
Where a spec does declare an operationId, that value wins.
Specs
Specs are not bundled. Each deployment's document is fetched on demand — an
unauthenticated GET — and cached under
~/.cache/mcp-openapix/{platform}/{region}/{service}.json.
A document MUST declare at least one operation before it is installed, so a deployment
answering 200 with an error body cannot replace a working snapshot with one that
serves nothing.
Cached specs refresh in the background: once at startup, then every
spec_refresh.interval days. Set auto to false to stop it; the manual lever still
works:
uvx mcp-openapix --refresh
MCP resources
| Resource URI | Description |
|---|---|
openapi://responses/{request_id} |
Full body of a truncated call_endpoint response |
openapi://curl/{request_id} |
Equivalent curl command for a call_endpoint request |
Both expire response_cache_ttl seconds after the call. The curl command may embed
a short-lived token.
Tokens at rest
Tokens are cached in memory and, when expiry metadata is available, under
~/.cache/mcp-openapix/tokens/ (mode 0600) keyed by the token-helper declaration
and username. This lets client sessions share a login without spawning a helper each.
A 401 retires the cached token so the next call obtains a fresh one. To clear them all:
uvx mcp-openapix --logout
MCP host examples
Cursor / Claude Code
{
"mcpServers": {
"openapi": { "command": "uvx", "args": ["mcp-openapix"] }
}
}
Codex
[mcp_servers.openapi]
command = "uvx"
args = ["mcp-openapix"]
Development
uv sync --extra dev
uv run ruff check .
uv run ruff format --check .
uv run pyright
uv run pytest
All four MUST pass; see AGENTS.md. Tests use
respx to mock HTTP and real subprocesses for
token helpers, so no live API access is required.
License
MIT.
Release files for mcp-openapix 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| mcp_openapix-0.1.0.tar.gz | 104.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| mcp_openapix-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 145.7 kB
Release files / mcp_openapix-0.1.0.tar.gz
| Download URL | mcp_openapix-0.1.0.tar.gz |
|---|---|
| Size | 104.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
48313c9da425a6fd8de0af66764aff58e7055827a13b25f6ab748dd36eedd739
|
|
BLAKE2b-256 checksum How to use checksums |
7552e440cc08a898417a10d4d4f1c2aa7744b23fba1a9d734ff06083ca379da3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency logRelease files / mcp_openapix-0.1.0-py3-none-any.whl
| Download URL | mcp_openapix-0.1.0-py3-none-any.whl |
|---|---|
| Size | 41.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
733980c4a4a61dc4f3f806e4bbed8ea5882243af6247f7ab2ce051846faada5b
|
|
BLAKE2b-256 checksum How to use checksums |
f8cfc0913a50450ded0d8d94edc81eb14d55884872d26944f79f1db56b4a7985
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
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 Sep 21, 2026.
Transparency log