User guide - ivo-toby/mcp-openapi-server GitHub Wiki
This section covers how to use the MCP server as an end user with Claude Desktop, Cursor, or other MCP-compatible tools.
This MCP server can be used in two ways:
-
CLI Tool: Use
npx @ivotoby/openapi-mcp-server
directly with command-line arguments for quick setup -
Library: Import and use the
OpenAPIServer
class in your own Node.js applications for custom implementations
The server supports two transport methods:
- Stdio Transport (default): For direct integration with AI systems like Claude Desktop that manage MCP connections through standard input/output.
- Streamable HTTP Transport: For connecting to the server over HTTP, allowing web clients and other HTTP-capable systems to use the MCP protocol.
No need to clone this repository. Simply configure Claude Desktop to use this MCP server:
-
Locate or create your Claude Desktop configuration file:
- On macOS:
~/Library/Application Support/Claude/claude_desktop_config.json
- On macOS:
-
Add the following configuration:
{
"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"
}
}
}
}
- Replace the environment variables with your actual API configuration:
-
API_BASE_URL
: The base URL of your API -
OPENAPI_SPEC_PATH
: URL or path to your OpenAPI specification -
API_HEADERS
: Comma-separated key:value pairs for API authentication headers
-
To use the server with HTTP clients:
- No installation required! Use npx to run the package directly:
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
- Interact with the server using HTTP requests:
# Initialize a session (first request)
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"curl-client","version":"1.0.0"}}}'
# The response includes a Mcp-Session-Id header that you must use for subsequent requests
# and the InitializeResult directly in the POST response body.
# Send a request to list tools
# This also receives its response directly on this POST request.
curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: your-session-id" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# Open a streaming connection for other server responses (e.g., tool execution results)
# This uses Server-Sent Events (SSE).
curl -N http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"
# Example: Execute a tool (response will arrive on the GET stream)
# curl -X POST http://localhost:3000/mcp \
# -H "Content-Type: application/json" \
# -H "Mcp-Session-Id: your-session-id" \
# -d '{"jsonrpc":"2.0","id":2,"method":"tools/execute","params":{"name":"yourToolName", "arguments": {}}}'
# Terminate the session when done
curl -X DELETE http://localhost:3000/mcp -H "Mcp-Session-Id: your-session-id"
The server can be configured through environment variables or command line arguments:
-
API_BASE_URL
- Base URL for the API endpoints -
OPENAPI_SPEC_PATH
- Path or URL to OpenAPI specification -
OPENAPI_SPEC_FROM_STDIN
- Set to "true" to read OpenAPI spec from standard input -
OPENAPI_SPEC_INLINE
- Provide OpenAPI spec content directly as a string -
API_HEADERS
- Comma-separated key:value pairs for API headers -
SERVER_NAME
- Name for the MCP server (default: "mcp-openapi-server") -
SERVER_VERSION
- Version of the server (default: "1.0.0") -
TRANSPORT_TYPE
- Transport type to use: "stdio" or "http" (default: "stdio") -
HTTP_PORT
- Port for HTTP transport (default: 3000) -
HTTP_HOST
- Host for HTTP transport (default: "127.0.0.1") -
ENDPOINT_PATH
- Endpoint path for HTTP transport (default: "/mcp") -
TOOLS_MODE
- Tools loading mode: "all" (load all endpoint-based tools), "dynamic" (load only meta-tools), or "explicit" (load only tools specified in includeTools) (default: "all") -
DISABLE_ABBREVIATION
- Disable name optimization (this could throw errors when name is > 64 chars)
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json \
--headers "Authorization:Bearer token123,X-API-Key:your-api-key" \
--name "my-mcp-server" \
--server-version "1.0.0" \
--transport http \
--port 3000 \
--host 127.0.0.1 \
--path /mcp \
--disable-abbreviation true
The MCP server supports multiple methods for loading OpenAPI specifications, providing flexibility for different deployment scenarios:
Load the OpenAPI spec from a remote URL:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec https://api.example.com/openapi.json
Load the OpenAPI spec from a local file:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec ./path/to/openapi.yaml
Read the OpenAPI spec from standard input (useful for piping or containerized environments):
# Pipe from file
cat openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Pipe from curl
curl -s https://api.example.com/openapi.json | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
# Using environment variable
export OPENAPI_SPEC_FROM_STDIN=true
echo '{"openapi": "3.0.0", ...}' | npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com
Provide the OpenAPI spec content directly as a command line argument:
npx @ivotoby/openapi-mcp-server \
--api-base-url https://api.example.com \
--spec-inline '{"openapi": "3.0.0", "info": {"title": "My API", "version": "1.0.0"}, "paths": {}}'
# Using environment variable
export OPENAPI_SPEC_INLINE='{"openapi": "3.0.0", ...}'
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com
All loading methods support both JSON and YAML formats. The server automatically detects the format and parses accordingly.
For containerized deployments, you can mount OpenAPI specs or use stdin:
# Mount local file
docker run -v /path/to/spec:/app/spec.json your-mcp-server \
--api-base-url https://api.example.com \
--openapi-spec /app/spec.json
# Use stdin with docker
cat openapi.json | docker run -i your-mcp-server \
--api-base-url https://api.example.com \
--spec-from-stdin
The server provides detailed error messages for spec loading failures:
- URL loading: HTTP status codes and network errors
- File loading: File system errors (not found, permissions, etc.)
- Stdin loading: Empty input or read errors
- Inline loading: Missing content errors
- Parsing errors: Detailed JSON/YAML syntax error messages
Only one specification source can be used at a time. The server will validate that exactly one of the following is provided:
-
--openapi-spec
(URL or file path) --spec-from-stdin
--spec-inline
If multiple sources are specified, the server will exit with an error message.
Based on the Stainless article "What We Learned Converting Complex OpenAPI Specs to MCP Servers" (https://www.stainless.com/blog/what-we-learned-converting-complex-openapi-specs-to-mcp-servers), the following flags were added to control which API endpoints (tools) are loaded:
-
--tools <all|dynamic|explicit>
: Choose tool loading mode:-
all
(default): Load all tools from the OpenAPI spec, applying any specified filters -
dynamic
: Load only dynamic meta-tools (list-api-endpoints
,get-api-endpoint-schema
,invoke-api-endpoint
) -
explicit
: Load only tools explicitly listed in--tool
options, ignoring all other filters
-
-
--tool <toolId>
: Import only specified tool IDs or names. Can be used multiple times. -
--tag <tag>
: Import only tools with the specified OpenAPI tag. Can be used multiple times. -
--resource <resource>
: Import only tools under the specified resource path prefixes. Can be used multiple times. -
--operation <method>
: Import only tools for the specified HTTP methods (get, post, etc). Can be used multiple times.
Examples:
# Load only dynamic meta-tools
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools dynamic
# Load only explicitly specified tools (ignores other filters)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tools explicit --tool GET::users --tool POST::users
# Load only the GET /users endpoint tool (using all mode with filtering)
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tool GET-users
# Load tools tagged with "user" under the "/users" resource
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --tag user --resource users
# Load only POST operations
npx @ivotoby/openapi-mcp-server --api-base-url https://api.example.com --openapi-spec https://api.example.com/openapi.json --operation post
The stdio transport is designed for direct integration with AI systems like Claude Desktop that manage MCP connections through standard input/output. This is the simplest setup and requires no network configuration.
When to use: When integrating with Claude Desktop or other systems that support stdio-based MCP communication.
The HTTP transport allows the MCP server to be accessed over HTTP, enabling web applications and other HTTP-capable clients to interact with the MCP protocol. It supports session management, streaming responses, and standard HTTP methods.
Key features:
- Session management with Mcp-Session-Id header
- HTTP responses for
initialize
andtools/list
requests are sent synchronously on the POST. - Other server-to-client messages (e.g.,
tools/execute
results, notifications) are streamed over a GET connection using Server-Sent Events (SSE). - Support for POST/GET/DELETE methods
When to use: When you need to expose the MCP server to web clients or systems that communicate over HTTP rather than stdio.
- The HTTP transport validates Origin headers to prevent DNS rebinding attacks
- By default, HTTP transport only binds to localhost (127.0.0.1)
- If exposing to other hosts, consider implementing additional authentication
To see debug logs:
-
When using stdio transport with Claude Desktop:
- Logs appear in the Claude Desktop logs
-
When using HTTP transport:
npx @ivotoby/openapi-mcp-server --transport http &2>debug.log