mcp-openapi-gateway
A Model Context Protocol (MCP) mechanism to serve RESTful interfaces, defined via OpenAPI documents, as consumable MCP resources. This enables LLMs to natively discover and invoke external web services.
Author

ivo-toby
Quick Info
Actions
Tags
OpenAPI MCP Gateway for LLM Tooling
This utility component transforms OpenAPI specification documents into resources accessible via the Model Context Protocol (MCP). It bridges the gap between structured API definitions and intelligent agents leveraging MCP for seamless external function calling.
📖 User Reference
- Operational Manual - Instructions for end-users integrating this gateway with clients like Claude Desktop or Cursor.
- Developer Integration - Guidance for software engineers embedding this functionality within custom Node.js applications.
- Codebase Contribution Guide - Details for those wishing to contribute to the source repository.
- Authentication Provider Details - Comprehensive overview of advanced authentication strategies.
User Guide
This guide details how to deploy and utilize the MCP Gateway alongside MCP-compatible assistants (e.g., Claude Desktop, Cursor).
Deployment Modes
This service operates in two primary configurations:
- Command Line Interface (CLI): Quick activation using
npx @ivotoby/openapi-mcp-serveralong with specified runtime arguments. - Programmatic Library: Importing the core
OpenAPIServerclass into your own application for bespoke setups.
The communication layer can be established via two transport mechanisms:
- Standard I/O (Stdio) (Default): Ideal for direct process integration, typical when the AI client manages the process lifecycle.
- HTTP Stream Transport: Exposes the MCP interface over a local TCP socket, accessible by HTTP clients.
Initial Setup Scenarios
Scenario 1: Integration with Claude Desktop (Stdio Mode)
No repository cloning is necessary. Configure your Claude Desktop settings:
-
Locate or establish the configuration file (e.g.,
~/Library/Application Support/Claude/claude_desktop_config.jsonon macOS). -
Inject the following server definition:
{ "mcpServers": { "openapi": { "command": "npx", "args": ["-y", "@ivotoby/openapi-mcp-server"], "env": { "API_BASE_URL": "https://api.example.com", "OPENAPI_SPEC_PATH": "https://api.example.com/openapi.json", "API_HEADERS": "Authorization:Bearer token123,X-API-Key:your-api-key" } } } }
- Customize the environment settings:
API_BASE_URL: The root URL for the target API.OPENAPI_SPEC_PATH: The URI pointing to the specification document.API_HEADERS: A comma-delimited list of authorization headers (Key:Value).
Scenario 2: Access via HTTP Clients (HTTP Transport)
Run the package directly via npx specifying the HTTP parameters:
bash npx @ivotoby/openapi-mcp-server \ --api-base-url https://api.example.com \ --openapi-spec https://api.example.com/openapi.json \ --headers "Authorization:Bearer token123" \ --transport http \ --port 3000
Interaction proceeds via JSON-RPC over HTTP POST, utilizing the Mcp-Session-Id header for stateful operations:
bash
1. Establish Session (Initialize)
curl -X POST http://localhost:3000/mcp \ -H "Content-Type: application/json" \ -d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{...}}'
2. List Available Capabilities (Tools)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id:
3. Stream Server Notifications (Results, Notifications) via SSE
curl -N http://localhost:3000/mcp -H "Mcp-Session-Id:
4. Terminate Session
curl -X DELETE http://localhost:3000/mcp -H "Mcp-Session-Id:
Configuration Parameters
The operational behavior is controlled via environment variables or CLI flags:
| Variable/Flag | Description | Default Value |
|---|---|---|
API_BASE_URL |
Root URI for external API calls. | N/A |
OPENAPI_SPEC_PATH |
Location (URL/File Path) of the OpenAPI definition. | N/A |
OPENAPI_SPEC_FROM_STDIN |
Set to "true" to ingest spec from standard input. | "false" |
OPENAPI_SPEC_INLINE |
Raw specification content provided as a string. | Empty String |
API_HEADERS |
Comma-delimited set of headers for outbound requests. | Empty String |
SERVER_NAME |
Identifier for this MCP service instance. | "mcp-openapi-server" |
SERVER_VERSION |
Reported version number. | "1.0.0" |
TRANSPORT_TYPE |
Communication protocol: "stdio" or "http". | "stdio" |
HTTP_PORT |
TCP port binding for HTTP transport. | 3000 |
HTTP_HOST |
Network interface binding for HTTP transport. | "127.0.0.1" |
ENDPOINT_PATH |
URI path for HTTP MCP endpoint. | "/mcp" |
TOOLS_MODE |
Loading strategy: "all", "dynamic", or "explicit". | "all" |
DISABLE_ABBREVIATION |
Bypasses name optimization (useful if auto-generated names exceed 64 chars). | "false" |
Specification Ingestion Flexibility
The gateway accommodates diverse methods for providing the OpenAPI schema:
- Remote URL (Default): Specify via
--openapi-spec. - Local File Path: Reference a local YAML/JSON file.
- Standard Input Piping: Use
--spec-from-stdinwhen piping data (e.g., fromcatorcurl). - Inline Content: Provide the schema directly via
--spec-inline.
Both JSON and YAML formats are accepted across all loading methods.
Tool Filtering & Granular Control
Drawing inspiration from practices outlined in Stainless's analysis of complex OpenAPI specs, configuration flags allow precise control over which API operations are exposed as MCP tools:
--tools <mode>: Defines the loading strategy:all(Default): Loads all operations, subject to subsequent filters.dynamic: Loads only the inspection meta-tools (list-api-endpoints,get-api-endpoint-schema,invoke-api-endpoint).explicit: Loads only operations explicitly named via the--toolargument.
--tool <toolId>: Selects specific operations by their generated ID/name.--tag <tag>: Filters based on OpenAPI tags.--resource <pathPrefix>: Filters based on URI path structure.--operation <method>: Filters by HTTP verb (e.g.,get,put).
Example: Loading only dynamic introspection tools: bash npx @ivotoby/openapi-mcp-server --tools dynamic ...
Transport Deep Dive
Stdio Transport
Best suited for tight coupling with local AI environments where process streams are managed externally.
Streamable HTTP Transport
This mode facilitates web accessibility. It uses a standard POST endpoint for request/response initialization, but crucially switches to Server-Sent Events (SSE) over a dedicated GET connection to stream asynchronous results back to the client, maintaining session state via the Mcp-Session-Id header.
Security Notes
For HTTP transport, origin header validation is active to mitigate DNS rebinding. The server defaults to binding only to 127.0.0.1 unless explicitly configured otherwise.
Library Usage
Developers can leverage the OpenAPIServer class for embedding this functionality.
Core Initialization Example (Stdio)
typescript import { OpenAPIServer } from "@ivotoby/openapi-mcp-server" import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
const config = { name: "my-custom-service", apiBaseUrl: "https://api.example.com", openApiSpec: "./spec.json", specInputMethod: "file" as const, headers: { Authorization: "Bearer token..." }, transportType: "stdio" as const, toolsMode: "all" as const, }
const server = new OpenAPIServer(config) await server.start(new StdioServerTransport())
Dynamic Authentication with AuthProvider
To manage credentials that expire or require periodic refresh (e.g., OAuth flows):
typescript import { OpenAPIServer, AuthProvider } from "@ivotoby/openapi-mcp-server"
class TokenRefresher implements AuthProvider {
async getAuthHeaders(): PromiseBearer ${this.currentAuthToken} }
}
async handleAuthError(error: any): Promise
const authProviderInstance = new TokenRefresher() const server = new OpenAPIServer({ / ...config /, authProvider: authProviderInstance })
Refer to the examples/ subdirectory for production-ready implementations including specialized AuthProvider patterns (e.g., Beatport integration).
OpenAPI Schema Transformation Logic
Reference Resolution
The component ensures comprehensive $ref resolution across parameter definitions and schema components, preserving fidelity in deeply nested structures and preventing recursive loop invocation.
Input Schema Composition
It intelligently merges disparate parameter locations (path, query, header) with request body definitions into a unified, single input structure for the resulting MCP tool, managing potential naming collisions by property prefixing.
FAQ
Q: How are API endpoints mapped to MCP tools? A: Each distinct, valid API operation described in the specification becomes an individual tool available through the MCP protocol.
Q: What is the benefit of using the library over the CLI?
A: The library offers customization hooks, most notably the AuthProvider for dynamic credential management, and permits bundling the server logic into specialized npm modules for distribution.
Q: If an API returns a 401 error, how can I automatically retry the request?
A: Implement the handleAuthError method within your custom AuthProvider. Returning true signals the gateway to re-execute the request after the error handling logic (e.g., token refresh) completes.
License
MIT
