Convert OpenAPI specifications to MCP (Model Context Protocol) servers. This tool automatically generates MCP tools from your OpenAPI spec, allowing AI assistants like Claude to interact with your APIs.
- 🔄 Automatic Tool Generation - Converts OpenAPI operations to MCP tools
- � Dynamic API Registration - Register and manage multiple APIs at runtime
- 🔍 Semantic Search - Find relevant endpoints using natural language queries
- 📊 Dependency Detection - Automatically discover endpoint dependencies
- ⚡ Workflow Execution - Execute multi-step API workflows with data flow
- 📁 Multiple Input Sources - Load specs from local files or URLs
- 📋 Format Support - JSON, YAML, and TOML formats
- 🔧 Flexible Configuration - Override base URLs, add headers, set timeouts
- 🔐 Auth Support - API key, Bearer token, Basic auth, OAuth2
- 💻 Easy Integration - Compatible with Claude Desktop, VS Code, and any MCP client
npm install -g @longcipher/openapi-mcpbun add -g @longcipher/openapi-mcpgit clone https://github.com/longcipher/openapi-mcp.git
cd openapi-mcp
bun install
bun run buildServe a single OpenAPI spec with pre-defined tools:
# From a local file
openapi-mcp serve ./api.yaml
# From a URL
openapi-mcp serve https://petstore3.swagger.io/api/v3/openapi.json
# With custom base URL
openapi-mcp serve ./api.yaml --base-url https://api.example.com/v2
# With authentication header
openapi-mcp serve ./api.yaml --header "Authorization: Bearer token123"
# With verbose logging
openapi-mcp serve ./api.yaml --verboseStart in dynamic mode to register and manage multiple APIs at runtime:
# Start in dynamic mode
openapi-mcp dynamic
# With custom data directory
openapi-mcp dynamic --data-dir ~/.my-openapi-mcp
# Using the default command (no source = dynamic mode)
openapi-mcp --dynamicIn dynamic mode, the server exposes these tools:
| Tool | Description |
|---|---|
register_api |
Register a new OpenAPI spec (parses, indexes, creates embeddings) |
unregister_api |
Remove a registered API |
list_apis |
List all registered APIs |
search_endpoints |
Semantic search for endpoints using natural language |
get_endpoint |
Get detailed endpoint information |
expand_dependencies |
Get endpoint with its required dependencies |
execute_endpoint |
Execute a single API call |
execute_workflow |
Execute multi-step API workflows |
set_auth |
Configure authentication for an API |
Usage: openapi-mcp [options] [command] [source]
Commands:
serve <source> Start MCP server with a single OpenAPI spec (static mode)
dynamic Start MCP server in dynamic mode (register APIs at runtime)
Options:
-V, --version output the version number
-b, --base-url <url> Override the base URL for API requests
-H, --header <header...> Add custom headers (format: 'Name: Value')
-t, --timeout <ms> Request timeout in milliseconds (default: "30000")
-n, --name <name> Server name (default: "openapi-mcp")
-v, --verbose Enable verbose logging
-d, --dynamic Start in dynamic mode (no source required)
--data-dir <path> Data directory for dynamic mode
-h, --help display help for command
Add to your Claude Desktop configuration (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):
Static Mode (single API):
{
"mcpServers": {
"petstore": {
"command": "openapi-mcp",
"args": [
"serve",
"https://petstore3.swagger.io/api/v3/openapi.json"
]
},
"my-api": {
"command": "openapi-mcp",
"args": [
"serve",
"/path/to/my-api.yaml",
"--base-url", "https://api.myservice.com",
"--header", "Authorization: Bearer ${API_TOKEN}"
],
"env": {
"API_TOKEN": "your-token-here"
}
}
}
}Dynamic Mode (multiple APIs at runtime):
{
"mcpServers": {
"api-hub": {
"command": "openapi-mcp",
"args": ["dynamic"]
}
}
}Then use natural language to interact:
- "Register the Petstore API from https://petstore3.swagger.io/api/v3/openapi.json"
- "Search for endpoints to create a new pet"
- "Show me the dependencies for GET /pets/{petId}"
- "Execute POST /pets with name='Max' and status='available'"
Add to your VS Code settings or .vscode/mcp.json:
Static Mode:
{
"mcp": {
"servers": {
"petstore": {
"command": "openapi-mcp",
"args": ["serve", "https://petstore3.swagger.io/api/v3/openapi.json"]
}
}
}
}Dynamic Mode:
{
"mcp": {
"servers": {
"api-hub": {
"command": "openapi-mcp",
"args": ["dynamic"]
}
}
}
}You can run without installing globally:
{
"mcpServers": {
"my-api": {
"command": "npx",
"args": [
"-y",
"@longcipher/openapi-mcp",
"serve",
"https://example.com/api.yaml"
]
}
}
}Dynamic mode transforms openapi-mcp from a single-API server into a multi-API orchestration platform. APIs are registered at runtime, indexed for semantic search, and made available for execution.
-
Register APIs:
User: Register the GitHub API from https://api.github.com/openapi.json Claude: [calls register_api] ✓ Registered "GitHub API" with 245 endpoints -
Search for endpoints:
User: Find endpoints to list repository issues Claude: [calls search_endpoints] Found: - GET /repos/{owner}/{repo}/issues (0.92) - GET /repos/{owner}/{repo}/issues/{issue_number} (0.85) -
Explore dependencies:
User: What do I need to call before GET /repos/{owner}/{repo}/issues/{issue_number}? Claude: [calls expand_dependencies] Execution order: 1. GET /repos/{owner}/{repo}/issues (to get issue_number) 2. GET /repos/{owner}/{repo}/issues/{issue_number} -
Set authentication:
User: Set my GitHub token Claude: [calls set_auth] ✓ Configured bearer authentication for GitHub API -
Execute:
User: Get issues for facebook/react Claude: [calls execute_endpoint] Retrieved 30 issues...
Dynamic mode uses local embeddings via @huggingface/transformers with the Xenova/all-MiniLM-L6-v2 model. This means:
- No API keys required - Everything runs locally
- Privacy - Your API specs never leave your machine
- Offline capable - Works without internet after first model download
- Fast - 384-dimensional embeddings optimized for semantic search
By default, data is stored in ~/.openapi-mcp/:
specs/- Raw OpenAPI specificationsendpoints/- Parsed endpoint datagraphs/- Dependency graphsvectors/- Embedding vectors
Use --data-dir to customize the storage location.
- All HTTP methods: GET, POST, PUT, DELETE, PATCH, OPTIONS, HEAD
- Operation IDs are converted to snake_case tool names
- Fallback to
{method}_{path}when operationId is missing
- Path parameters - Automatically substituted in URLs
- Query parameters - Added as URL query string
- Header parameters - Added as request headers
- Request body - Sent as JSON or form data
- Primitive types (string, number, integer, boolean)
- Arrays and objects
- Enums
- Format hints (email, date-time, etc.)
- Required field validation
openapi-mcp examples/petstore.yamlThis exposes tools like:
add_pet- Add a new pet to the storefind_pets_by_status- Find pets by their statusget_pet_by_id- Get a pet by its IDdelete_pet- Delete a pet
openapi-mcp examples/httpbin.jsonThis exposes tools like:
http_get- Make a GET requesthttp_post- Make a POST requestget_ip- Get your IP addressget_uuid- Generate a UUID
- Bun v1.0 or later
# Clone the repository
git clone https://github.com/longcipher/openapi-mcp.git
cd openapi-mcp
# Install dependencies
bun install
# Build
bun run build
# Run tests
bun test
# Lint & format
bun run lint
bun run formatopenapi-mcp/
├── src/
│ ├── index.ts # Main entry point
│ ├── cli.ts # CLI implementation
│ ├── logger.ts # Logging utilities
│ ├── errors.ts # Error definitions
│ ├── types/ # Core type definitions
│ │ └── index.ts # Endpoint, Graph, Workflow types
│ ├── loader/ # Spec loading module
│ │ ├── types.ts # OpenAPI type definitions
│ │ ├── parser.ts # Format detection & parsing
│ │ ├── file-loader.ts # Local file loading
│ │ ├── url-loader.ts # URL loading
│ │ └── index.ts # Module exports
│ ├── adapter/ # OpenAPI to MCP adapter
│ │ ├── types.ts # MCP type definitions
│ │ ├── openapi-adapter.ts
│ │ └── index.ts
│ ├── ingestion/ # API parsing and indexing
│ │ ├── parser.ts # Enhanced OpenAPI parser
│ │ ├── graph-builder.ts # Dependency graph construction
│ │ ├── embedder.ts # Local embedding generation
│ │ └── index.ts
│ ├── stores/ # Persistence layer
│ │ ├── spec-store.ts # API spec storage
│ │ ├── graph-store.ts # Dependency graph storage
│ │ ├── vector-store.ts # Embedding vector storage
│ │ └── index.ts
│ ├── retrieval/ # Search and ranking
│ │ ├── vector-search.ts # Semantic search
│ │ ├── graph-expander.ts # Dependency expansion
│ │ ├── reranker.ts # Result reranking
│ │ └── index.ts
│ ├── execution/ # API execution
│ │ ├── schema-formatter.ts # Endpoint formatting
│ │ ├── auth-handler.ts # Authentication handling
│ │ ├── http-executor.ts # HTTP request execution
│ │ ├── workflow-executor.ts # Multi-step workflows
│ │ └── index.ts
│ ├── mcp/ # MCP integration
│ │ ├── tools.ts # Dynamic API tools
│ │ ├── resources.ts # API resources
│ │ └── index.ts
│ └── server/ # MCP server implementation
│ ├── mcp-server.ts # Static & dynamic servers
│ └── index.ts
├── tests/ # Test files
├── examples/ # Example OpenAPI specs
└── docs/ # Documentation
- Load - Reads OpenAPI spec from file or URL
- Parse - Detects format (JSON/YAML/TOML) and validates the spec
- Convert - Transforms OpenAPI operations into MCP tool definitions
- Serve - Starts an MCP server over STDIO transport
- Execute - When a tool is called, makes the actual HTTP request
"Tool not found" error
- Check that the operationId matches (converted to snake_case)
- Run with
--verboseto see available tools
Connection timeouts
- Increase timeout with
--timeout 60000(60 seconds) - Check network connectivity to the API
Authentication errors
- Add auth headers with
--header "Authorization: Bearer token" - Ensure the token is valid and not expired
Invalid spec error
- Ensure the spec is valid OpenAPI 3.0.x
- Check for syntax errors in YAML/JSON/TOML
Run with verbose logging to see detailed information:
openapi-mcp ./api.yaml --verboseContributions are welcome! Please feel free to submit a Pull Request.
Apache License 2.0 - see LICENSE for details.