Skip to content

davidruzicka/mcp4openapi

Repository files navigation

MCP from OpenAPI

CI codecov npm Docker Hub License: MIT

Universal MCP server that generates tools from any OpenAPI specification.

Why This Project?

Transform any OpenAPI specification into MCP tools without writing code. Configure everything via MCP profiles, reduce LLM context pollution, and get production-ready features out of the box.

+-------------------+
|     MCP Client    |
| (Claude/IDE etc.) |
+---------+---------+
          |
          v
+--+------+---------+
|  |  MCP Profile   |
|  | (autogenerated |
|  |  if missing)   |
|  +----------------+
|                   |
| MCP Server        |
|                   |
|  +----------------+
|  |  OpenAPI Spec  |
|  |  (YAML/JSON)   |
+--+------+---------+
          |
          v
+---------+---------+
|    Service API    |
+-------------------+

Use Cases

  1. Less Context Pollution: Fewer tools with filtered response fields through profiles = more relevant context for LLM
  2. Multi-Environment: Same server, different profiles (dev/staging/prod)
  3. Custom Workflows: Composite tools for common multi-step operations

More about profiles: docs/PROFILE-GUIDE.md.

Key Features

Core

  • Any OpenAPI API: Works with OpenAPI 3.x specifications
  • Profiles: Create JSON configuration transforming API to MCP tools LLM friendly in profiles
  • Tool Aggregation: Reduce tool clutter - group related operations in profiles
  • Composite Actions: Chain API calls into workflows in profiles
  • OAuth 2.0: Browser-based authentication flow for HTTP transport (see docs/OAUTH.md)
  • Multi-Auth: Support multiple auth methods (OAuth + Bearer) with priority-based fallback (see docs/MULTI-AUTH.md)
  • Observability: Structured logging (console/JSON) with profile-aware token redaction, Prometheus metrics

Security Note

  • DNS rebinding protection: when binding to localhost (127.0.0.1/::1), the HTTP transport enforces Host header validation and returns 403 { "error": "Forbidden" } on mismatch. This mitigates browser-based DNS rebinding attacks against local development servers.
  • For remote deployments, bind to an explicit interface or place the server behind a reverse proxy that enforces strict Host checks and origin allowlists.

Check example profiles in profiles/.

Quick Start

Configuration File Locations

Cursor:

  • Project-Specific: .cursor/mcp.json in your project root
  • Global: default ~/.cursor/mcp.json in your home directory (various, platform-dependent location based on current Cursor profile; use Tools & MCPNew MCP Server)

VS Code + Copilot:

  • Project-Specific: .vscode/mcp.json in your project root
  • Global: ~/.config/Code/User/mcp.json in your home directory (platform-dependent; use Ctrl+Shift+PMCP: Open User Configuration)

JetBrains IDEs + Copilot:

  • Project-Specific: .idea/mcp.json in your project root
  • Global: ~/.config/github-copilot/intellij/mcp.json (platform-dependent; use GitHub Copilot icon bottom right → Edit Setting...Model Context Protocol (MCP)Configure)

Claude Code:

  • Project-Specific: .claude/mcp.json in your project root
  • Global: ~/.claude/mcp.json in your home directory (platform-dependent)

Option A: npx

No installation required.

VS Code + Copilot example:

Use VS Code dialog to enter access token (recommended for security):

Access Token (Bearer) example:

{
    "servers": {
        "mcp4openapi": {
            "command": "npx",
            "args": ["mcp4openapi"],
            "env": {
                "MCP4_OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
                "MCP4_API_TOKEN": "${input:MCP4_API_TOKEN}",
                "MCP4_API_BASE_URL": "https://api.example.com",
                "MCP4_PROFILE_PATH": "path/to/mcp-profile.json" //optional
            }
        },
        "inputs": [
            {
                "type": "promptString",
                "id": "MCP4_API_TOKEN",
                "description": "API Authorization Token",
                "password": true
            }
        ]
    }
}

inputs section prompts you for the token when the server starts, so environment variables are not needed.

Cursor example:

{
    "mcpServers": {
        "mcp4openapi": {
            "command": "npx",
            "args": ["mcp4openapi"],
            "env": {
                "MCP4_OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
                "MCP4_API_TOKEN": "${env:MCP4_API_TOKEN}",
                "MCP4_API_BASE_URL": "https://api.example.com",
                "MCP4_PROFILE_PATH": "path/to/mcp-profile.json" //optional
            }
        }
    }
}
⚠️ Prerequisites
  • MCP4_API_TOKEN with access token (Bearer) must be set.

Claude Code example:

claude mcp add --transport stdio mcp4openapi \
  --env MCP4_API_TOKEN="${MCP4_API_TOKEN}" \
  --env MCP4_OPENAPI_SPEC_PATH=path/to/openapi.yaml \
  --env MCP4_API_BASE_URL=https://api.example.com \
  --env MCP4_PROFILE_PATH=path/to/mcp-profile.json \
  -- npx mcp4openapi
⚠️ Prerequisites
  • MCP4_API_TOKEN with access token (Bearer) must be set.

JetBrains IDEs + Copilot example:

{
    "servers": {
        "mcp4openapi": {
            "command": "npx",
            "args": ["mcp4openapi"],
            "env": {
                "MCP4_OPENAPI_SPEC_PATH": "path/to/openapi.yaml",
                "MCP4_API_TOKEN": "${input:api_token}",
                "MCP4_API_BASE_URL": "https://api.example.com",
                "MCP4_PROFILE_PATH": "path/to/mcp-profile.json" //optional
            }
        }
    }
}
Note
  • JetBrains IDEs show ⚠️ right next to ${input:api_token} to indicate that you need to enter the token manually in the IDE dialog.

Option B: Docker

See docs/DOCKER.md for build, run, authentication modes, production deployment, and security.

Local Development

1. Clone & Install:

git clone https://github.com/davidruzicka/mcp4openapi.git
cd mcp4openapi
npm install

2. Build:

npm run build

3. Configure:

cp env.example .env
# Edit .env with your settings

4. Run:

npm start

See docs/HTTP-TRANSPORT.md for transport options (stdio vs HTTP) and authentication modes.

Custom CA Certificates

Node.js has a fixed list of certificate authorities. If your MCP server uses self-signed certificates, you need to configure Node.js to trust them.

Linux

Option 1: Disable certificate validation (test only)

export NODE_TLS_REJECT_UNAUTHORIZED=0
# Persist for current user
echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.profile

Option 2: Add custom CA to Node.js

export NODE_EXTRA_CA_CERTS=$HOME/ca-bundle.pem
# Persist for current user
echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.profile

Windows (PowerShell)

Option 1: Disable certificate validation (test only)

# Session only
$env:NODE_TLS_REJECT_UNAUTHORIZED = "0"
# Persist for current user
setx NODE_TLS_REJECT_UNAUTHORIZED 0

Option 2: Add custom CA to Node.js

# Session only
$env:NODE_EXTRA_CA_CERTS = "$env:USERPROFILE\ca-bundle.pem"
# Persist for current user
setx NODE_EXTRA_CA_CERTS "%USERPROFILE%\ca-bundle.pem"

macOS (zsh/bash)

Option 1: Disable certificate validation (test only)

# Session only
export NODE_TLS_REJECT_UNAUTHORIZED=0
# Persist for current user (zsh)
echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.zshrc
# or for bash
echo 'export NODE_TLS_REJECT_UNAUTHORIZED=0' >> $HOME/.bash_profile

Option 2: Add custom CA to Node.js

# Session only
export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"
# Persist for current user (zsh)
echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.zshrc
# or for bash
echo 'export NODE_EXTRA_CA_CERTS="$HOME/ca-bundle.pem"' >> $HOME/.bash_profile

Environment Variables

Required

  • MCP4_OPENAPI_SPEC_PATH: Path or URL to OpenAPI spec (YAML/JSON, supports local files and HTTP/HTTPS URLs)
  • MCP4_API_TOKEN: API token (default env var name; customizable via MCP4_AUTH_ENV_VAR)
    • Required for stdio mode with authenticated APIs
    • Optional for HTTP mode with per-session tokens sent in HTTP headers
    • When using no profile mode, auth type is auto-detected from OpenAPI security schemes if present

Optional - Core

  • MCP4_PROFILE_PATH: Profile JSON path (default: auto-generate tools from OpenAPI spec; warning logged if tool exceeds 60 parameters)
  • MCP4_TRANSPORT: stdio (default) or http
  • MCP4_API_BASE_URL: Override OpenAPI server URL

Optional - Authentication (No-Profile Mode)

When running without a profile, authentication is automatically configured from OpenAPI spec's security schemes:

  • MCP4_AUTH_ENV_VAR: Environment variable name for auth token (default: MCP4_API_TOKEN)

Supported OpenAPI Security Types:

  • Bearer Token (http with scheme: bearer): Uses Authorization: Bearer <token> header
  • API Key in Header (apiKey with in: header): Uses custom header (e.g., X-API-Key: <token>)
  • API Key in Query (apiKey with in: query): Adds token to query string (e.g., ?api_key=<token>)
  • OAuth2/OpenID Connect: Mapped to bearer token authentication (profile mode only)
  • Public APIs: No authentication if OpenAPI spec has no security defined

Example: Use custom env var for GitLab own instance token:

export MCP4_API_TOKEN=glpat-xxxxxxxxxxxx
export MCP4_API_BASE_URL=https://gitlab.example.com/api/v4
export MCP4_OPENAPI_SPEC_PATH=profiles/gitlab/openapi.yaml
export MCP4_PROFILE_PATH=profiles/gitlab/developer-profile.json
npm start

Force Authentication Override

For APIs with incomplete OpenAPI specs (missing security definition but requiring authentication):

  • MCP4_AUTH_FORCE: Enable force auth override (true|false, default: false)
  • MCP4_AUTH_TYPE: Authentication type: bearer|query|custom-header (default: bearer)
  • MCP4_AUTH_HEADER_NAME: Custom header name (required when MCP4_AUTH_TYPE=custom-header)
  • MCP4_AUTH_QUERY_PARAM: Query parameter name (required when MCP4_AUTH_TYPE=query)

Example: Force bearer authentication for incomplete spec:

export MCP4_AUTH_FORCE=true
export MCP4_AUTH_TYPE=bearer
export MCP4_API_TOKEN=your_token_here
export MCP4_OPENAPI_SPEC_PATH=./incomplete-spec.yaml
npm start

Example: Force custom header authentication:

export MCP4_AUTH_FORCE=true
export MCP4_AUTH_TYPE=custom-header
export MCP4_AUTH_HEADER_NAME=X-API-Key
export MCP4_API_TOKEN=your_api_key_here
npm start

Note: If OpenAPI spec has security defined, it takes precedence over force auth settings.

Optional - Tool Name Shortening

When generating tools from OpenAPI without a profile, long operation IDs may exceed limits. Configure automatic shortening:

  • MCP4_TOOLNAME_MAX: Maximum tool name length (default: 45)
  • MCP4_TOOLNAME_STRATEGY: Shortening strategy: none|balanced|iterative|hash|auto (default: none)
    • none: No shortening, only warnings
    • balanced: Add parts by importance until unique & meaningful (recommended)
    • iterative: Progressively remove noise until under limit (conservative)
    • hash: Use verb + resource + hash for guaranteed uniqueness
    • auto: Try strategies in order: balanced → iterative → hash
  • MCP4_TOOLNAME_WARN_ONLY: Only warn, don't shorten: true|false (default: true)
  • MCP4_TOOLNAME_MIN_PARTS: Minimum parts for balanced strategy (default: 3)
  • MCP4_TOOLNAME_MIN_LENGTH: Minimum length in chars for balanced strategy (default: 20)

Example: Apply balanced shortening (recommended):

export MCP4_TOOLNAME_STRATEGY=balanced
export MCP4_TOOLNAME_WARN_ONLY=false

Result for balanced strategy:

putApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId
    → put_alert_management_image (26 chars)
deleteApiV4ProjectsIdAlertManagementAlertsAlertIidMetricImagesMetricImageId
    → delete_alert_management_image (26 chars)

Example 2: Apply iterative shortening with 30 char limit:

export MCP4_TOOLNAME_STRATEGY=iterative
export MCP4_TOOLNAME_WARN_ONLY=false
export MCP4_TOOLNAME_MAX=30

Optional - HTTP Transport

  • MCP4_HOST: Bind address (default: 127.0.0.1)
  • MCP4_PORT: Port (default: 3003)
  • MCP4_ALLOWED_ORIGINS: Comma-separated origins (supports exact, wildcard *.domain.com, CIDR 192.168.1.0/24)
  • MCP4_SESSION_TIMEOUT_MS: Session timeout (default: 1800000 = 30min)
  • MCP4_HEARTBEAT_ENABLED, MCP4_HEARTBEAT_INTERVAL_MS: SSE heartbeat settings
  • MCP4_TOKEN_MAX_LENGTH: Maximum token length in characters (default: 1000)

See docs/HTTP-TRANSPORT.md for detailed HTTP transport configuration.

SSL/TLS Configuration

  • MCP4_SSL_CERT_FILE, MCP4_SSL_KEY_FILE: SSL certificate and key (PEM format)

When both are set, server automatically starts in HTTPS mode.

See docs/OAUTH.md for SSL configuration with OAuth.

OAuth 2.0 Configuration

Autodiscovery - Just provide DCR (Dynamic Client Registration) credentials, API base URL and OAuth callback:

export MCP4_API_BASE_URL=https://www.gitlab.com/api/v4
export MCP4_OAUTH_CLIENT_ID=your_dcr_client_id
export MCP4_OAUTH_CLIENT_SECRET=your_dcr_client_secret
export MCP4_OAUTH_REDIRECT_URI=http://mcp.local:3003/oauth/callback
# OAuth endpoints are automatically discovered from API base URL

Note: DCR and OAuth callback must be registered with the OAuth provider.

Configuration priority:

  1. Explicit URLs: MCP4_OAUTH_AUTHORIZATION_URL, MCP4_OAUTH_TOKEN_URL (highest priority)
  2. Explicit issuer: MCP4_OAUTH_ISSUER (auto-derives standard OAuth paths)
  3. Autodiscovery: From MCP4_API_BASE_URL (fetches RFC 8414 metadata or uses standard paths)

Environment variables:

  • MCP4_OAUTH_CLIENT_ID, MCP4_OAUTH_CLIENT_SECRET: OAuth client credentials (required)
  • MCP4_OAUTH_REDIRECT_URI: OAuth redirect URI (required, must match registered URI)
  • MCP4_OAUTH_ISSUER: OAuth provider issuer URL (optional, auto-derives endpoints)
  • MCP4_OAUTH_AUTHORIZATION_URL, MCP4_OAUTH_TOKEN_URL: OAuth endpoints (optional, for non-standard paths)

See docs/OAUTH.md for complete setup guide including OAuth application registration, SSL configuration, and troubleshooting.

HTTP Rate Limiting (Security)

  • MCP4_HTTP_RATE_LIMIT_ENABLED: Enable rate limiting (default: true)
  • MCP4_HTTP_RATE_LIMIT_WINDOW_MS: Rate limit window (default: 60000 = 1 minute)
  • MCP4_HTTP_RATE_LIMIT_MAX_REQUESTS: Max requests for MCP endpoints (default: 100)
  • MCP4_HTTP_RATE_LIMIT_METRICS_MAX: Max requests for /metrics (default: 10)

OAuth Rate Limiting (stricter limits for OAuth endpoints):

  • MCP4_OAUTH_RATE_LIMIT_MAX: Max OAuth requests per window (default: 10)
  • MCP4_OAUTH_RATE_LIMIT_WINDOW_MS: OAuth rate limit window (default: 600000 = 10 minutes)

Configuration Priority: Profile > Environment variables > Defaults

Defaults:

  • 100 requests/minute for MCP endpoints, 10 requests/minute for metrics
  • 10 requests/10 minutes for OAuth endpoints (/oauth/authorize, /oauth/token, /oauth/callback)

Returns 429 Too Many Requests when exceeded.

Optional - Observability

  • MCP4_LOG_LEVEL: debug, info (default), warn, error
  • MCP4_LOG_FORMAT: console (default) or json
  • MCP4_METRICS_ENABLED: Enable Prometheus metrics (default: false)
  • MCP4_METRICS_PATH: Metrics endpoint (default: /metrics)

Security Note:

  • Sensitive auth tokens are automatically redacted from logs based on your profile's auth configuration (bearer, query, or custom-header)
  • All errors returned to clients are sanitized to generic messages (Internal error) while full details are logged server-side

Profile System

Profile defines which MCP tools from OpenAPI spec are exposed and how to aggregate them. Start with existing profiles from profiles/ (e.g., GitLab).

Features:

  • Tool aggregation (group related operations)
  • Response field filtering (reduce LLM context)
  • Composite actions (chain API calls)
  • Rate limiting & retry logic

Create your own profiles: See docs/PROFILE-GUIDE.md

Testing & Validation

Validate Profile

npm run validate
# Checks: JSON syntax, schema, logic, OpenAPI operations

Validate Schema

npm run validate:schema
# Validates profile-schema.json itself

Run Tests

npm test

Troubleshooting MCP

Cursor:

  1. Open "Output" panel (Ctrl+Shift+U / Cmd+Shift+U)
  2. Select "MCP Logs" from dropdown
  3. Check for connection errors or authentication issues

VS Code:

  1. Open "Output" from View menu
  2. Select problematic MCP server from dropdown
  3. Review MCP tool logs for errors

JetBrains IDEs:

  1. Open "Help" → "Show Log in <your_explorer>" → "mcp" directory to access MCP log files
  2. Check <your_mcp_server>.log for MCP-related errors

Common Issues:

  • Connection refused: Check if MCP server is running and accessible
  • Authentication failed: Verify token is correct and has required permissions
  • Certificate errors: Configure Node.js to trust custom CA certificates (see Custom CA Certificates)
  • Tool not found: Verify OpenAPI spec path and profile configuration

IDE-Specific Documentation

Documentation

Project Status

  • Core MCP server with tool generation
  • stdio transport (MCP SDK)
  • HTTP Streamable transport (MCP Spec 2025-03-26)
  • Session management & SSE resumability
  • Profile system with validation
  • Prometheus metrics (HTTP, sessions, tools, API calls)

Contributing

See CONTRIBUTING.md for development guidelines.

License

MIT

About

Universal MCP server that generates MCP tools for any OpenAPI 3.x specification.

Resources

License

Contributing

Stars

Watchers

Forks

Packages