MCP Proxy

Um servidor proxy para requisições MCP, suportando transportes SSE e stdio.

Documentação

mcp-proxy

GitHub License PyPI - Python Version PyPI - Downloads codecov

Sobre

O mcp-proxy é uma ferramenta que permite alternar entre transportes de servidor. Há dois modos suportados:

  1. stdio para SSE/StreamableHTTP
  2. SSE para stdio

1. stdio para SSE/StreamableHTTP

Execute um servidor proxy a partir do stdio que se conecta a um servidor SSE remoto.

Este modo permite que clientes como o Claude Desktop se comuniquem com um servidor remoto via SSE, mesmo que isso não seja suportado nativamente.

graph LR
    A["Claude Desktop"] <--> |stdio| B["mcp-proxy"]
    B <--> |SSE| C["External MCP Server"]

    style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px
    style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px
    style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px

1.1 Configuração

Este modo exige fornecer a URL do endpoint SSE do Servidor MCP como o primeiro argumento do programa. Se o servidor usar transporte Streamable HTTP, certifique-se de impô-lo no lado do mcp-proxy passando --transport=streamablehttp.

Argumentos

NomeObrigatórioDescriçãoExemplo
command_or_urlSimO endpoint SSE do servidor MCP ao qual se conectarhttp://example.io/sse
--headersNãoCabeçalhos a usar para a conexão SSE do servidor MCPAuthorization 'Bearer my-secret-access-token'
--transportNãoDecide qual protocolo de transporte usar ao conectar a um servidor MCP. Pode ser 'sse' ou 'streamablehttp'streamablehttp
--client-idNãoID do cliente OAuth2 para autenticaçãoyour_client_id
--client-secretNãoSegredo do cliente OAuth2 para autenticaçãoyour_client_secret
--token-urlNãoURL do endpoint de token OAuth2 para autenticaçãohttps://auth.example.com/oauth/token

Variáveis de Ambiente

NomeObrigatórioDescriçãoExemplo
API_ACCESS_TOKENNãoPode ser usado em vez de --headers Authorization 'Bearer <API_ACCESS_TOKEN>'YOUR_TOKEN

1.2 Exemplo de uso

O mcp-proxy deve ser iniciado pelo Cliente MCP, portanto a configuração deve ser feita de acordo.

Para o Claude Desktop, a entrada de configuração pode ser assim:

{
  "mcpServers": {
    "mcp-proxy": {
      "command": "mcp-proxy",
      "args": [
        "http://example.io/sse"
      ],
      "env": {
        "API_ACCESS_TOKEN": "access-token"
      }
    }
  }
}

2. SSE para stdio

Execute um servidor proxy expondo um servidor SSE que se conecta a um servidor stdio local.

Isso permite conexões remotas ao servidor stdio local. O mcp-proxy abre uma porta para escutar solicitações SSE, inicia um servidor stdio local que lida com solicitações MCP.

graph LR
    A["LLM Client"] <-->|SSE| B["mcp-proxy"]
    B <-->|stdio| C["Local MCP Server"]

    style A fill:#ffe6f9,stroke:#333,color:black,stroke-width:2px
    style B fill:#e6e6ff,stroke:#333,color:black,stroke-width:2px
    style C fill:#e6ffe6,stroke:#333,color:black,stroke-width:2px

2.1 Configuração

Este modo exige que o argumento --sse-port seja definido. O argumento --sse-host pode ser definido para especificar o endereço IP do host no qual o servidor SSE escutará. Variáveis de ambiente adicionais podem ser passadas ao servidor stdio local usando o argumento --env. Os argumentos de linha de comando para o servidor stdio local devem ser passados após o separador --.

Argumentos

NomeObrigatórioDescriçãoExemplo
command_or_urlSimO comando para iniciar o servidor stdio MCPuvx mcp-server-fetch
--portNão, porta disponível aleatóriaA porta do servidor MCP para escutar8080
--hostNão, 127.0.0.1 por padrãoO endereço IP do host no qual o servidor MCP escutará0.0.0.0
--envNãoVariáveis de ambiente adicionais a passar ao servidor stdio MCP. Pode ser usado várias vezes.FOO BAR
--cwdNãoO diretório de trabalho a passar ao processo do servidor stdio MCP./tmp
--pass-environmentNãoRepassar todas as variáveis de ambiente ao iniciar o servidor--no-pass-environment
--allow-originNãoOrigens permitidas para o servidor SSE. Pode ser usado várias vezes. O padrão é sem CORS permitido.--allow-origin "*"
--expose-headerNãoCabeçalhos adicionados a Access-Control-Expose-Headers. Pode ser usado várias vezes. O padrão é mcp-session-id.--expose-header Custom-Header
--statelessNãoAtivar modo sem estado para transportes streamable http. O padrão é False--no-stateless
--named-server NAME COMMAND_STRINGNãoDefine um servidor stdio nomeado.--named-server fetch 'uvx mcp-server-fetch'
--named-server-config FILE_PATHNãoCaminho para um arquivo JSON definindo servidores stdio nomeados.--named-server-config /path/to/servers.json
--sse-port (obsoleto)Não, porta disponível aleatóriaA porta do servidor SSE para escutar8080
--sse-host (obsoleto)Não, 127.0.0.1 por padrãoO endereço IP do host no qual o servidor SSE escutará0.0.0.0

2.2 Exemplo de uso

Para iniciar o servidor mcp-proxy que escuta na porta 8080 e se conecta ao servidor MCP local:

# Start the MCP server behind the proxy
mcp-proxy uvx mcp-server-fetch

# Start the MCP server behind the proxy with a custom port
# (deprecated) mcp-proxy --sse-port=8080 uvx mcp-server-fetch
mcp-proxy --port=8080 uvx mcp-server-fetch

# Start the MCP server behind the proxy with a custom host and port
# (deprecated) mcp-proxy --sse-host=0.0.0.0 --sse-port=8080 uvx mcp-server-fetch
mcp-proxy --host=0.0.0.0 --port=8080 uvx mcp-server-fetch

# Start the MCP server behind the proxy with a custom user agent
# Note that the `--` separator is used to separate the `mcp-proxy` arguments from the `mcp-server-fetch` arguments
# (deprecated) mcp-proxy --sse-port=8080 -- uvx mcp-server-fetch --user-agent=YourUserAgent
mcp-proxy --port=8080 -- uvx mcp-server-fetch --user-agent=YourUserAgent

# Start multiple named MCP servers behind the proxy
mcp-proxy --port=8080 --named-server fetch 'uvx mcp-server-fetch' --named-server fetch2 'uvx mcp-server-fetch'

# Start multiple named MCP servers using a configuration file
mcp-proxy --port=8080 --named-server-config ./servers.json

# Start the MCP server with CORS enabled and custom exposed headers
mcp-proxy --port=8080 --allow-origin='*' --expose-header Custom-Header uvx mcp-server-fetch

Servidores nomeados

  • NAME é usado no caminho da URL /servers/NAME/.
  • COMMAND_STRING é o comando para iniciar o servidor (ex.: 'uvx mcp-server-fetch').
    • Pode ser usado várias vezes.
    • Este argumento é ignorado se --named-server-config for usado.
  • FILE_PATH - Se fornecido, esta é a fonte exclusiva para servidores nomeados, e os argumentos de CLI --named-server são ignorados.

Se um servidor padrão for especificado (o argumento command_or_url sem --named-server ou --named-server-config), ele estará acessível nos caminhos raiz (ex.: http://127.0.0.1:8080/sse).

Servidores nomeados (definidos por --named-server ou --named-server-config) estarão acessíveis sob /servers/<server-name>/ (ex.: http://127.0.0.1:8080/servers/fetch1/sse). O endpoint /status fornece status global.

Formato do Arquivo de Configuração JSON para --named-server-config:

O arquivo JSON deve seguir esta estrutura:

{
  "mcpServers": {
    "fetch": {
      "disabled": false,
      "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"
    }
  }
}
  • mcpServers: Um dicionário onde cada chave é o nome do servidor (usado no caminho da URL, ex.: /servers/fetch/) e o valor é um objeto que define o servidor.
  • command: (Obrigatório) O comando a executar para o servidor stdio.
  • args: (Opcional) Uma lista de argumentos para o comando. O padrão é uma lista vazia.
  • enabled: (Opcional) Se false, esta definição de servidor será ignorada. O padrão é true.
  • timeout e transportType: Esses campos estão presentes nas configurações padrão de clientes MCP, mas são atualmente ignorados pelo mcp-proxy ao carregar servidores nomeados. O tipo de transporte é implicitamente "stdio".

Instalação

Instalando via PyPI

A versão estável do pacote está disponível no repositório PyPI. Você pode instalá-lo usando o seguinte comando:

# Option 1: With uv (recommended)
uv tool install mcp-proxy

# Option 2: With pipx (alternative)
pipx install mcp-proxy

Uma vez instalado, você pode executar o servidor usando o comando mcp-proxy. Veja as opções de configuração para cada modo acima.

Instalando via repositório Github (última versão)

A versão mais recente do pacote pode ser instalada a partir do repositório git usando o seguinte comando:

uv tool install git+https://github.com/sparfenyuk/mcp-proxy

[!NOTE] Se você já instalou o servidor, pode atualizá-lo usando o comando uv tool upgrade --reinstall.

[!NOTE] Se você quiser excluir o servidor, use o comando uv tool uninstall mcp-proxy.

Instalando como contêiner

A partir da versão 0.3.2, é possível baixar e executar a imagem de contêiner correspondente. As imagens de lançamento são publicadas no GHCR e no Docker Hub como manifestos multi-plataforma para linux/amd64 e linux/arm64; o Docker seleciona automaticamente a imagem correspondente para a arquitetura do host.

docker run --rm -t ghcr.io/sparfenyuk/mcp-proxy:v0.12.0 --help
docker run --rm -t sparfenyuk/mcp-proxy:v0.12.0 --help

Solução de problemas

  • Problema: O Claude Desktop não consegue iniciar o servidor: código ENOENT nos logs

    Solução: Tente usar o caminho completo para o binário. Para isso, abra um terminal e execute o comando which mcp-proxy ( macOS, Linux) ou where.exe mcp-proxy (Windows). Em seguida, use o caminho de saída como valor para o atributo 'command':

      "fetch": {
        "command": "/full/path/to/bin/mcp-proxy",
        "args": [
          "http://localhost:8932/sse"
        ]
      }
    

Estendendo a imagem do contêiner

Você pode estender a imagem do contêiner mcp-proxy para incluir executáveis adicionais. Por exemplo, uv não está incluído por padrão, mas você pode criar uma imagem personalizada com ele:

# file: mcp-proxy.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"]

Configuração do Docker Compose

Com o Dockerfile personalizado, você pode definir um serviço no seu arquivo Docker Compose:

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"

[!NOTE] Não se esqueça de definir o argumento --pass-environment, caso contrário você terminará com o erro "No interpreter found in managed installations or search path"

Argumentos de linha de comando

usage: mcp-proxy [-h] [--version] [-H KEY VALUE]
                 [--transport {sse,streamablehttp}] [--verify-ssl [VALUE]]
                 [--no-verify-ssl] [-e KEY VALUE] [--cwd CWD]
                 [--client-id CLIENT_ID] [--client-secret CLIENT_SECRET] [--token-url TOKEN_URL]
                 [--pass-environment | --no-pass-environment]
                 [--log-level LEVEL] [--debug | --no-debug]
                 [--named-server NAME COMMAND_STRING]
                 [--named-server-config FILE_PATH] [--port PORT] [--host HOST]
                 [--stateless | --no-stateless] [--sse-port SSE_PORT]
                 [--sse-host SSE_HOST]
                 [--allow-origin ALLOW_ORIGIN [ALLOW_ORIGIN ...]]
                 [--expose-header HEADER]
                 [command_or_url] [args ...]

Start the MCP proxy in one of two possible modes: as a client or a server.

positional arguments:
  command_or_url        Command or URL to connect to. When a URL, will run an SSE/StreamableHTTP client. Otherwise, if --named-server is not used, this will be the command for the default stdio client. If --named-server is used, this argument is ignored for stdio mode unless no default server is desired. See corresponding options for more details.

options:
  -h, --help            show this help message and exit
  --version             Show the version and exit

SSE/StreamableHTTP client options:
  -H, --headers KEY VALUE
                        Headers to pass to the SSE server. Can be used multiple times.
  --transport {sse,streamablehttp}
                        The transport to use for the client. Default is SSE.
  --verify-ssl [VALUE]  Control SSL verification when acting as a client. Use without a value to force verification, pass 'false' to disable, or provide a path to a PEM bundle.
  --no-verify-ssl       Disable SSL verification (alias for --verify-ssl false).
  --client-id CLIENT_ID
                        OAuth2 client ID for authentication
  --client-secret CLIENT_SECRET
                        OAuth2 client secret for authentication
  --token-url TOKEN_URL
                        OAuth2 token URL for authentication

stdio client options:
  args                  Any extra arguments to the command to spawn the default server. Ignored if only named servers are defined.
  -e, --env KEY VALUE   Environment variables used when spawning the default server. Can be used multiple times. For named servers, environment is inherited or passed via --pass-environment.
  --cwd CWD             The working directory to use when spawning the default server process. Named servers inherit the proxy's CWD.
  --pass-environment, --no-pass-environment
                        Pass through all environment variables when spawning all server processes.
  --log-level LEVEL     Set the log level. Default is INFO.
  --debug, --no-debug   Enable debug mode with detailed logging output. Equivalent to --log-level DEBUG. If both --debug and --log-level are provided, --debug takes precedence.
  --named-server NAME COMMAND_STRING
                        Define a named stdio server. NAME is for the URL path /servers/NAME/. COMMAND_STRING is a single string with the command and its arguments (e.g., 'uvx mcp-server-fetch --timeout 10'). These servers inherit the proxy's CWD and environment from --pass-environment.
  --named-server-config FILE_PATH
                        Path to a JSON configuration file for named stdio servers. If provided, this will be the exclusive source for named server definitions, and any --named-server CLI arguments will be ignored.

SSE server options:
  --port PORT           Port to expose an SSE server on. Default is a random port
  --host HOST           Host to expose an SSE server on. Default is 127.0.0.1
  --stateless, --no-stateless
                        Enable stateless mode for streamable http transports. Default is False
  --sse-port SSE_PORT   (deprecated) Same as --port
  --sse-host SSE_HOST   (deprecated) Same as --host
  --allow-origin ALLOW_ORIGIN [ALLOW_ORIGIN ...]
                        Allowed origins for the SSE server. Can be used multiple times. Default is no CORS allowed.
  --expose-header HEADER
                        Headers to expose via Access-Control-Expose-Headers. Defaults to 'Mcp-Session-Id'. Can be used multiple times.

Examples:
  mcp-proxy http://localhost:8080/sse
  mcp-proxy --no-verify-ssl https://server.local/sse
  mcp-proxy --transport streamablehttp http://localhost:8080/mcp
  mcp-proxy --headers Authorization 'Bearer YOUR_TOKEN' http://localhost:8080/sse
  mcp-proxy --client-id CLIENT_ID --client-secret CLIENT_SECRET --token-url https://auth.example.com/token http://localhost:8080/sse
  mcp-proxy --port 8080 -- your-command --arg1 value1 --arg2 value2
  mcp-proxy --named-server fetch 'uvx mcp-server-fetch' --port 8080
  mcp-proxy your-command --port 8080 -e KEY VALUE -e ANOTHER_KEY ANOTHER_VALUE
  mcp-proxy your-command --port 8080 --allow-origin='*'
  mcp-proxy your-command --port 8080 --allow-origin='*' --expose-header Custom-Header

Exemplo de arquivo de configuração

{
  "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"
    }
  }
}

Testes

Verifique o servidor mcp-proxy executando-o com o servidor mcp-server-fetch. Você pode usar a ferramenta de inspeção para testar o servidor de destino.

# Run the stdio server called mcp-server-fetch behind the proxy over SSE
mcp-proxy --port=8080 uvx mcp-server-fetch &

# Connect to the SSE proxy server spawned above using another instance of mcp-proxy given the URL of the SSE server
mcp-proxy http://127.0.0.1:8080/sse

# Send CTRL+C to stop the second server

# Bring the first server to the foreground
fg

# Send CTRL+C to stop the first server