Skip to content
This project is part of pgEdge Labs and is under active development. APIs and features may change without notice.

Server Mode

In server mode, the MCP Bridge wraps a local stdio-based MCP server and exposes it over HTTP. This allows remote clients to connect to MCP servers that would otherwise only be accessible locally.

How It Works

HTTP Client                    MCP Bridge                    MCP Server
    |                              |                              |
    |-- POST /mcp (request) ------>|                              |
    |                              |-- stdin (JSON-RPC) --------->|
    |                              |<-- stdout (response) --------|
    |<---- HTTP Response ----------|                              |
    |                              |                              |
    |-- GET /mcp (SSE) ----------->|                              |
    |<---- SSE notifications ------|<-- stdout (notifications) ---|

The bridge:

  1. Starts your MCP server as a subprocess
  2. Listens for HTTP requests on the configured port
  3. Forwards requests to the subprocess via stdin
  4. Returns responses from stdout as HTTP responses
  5. Streams notifications via Server-Sent Events (SSE)

Basic Configuration

Create a config.yaml file:

mode: server

server:
  listen: ":8080"

  mcp_server:
    command: "python"
    args: ["-m", "my_mcp_server"]

Run the bridge:

mcp-bridge -c config.yaml

HTTP Endpoints

The bridge exposes the following endpoints:

POST /mcp - Send Requests

Send JSON-RPC requests to the MCP server:

curl -X POST http://localhost:8080/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
  }'

GET /mcp - SSE Notifications

Subscribe to server notifications via Server-Sent Events:

curl -N http://localhost:8080/mcp \
  -H "Accept: text/event-stream"

DELETE /mcp - Close Session

Close a session and release resources:

curl -X DELETE http://localhost:8080/mcp \
  -H "Mcp-Session-Id: session-123"

GET /health - Health Check

Check if the bridge is running:

curl http://localhost:8080/health
# {"status":"healthy"}

Server Configuration Options

Listen Address

Configure the address and port to listen on:

server:
  # Listen on all interfaces
  listen: ":8080"

  # Listen only on localhost
  listen: "127.0.0.1:8080"

  # Listen on specific IP
  listen: "192.168.1.100:8080"

HTTP Timeouts

Configure HTTP server timeouts:

server:
  listen: ":8080"
  read_timeout: 30s      # Time to read request headers and body
  write_timeout: 60s     # Time to write the response
  idle_timeout: 120s     # Keep-alive connection timeout

MCP Server Configuration

The MCP subprocess is configured under server.mcp_server.

Basic Command

Specify the command to run your MCP server:

server:
  mcp_server:
    command: "python"
    args: ["-m", "my_mcp_server"]

Working Directory

Set the working directory for the subprocess:

server:
  mcp_server:
    command: "./mcp-server"
    dir: "/opt/mcp-server"

Environment Variables

Pass environment variables to the subprocess:

server:
  mcp_server:
    command: "node"
    args: ["server.js"]
    env:
      NODE_ENV: "production"
      LOG_LEVEL: "info"
      DATABASE_URL: "${DATABASE_URL}"  # From bridge's environment

Graceful Shutdown

Configure shutdown behavior:

server:
  mcp_server:
    command: "python"
    args: ["-m", "mcp_server"]
    graceful_shutdown_timeout: 30s    # Wait for graceful shutdown

Auto-Restart on Failure

Enable automatic restart when the subprocess crashes:

server:
  mcp_server:
    command: "python"
    args: ["-m", "mcp_server"]
    restart_on_failure: true
    max_restarts: 5          # Maximum restart attempts
    restart_delay: 5s        # Delay between restarts

Session Management

Sessions allow clients to maintain state across requests:

server:
  session:
    enabled: true
    timeout: 30m           # Session expires after 30 minutes of inactivity
    max_sessions: 100      # Maximum concurrent sessions
    cleanup_interval: 5m   # How often to clean up expired sessions

Clients include the session ID in requests:

# First request creates a session
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","method":"initialize","params":{},"id":1}'

# Response includes session ID header
# Mcp-Session-Id: abc123

# Subsequent requests use the session
curl -X POST http://localhost:8080/mcp \
  -H "Content-Type: application/json" \
  -H "Mcp-Session-Id: abc123" \
  -d '{"jsonrpc":"2.0","method":"tools/list","params":{},"id":2}'

Complete Example

Here's a complete server mode configuration:

mode: server

server:
  listen: ":8080"
  read_timeout: 30s
  write_timeout: 60s
  idle_timeout: 120s

  mcp_server:
    command: "python"
    args:
      - "-m"
      - "mcp_server"
      - "--config"
      - "/etc/mcp/config.json"
    dir: "/opt/mcp-server"
    env:
      PYTHONUNBUFFERED: "1"
      LOG_LEVEL: "info"
    graceful_shutdown_timeout: 30s
    restart_on_failure: true
    max_restarts: 5
    restart_delay: 5s

  session:
    enabled: true
    timeout: 30m
    max_sessions: 100

  auth:
    type: bearer
    bearer:
      valid_tokens:
        - "${MCP_AUTH_TOKEN}"

  cors:
    enabled: true
    allowed_origins:
      - "https://app.example.com"
    allowed_methods:
      - "GET"
      - "POST"
      - "DELETE"
      - "OPTIONS"
    allowed_headers:
      - "Authorization"
      - "Content-Type"
      - "Mcp-Session-Id"
    allow_credentials: true

log:
  level: info
  format: json

Next Steps