Transform any OpenAPI or Swagger-described REST API into an MCP server
OpenAPI to MCP
Standalone proxy that turns any OpenAPI/Swagger-described HTTP API into an MCP (Model Context Protocol) server. It loads the spec at startup, filters operations by include/exclude, and registers one MCP tool per API operation. Tool calls are executed as HTTP requests to the backend API.
Useful when you already have (or want) a REST API with an OpenAPI/Swagger spec: the same spec drives both human-readable API docs and MCP tools for AI clients.
How it works
flowchart LR
subgraph startup["Startup"]
A[OpenAPI specURL or file] --> B[Load and filterinclude or exclude]
B --> C[N MCP toolsone per operation]
end
subgraph runtime["Runtime"]
D[MCP client] <-->|Streamable HTTPPOST/GET /mcp| E[openapi-to-mcp]
E <-->|HTTP| F[Backend API]
end
C -.->|registered in| E
Logging and Correlation IDs
The server includes comprehensive logging with correlation ID support for request tracking:
- Correlation ID: Extracted from
X-Correlation-IDheader (case-insensitive) or auto-generated for each request - Log levels:
DEBUG,INFO,WARN,ERROR(configurable viaMCP_LOG_LEVELenv var, default:INFO) - Log format:
[correlation_id] LEVEL messagewith optional context data - Request tracking: All logs include correlation ID for tracing requests through the system
For E2E testing, pass X-Correlation-ID header with your request to track it across all logs.
- Load OpenAPI spec from
MCP_OPENAPI_SPEC(URL starting withhttp://orhttps://, or file path). - Collect operations (method + path). Filter: if
MCP_INCLUDE_ENDPOINTSis set, keep only those; otherwise drop any inMCP_EXCLUDE_ENDPOINTS. Include has priority over exclude. - For each operation create an MCP tool: name =
MCP_TOOL_PREFIX+ path segment (e.g.api_+messages=api_messages). Path parameters are included in the tool name (e.g./channels/{username}becomeschannels_username). If the same path segment is used by more than one method (e.g. GET and PUT on/pet/{id}), the tool name is made unique by appending the method (e.g.pet_id_get,pet_id_put). Input schema from parameters and requestBody (Zod), handler = HTTP call toMCP_API_BASE_URL. - Load MCP server instructions: by default uses
info.descriptionfrom OpenAPI spec. Optionally, load custom instructions fromMCP_INSTRUCTIONS_FILEand combine with OpenAPI description according toMCP_INSTRUCTIONS_MODE(default/replace/append/prepend). If file loading fails, server logs a warning and continues with OpenAPI instructions only.
Transport: Streamable HTTP. Endpoint: POST /mcp and GET /mcp.
Environment variables (MCP_ prefix)
Environment variables are loaded from .env file in the project root (using dotenv). You can also set them directly in your shell environment. See .env.example for a template.
| Variable | Description | Default |
|---|---|---|
MCP_API_BASE_URL |
Base URL for API requests | http://127.0.0.1:3000 |
MCP_API_BASIC_AUTH |
Basic auth for API requests: username:password. Use when the remote API is protected by HTTP Basic Auth. If both this and MCP_API_BEARER_TOKEN are set, Bearer is used. |
- |
MCP_API_BEARER_TOKEN |
Bearer token for API requests. Use when the remote API expects Authorization: Bearer <token>. Takes precedence over MCP_API_BASIC_AUTH when both set. |
- |
MCP_OPENAPI_SPEC |
OpenAPI spec source: URL (starts with http:// or https://) or file path (e.g. http://api:3000/openapi.json or ./openapi.json). Automatically detects URL vs file. |
- |
MCP_INCLUDE_ENDPOINTS |
Comma-separated method:path (e.g. get:/messages,get:/channels). If set, only these become tools. |
- |
MCP_EXCLUDE_ENDPOINTS |
Comma-separated method:path to exclude. Ignored for endpoints in include. |
- |
MCP_TOOL_PREFIX |
Prefix for tool names (e.g. api_ -> api_messages, api_channels) |
(empty) |
MCP_SERVER_NAME |
Server name reported to MCP clients | openapi-to-mcp |
MCP_PORT |
Port for Streamable HTTP server | 3100 |
MCP_HOST |
Bind host | 0.0.0.0 |
MCP_LOG_LEVEL |
Log level: DEBUG, INFO, WARN, ERROR (case-insensitive) |
INFO |
MCP_INSTRUCTIONS_FILE |
Path to custom instructions file (text file with MCP server instructions) | - |
MCP_INSTRUCTIONS_MODE |
How to combine custom instructions with OpenAPI spec description: default (use only OpenAPI description, ignore custom file), replace (use only custom file, ignore OpenAPI), append (OpenAPI + custom file), prepend (custom file + OpenAPI). Case-insensitive. |
default |
MCP_CONVERT_HTML_TO_MARKDOWN |
Convert HTML tags in operation descriptions to Markdown format. Set to false to disable. |
true |
MCP_OPENAPI_SPEC must be set. If it starts with http:// or https://, it's treated as a URL; otherwise, it's treated as a file path.
**Backw
Tools (1)
dynamic-api-operationsTools are dynamically generated based on the provided OpenAPI specification, mapping each operation to an executable tool.Environment Variables
MCP_OPENAPI_SPECrequiredOpenAPI spec source: URL or file pathMCP_API_BASE_URLBase URL for API requestsMCP_API_BEARER_TOKENBearer token for API requestsMCP_INCLUDE_ENDPOINTSComma-separated method:path to includeMCP_LOG_LEVELLog level: DEBUG, INFO, WARN, ERRORConfiguration
{"mcpServers": {"openapi-to-mcp": {"command": "npx", "args": ["-y", "@evilfreelancer/openapi-to-mcp"], "env": {"MCP_OPENAPI_SPEC": "https://api.example.com/openapi.json"}}}}