OpenAPI-MCP

mcp
Guvenlik Denetimi
Gecti
Health Gecti
  • License — License: MIT
  • Description — Repository has a description
  • Active repo — Last push 0 days ago
  • Community trust — 69 GitHub stars
Code Gecti
  • Code scan — Scanned 12 files during light audit, no dangerous patterns found
Permissions Gecti
  • Permissions — No dangerous permissions requested

Bu listing icin henuz AI raporu yok.

SUMMARY

The OpenAPI-MCP proxy translates OpenAPI specs into MCP tools, enabling AI agents to access external APIs without custom wrappers!

README.md

OpenAPI to Model Context Protocol (MCP)

PyPI version
License: MIT
Python version

OpenAPI-MCP exposes operations from an OpenAPI document as MCP tools. It also
provides schema resources, a usage prompt, and request previews. The server uses
FastMCP for MCP transport and tool registration.

OpenAPI-MCP

Development status: the changes described below are unreleased. PyPI 1.0.4
does not contain these fixes. This source version targets FastMCP 4.1.6 and MCP
Python SDK 2.3.0, with compatible minor updates allowed. See the
review and validation record
for tested versions, findings, and remaining work.

Install and run

Python 3.10 or later is required. To use this checkout:

python -m venv .venv
source .venv/bin/activate
pip install -e .
OPENAPI_URL="./test/fixtures/petstore.json" \
MCP_ALLOWED_OPERATIONS='["GET /pets"]' \
SERVER_NAME="petstore" openapi-mcp

The default transport is stdio. A client launches the process and communicates
through its standard input and output. OPENAPI_URL accepts a local JSON/YAML
file or an HTTP(S) URL. Use specifications and API endpoints you trust.

A stdio client configuration can use the installed executable:

{
  "mcpServers": {
    "petstore": {
      "command": "/absolute/path/to/.venv/bin/openapi-mcp",
      "env": {
        "OPENAPI_URL": "/absolute/path/to/OpenAPI-MCP/test/fixtures/petstore.json",
        "SERVER_NAME": "petstore",
        "MCP_ALLOWED_OPERATIONS": "[\"GET /pets\"]"
      }
    }
  }
}

For Streamable HTTP:

OPENAPI_URL="./test/fixtures/petstore.json" \
SERVER_NAME="petstore" \
MCP_ALLOWED_OPERATIONS='["GET /pets"]' \
MCP_HTTP_ENABLED=true \
MCP_HTTP_PORT=8001 \
openapi-mcp

The MCP endpoint is http://127.0.0.1:8001/mcp. The supplied
client configuration uses mcp-remote to connect
stdio clients to HTTP. Client applications and mcp-remote are separate
components and were not tested in the offline review.

Legacy SSE is available explicitly with MCP_TRANSPORT_TYPE=sse, at /sse.
The default HTTP endpoint changed from /sse to /mcp; update existing clients.

Choose which API operations to expose

By default, no API operations are exposed. Set MCP_ALLOWED_OPERATIONS to a
JSON array of exact uppercase HTTP method and OpenAPI path pairs:

MCP_ALLOWED_OPERATIONS='["GET /pets", "GET /pets/{petId}"]'

Selectors use the paths in the specification, without the server URL/base path.
They are literal matches, not regular expressions or wildcards. An unknown
selector, malformed list, duplicate selector, or conflicting policy stops startup.
Only permitted operations appear as tools, in the operation list, and in the
usage prompt. A direct call to an omitted tool is rejected before request
preparation or authentication. An empty list leaves only the information tools,
usage prompt, and schema resources available. API descriptions and component
schemas remain metadata; this policy is not a document-redaction feature.

To deliberately expose every operation, set MCP_OPERATION_POLICY=all and leave
MCP_ALLOWED_OPERATIONS unset. This restores the previous exposure behavior.
A policy applies to the entire server instance, not individual users. Restart
with a new server instance to apply changes. A GET-only list is not a guarantee
of harmless operations; choose each route based on what its API actually does.

Operation IDs that collide after name sanitization, or permitted IDs that collide
with management tool names, are rejected instead of silently replacing a tool.

Tools and request previews

Each permitted API operation becomes a tool named <server_name>_<operation_id>.
Inputs use the parameter names from the specification, including names such as
customerId or X-Trace. JSON request bodies use the argument body.
Required fields and supported JSON Schema constraints are checked before an API
request. Local #/components/schemas/ references are supported; external schema
references are not fetched.

Every generated operation accepts two additional arguments:

  • dry_run: true returns the prepared URL, parameters, caller-supplied headers,
    and body without executing the API request or obtaining an authentication token.
    Server-configured authentication headers are omitted from the preview.
  • req_id is an optional correlation string.

For example, a tool with a customerId path parameter and JSON request body can
be called with:

{"customerId": "c1", "body": {"quantity": 2}, "dry_run": true}

Previews still contain caller-supplied data. They are not a general redaction
service. dry_run and req_id are reserved names; specifications that use them,
or reuse one input name across locations, are rejected rather than silently
mapped to the wrong input.

Additional tools list operations and server information. Component schemas are
available as JSON resources under schema://<server_name>_<schema_name> (with
sanitized names), and a generated prompt describes API usage.

Configuration

Environment variables and a local .env file configure the executable.
The Python API also exposes ServerConfig.from_file() for JSON/YAML settings.
Process environment overrides .env, which overrides file values. Loading a
file does not modify the process environment or other server instances.

Variable Meaning Default
OPENAPI_URL Trusted specification URL or local file Required
SERVER_NAME Prefix for tools and resources openapi_proxy_server
MCP_OPERATION_POLICY allowlist or explicit all allowlist
MCP_ALLOWED_OPERATIONS JSON array of exact METHOD /path selectors [] (no API operations)
MCP_HTTP_ENABLED Enable HTTP instead of stdio false
MCP_HTTP_HOST Address to bind 127.0.0.1
MCP_HTTP_PORT Port 8000
MCP_TRANSPORT_TYPE http or legacy sse http
MCP_ALLOWED_HOSTS Additional trusted HTTP Host values, comma-separated FastMCP loopback defaults
MCP_CORS_ORIGINS Allowed HTTP Origin values, comma-separated localhost and 127.0.0.1 on ports 3000 and 8080
MCP_AUTH_HEADERS Upstream headers as JSON or key=value,key2=value2 Empty
OAUTH_CLIENT_ID, OAUTH_CLIENT_SECRET, OAUTH_TOKEN_URL Upstream OAuth client credentials Unset
OAUTH_SCOPE Upstream OAuth scope api
API_USERNAME, API_PASSWORD, API_LOGIN_ENDPOINT Upstream username/password login Unset
HTTP_TIMEOUT Upstream request timeout in seconds 30
HTTP_MAX_RETRIES Retries for idempotent HTTP methods 3
HTTP_RETRY_BASE_DELAY, HTTP_RETRY_MAX_DELAY Retry delays in seconds 1, 30
MCP_DEBUG Enable debug logging false

MCP_CORS_ORIGINS is retained as a configuration name for compatibility; it
controls Origin validation in the FastMCP transport, not MCP client identity or
a complete browser CORS policy. HTTP Host/Origin protection is enabled explicitly.

The old MCP_MESSAGE_SIZE_LIMIT, MCP_BATCH_TIMEOUT, MCP_SESSION_TIMEOUT, and
SSE_* settings belong to legacy modules. They do not configure limits or
transport selection in the current openapi-mcp executable.

Upstream authentication

OPENAPI_URL="./specs/my-api.yaml" \
MCP_AUTH_HEADERS='{"X-API-Key": "example-placeholder"}' \
MCP_ALLOWED_OPERATIONS='["GET /items"]' \
openapi-mcp

These credentials authenticate outgoing API calls, not incoming MCP clients.
Anyone allowed to call this MCP server can invoke its registered API operations
with the server's API privileges. The operation allowlist limits those tools,
but there is no per-user authorization layer yet. Use restricted API credentials
and allow only the operations you intend to expose. See SECURITY.md.

A configured token login that fails now stops the API request. POST and PATCH
requests are not retried automatically, because a lost response may hide a
successful mutation. GET, HEAD, OPTIONS, PUT, and DELETE may be retried according
to the configured limit; set HTTP_MAX_RETRIES=0 if the API does not implement
those methods idempotently. Numeric Retry-After delays are bounded by the
configured maximum; HTTP-date values fall back to exponential delay.

Docker

docker compose up --build -d

The example services publish ports 8001 and 8002 on 127.0.0.1 only. The
process binds to 0.0.0.0 inside each container. Both example services fetch
public specifications at startup. GET /health reports process liveness; it
does not test upstream authentication or API availability. Health checks fail
on HTTP errors. Container builds were not exercised in the local review.

Development and current scope

pip install -e '.[dev]'
python -m pytest test/ -q

Normal tests block network sockets, isolate credentials, and use fixtures or
mock HTTP responses. Eleven legacy live examples are skipped explicitly.
Returning a value from a test is an error, so returning False cannot masquerade
as a passing assertion. See CONTRIBUTING.md for the checks and
the opt-in command for legacy live examples.

This is a custom OpenAPI adapter, not a complete OpenAPI implementation. Complex
parameter serialization, multipart/form bodies, external references, response
size limits, and per-user MCP authorization require more work. Deprecated server
and transport modules remain for historical compatibility and have not received
the same end-to-end validation as fastmcp_server.py.

FastMCP's native OpenAPI integration
handles additional request formats. The adapter comparison and policy review
records a shared-fixture comparison, including differences in body input shapes,
argument validation, and request previews. The current adapter remains in use;
a replacement must preserve those contracts. The comparison script reports
known gaps with a nonzero exit status:

python scripts/compare_openapi_adapters.py --output build/adapter-comparison.json

The initial review also
covers the July 2026 MCP protocol changes. Updating the SDK alone is not proof
of complete protocol conformance.

License

MIT.

Yorumlar (0)

Sonuc bulunamadi