A multipurpose, configurable MCP (Model Context Protocol) server that automatically generates MCP tools, resources, and prompts from OpenAPI specifications and hosts a proxy, via the MCP protocol, to those API endpoints.
Given a set of openapi specs, it will create, via sensible defaults, a set of MCP Tools and MCP Resources. Also given a set of prompts provided as a set of JSON files, it will create MCP prompts for them and will be published together with the MCP Tools and Resources as a complete set of MCP capabilities to be used by any tool enabled LLM.
This app will work with an OpenAPI compliant endpoints and specification. The sensible defaults are overidable via configuration.
- π§ Automatic Tool Generation: Converts REST API endpoints to MCP tools
- π Resource Management: Exposes read-only data as MCP resources
- π¬ Custom Prompts: Load domain-specific prompt templates
- βοΈ Configurable Mapping: Override default tool/resource classification and function descriptions
- π Authentication Support: Bearer, API Key, and Basic auth
- π Multiple Deployment Modes: stdio for IDEs, MCP Streaming HTTP for web deployment
- π Multi-Spec Support: Load multiple OpenAPI specifications
Currently the app only takes a single network address as base backend API proxy address.
Therefore it is only suitable to be run as a sidecar for microservices where proxying is to localhost or if proxying to many different endpoints, it'll expect an API gateway address.
npm install -g mcp-openapi-servernpm install mcp-openapi-serverCreate a specs directory and add your OpenAPI specification files:
specs/
βββ banking-products.yaml
βββ banking-payments.yaml
βββ banking-payees.yaml
For IDE Integration (stdio mode):
mcp-openapi-serverFor Standalone Deployment (MCP Streaming HTTP mode):
mcp-openapi-server --http --port 4000With Custom Directories:
mcp-openapi-server --specs ./my-specs --config ./my-config.json --prompts ./my-prompts --verboseWith Custom Base URL:
# Override the backend API base URL (takes precedence over config file)
mcp-openapi-server --base-url https://api.example.com --specs ./specs --verbose
# For different environments (stdio mode)
mcp-openapi-server --base-url http://localhost:8080 --specs ./specs # Development
mcp-openapi-server --base-url https://staging-api.com --specs ./specs # Staging
mcp-openapi-server --base-url https://api.production.com --specs ./specs # Production
# For HTTP mode deployments
mcp-openapi-server --http --base-url https://api.example.com --specs ./specs --port 4000When to use Stdio Mode (Default):
- β IDE integration (Cursor, Claude Desktop, VS Code with MCP extensions)
- β Production MCP server deployment
- β Direct MCP client connections
- β Microservices with MCP protocol
When to use MCP Streaming HTTP Mode (--http flag):
- β Web application integration
- β Development and testing with HTTP clients
- β Health checks and monitoring endpoints
- β Docker deployments with port mapping
- β Load balancing and reverse proxy setups
- β Session-based MCP client connections
- π§ Future Server-Sent Events (SSE) streaming support
When to use HTTPS Mode (--https flag):
- β Production deployments requiring encryption
- β Secure MCP client connections over TLS
- β Compliance with security policies
- β Public-facing MCP server deployments
- β Integration with enterprise security infrastructure
Quick Mode Selection:
# For IDEs and MCP clients (recommended)
mcp-openapi-server
# For web APIs and MCP streaming HTTP
mcp-openapi-server --http
# For secure production deployments
mcp-openapi-server --https --key-file ./certs/server.key --cert-file ./certs/server.crtWhen developing the MCP OpenAPI server locally in your IDE, you can run it directly from the source code without installing globally:
Important: This project uses a spec duplication architecture that mirrors real-world deployment scenarios:
- Source Specs: The
sample-banking-apiproject contains the authoritative OpenAPI specifications - Example Specs: The
mcp-openapi/examples/specs/directory contains duplicated copies of these specs - Development Default: The MCP server defaults to using the example specs for development and testing
This architecture intentionally mimics production environments where:
- API services deploy their specs to accessible locations (registries, CDNs, etc.)
- MCP servers read specs from these deployed locations, not directly from source code
- Spec changes require explicit deployment/copying to be picked up by consumers
sample-banking-api/specs/, you must manually copy them to mcp-openapi/examples/specs/ for the MCP server to pick up the latest API signatures.
# After changing specs in sample-banking-api:
cp sample-banking-api/specs/*.yaml mcp-openapi/examples/specs/This manual step ensures you're consciously aware of API contract changes and their impact on MCP tool generation.
# Install dependencies first
npm installDevelopment Mode with Hot Reload (HTTP mode - Recommended for testing):
npm run devDevelopment Mode (Stdio mode for MCP integration testing):
npm run dev:stdioProduction HTTP Mode:
npm run build
npm run start:httpProduction Stdio Mode (MCP Integration):
npm run build
npm run start:stdioLegacy Start Command (HTTP mode):
npm run build
npm startRun Semgrep SAST
npm run sastFor Stdio Mode (IDE Integration):
# Set environment variables for authentication
export BANKING_API_TOKEN="your-service-token-here"
export USER_API_TOKEN="your-user-token-here"
# Run in stdio mode for MCP testing
npm run dev:stdioFor HTTP Mode (API Testing):
# Start HTTP server on port 4000
npm run start:http
# Test health endpoint
curl http://localhost:4000/health
# Test server info
curl http://localhost:4000/infoHTTP Mode (npm run dev or --http flag):
π MCP OpenAPI Server running on port 4000
π Health check: http://localhost:4000/health
βΉοΈ Server info: http://localhost:4000/info
π Loaded 3 specs, 4 tools, 5 resources, 2 prompts
Stdio Mode (npm run dev:stdio or default CLI):
π MCP OpenAPI Server running on stdio
π Using base URL: http://localhost:3001 (from config file)
β
Loaded 3 specs, 4 tools, 5 resources, 2 prompts
| Script | Mode | Purpose |
|---|---|---|
npm run dev |
HTTP | Development with hot reload and web interface |
npm run dev:stdio |
Stdio | Development for MCP integration testing |
npm run start |
HTTP | Production HTTP server (legacy) |
npm run start:stdio |
Stdio | Production MCP server (stdio mode) |
npm run start:http |
HTTP | Production HTTP server (explicit) |
npm run build |
- | Build TypeScript to JavaScript |
npm run test |
- | Run all tests |
- Hot Reload: The
npm run devcommand usestsxfor automatic TypeScript compilation and hot reloading - MCP Testing: Use
npm run dev:stdioto test MCP integration locally - Verbose Logging: Enabled by default, add
--verbose=falseto disable - Banking Examples: Use the pre-configured banking examples in
./examples/for testing - Authentication Testing: Set environment variables for token passthrough testing
- Mode Selection: Choose stdio for IDE integration, HTTP for web APIs
- Testing:
β οΈ Stopsample-banking-apiserver before running tests - tests expect specific error conditions
The MCP OpenAPI Server can be used in two primary ways:
Run as an independent server process, perfect for:
- IDE integration (Cursor, Claude Desktop)
- Microservices architecture
- Development and testing
# Install globally
npm install -g mcp-openapi-server
# Run in stdio mode (default - for IDE integration)
mcp-openapi-server --specs ./specs --config ./mcp-config.json
# Run in HTTP mode (for web integration and testing)
mcp-openapi-server --http --port 4000 --specs ./specs --config ./mcp-config.json
# Run with custom base URL (overrides config file setting)
mcp-openapi-server --base-url https://api.example.com --specs ./specs --config ./mcp-config.json
# Stdio mode with custom base URL (for production MCP servers)
mcp-openapi-server --base-url https://api.production.com --specs ./specs --config ./mcp-config.json# Build Docker image
docker build -t mcp-openapi-server .
# Run container in HTTP mode (for web deployment)
docker run -p 4000:4000 -v ./specs:/app/specs -v ./config:/app/config mcp-openapi-server --http --port 4000
# Run container in stdio mode (for MCP integration - requires interactive mode)
docker run -i -v ./specs:/app/specs -v ./config:/app/config mcp-openapi-serverImport into your existing Node.js applications:
npm install mcp-openapi-serverimport { MCPOpenAPIServer } from 'mcp-openapi-server';
// Create and initialize server
const mcpServer = new MCPOpenAPIServer({
specsDir: './api-specs',
configFile: './mcp-config.json',
promptsDir: './prompts',
verbose: true
});
await mcpServer.initialize();
// Run in stdio mode (default - for MCP integration)
await mcpServer.runStdio();
// OR run in HTTP mode (for web integration)
// await mcpServer.runHttp(4000);import express from 'express';
import { MCPOpenAPIServer } from 'mcp-openapi-server';
const app = express();
const mcpServer = new MCPOpenAPIServer({
specsDir: './specs',
configFile: './config.json'
});
await mcpServer.initialize();
// Add MCP endpoint to existing Express app
app.post('/mcp', async (req, res) => {
// Custom MCP request handling
res.json({ status: 'MCP server integrated' });
});
// Run your existing app with MCP capabilities
app.listen(8080);import { createMCPServer, startServer } from 'mcp-openapi-server';
// Quick server creation
const server = createMCPServer({
specsDir: './specs',
port: 3000
});
// One-line server start
await startServer({
specsDir: './specs',
mode: 'http',
port: 4000
});import { MCPOpenAPIServer, ServerOptions } from 'mcp-openapi-server';
class CustomMCPServer extends MCPOpenAPIServer {
constructor(options: ServerOptions) {
super(options);
}
// Override or extend functionality
async customInitialization() {
await this.initialize();
// Add custom logic
}
}
const customServer = new CustomMCPServer({
specsDir: './specs',
configFile: './config.json'
});{
"baseUrl": "http://localhost:3000",
"authentication": {
"type": "bearer",
"envVar": "API_TOKEN"
},
"cors": {
"origin": "*",
"credentials": true
},
"overrides": [
{
"specId": "banking-payments",
"path": "/api/payments",
"method": "get",
"type": "tool",
"toolName": "search_payments"
},
{
"specId": "banking-products",
"path": "/api/products",
"method": "get",
"type": "resource",
"resourceUri": "banking://products/catalog"
}
]
}The base URL for backend APIs can be configured in multiple ways with the following priority order:
- CLI
--base-urloption (highest priority) - Config file
baseUrlsetting - Default:
http://localhost:3000(lowest priority)
Examples:
# CLI option overrides config file
mcp-openapi-server --base-url https://api.production.com --config ./mcp-config.json
# When --verbose is used, you'll see which base URL source is active:
# π Using base URL: https://api.production.com (from CLI --base-url)The MCP server supports token passthrough - user tokens take priority over service tokens for better security.
Bearer Token:
{
"authentication": {
"type": "bearer",
"envVar": "API_TOKEN" // Service token fallback
}
}API Key:
{
"authentication": {
"type": "apikey",
"headerName": "X-API-Key",
"envVar": "API_KEY" // Service token fallback
}
}Basic Auth:
{
"authentication": {
"type": "basic",
"envVar": "BASIC_AUTH_CREDENTIALS" // Service token fallback
}
}- User Token (highest priority) - forwarded from MCP client
- stdio mode:
USER_API_TOKENorMCP_USER_TOKENenvironment variable - HTTP mode:
Authorizationheader from request
- stdio mode:
- Service Token (fallback) - configured in
mcp-config.json- Used when no user token is available
- Good for system operations and testing
The MCP server provides authentication-aware error handling with structured responses and security monitoring.
401 Unauthorized:
{
"error": "AUTHENTICATION_REQUIRED",
"message": "Invalid or expired authentication token",
"suggestion": "Check your API token or re-authenticate",
"status": 401,
"tool": "banking-payments_post__banking_payments_payTo"
}403 Forbidden:
{
"error": "INSUFFICIENT_PERMISSIONS",
"message": "Access denied for this operation",
"suggestion": "Contact administrator for required permissions",
"status": 403,
"tool": "banking-payments_post__banking_payments_payTo"
}Other HTTP Errors (400, 500, etc.):
{
"error": "HTTP_ERROR",
"message": "HTTP 400: Bad Request",
"status": 400,
"tool": "banking-payments_post__banking_payments_payTo",
"url": "http://localhost:3000/banking/payments",
"details": {
"error": "VALIDATION_ERROR",
"message": "Invalid payment amount",
"field": "amount"
}
}- Request Size Limiting: Configurable JSON payload size limits prevent DoS attacks (default: 2MB)
- Security Event Logging: 401/403 errors are logged with
[SECURITY]prefix for monitoring - Error Context Preservation: Backend API error responses are included in
details - Privacy Protection: Query parameters are stripped from URLs in error messages
- Structured Responses: All errors return JSON with consistent format instead of throwing exceptions
The server automatically limits JSON request body sizes to prevent denial-of-service attacks and memory exhaustion:
# Use default 2MB limit
mcp-openapi-server --http
# Set custom request limit
mcp-openapi-server --http --max-request-size 5mb
# Set custom response limit (for large backend API responses)
mcp-openapi-server --http --max-response-size-mb 100
# Other valid request size formats
mcp-openapi-server --max-request-size 1024kb
mcp-openapi-server --max-request-size 512kbRecommended limits for banking APIs:
- Conservative:
1mb- Handles most banking operations with safety margin - Standard:
2mb(default) - Balances security and functionality - Liberal:
5mb- For batch operations or document attachments
Add x-spec-id to avoid naming conflicts:
openapi: 3.0.0
info:
title: Banking Products API
version: 1.0.0
x-spec-id: banking-products # Custom identifier
paths:
/api/products:
get:
summary: Get all products
# ... rest of specDefault Mapping:
GETrequests β Resources (unless complex)POST,PUT,PATCH,DELETEβ Tools
Complex GET requests become Tools if they have:
- Parameters named:
search,filter,query,analyze - Summaries containing:
search,analyze,calculate,generate,process,compute
Create JSON files in the prompts directory:
{
"name": "fraud_analysis",
"description": "Analyze transaction for fraud indicators",
"arguments": [
{
"name": "transaction",
"description": "Transaction data to analyze",
"required": true
},
{
"name": "account_history",
"description": "Recent account activity",
"required": true
}
],
"template": "You are a banking fraud detection expert. Analyze this transaction:\n\nTRANSACTION:\n{{transaction}}\n\nACCOUNT HISTORY:\n{{account_history}}\n\nProvide:\n1. Risk score (0-100)\n2. Risk factors identified\n3. Recommendation (APPROVE/REVIEW/BLOCK)\n4. Reasoning"
}Create .cursor/mcp.json:
β οΈ Important: Cursor's MCP implementation doesn't support thecwdproperty and requires absolute paths.
{
"mcpServers": {
"mcp-openapi": {
"command": "node",
"args": [
"/absolute/path/to/your/project/mcp-openapi/dist/cli.js",
"--specs", "/absolute/path/to/your/project/mcp-openapi/examples/specs",
"--config", "/absolute/path/to/your/project/mcp-openapi/examples/mcp-config.json",
"--prompts", "/absolute/path/to/your/project/mcp-openapi/examples/prompts"
],
"env": {
"BANKING_API_TOKEN": "mcp-service-token-demo-123"
}
}
}
}Configuration Notes:
- Replace
/absolute/path/to/your/projectwith the actual absolute path where you've cloned this repository - The
env.BANKING_API_TOKENis configured to work with the included sample banking API - Ensure the project is built (
npm run build) before running - All paths must be absolute - relative paths and
cwdproperties don't work reliably in Cursor
Add to claude_desktop_config.json:
{
"mcpServers": {
"banking-apis": {
"command": "mcp-openapi-server",
"args": ["--specs", "./specs"]
}
}
}For detailed programmatic usage examples, see the Usage Modes section above.
// Main class
export { MCPOpenAPIServer } from './server.js';
// All TypeScript interfaces
export * from './types.js';
// Helper functions
export function createMCPServer(options?: ServerOptions): MCPOpenAPIServer;
export async function startServer(options?: ServerOptions & { mode?: 'stdio' | 'http' }): Promise<void>;interface ServerOptions {
specsDir?: string; // Directory containing OpenAPI specs
configFile?: string; // Path to MCP configuration file
promptsDir?: string; // Directory containing prompt templates
port?: number; // HTTP server port
verbose?: boolean; // Enable verbose logging
baseUrl?: string; // Base URL for backend APIs (overrides config file)
maxToolNameLength?: number; // Maximum length for generated tool names (default: 48)
maxRequestSize?: string; // Maximum size for JSON request bodies (default: "2mb")
}Options:
-s, --specs <dir> Directory containing OpenAPI specifications (default: "./examples/specs")
-c, --config <file> Configuration file path (default: "./examples/mcp-config.json")
-p, --prompts <dir> Directory containing prompt specifications (default: "./examples/prompts")
--port <number> Port for HTTP server mode (default: "4000")
--base-url <url> Base URL for backend APIs (overrides config file)
--max-tool-name-length <number> Maximum length for generated tool names (default: "48")
--max-request-size <size> Maximum size for JSON request bodies (default: "2mb")
--max-response-size-mb <number> Maximum size for backend API responses in MB (default: "50")
--https-client-ca <path> Path to CA certificate file for HTTPS backend APIs
--https-client-cert <path> Path to client certificate file for HTTPS backend APIs
--https-client-key <path> Path to client private key file for HTTPS backend APIs
--https-client-pfx <path> Path to client PFX/PKCS12 file for HTTPS backend APIs
--https-client-passphrase <pass> Passphrase for client private key
--https-client-reject-unauthorized Reject self-signed certificates (default: true)
--https-client-timeout <ms> HTTPS request timeout in milliseconds (default: "30000")
--http Run in HTTP server mode instead of stdio (default: false)
--https Enable HTTPS mode (requires certificate files)
--https-port <number> Port for HTTPS server mode (default: "4443")
--key-file <path> Path to private key file for HTTPS
--cert-file <path> Path to certificate file for HTTPS
--pfx-file <path> Path to PFX/PKCS12 file for HTTPS (alternative to key/cert)
--passphrase <passphrase> Passphrase for encrypted private key
-v, --verbose Enable verbose logging (default: true)
-h, --help Display help for command
Mode Selection:
- Default (no
--httpflag): Stdio mode - ideal for IDE integration (Cursor, Claude Desktop) - With
--httpflag: HTTP mode - ideal for web integration, testing, and standalone deployment - With
--httpsflag: HTTPS mode - secure web integration with TLS encryption
When running with --http, the server implements the MCP Streaming HTTP protocol with session management:
- β
Session Management: Each client gets a unique session ID via
Mcp-Session-Idheader - β JSON-RPC 2.0: Standard MCP message format over HTTP
- β Stateful Connections: Sessions maintain client context and authentication
- β Session Cleanup: Automatic cleanup of expired sessions (30 minutes)
- π§ Server-Sent Events: Placeholder for future streaming implementation
The server exposes exactly 3 endpoints when running in HTTP/HTTPS mode:
| Method | Endpoint | Purpose | Status |
|---|---|---|---|
POST |
/mcp |
MCP JSON-RPC endpoint - All MCP protocol communication | β Active |
GET |
/mcp |
SSE streaming placeholder - Future server-to-client streaming | π§ Placeholder |
GET |
/health |
Health check - Server status and session count | β Active |
GET |
/info |
Server information - Specs, tools, resources, prompts | β Active |
Important Notes:
- β
All MCP operations (tools, resources, prompts) go through the single
POST /mcpendpoint using JSON-RPC 2.0 messages - β No separate REST endpoints - The server follows MCP Streaming HTTP protocol specification
- β Health and info endpoints remain separate for monitoring and DevOps purposes
- Initialize Session: Client sends
initializemethod toPOST /mcp - Session Created: Server responds with
Mcp-Session-Idheader - Subsequent Requests: Client includes session ID in all future requests
- Session Validation: Server validates session for each request
MCP Protocol Communication:
# Initialize session
curl -X POST http://localhost:4000/mcp \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "initialize",
"params": {
"protocolVersion": "2024-11-05",
"clientInfo": {"name": "my-client", "version": "1.0.0"}
},
"id": 1
}'
# Response includes: Mcp-Session-Id header
# List tools (requires session ID)
curl -X POST http://localhost:4000/mcp \
-H "Content-Type: application/json" \
-H "Mcp-Session-Id: your-session-id" \
-d '{
"jsonrpc": "2.0",
"method": "tools/list",
"id": 2
}'Health Check:
curl http://localhost:4000/health
# Returns: {"status": "ok", "sessions": 2, "tools": 5, ...}Server Information:
curl http://localhost:4000/info
# Returns: {"specs": [...], "tools": [...], "resources": [...]}{
"status": "ok",
"specs": ["banking-products", "banking-payments"],
"tools": 12,
"resources": 3,
"prompts": 2,
"sessions": 3,
"version": "1.0.0",
"protocol": "MCP Streaming HTTP (SSE placeholder)"
}Configure the MCP OpenAPI server to serve MCP clients over secure HTTPS connections with TLS encryption:
Option 1: Separate Key and Certificate Files
# Generate or obtain SSL certificate files for the MCP server
mcp-openapi-server --https \
--key-file ./certs/mcp-server.key \
--cert-file ./certs/mcp-server.crt \
--https-port 4443Option 2: PFX/PKCS12 File
# Use a single PFX file for the MCP server (common in Windows environments)
mcp-openapi-server --https \
--pfx-file ./certs/mcp-server.pfx \
--passphrase mypassword \
--https-port 4443Development HTTPS Setup:
# Development HTTPS mode for secure MCP client connections
mcp-openapi-server --https \
--key-file ./certs/dev-server.key \
--cert-file ./certs/dev-server.crt \
--https-port 4443 \
--specs ./specs \
--config ./mcp-config.jsonProduction HTTPS Setup:
# Production HTTPS setup for serving MCP clients securely
mcp-openapi-server --https \
--pfx-file ./production/certs/mcp-server.pfx \
--passphrase $MCP_SERVER_CERT_PASSPHRASE \
--https-port 443 \
--specs ./production/specs \
--config ./production/mcp-config.jsonWhen MCP server HTTPS is enabled, you'll see:
π MCP OpenAPI HTTPS Server running on port 4443
π Health check: https://localhost:4443/health
βΉοΈ Server info: https://localhost:4443/info
π Loaded 3 specs, 4 tools, 5 resources, 2 prompts
For MCP Server --key-file and --cert-file:
- Private key file (
.key,.pem) for the MCP server - Certificate file (
.crt,.cer,.pem) for the MCP server - Both files must be readable by the MCP server process
- Certificate must be valid for the domain/IP where MCP clients will connect
For MCP Server --pfx-file:
- Single PKCS#12 file (
.pfx,.p12) containing both key and certificate for the MCP server - Optional passphrase for encrypted PFX files
- Certificate must be valid for the domain/IP where MCP clients will connect
MCP Server HTTPS mode provides:
- β Encrypted MCP client connections - All JSON-RPC 2.0 messages from clients encrypted with TLS
- β
Secure session management -
Mcp-Session-Idheaders protected in transit - β TLS certificate validation - Standard HTTPS security for MCP clients
- β Future secure SSE - Ready for encrypted Server-Sent Events to clients
- β Production-ready - Suitable for production MCP server deployments serving multiple clients
Certificate file not found:
β οΈ Private key file not found: ./certs/private.key
- Verify file paths are correct and files exist
- Check file permissions are readable
Invalid certificate:
β οΈ Error reading HTTPS certificate files: Invalid certificate format
- Verify certificate files are valid PEM or PFX format
- Check certificate and key match
- Ensure passphrase is correct for encrypted files
The examples/ directory contains a complete banking API example:
Directory Structure:
examples/
βββ specs/
β βββ banking-products.yaml # Product management API
β βββ banking-payments.yaml # Payment processing API
β βββ banking-payees.yaml # Payee management API
βββ prompts/
β βββ fraud-analysis.json # Fraud detection prompt
β βββ loan-recommendation.json # Loan recommendation prompt
βββ mcp-config.json # Configuration with overrides
Generated MCP Items:
- Tools:
banking_payments_post_payTo,banking_payees_post,banking_payees_put,banking_payees_delete,search_payments - Resources:
banking-products://banking/products,banking-payees://banking/payees - Prompts:
fraud_analysis,loan_recommendation
# Run with the banking examples
mcp-openapi-server --specs ./examples/specs --config ./examples/mcp-config.json --prompts ./examples/prompts --verbose
# Or for HTTP mode
mcp-openapi-server --http --specs ./examples/specs --config ./examples/mcp-config.json --prompts ./examples/promptsOpenAPI Spec (specs/ecommerce.yaml):
openapi: 3.0.0
info:
title: E-commerce API
x-spec-id: ecommerce
paths:
/products:
get:
summary: List products
/orders:
post:
summary: Create order
/orders/search:
get:
summary: Search orders with filters
parameters:
- name: search
in: queryGenerated:
- Resource:
ecommerce://products(simple GET) - Tool:
ecommerce_post_orders(POST operation) - Tool:
ecommerce_get_orders_search(complex GET with search)
1. "Specs directory does not exist"
mkdir specs
# Add your OpenAPI files to specs/2. "Tool execution failed"
- Check
baseUrlin config - Verify API server is running
- Check authentication configuration
3. "No tools/resources generated"
- Verify OpenAPI specs are valid
- Check file extensions (.yaml, .yml, .json)
- Enable
--verbosefor detailed logging
mcp-openapi-server --verboseThe project includes comprehensive unit and integration tests:
sample-banking-api server before running tests. The integration tests will fail if the banking API server is running because the tests expect specific error conditions that get masked when the real API responds.
# FIRST: Stop the sample-banking-api if it's running
# (In the sample-banking-api directory: Ctrl+C or kill the process)
# THEN: Run all tests
npm test
# Run unit tests only
npm run test:unit
# Run integration tests only
npm run test:integration
# Run MSW HTTP mocking tests only
npm run test:msw
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coveragetests/basic.test.ts- Unit tests validating the banking examples and core functionality (27 tests)tests/integration.test.ts- Integration tests validating server functionality end-to-end (21 tests)tests/msw-integration.test.ts- HTTP mocking tests using MSW (Mock Service Worker) (8 tests)
The tests validate:
-
Unit Tests (27/27 passing):
- File structure and example completeness
- OpenAPI spec structure and content
- Banking API schema definitions and constraints
- MCP configuration and overrides
- Custom prompt structure and templates
- HTTP method classification logic
- Banking domain-specific validation patterns
- Authentication configuration handling
-
Integration Tests (21/21 passing):
- Server initialization with banking examples
- Tool and resource generation from OpenAPI specs
- Tool structure validation and URL construction
- Resource URI validation and parsing
- Custom prompt loading and template processing
- Configuration handling and authentication
- Error handling and validation
- Non-existent item handling
-
MSW HTTP Mocking Tests (13/13 passing):
- HTTP request mocking with successful responses
- HTTP error response handling (400, 500, etc.)
- Resource reading with mocked GET requests
- Token Passthrough Validation:
- 401 errors when no authentication token provided
- User token passthrough to backend APIs
- Service token fallback when no user token available
- User token priority over service tokens
- Token passthrough for both tools and resources
- Enhanced Error Handling:
- Authentication-aware error responses (401/403)
- Structured error messages with actionable suggestions
- Security event logging for monitoring
- Backend error context preservation
- Network error graceful handling
Total: 61/61 tests passing (100% success rate)
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE file for details.
Configure the MCP OpenAPI server to connect securely to backend APIs over HTTPS with custom certificates and validation options.
Add httpsClient configuration to your mcp-config.json for secure backend API connections:
{
"baseUrl": "https://secure-backend-api.example.com",
"httpsClient": {
"rejectUnauthorized": true,
"timeout": 30000,
"keepAlive": true,
"certFile": "./certs/backend-client.crt",
"keyFile": "./certs/backend-client.key",
"caFile": "./certs/backend-ca.crt",
"passphrase": "optional-key-passphrase"
}
}# Basic backend API HTTPS client options
mcp-openapi-server --base-url https://secure-backend-api.com \
--https-client-reject-unauthorized \
--https-client-timeout 30000
# Backend API client certificate authentication
mcp-openapi-server --base-url https://secure-backend-api.com \
--https-client-cert ./certs/backend-client.crt \
--https-client-key ./certs/backend-client.key
# Custom CA certificate for backend API
mcp-openapi-server --base-url https://secure-backend-api.com \
--https-client-ca ./certs/backend-ca.crt
# PFX/PKCS12 certificate for backend API
mcp-openapi-server --base-url https://secure-backend-api.com \
--https-client-pfx ./certs/backend-client.p12 \
--https-client-passphrase mypassword| Option | Type | Default | Description |
|---|---|---|---|
rejectUnauthorized |
boolean | true |
Reject self-signed certificates from backend APIs |
timeout |
number | 30000 |
Request timeout for backend API calls in milliseconds |
keepAlive |
boolean | true |
Use HTTP keep-alive for backend API connections |
certFile |
string | - | Path to client certificate file for backend API authentication |
keyFile |
string | - | Path to client private key file for backend API authentication |
pfxFile |
string | - | Path to PFX/PKCS12 file for backend API authentication (alternative to cert/key) |
caFile |
string | - | Path to custom CA certificate for backend API validation |
passphrase |
string | - | Passphrase for encrypted private key used with backend APIs |
-
Separate Certificate and Key Files for Backend API
{ "certFile": "./certs/backend-client.crt", "keyFile": "./certs/backend-client.key" } -
PFX/PKCS12 Bundle for Backend API
{ "pfxFile": "./certs/backend-client.p12", "passphrase": "optional" } -
Custom CA Certificate for Backend API
{ "caFile": "./certs/backend-ca.crt" }
- If
certFileis provided for backend API authentication,keyFileis required - If
keyFileis provided for backend API authentication,certFileis required - Cannot specify both
cert/keyfiles andpfxFilesimultaneously for backend API authentication - Encrypted certificate files require
passphrasefor backend API connections - All certificate files must exist and be readable by the MCP server
- Timeout must be between 1000ms and 300000ms for backend API requests
- No HTTPS config: Uses standard HTTP client with default Node.js settings for backend API connections
- Partial config: Validates configuration and fails startup if incomplete backend API HTTPS configuration
- Complete config: Enables HTTPS client with custom certificates and settings for secure backend API connections
- Memory Limit: Responses larger than 50MB (configurable via
maxResponseSizeMB) will be rejected to prevent memory issues - No Streaming: Server-Sent Events (SSE) streaming is not yet implemented, so large responses must be handled by:
- Increasing the
maxResponseSizeMBlimit (not recommended for very large payloads) - Implementing pagination at the backend API level
- Waiting for SSE streaming implementation (future enhancement)
- Increasing the
Configuration Options:
# CLI option
--max-response-size-mb 100
# Config file option
{
"maxResponseSizeMB": 100
}- Single Base URL: Only one backend API base URL is supported per server instance
- Multi-Backend Workaround: For multiple backend services, use an API Gateway or reverse proxy to provide a unified endpoint
- Recommended Architecture:
MCP Client β mcp-openapi β API Gateway β Multiple Backend APIs
- SSE Streaming: Server-Sent Events endpoint (
GET /mcp) is a placeholder - not yet implemented - Session Persistence: Sessions are in-memory only (lost on server restart)
- Real-time Updates: No push notifications or real-time data streaming
- π Report Issues
- π¬ Discussions
- π Documentation