mcp-proxy

repository·main·Indexed 25 days ago

https://github.com/sparfenyuk/mcp-proxy

A transport bridge for the Model Context Protocol (MCP) version 0.12.0 that enables switching between stdio and SSE/StreamableHTTP transports. It allows stdio-only clients, such as Claude Desktop, to connect to remote MCP servers, or remote clients to connect to local stdio-based servers via a network port.

Tokens
3.8K
Snippets
7
Records
22
Agent score
82%

What's inside mcp-proxy

  1. Install mcp-proxy

    main

    You can install mcp-proxy using uv, pipx, or by pulling a container image.

    uv tool install mcp-proxy

    Using pipx

    pipx install mcp-proxy

    Using Docker

    Pull and run the multi-platform image (supports linux/amd64 and linux/arm64):

    docker run --rm -t ghcr.io/sparfenyuk/mcp-proxy:v0.12.0 --help
    uv tool install mcp-proxy
  2. Extend mcp-proxy container image with 'uv'

    main

    The default mcp-proxy container image does not include uv. To use uv inside the container, create a custom Dockerfile:

    FROM ghcr.io/sparfenyuk/mcp-proxy:latest
    
    # Install the 'uv' package
    RUN python3 -m ensurepip && pip install --no-cache-dir uv
    
    ENV PATH="/usr/local/bin:$PATH" \
        UV_PYTHON_PREFERENCE=only-system
    
    ENTRYPOINT ["catatonit", "--", "mcp-proxy"]
    FROM ghcr.io/sparfenyuk/mcp-proxy:latest
    
    # Install the 'uv' package
    RUN python3 -m ensurepip && pip install --no-cache-dir uv
    
    ENV PATH="/usr/local/bin:$PATH" \
        UV_PYTHON_PREFERENCE=only-system
    
    ENTRYPOINT ["catatonit", "--", "mcp-proxy"]
  3. Use stdio to SSE/StreamableHTTP mode

    main

    This mode allows clients that only support stdio (like Claude Desktop) to communicate with a remote MCP server over SSE or Streamable HTTP. The proxy acts as a bridge: the client talks to the proxy via stdio, and the proxy talks to the remote server via SSE.

    {
      "mcpServers": {
        "mcp-proxy": {
          "command": "mcp-proxy",
          "args": [
            "http://example.io/sse"
          ],
          "env": {
            "API_ACCESS_TOKEN": "access-token"
          }
        }
      }
    }
  4. Use SSE to stdio mode

    main

    This mode exposes a local stdio MCP server as an SSE server. The proxy opens a network port to listen for SSE requests and spawns a local process to handle the MCP requests via stdio. This allows remote clients to connect to a local MCP server.

    # Start the MCP server behind the proxy on a default port
    mcp-proxy uvx mcp-server-fetch
    
    # Start the MCP server behind the proxy with a custom port
    mcp-proxy --port=8080 uvx mcp-server-fetch
    
    # Start the MCP server with a custom host and port
    mcp-proxy --host=0.0.0.0 --port=8080 uvx mcp-server-fetch
  5. Configure named servers via JSON file

    main

    You can define multiple named MCP servers using a JSON configuration file passed to the --named-server-config flag. Named servers are accessible via the URL path /servers/<server-name>/sse/.

    Configuration Schema:

    • mcpServers: A dictionary where each key is the server name.
    • command (Required): The command to execute.
    • args (Optional): A list of arguments for the command.
    • enabled (Optional): Set to false to skip this server. Defaults to true.
    • env (Optional): Environment variables for the server.

    Note: timeout and transportType are currently ignored; transport is implicitly stdio.

    {
      "mcpServers": {
        "fetch": {
          "enabled": true,
          "timeout": 60,
          "command": "uvx",
          "args": [
            "mcp-server-fetch"
          ],
          "transportType": "stdio"
        },
        "github": {
          "timeout": 60,
          "command": "npx",
          "args": [
            "-y",
            "@modelcontextprotocol/server-github"
          ],
          "env": {
            "GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
          },
          "transportType": "stdio"
        }
      }
    }
  6. Troubleshoot Claude Desktop ENOENT errors

    main

    If Claude Desktop fails to start the server with an ENOENT error, it is likely because the binary path is not being resolved correctly.

    Solution: Use the absolute path to the binary in your configuration.

    1. Find the path using which mcp-proxy (macOS/Linux) or where.exe mcp-proxy (Windows).
    2. Use that full path in the command field of your configuration.

    Example:

    "fetch": {
      "command": "/full/path/to/bin/mcp-proxy",
      "args": [
        "http://localhost:8932/sse"
      ]
    }
  7. Run mcp-proxy with Docker Compose

    main

    To run a custom mcp-proxy image (e.g., one containing uv) via Docker Compose, use the following configuration.

    Important: You must include the --pass-environment argument to ensure the proxy can find interpreters/installations.

    services:
      mcp-proxy-custom:
        build:
          context: .
          dockerfile: mcp-proxy.Dockerfile
        network_mode: host
        restart: unless-stopped
        ports:
          - 8096:8096
        command: "--pass-environment --port=8096 --sse-host 0.0.0.0 uvx mcp-server-fetch"
    services:
      mcp-proxy-custom:
        build:
          context: .
          dockerfile: mcp-proxy.Dockerfile
        network_mode: host
        restart: unless-stopped
        ports:
          - 8096:8096
        command: "--pass-environment --port=8096 --sse-host 0.0.0.0 uvx mcp-server-fetch"
  8. Configure named MCP servers via JSON configuration

    main

    The mcp-proxy can load multiple named MCP server configurations from a single JSON file. This allows you to manage several stdio servers with specific commands, arguments, and environment variables in one place.

    JSON Configuration Format

    The configuration file must be a JSON object containing an mcpServers key. Each entry under mcpServers represents a named server.

    Required and Optional Fields per Server:

    • command (string, required): The executable command to run the server.
    • args (array of strings, optional): Arguments to pass to the command. Defaults to an empty list [].
    • env (object, optional): Environment variables specific to this server. These are merged with the base_env provided during loading.
    • enabled (boolean, optional): If set to false, the server will be skipped. Defaults to true.

    Example Configuration File

    {
      "mcpServers": {
        "fetch": {
          "command": "uvx",
          "args": ["mcp-server-fetch"],
          "env": {
            "API_KEY": "your_key_here"
          }
        },
        "sqlite": {
          "command": "npx",
          "args": ["-y", "@modelcontextprotocol/server-sqlite"],
          "enabled": true
        },
        "disabled-server": {
          "command": "echo",
          "enabled": false
        }
      }
    }
  9. Configure MCPServerSettings

    main

    Use the MCPServerSettings dataclass to define how the proxy server binds to the network and handles security/logging.

    Available fields:

    • bind_host: The host address to bind to.
    • port: The port number to listen on.
    • stateless: Boolean indicating if the server should operate in stateless mode (default: False).
    • allow_origins: A list of allowed CORS origins. If provided, CORSMiddleware is enabled.
    • expose_headers: A list of HTTP headers to expose to the client (defaults to ("mcp-session-id",)).
    • log_level: The logging level. Supported values: "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL" (default: "INFO").
  10. Reference: mcp-proxy CLI arguments

    main

    The mcp-proxy command operates in two modes: as a client (connecting to an existing SSE/StreamableHTTP server) or as a server (proxying stdio servers to SSE/StreamableHTTP).

    SSE/StreamableHTTP Client Options

    Used when command_or_url is a URL.

    • -H, --headers KEY VALUE: Headers to pass to the SSE server (can be used multiple times).
    • --transport {sse,streamablehttp}: Transport type. Default is sse.
    • --verify-ssl [VALUE]: Control SSL verification. Use without value to force, false to disable, or provide a PEM path.
    • --no-verify-ssl: Disable SSL verification.
    • --client-id CLIENT_ID: OAuth2 client ID.
    • --client-secret CLIENT_SECRET: OAuth2 client secret.
    • --token-url TOKEN_URL: OAuth2 token URL.

    stdio Client Options

    Used when spawning local servers.

    • args: Extra arguments for the default command.
    • -e, --env KEY VALUE: Environment variables (can be used multiple times).
    • --cwd CWD: Working directory.
    • --pass-environment: Pass through all host environment variables.
    • --named-server NAME COMMAND_STRING: Define a named stdio server.
    • --named-server-config FILE_PATH: Path to JSON config (overrides --named-server).
    • --log-level LEVEL: Set log level (default INFO).
    • --debug: Enable debug mode.

    SSE Server Options

    Used when proxying to SSE.

    • --port PORT: Port to expose (default is random).
    • --host HOST: Host to expose (default 127.0.0.1).
    • --stateless: Enable stateless mode for streamable http.
    • --allow-origin ALLOW_ORIGIN [ALLOW_ORIGIN ...]: Allowed CORS origins.
    • --expose-header HEADER: Headers to expose via Access-Control-Expose-Headers (default Mcp-Session-Id).
  11. Configure stdio to SSE/StreamableHTTP mode

    main

    When running in stdio to SSE mode, provide the remote MCP server's SSE endpoint as the first argument.

    Arguments:

    • command_or_url (Required): The MCP server SSE endpoint (e.g., http://example.io/sse).
    • --transport: Specifies the protocol. Options: sse or streamablehttp. Use streamablehttp if the server requires it.
    • --headers: Headers for the SSE connection (e.g., Authorization 'Bearer my-token').
    • --client-id, --client-secret, --token-url: OAuth2 authentication parameters.

    Environment Variables:

    • API_ACCESS_TOKEN: Can be used instead of the --headers Authorization 'Bearer <TOKEN>' argument.