MCP ExplorerExplorer

Mcpgateway

@michlynon a month ago
1 MIT
FreeCommunity
AI Systems
Enhanced version of supergateway, adding streamablehttp support and the ability to run MCP services based on both OpenAPI protocol interface documentation and higress MCP template files.

Overview

What is Mcpgateway

McpGateway is an enhanced version of supergateway that adds support for streamable HTTP and enables the execution of MCP services based on OpenAPI protocol interface documentation and higress MCP template files.

Use cases

Use cases for McpGateway include running MCP servers over different transport protocols, converting existing OpenAPI specifications into MCP tools, and managing multiple concurrent sessions in a scalable manner.

How to use

To use McpGateway, run it via npx with the command: npx -y @michlyn/mcpgateway --stdio "uvx mcp-server-git". You can specify various options such as the transport method and server URL.

Key features

Key features include protocol conversion between stdio, SSE, WS, and Streamable HTTP, automatic conversion of OpenAPI 3 specifications to MCP tools, robust session management, and detailed logging.

Where to use

McpGateway can be used in various fields including web services, API integration, and real-time data streaming applications where interoperability between different MCP transport protocols is required.

Content

Enhanced version of https://github.com/supercorp-ai/supergateway, adding streamablehttp support and the ability to run MCP services based on both OpenAPI protocol interface documentation and higress MCP template files.

McpGateway

McpGateway is a versatile protocol conversion tool for Model Context Protocol (MCP) servers, enabling:

  1. Running MCP stdio-based servers over SSE (Server-Sent Events), WebSockets (WS), or Streamable HTTP
  2. Converting OpenAPI 3.0.1 interface definitions to MCP tools
  3. Providing seamless interoperability between different MCP transport protocols

Key Features

Protocol Conversion

  • Convert between stdio, SSE, WS, and Streamable HTTP (bidirectionally)
  • Support multiple concurrent sessions with proper session management
  • Provide comprehensive MCP protocol compatibility

API Integration

  • Convert OpenAPI 3 specifications to MCP tools automatically
  • Generate tool names, descriptions, and parameter definitions from API specs
  • Support complex parameter types with validation rules
  • Automatically detect OpenAPI specs or MCP templates

Session Management

  • Robust session tracking with unique session IDs
  • Automatic session timeout cleanup
  • Detailed session status logging
  • Fallback mechanisms for session ID mismatches

Installation & Usage

Run McpGateway via the unified npx command. The system automatically detects whether to run in single-server or multi-server mode based on your parameters:

# Single server mode (auto-detected from parameters)
npx -y @michlyn/mcpgateway --stdio "uvx mcp-server-git"
npx -y @michlyn/mcpgateway --stdio "uvx mcp-server-git" --outputTransport streamable-http

# Multi-server mode (auto-detected from parameters)
npx -y @michlyn/mcpgateway --config mcp-servers.json
npx -y @michlyn/mcpgateway mcp-servers.json

Automatic Mode Detection

The unified mcpgateway command intelligently determines the appropriate mode:

Single Server Mode - Detected when using:

  • --stdio "command" - Run MCP stdio server
  • --sse "url" - Connect to SSE server
  • --api "spec.json" --apiHost "url" - Convert OpenAPI to MCP
  • Other single-server specific parameters

Multi Server Mode - Detected when using:

  • --config config.json - Multi-server configuration
  • config.json - Direct config file path
  • --routerPort - Router port specification

Multi-Server Mode

Support running multiple MCP servers with dynamic routing through a single unified port. Features hot configuration reload and automatic server discovery.

Dynamic Routing Features

  • Single External Port: Docker exposes only port 80
  • Hot Configuration Reload: Modify mcp-servers.json without restart
  • Automatic Server Discovery: Routes based on server names
  • Health Monitoring: Built-in health checks for all servers
  • Simplified Architecture: Direct routing without proxy layer

Configuration File Format

Create a mcp-servers.json configuration file:

{
  "mcpServers": {
    "mcp-server-feedback": {
      "api": "https://example.com/api/feedback.json",
      "apiHost": "https://example.com/api",
      "outputTransport": "streamable-http",
      "port": 8000,
      "httpPath": "/mcp",
      "ignoreHeader": true
    },
    "server-filesystem": {
      "stdio": "npx -y @modelcontextprotocol/server-filesystem /data",
      "outputTransport": "sse",
      "port": 8001,
      "ssePath": "/sse",
      "messagePath": "/message"
    },
    "comp-info-server": {
      "api": "/data/openapi.json",
      "apiHost": "https://example.com/api",
      "outputTransport": "sse",
      "port": 8002,
      "ssePath": "/sse",
      "messagePath": "/message"
    }
  }
}

Start Multi-Server

# Dynamic multi-server with unified routing (Recommended)
npx -y @michlyn/mcpgateway --config mcp-servers.json

# 🆕 Remote configuration support
npx -y @michlyn/mcpgateway --config https://api.example.com/mcp-servers.json

🆕 Remote Configuration Support

The configuration file now supports remote URLs with automatic monitoring for changes:

Features:

  • 🌐 HTTP/HTTPS URLs: Load configuration from remote servers
  • 🔄 Auto-monitoring: Check for updates every 30 seconds
  • Cache Validation: Support Last-Modified and ETag headers
  • 🚀 Hot Reload: Automatically reload routes when config changes
  • ⏱️ Fast Response: 1-second response time for configuration updates

Examples:

# Use remote configuration
npx -y @michlyn/mcpgateway --config https://api.example.com/mcp-servers.json --routerPort 80

# Use local configuration
npx -y @michlyn/mcpgateway --config ./mcp-servers.json --routerPort 80

Access Patterns

Dynamic Routing (Recommended):

  • Unified Entry: http://localhost:80/{server-name}/{path}
  • Server Status: http://localhost:80/servers
  • Health Check: http://localhost:80/health

Examples:

  • Feedback Server: http://localhost:80/mcp-server-feedback/mcp
  • Filesystem Server: http://localhost:80/server-filesystem/sse
  • Info Server: http://localhost:80/comp-info-server/sse

Docker Deployment

Deploy using the unified Docker configuration that supports both single and multi-server modes:

# Multi-server mode (auto-detected)
docker run -it --rm -p 80:80 -v $(pwd)/mcp-servers.json:/app/mcp-servers.json \
    michlyn/mcpgateway --config mcp-servers.json

# Single server mode (auto-detected)
docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /" --port 8000

Unified Docker Features:

  • Intelligent Startup: Automatically detects single vs multi-server mode
  • Single Port: External port 80 with internal dynamic routing
  • Smart Health Checks: Multi-port health monitoring
  • Seamless Operation: No mode keywords needed, just provide your parameters

For detailed Docker usage instructions, see: Docker Usage Guide

Common Options

  • --stdio "command": Command that runs an MCP server over stdio
  • --sse "https://mcp-server-url.example.com": SSE URL to connect to (SSE→stdio mode)
  • --outputTransport stdio | sse | ws | streamable-http: Output MCP transport (default: sse with --stdio, stdio with --sse)
  • --port 8000: Port to listen on (default: 8000)
  • --baseUrl "http://localhost:8000": Base URL for SSE, WS, or Streamable HTTP clients (optional)
  • --header "x-user-id: 123": Add custom headers (can be used multiple times)
  • --oauth2Bearer "some-access-token": Add an Authorization header with the provided Bearer token
  • --logLevel info | none: Control logging level (default: info)
  • --cors: Enable CORS (use with no values to allow all origins, or specify allowed origins)
  • --healthEndpoint /healthz: Register endpoints that respond with "ok"

Path Options

  • --ssePath "/sse": Path for SSE subscriptions (default: /sse)
  • --messagePath "/message": Path for messages (default: /message)
  • --httpPath "/mcp": Path for Streamable HTTP (default: /mcp)

API Integration Options

  • --api "./openapi.json": OpenAPI document or MCP template file (JSON or YAML), supports both local file paths and remote URLs (http:// or https://)
  • --apiHost "https://api.example.com": Base URL for the API server
  • --ignoreHeader: Ignore header parameters defined in OpenAPI specification during conversion (default: false)

Remote URL Support

The --api parameter now supports downloading files from remote URLs. This is useful for:

  • Loading OpenAPI specifications from API documentation servers
  • Using centralized configuration files stored on web servers
  • Fetching MCP templates from content delivery networks

Examples:

# Using a remote OpenAPI specification
npx -y @michlyn/mcpgateway \
    --api https://api.example.com/openapi.json \
    --apiHost https://api.example.com \
    --outputTransport streamable-http

# Using a remote MCP template file
npx -y @michlyn/mcpgateway \
    --api https://cdn.example.com/mcp-templates/my-service.yaml \
    --apiHost https://api.example.com \
    --outputTransport sse

# With URL encoding (Chinese characters in path)
npx -y @michlyn/mcpgateway \
    --api "http://localhost:8081/bsp-admin/files/mcp/%E6%84%8F%E8%A7%81%E5%8F%8D%E9%A6%88.json" \
    --apiHost https://api.example.com \
    --outputTransport streamable-http

Features:

  • Automatic file type detection from URL extension (.json, .yaml, .yml)
  • Supports standard HTTP/HTTPS protocols
  • Automatic cleanup of temporary files used during conversion
  • Detailed logging of download process
  • Error handling for network failures and invalid URLs

Usage Scenarios

stdio → SSE

Expose an MCP stdio server as an SSE server:

npx -y @michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem ./my-folder" \
    --port 8000 --baseUrl http://localhost:8000 \
    --ssePath /sse --messagePath /message
  • Subscribe to events: GET http://localhost:8000/sse
  • Send messages: POST http://localhost:8000/message

stdio → Streamable HTTP

Expose an MCP stdio server as a Streamable HTTP server:

npx -y @michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem ./my-folder" \
    --port 8000 --baseUrl http://localhost:8000 \
    --outputTransport streamable-http --httpPath /mcp
  • Streamable HTTP endpoint: http://localhost:8000/mcp

SSE → stdio

Connect to a remote SSE server and expose locally via stdio:

npx -y @michlyn/mcpgateway --sse "https://mcp-server-ab71a6b2-cd55-49d0-adba-562bc85956e3.supermachine.app"

You can add authentication headers:

npx -y @michlyn/mcpgateway \
    --sse "https://mcp-server-ab71a6b2-cd55-49d0-adba-562bc85956e3.supermachine.app" \
    --oauth2Bearer "some-access-token" \
    --header "X-My-Header: another-header-value"

SSE → Streamable HTTP

Convert a remote SSE MCP server to Streamable HTTP:

npx -y @michlyn/mcpgateway \
    --sse "https://mcp-server-ab71a6b2-cd55-49d0-adba-562bc85956e3.supermachine.app" \
    --outputTransport streamable-http --port 8000 --httpPath /mcp
  • Streamable HTTP endpoint: http://localhost:8000/mcp

stdio → WS

Expose an MCP stdio server as a WebSocket server:

npx -y @michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem ./my-folder" \
    --port 8000 --outputTransport ws --messagePath /message
  • WebSocket endpoint: ws://localhost:8000/message

API → SSE or Streamable HTTP

Convert an OpenAPI specification to an MCP server:

# Using Streamable HTTP
npx -y @michlyn/mcpgateway \
    --api ./openapi.json --apiHost https://api.example.com \
    --outputTransport streamable-http --port 8000 --httpPath /mcp

# Using SSE
npx -y @michlyn/mcpgateway \
    --api ./openapi.json --apiHost https://api.example.com \
    --outputTransport sse --port 8000 --ssePath /sse --messagePath /message

# Ignore header parameters in OpenAPI spec (useful when headers are handled elsewhere)
npx -y @michlyn/mcpgateway \
    --api ./openapi.json --apiHost https://api.example.com \
    --outputTransport streamable-http --port 8000 --httpPath /mcp \
    --ignoreHeader

McpGateway automatically detects whether the input file is an OpenAPI specification or an MCP template:

  • If it’s an OpenAPI spec, it converts it to an MCP template and provides the service
  • If it’s already an MCP template, it uses it directly

OpenAPI to MCP Conversion Tool

McpGateway includes a standalone tool to convert OpenAPI documents to MCP templates:

# Using npx
npx -y @michlyn/mcpgateway openapi-to-mcp --input openapi.json --output mcp-template.json

# Or use the direct command
openapi-to-mcp --input openapi.json --output mcp-template.json

# Ignore header parameters during conversion
openapi-to-mcp --input openapi.json --output mcp-template.json --ignore-header

Parameters

  • --input, -i: Path to OpenAPI spec file (JSON or YAML)
  • --output, -o: Path for output MCP config file
  • --server-name, -n: MCP server name (default: “openapi-server”)
  • --tool-prefix, -p: Tool name prefix (default: “”)
  • --format, -f: Output format (yaml or json) (default: “yaml”)
  • --validate, -v: Validate OpenAPI spec (default: false)
  • --template, -t: Template file path for patching output (default: “”)
  • --ignore-header: Ignore header parameters in OpenAPI specification (default: false)

Client Integrations

Example with MCP Inspector (stdio → SSE mode)

  1. Run McpGateway:
npx -y @michlyn/mcpgateway --port 8000 \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /Users/MyName/Desktop"
  1. Use MCP Inspector:
npx @modelcontextprotocol/inspector

Using with Cursor (SSE → stdio mode)

Cursor can integrate with McpGateway in SSE→stdio mode:

{
  "mcpServers": {
    "cursorExampleNpx": {
      "command": "npx",
      "args": [
        "-y",
        "@michlyn/mcpgateway",
        "--sse",
        "https://mcp-server-ab71a6b2-cd55-49d0-adba-562bc85956e3.supermachine.app"
      ]
    }
  }
}

Using with Modern Cursor (Streamable HTTP mode)

Cursor can use McpGateway’s stdio→Streamable HTTP mode:

{
  "mcpServers": {
    "modernCursorExample": {
      "type": "streamableHttp",
      "url": "http://localhost:8000/mcp"
    }
  }
}

Run McpGateway on your local machine:

npx -y @michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem ./my-folder" \
    --outputTransport streamable-http --port 8000 --httpPath /mcp

Docker Support

McpGateway is available as a Docker image, making it easy to run without installing Node.js locally.

Docker Image

Available on Docker Hub: michlyn/mcpgateway

Docker Examples for All Gateway Types

stdio → SSE

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /" \
    --port 8000 --ssePath /sse --messagePath /message

stdio → Streamable HTTP

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /" \
    --outputTransport streamable-http --port 8000 --httpPath /mcp

stdio → WS

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /" \
    --outputTransport ws --port 8000 --messagePath /message

SSE → stdio

docker run -it --rm michlyn/mcpgateway \
    --sse "https://mcp-server-example.supermachine.app" \
    --outputTransport stdio

SSE → Streamable HTTP

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --sse "https://mcp-server-example.supermachine.app" \
    --outputTransport streamable-http --port 8000 --httpPath /mcp

API → SSE

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --api /path/to/openapi.json --apiHost https://api.example.com \
    --outputTransport sse --port 8000 --ssePath /sse --messagePath /message

API → Streamable HTTP

docker run -it --rm -p 8000:8000 michlyn/mcpgateway \
    --api /path/to/openapi.json --apiHost https://api.example.com \
    --outputTransport streamable-http --port 8000 --httpPath /mcp

Multi-Server Mode

# Multi-server with config file
docker run -it --rm -p 80:80 -v $(pwd)/mcp-servers.json:/app/mcp-servers.json \
    michlyn/mcpgateway --config mcp-servers.json

# Multi-server with remote config
docker run -it --rm -p 80:80 michlyn/mcpgateway \
    --config https://api.example.com/mcp-servers.json

Volume Mounting

To provide files from your host system:

docker run -it --rm -p 8000:8000 -v $(pwd):/workspace michlyn/mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /workspace" \
    --port 8000

Building the Image Yourself

# 1. Compile TypeScript
npm run build

# 2. Build Docker image
docker build -t mcpgateway .

# 3. Run the container (single server)
docker run -it --rm -p 8000:8000 mcpgateway \
    --stdio "npx -y @modelcontextprotocol/server-filesystem /" \
    --port 8000

# 4. Run the container (multi-server)
docker run -it --rm -p 80:80 -v $(pwd)/mcp-servers.json:/app/mcp-servers.json \
    mcpgateway --config mcp-servers.json

Public Access with ngrok

Share your local MCP server publicly:

# Single server mode
npx -y @michlyn/mcpgateway --port 8000 --stdio "npx -y @modelcontextprotocol/server-filesystem ."

# In another terminal:
ngrok http 8000

The MCP server will be available at a URL similar to: https://1234-567-890-12-456.ngrok-free.app/sse

Troubleshooting SSE Connections

If you encounter issues with SSE connections or tool calls not being processed:

  1. Check Session IDs: Ensure the client is using the session ID returned by the server in the SSE response headers:

    // Example JavaScript client code
    const sseConnection = new EventSource('/sse')
    let sessionId
    
    sseConnection.onopen = (event) => {
      // Get session ID from response headers
      sessionId = event.target.getResponseHeader('mcp-session-id')
      console.log('Connected with session ID:', sessionId)
    }
    
    // Use that session ID for message requests
    async function callTool(toolName, parameters) {
      const response = await fetch('/message', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          'mcp-session-id': sessionId,
        },
        body: JSON.stringify({
          jsonrpc: '2.0',
          method: 'tools/call',
          params: { name: toolName, arguments: parameters },
          id: Date.now(),
        }),
      })
      return await response.json()
    }
    

2. **Standard MCP tools/call Format**: Use the standard MCP tools/call message format:

   ```json
   {
     "jsonrpc": "2.0",
     "method": "tools/call",
     "params": {
       "name": "toolName",
       "arguments": {
         "param1": "value1",
         "param2": "value2"
       }
     },
     "id": 1
   }

Note: The arguments field is used instead of parameters. This is required for compatibility with the standard MCP tools/call format and direct-intercept mode.

  1. Use the Debug Tool: The server includes a built-in debug tool to test tool invocation:

    curl -X POST \
      -H "Content-Type: application/json" \
      -H "mcp-session-id: YOUR_SESSION_ID" \
      http://localhost:8080/message \
      -d '{
        "jsonrpc": "2.0",
        "method": "tools/call",
        "params": {
          "name": "debug",
          "arguments": {
            "message": "Testing connection",
            "testMode": true
          }
        },
        "id": 1
      }'
    
  2. Check Server Logs: Look for detailed logs showing:

    • SSE connection establishment
    • Session ID creation and tracking
    • JSON parsing of message bodies
    • Tool call processing
    • Direct interception of tools/call requests
  3. Common Issues:

    • “Headers already sent” errors can occur if trying to modify response headers after sending data
    • Missing session ID in message requests
    • Incorrect JSON formatting in tool call requests
    • CORS issues when connecting from a different origin
    • “stream is not readable” errors when the request body is consumed before the SSE transport can process it
    • Tool calls not being executed (looking for “EXECUTING TOOL” in logs)
  4. Authentication Headers Handling:

    • The gateway seamlessly passes authentication headers (Authorization, tokens, etc.) through the entire request chain
    • Authentication headers are automatically detected and preserved across all transport layers
    • Handles various authentication header formats: Authorization, bspa_access_token, api-key, etc.
    • When experiencing “登录信息超时” (login timeout) errors, check that:
      • Your client is sending proper authentication headers
      • The headers are being correctly passed through (see server logs)
      • The format of authentication headers matches what the API expects
    • You can test authentication header passing with a simple curl command:
      curl -X POST \
        -H "Content-Type: application/json" \
        -H "Authorization: Bearer YOUR_TOKEN" \
        -H "mcp-session-id: YOUR_SESSION_ID" \
        http://localhost:8000/message \
        -d '{
          "jsonrpc": "2.0",
          "method": "tools/call",
          "params": {
            "name": "debug",
            "arguments": {
              "message": "Testing auth headers",
              "testMode": true
            }
          },
          "id": 1
        }'
      
    • The authentication header will be passed to the SSE server and then to the API call
  5. tools/call Direct Interception:

    • The apiToSse module uses direct interception for tools/call requests
    • These requests are intercepted before passing to the SSE transport
    • Direct interception logs will show: “===== 直接拦截并处理tools/call请求 =====”
    • If you don’t see this log, check that your request format follows the standard MCP tools/call format
    • This approach bypasses any potential issues with the SSE transport’s handling of tools/call requests
  6. Request Body Handling:

    • The apiToSse module includes special handling for message path request bodies
    • For message endpoint requests, the raw request body is preserved for processing
    • Ensure that Content-Type header is set to “application/json” for message requests
    • When testing with curl, verify the full request body syntax matches JSON-RPC format
    • Use --logLevel debug flag when starting the server to see detailed request processing logs
  7. Request Headers Pass-through:

    • Authentication headers (Authorization, bspa_access_token) from SSE connection are passed to API calls
    • Session headers are preserved and tracked throughout the connection lifecycle
    • To verify headers are passed correctly, check the RequestHeaders log entries

Why MCP?

Model Context Protocol standardizes AI tool interactions. McpGateway converts between different MCP transport types (stdio, SSE, WS, and Streamable HTTP), simplifying integration and debugging with various clients.

The Streamable HTTP transport is the latest MCP standard, offering improved performance and better compatibility with modern web infrastructure. McpGateway makes it easy to use this transport with any MCP server, regardless of the transport it natively supports.

Advanced Features

  • Automatic File Type Detection: McpGateway intelligently detects whether input files are OpenAPI specs or MCP templates
  • Parameter Type Validation: Robust validation and conversion for different parameter types
  • Comprehensive CORS Support: Configurable cross-origin resource sharing
  • Enhanced Session Management: Robust handling of session IDs with fallback mechanisms
  • Detailed Logging: Comprehensive logging for debugging and monitoring
  • Robust Error Handling: Prevents common issues like “Headers already sent” errors in SSE connections
  • Tool Call Debugging: Built-in debug tools to test and validate tool invocation chains
  • Auto-Session Detection: Automatically selects the correct session when only one is active

Contributors

Contributing

Issues and PRs welcome. Please open one if you encounter problems or have feature suggestions.

License

MIT License

Contact

欢迎有兴趣的伙伴+v入群技术沟通:

微信二维码

Tools

No tools

Comments

Recommend MCP Servers

View All MCP Servers