Standalone proxy: loads an OpenAPI spec and exposes each API operation as an MCP tool.
2.0K
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.
MCP_OPENAPI_SPEC_URL (preferred) or MCP_OPENAPI_SPEC_FILE.MCP_INCLUDE_ENDPOINTS is set, keep only those; otherwise drop any in MCP_EXCLUDE_ENDPOINTS. Include has priority over exclude.MCP_TOOL_PREFIX + path segment (e.g. api_ + messages = api_messages), input schema from parameters and requestBody (Zod), handler = HTTP call to MCP_API_BASE_URL.Transport: Streamable HTTP. Endpoint: POST /mcp and GET /mcp.
| Variable | Description | Default |
|---|---|---|
MCP_API_BASE_URL | Base URL for API requests | http://127.0.0.1:3000 |
MCP_OPENAPI_SPEC_URL | URL of OpenAPI spec (e.g. http://api:3000/openapi.json). Takes precedence over file. | - |
MCP_OPENAPI_SPEC_FILE | Path to OpenAPI JSON file (used if URL not set) | - |
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 |
At least one of MCP_OPENAPI_SPEC_URL or MCP_OPENAPI_SPEC_FILE must be set.
Copy .env.example to .env and set at least the OpenAPI spec source and API base URL:
cp .env.example .env
# Edit .env: MCP_OPENAPI_SPEC_URL or MCP_OPENAPI_SPEC_FILE, MCP_API_BASE_URL
Install, build, and start:
npm ci
npm run build
npm run start
The server listens on http://<MCP_HOST>:<MCP_PORT> (default http://0.0.0.0:3100). Connect MCP clients to POST/GET http://localhost:3100/mcp (Streamable HTTP).
Ensure the backend API is reachable at MCP_API_BASE_URL and that the OpenAPI spec URL (or file) returns a valid OpenAPI 3.x JSON.
Image on Docker Hub: evilfreelancer/openapi-to-mcp. Use tag latest or a version tag (e.g. v1.0.0).
Pull and run with env vars (example: spec from URL, API at host):
docker run --rm -p 3100:3100 \
-e MCP_OPENAPI_SPEC_URL=http://host.docker.internal:3000/openapi.json \
-e MCP_API_BASE_URL=http://host.docker.internal:3000 \
evilfreelancer/openapi-to-mcp:latest
On Linux you may need --add-host=host.docker.internal:host-gateway or use the host network. Alternatively pass a file path and mount the spec:
docker run --rm -p 3100:3100 \
-v $(pwd)/openapi.json:/app/openapi.json:ro \
-e MCP_OPENAPI_SPEC_FILE=/app/openapi.json \
-e MCP_API_BASE_URL=http://host.docker.internal:3000 \
evilfreelancer/openapi-to-mcp:latest
To build the image locally instead: docker build -t openapi-to-mcp . and use openapi-to-mcp as the image name in the commands above.
A minimal docker-compose.yaml is included so you can run the MCP server and optionally point it at an existing API. It uses the image from Docker Hub (evilfreelancer/openapi-to-mcp).
Copy .env.example to .env and set:
MCP_OPENAPI_SPEC_URL (e.g. your API’s /openapi.json URL)MCP_API_BASE_URL (e.g. http://api:3000 if the API runs in another container)From the project root:
docker compose up -d
The MCP server will be available at http://localhost:3100/mcp (Streamable HTTP).
To use a local OpenAPI file instead of a URL, set MCP_OPENAPI_SPEC_FILE and mount the file into the container (see docker-compose.yaml comments if present).
npm test
Tests cover: config (env vars, include/exclude, defaults), OpenAPI loader (URL and file, URL over file, error when both unset), and openapi-to-tools (filtering, prefix, handler calling API with success and error). HTTP is mocked (axios-mock-adapter).
The project includes a Dockerfile (Node 20 Alpine): install deps, build TypeScript, production prune, run node dist/index.js. No dev dependencies or tests in the image. Pre-built images are published to Docker Hub. To build locally:
docker build -t openapi-to-mcp .
A GitHub Actions workflow (.github/workflows/docker-publish.yml) runs tests, then builds the image and pushes it to Docker Hub.
v1.0.0); on manual run you can set a version (default latest).main; otherwise the run fails.Required repository secrets (Settings → Secrets and variables → Actions):
| Secret | Description |
|---|---|
DOCKERHUB_USERNAME | Docker Hub username (image will be DOCKERHUB_USERNAME/openapi-to-mcp) |
DOCKERHUB_TOKEN | Docker Hub access token (recommended) or password |
uvx mcp-openapi-proxy.npm install -g openapi-mcp-generator.Content type
Image
Digest
sha256:5ab31fd9c…
Size
77.3 MB
Last updated
7 months ago
docker pull evilfreelancer/openapi-to-mcp