openapi-mcp-bridge
v0.1.6
Published
Transform OpenAPI definitions into MCP (Model Context Protocol) tools for seamless LLM-API integration
Downloads
19
Maintainers
Readme
OpenAPI MCP Bridge
Transform OpenAPI definitions into MCP (Model Context Protocol) tools for seamless LLM-API integration.
What is MCP?
Model Context Protocol (MCP) is a standard protocol that allows AI models to interact with external tools and data sources. Unlike REST APIs that use HTTP requests, MCP uses JSON-RPC messages over stdio or WebSocket connections.
Key Differences:
- REST API: HTTP requests → JSON responses
- MCP: JSON-RPC messages → Tool calls and responses
- Purpose: MCP bridges AI models with external systems safely and efficiently
Why OpenAPI → MCP?
- Your APIs are already documented in OpenAPI format
- AI models can't directly call REST APIs
- MCP provides a secure, standardized way to expose API functionality to AI
Quick Start (30 seconds)
1. Install and Run
npm install -g openapi-mcp-bridge
mkdir my-api && cd my-api2. Create OpenAPI Definition
cat > museum-api.yaml << 'EOF'
openapi: 3.1.0
info:
title: Museum API
version: 1.0.0
servers:
- url: https://redocly.com/_mock/demo/openapi/museum-api
paths:
/museum-hours:
get:
summary: Get museum hours
operationId: getMuseumHours
parameters:
- name: date
in: query
schema:
type: string
format: date
components:
securitySchemes:
BasicAuth:
type: http
scheme: basic
EOF3. Test with MCP Inspector
# Terminal 1: Start MCP server
openapi-mcp-bridge --definitions .
# Terminal 2: Test with inspector
npm install -g @modelcontextprotocol/inspector
mcp-inspector npx openapi-mcp-bridge --definitions .Result: You'll see getMuseumHours tool available in the MCP Inspector interface.
Integration Examples
Claude Desktop Integration
Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):
{
"mcpServers": {
"museum-api": {
"command": "npx",
"args": ["openapi-mcp-bridge", "--definitions", "/path/to/your/api-definitions"]
}
}
}Usage: Ask Claude "What are the museum hours?" and it will automatically call your API.
Claude Code Integration
- Create
.claude-code-mcp.jsonin your project:
{
"mcpServers": {
"my-api": {
"command": "npx",
"args": ["openapi-mcp-bridge", "--definitions", "./api-definitions"]
}
}
}- Claude Code will automatically detect and use your API tools.
Custom MCP Client
// TypeScript example with proper ES module setup
import { spawn } from 'child_process';
import { MCPClient } from '@modelcontextprotocol/client';
const serverProcess = spawn('npx', ['openapi-mcp-bridge', '--definitions', './api-definitions']);
const client = new MCPClient();
await client.connect({
stdio: {
stdin: serverProcess.stdin,
stdout: serverProcess.stdout
}
});
// List available tools
const tools = await client.listTools();
console.log('Available tools:', tools);
// Call a tool
const result = await client.callTool('getMuseumHours', { date: '2024-01-15' });
console.log('Result:', result);Usage Patterns
When to Use Each Approach
| Use Case | Approach | Best For |
|----------|----------|----------|
| AI Model Integration | CLI (openapi-mcp-bridge) | Claude Desktop, Claude Code, custom MCP clients |
| Web Application | Express/Fastify middleware | Adding MCP endpoints to existing web apps |
| Microservice | Standalone server | Dedicated MCP service, Docker deployments |
| Development/Testing | MCP Inspector | Testing and debugging MCP tools |
Decision Tree
Do you want to integrate with an AI model?
├── Yes → Use CLI approach
│ ├── Claude Desktop → Update claude_desktop_config.json
│ ├── Claude Code → Use `claude mcp add` command
│ └── Custom client → Use stdio connection
└── No → Use HTTP approach
├── Existing Express app → Use Express middleware
├── New microservice → Use standalone server
└── Testing → Use MCP InspectorTransport Mode Decision Matrix
| Transport | Use Case | Pros | Cons | Best For | |-----------|----------|------|------|----------| | stdio | AI model integration | Simple, secure, no network config | Single process, local only | Claude Desktop, Claude Code, development | | HTTP | Web applications | Multi-user, remote access, familiar | Network setup, security concerns | Production APIs, microservices | | WebSocket | Real-time updates | Bi-directional, low latency | Complex setup, connection management | Streaming, live data |
stdio is the recommended transport for AI model integration because:
- ✅ Security: No network exposure or authentication needed
- ✅ Simplicity: Direct process communication
- ✅ Performance: Lower overhead than HTTP
- ✅ Reliability: No network connectivity issues
- ✅ Lifecycle: Automatic process management
Troubleshooting
Common Issues
1. Import Path Errors
# ❌ Error: Cannot find module 'openapi-mcp-bridge/express'
import { createExpressMiddleware } from 'openapi-mcp-bridge/express';
# ✅ Solution: Use the correct package exports
import { createExpressMiddleware } from 'openapi-mcp-bridge/express';Root Cause: Package uses ES modules. Ensure your package.json has "type": "module".
2. "Cannot POST /mcp" Error
# ❌ Wrong: Trying to make HTTP requests to MCP endpoint
curl -X POST http://localhost:3000/mcp
# ✅ Right: Use MCP Inspector or MCP client
mcp-inspector http://localhost:3000/mcpRoot Cause: MCP is not a REST API. It uses JSON-RPC over stdio/WebSocket.
3. Port Conflicts
# ❌ Error: EADDRINUSE: address already in use :::3000
npm start
# ✅ Solution: Use a different port
PORT=3001 npm start
# or
npx openapi-mcp-bridge --definitions . --port 30014. CLI Warnings
# ❌ Warning: --port is not yet implemented in stdio mode
openapi-mcp-bridge --definitions . --port 3000
# ✅ Solution: Don't use --port with CLI (stdio mode)
openapi-mcp-bridge --definitions .Root Cause: CLI runs in stdio mode for MCP clients. Use standalone server for HTTP mode.
5. Module Import Issues
// ❌ CommonJS in ES module project
const { createExpressMiddleware } = require('openapi-mcp-bridge/express');
// ✅ ES modules syntax
import { createExpressMiddleware } from 'openapi-mcp-bridge/express';Setup for TypeScript projects:
// package.json
{
"type": "module",
"scripts": {
"start": "tsx src/server.ts"
}
}// tsconfig.json
{
"compilerOptions": {
"module": "ES2022",
"moduleResolution": "node",
"target": "ES2022",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}Debug Mode
Enable detailed logging:
# CLI
openapi-mcp-bridge --definitions . --debug
# Environment variable
DEBUG=true openapi-mcp-bridge --definitions .
# Programmatic
const config = {
logging: { consoleFallback: true },
debug: true
};Validation Issues
# Check if OpenAPI file is valid
npx @redocly/cli lint your-api.yaml
# Force cache regeneration
OPENAPI_FORCE_REGEN=true openapi-mcp-bridge --definitions .
# Test tool generation
mcp-inspector npx openapi-mcp-bridge --definitions .Advanced Usage
Express Integration
// server.ts
import express from 'express';
import { createExpressMiddleware } from 'openapi-mcp-bridge/express';
const app = express();
// Add MCP endpoint
app.use('/mcp', createExpressMiddleware({
definitionsDirectory: './api-definitions',
defaultCredentials: {
username: process.env.API_USERNAME,
password: process.env.API_PASSWORD
}
}));
// Add health check
app.get('/health', (req, res) => {
res.json({ status: 'healthy' });
});
app.listen(3000, () => {
console.log('MCP server: http://localhost:3000/mcp');
});Standalone Server
import { MCPServer } from 'openapi-mcp-bridge';
const server = new MCPServer({
definitionsDirectory: './api-definitions',
port: 3000,
mountPath: '/mcp',
defaultCredentials: {
username: process.env.API_USERNAME,
password: process.env.API_PASSWORD
}
});
await server.start();
console.log('MCP server running on http://localhost:3000/mcp');Configuration
interface Config {
definitionsDirectory: string;
cacheDirectory?: string;
defaultCredentials?: {
username?: string;
password?: string;
token?: string;
apiKey?: string;
};
logging?: {
winston?: any;
pino?: any;
consoleFallback?: boolean;
};
mcpOptions?: {
serverName?: string;
serverVersion?: string;
};
}🏷️ Tool Naming & Discoverability
Naming Patterns
The library generates predictable tool names from OpenAPI operations:
| OpenAPI Operation | Generated Tool Name | Rule |
|-------------------|-------------------|------|
| GET /museum-hours with operationId: getMuseumHours | getMuseumHours | Uses operationId when available |
| POST /special-events with operationId: createSpecialEvent | createSpecialEvent | Uses operationId when available |
| GET /events/{eventId} | get-events-by-eventId | Auto-generated: {method}-{path}-by-{param} |
| DELETE /tickets/{ticketId} | delete-tickets-by-ticketId | Auto-generated: {method}-{path}-by-{param} |
| PATCH /users/{userId}/profile | patch-users-by-userId-profile | Auto-generated: handles nested paths |
Custom Tool Names
Override generated names using customization:
# museum-api.custom.yaml
toolAliases:
"getMuseumHours": "get-hours"
"createSpecialEvent": "create-event"
"get-events-by-eventId": "get-event-details"Tool Discovery
List available tools programmatically:
# Using MCP Inspector
mcp-inspector npx openapi-mcp-bridge --definitions ./api-definitions
# In Claude Code
"What tools are available?"
# In Claude Desktop
"List all museum API tools"📁 Project Structure
your-project/
├── api-definitions/
│ ├── museum-api.yaml # OpenAPI specification
│ ├── museum-api.custom.yaml # Optional customization
│ └── .cache/ # Auto-generated cache
├── src/
│ └── server.ts # Your server code
├── package.json # {"type": "module"}
└── tsconfig.json # ES2022 modules🔐 Authentication
Supports HTTP Basic, Bearer tokens, and API keys:
# museum-api.custom.yaml
authenticationOverrides:
- endpoint: "*"
credentials:
username: "${API_USERNAME}"
password: "${API_PASSWORD}"🧪 Testing
# Test tool generation
npm install -g @modelcontextprotocol/inspector
mcp-inspector npx openapi-mcp-bridge --definitions ./api-definitions
# Validate OpenAPI specs
npx @redocly/cli lint api-definitions/*.yaml
# Test with real API calls
node -e "
import { MCPClient } from '@modelcontextprotocol/client';
// ... client code
"📝 Examples
- Express Integration
- Standalone Server
- CLI Usage
- Claude Desktop Setup
- Claude Code Integration
- Complete Museum API
🤝 Contributing
- Fork the repository
- Create a feature branch
- Add tests for new functionality
- Ensure all tests pass
- Submit a pull request
📄 License
MIT License - see LICENSE file for details.
🙏 Acknowledgments
- Model Context Protocol for the MCP specification
- OpenAPI Initiative for the OpenAPI specification
- ReadMe OpenAPI Parser for robust OpenAPI parsing
Need help? Check our troubleshooting guide or open an issue.
