OpenAPI Services

Official registry Developer tools

MCP server that fronts any OpenAPI service: discover operations from its spec and call them

Install

Add this to your client's MCP configuration (Claude Desktop: claude_desktop_config.json; Cursor: .cursor/mcp.json; VS Code and others use the same "mcpServers" shape).

PYPI package mcp-openapix
Claude Code
claude mcp add openapi-services -- uvx mcp-openapix==0.2.1
JSON configuration (Claude Desktop, Cursor, VS Code)
{
    "mcpServers": {
        "openapi-services": {
            "command": "uvx",
            "args": [
                "mcp-openapix==0.2.1"
            ]
        }
    }
}

Documentation

From the project's README on GitHub, refreshed weekly. Links open on GitHub.

Contents
  1. mcp-openapix
  2. Requirements
  3. Quick start
  4. Configuration
  5. Tools
  6. Specs
  7. MCP resources
  8. Tokens at rest
  9. MCP host examples
  10. Development
  11. License

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.json describing 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:

FieldNotes
spec_pathRequired. The OpenAPI JSON endpoint relative to the service URL
canonical_envRequired when more than one env is configured — the env whose URL the spec is fetched from
envsRequired. One entry per deployment environment, each carrying a full base url
descOptional. A short description surfaced by list_platforms
token_helperOptional. 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:

FieldRequiredDefaultNotes
commandyes—Resolved on PATH; never run through a shell
argsno[]Passed verbatim
timeoutno60Seconds 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
FieldDefaultNotes
truncate_threshold4096Response bytes returned inline before truncating to a preview
response_cache_ttl3600Seconds 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
Splitting the config

A stray comma while editing one platform takes down every platform: a parse failure precedes per-platform validation. The config MAY therefore be split into drop-in files under config.d/, in the style of an nginx conf.d. The recommended layout keeps server-wide settings in config.json and gives each platform its own file, named after it:

~/.config/mcp-openapix/
├── config.json      # defaults, headers, token_helpers, top-level options
└── config.d/
    ├── acme.json    # {"platforms": {"acme": …}}
    └── public.json  # {"platforms": {"public": …}}

A typo then costs one platform, and a platform can be handed over, or removed, as a single file. Token helpers stay in config.json because they are usually shared across platforms; a helper only one platform uses MAY live beside it in that platform's file.

The layout is a convention, not a rule:

  • config.json is read first, then every *.json directly in config.d/ in sorted order. Subdirectories, .bak and editor swap files are ignored; no config.d/ means no change in behavior.
  • A drop-in MAY declare anything config.json may, and config.json MAY be nearly empty.
  • Files merge as if pasted into one config in that order: objects merge key by key, and a later scalar or list replaces the earlier one. A later file can therefore override a single envs.prod.url or one defaults field.

A file that fails to parse costs only what it declares; the rest keep working. A malformed platform, in any file, MUST NOT stop the others loading, and neither does a missing token helper it names: its error lists any files that were skipped, since the helper may be declared in one. list_platforms shows a platform that failed with no regions and the loader's error, and a skipped file as {"file", "error"}; calling into a failed platform returns the same message. Defaults that point into a failed platform are ignored. An invalid setting outside platforms still stops the server, and the message names the file that set it.

A fix needs a restart. Check the config first, without starting the server; it also lists every value a later file overrode:

uvx mcp-openapix --check-config

Tools

ToolPurpose
list_platformsEvery platform with its regions, services, and envs
list_endpointsA service's operations, filtered by query, tag or method
describe_endpointOne operation plus the transitive closure of the schemas it references
call_endpointExecute 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> ":

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 URIDescription
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.

Frequently asked questions

What is OpenAPI Services?

MCP server that fronts any OpenAPI service: discover operations from its spec and call them

How do I install OpenAPI Services?

It runs on your machine. In Claude Code: claude mcp add openapi-services -- uvx mcp-openapix==0.2.1. For other clients, paste the JSON configuration from this page into their MCP settings.

Does OpenAPI Services need an API key?

Its registry entry lists no required key or secret. Some features may still need an account with the service it connects to.

Is OpenAPI Services open source?

Yes. Its code is on GitHub under the MIT license.

Who maintains OpenAPI Services?

It is published by alyiox. AI.tn lists it but does not maintain or endorse it.

From the official MCP Registry. Listing is not an endorsement: review a server's code and permissions before giving it access to your data.