MCP Remote

Um proxy remoto para MCP que permite que clientes locais se conectem a servidores remotos via OAuth.

Documentação

mcp-remote

Conecte um Cliente MCP que só suporta servidores locais (stdio) a um Servidor MCP Remoto, com suporte a autenticação:

Por que isso é necessário?

Até agora, a maioria dos servidores MCP existentes é instalada localmente, usando o transporte stdio. Isso tem algumas vantagens: tanto o cliente quanto o servidor podem confiar implicitamente um no outro, já que o usuário concedeu permissão de execução a ambos. Adicionar segredos como chaves de API pode ser feito usando variáveis de ambiente e nunca sai da sua máquina. E construir sobre npx e uvx permitiu que os usuários evitassem etapas explícitas de instalação também.

Mas há uma razão pela qual a maioria dos softwares que poderiam ser movidos para a web foram movidos para a web: é muito mais fácil encontrar e corrigir bugs e iterar em novos recursos quando você pode enviar atualizações para todos os seus usuários com um único deploy.

Com a mais recente especificação de Autorização do MCP, agora temos uma maneira segura de compartilhar nossos servidores MCP com o mundo sem executar código nos laptops dos usuários. Ou pelo menos, você teria, se todos os clientes MCP populares já suportassem isso. A maioria é apenas stdio, e aqueles que suportam HTTP+SSE ainda não suportam os fluxos OAuth necessários.

É aí que entra o mcp-remote. Assim que o seu cliente MCP escolhido suportar servidores remotos autorizados, você pode removê-lo. Até lá, use esta linha única e prepare-se para os clientes MCP que você deseja!

Uso

Todos os clientes MCP mais populares (Claude Desktop, Cursor e Windsurf) usam o seguinte formato de configuração:

{
  "mcpServers": {
    "remote-example": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse"
      ]
    }
  }
}

Cabeçalhos Personalizados

Para ignorar a autenticação ou emitir cabeçalhos personalizados em todas as solicitações ao seu servidor remoto, passe os argumentos de CLI --header:

{
  "mcpServers": {
    "remote-example": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--header",
        "Authorization: Bearer ${AUTH_TOKEN}"
      ],
      "env": {
        "AUTH_TOKEN": "..."
      }
    },
  }
}

Observação: Cursor, Codex-Cli e Claude Desktop (Windows) têm um bug em que espaços dentro de args não são escapados quando ele invoca npx, o que acaba corrompendo esses valores. Você pode contornar isso usando:

{
  // rest of config...
  "args": [
    "mcp-remote",
    "https://remote.mcp.server/sse",
    "--header",
    "Authorization:${AUTH_HEADER}" // note no spaces around ':'
  ],
  "env": {
    "AUTH_HEADER": "Bearer <auth-token>" // spaces OK in env vars
  }
},

Para manter uma credencial fora dos argumentos do processo — onde qualquer outro usuário na máquina pode lê-la na lista de processos — coloque os cabeçalhos em um arquivo e passe --header-file. Um Name: value por linha; # inicia um comentário.

      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--header-file",
        "/path/to/headers.txt"
      ]
# credentials for the example server
Authorization: Bearer my-token
X-Custom-Header: custom-value

Um arquivo que não pode ser lido é um erro em vez de um aviso, então um caminho digitado incorretamente falha imediatamente em vez de enviar a solicitação sem autenticação.

Múltiplas Instâncias

Para executar várias instâncias do mesmo servidor remoto com configurações diferentes (por exemplo, diferentes locatários Atlassian), use o sinalizador --resource para isolar sessões OAuth:

{
  "mcpServers": {
    "atlassian_tenant1": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.atlassian.com/v1/sse",
        "--resource",
        "https://tenant1.atlassian.net/"
      ]
    },
    "atlassian_tenant2": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://mcp.atlassian.com/v1/sse",
        "--resource",
        "https://tenant2.atlassian.net/"
      ]
    }
  }
}

Cada combinação única de URL do servidor, recurso, cabeçalhos personalizados e valores de --authorize-param manterá sessões OAuth e armazenamento de tokens separados.

O valor de --resource é enviado como o indicador de recurso RFC 8707 nas solicitações de autorização, token e atualização, para que estejam sempre em concordância.

Parâmetros extras de autorização

Alguns servidores de autorização exigem parâmetros próprios na chamada de autorização. Passe cada um como --authorize-param key=value, repetindo o sinalizador conforme necessário:

      "args": [
        "mcp-remote",
        "https://remote.mcp.server/mcp",
        "--authorize-param",
        "access_type=offline",
        "--authorize-param",
        "prompt=consent"
      ]

Esses dois são o que o Google exige antes de fornecer um token de atualização — ele não reconhece o escopo offline_access. O Auth0 quer audience=https://your-api para emitir um JWT em vez de um token opaco. login_hint=user@example.com também é comum.

Eles se aplicam apenas à solicitação de autorização. resource é a exceção: o RFC 8707 quer o mesmo valor nas solicitações de token e atualização também, e apenas --resource o coloca lá. Parâmetros que o fluxo deriva por solicitação — state, code_challenge, client_id, redirect_uri, response_type — são recusados, porque um valor que discorda do real aparece como um erro opaco do servidor.

Alterar esses parâmetros inicia um novo login, já que um parâmetro como audience decide para qual API o token é destinado, e um token emitido para uma não é válido para outra.

Alguns servidores de autorização rejeitam o parâmetro de recurso diretamente — o Microsoft Entra ID v2 responde AADSTS9010010, por exemplo. Passe --disable-resource-parameter para omiti-lo completamente:

{
  "mcpServers": {
    "entra-example": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/mcp",
        "--disable-resource-parameter"
      ]
    }
  }
}

Sinalizadores

  • Se npx estiver produzindo erros, considere adicionar -y como o primeiro argumento para aceitar automaticamente a instalação do pacote mcp-remote.
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "https://remote.mcp.server/sse"
      ]
  • Para forçar npx a sempre verificar se há uma versão atualizada de mcp-remote, adicione o sinalizador @latest:
      "args": [
        "mcp-remote@latest",
        "https://remote.mcp.server/sse"
      ]
  • Para alterar em qual porta mcp-remote escuta um redirecionamento OAuth, adicione um argumento adicional após a URL do servidor. Por padrão, a porta é derivada da URL do servidor, então cada servidor recebe uma porta estável própria em algum lugar entre 3335-49150, e mcp-remote percorre até 8 portas a partir daí se encontrar uma ocupada. Uma porta que você passa explicitamente é usada como está: ela implica um redirect_uri que o servidor de autorização já recebeu, então mcp-remote falha em vez de mover-se silenciosamente para outra. --static-oauth-client-info fixa a porta da mesma forma, pelo mesmo motivo.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "9696"
      ]
  • Para alterar em qual host mcp-remote registra a URL de callback OAuth (por padrão localhost), adicione o sinalizador --host.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--host",
        "127.0.0.1"
      ]
  • Para alterar o caminho em que mcp-remote serve o callback OAuth (por padrão /oauth/callback), adicione o sinalizador --callback-path. O caminho deve começar com /, e /wait-for-auth é reservado.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--callback-path",
        "/custom/callback"
      ]
  • Para permitir conexões HTTP em redes privadas confiáveis, adicione o sinalizador --allow-http. Observação: Isso deve ser usado apenas em redes privadas seguras onde o tráfego não pode ser interceptado.
      "args": [
        "mcp-remote",
        "http://internal-service.vpc/sse",
        "--allow-http"
      ]
  • Para habilitar logs de depuração detalhados, adicione o sinalizador --debug. Isso gravará logs detalhados em ~/.mcp-auth/{server_hash}_debug.log com carimbos de data/hora e informações detalhadas sobre o processo de autenticação, conexões e atualização de tokens.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--debug"
      ]
  • Para suprimir logs padrão, adicione o sinalizador --silent. Isso impedirá a emissão de logs, exceto no caso em que --debug também seja passado.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--silent"
      ]
  • Para habilitar um proxy HTTP(S) de saída para o mcp-remote, adicione o sinalizador --enable-proxy. Quando habilitado, o mcp-remote usará as configurações de proxy de variáveis de ambiente comuns (por exemplo, HTTP_PROXY, HTTPS_PROXY e NO_PROXY).
    "args": [
      "mcp-remote",
      "https://remote.mcp.server/sse",
      "--enable-proxy"
    ],
    "env": {
      "HTTPS_PROXY": "http://127.0.0.1:3128",
      "NO_PROXY": "localhost,127.0.0.1"
    }
  • Para ignorar ferramentas específicas do servidor remoto, adicione o sinalizador --ignore-tool. Isso filtrará ferramentas que correspondem aos padrões especificados tanto das respostas tools/list quanto bloqueará solicitações tools/call. Suporta padrões curinga com *.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--ignore-tool",
        "delete*",
        "--ignore-tool",
        "remove*"
      ]

Você pode especificar vários sinalizadores --ignore-tool para ignorar padrões diferentes. Exemplos:

  • delete* - ignora todas as ferramentas que começam com "delete" (por exemplo, deleteTask, deleteUser)
  • *account - ignora todas as ferramentas que terminam com "account" (por exemplo, getAccount, updateAccount)
  • exactTool - ignora apenas a ferramenta nomeada exatamente "exactTool"
  • Para alterar o tempo limite do callback OAuth (por padrão 30 segundos), adicione o sinalizador --auth-timeout com um valor em segundos. Isso é útil se o processo de autenticação no lado do servidor demorar muito.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--auth-timeout",
        "60"
      ]
  • Para alterar os tempos limite de rede, adicione --connect-timeout, --headers-timeout ou --body-timeout, cada um com um valor em segundos. Eles se aplicam a toda solicitação de saída, incluindo as de OAuth.

    • --connect-timeout limita o estabelecimento da conexão TCP (padrão 10). Reduza-o para falhar mais rápido em um servidor inacessível.
    • --headers-timeout limita a espera pelos cabeçalhos de resposta (padrão 300).
    • --body-timeout limita o intervalo entre blocos do corpo de uma resposta (padrão 300). Este é o que fecha um fluxo SSE ocioso após cinco minutos; passe 0 para desativá-lo para servidores que enviam dados com pouca frequência.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--connect-timeout",
        "30",
        "--body-timeout",
        "0"
      ]
  • Para impedir que uma conexão ociosa seja derrubada, adicione o sinalizador --keep-alive. O proxy então envia um ping a cada 30 segundos, o que é tráfego suficiente para impedir que um servidor — ou um balanceador de carga na frente dele — encerre uma sessão que ficou silenciosa por alguns minutos. Use --ping-interval com um valor em segundos para alterar o período; ativá-lo liga o keep-alive, então os dois sinalizadores só são necessários juntos quando você quer o período padrão escrito por extenso.

    Este é o extremo oposto do problema de --body-timeout: aquele governa quanto tempo nós esperamos, enquanto este impede que o outro lado desligue.

      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--keep-alive",
        "--ping-interval",
        "60"
      ]
  • Para conectar apenas via IPv4, adicione o sinalizador --ipv4. Útil quando um nome de host resolve para endereços IPv4 e IPv6, mas as rotas IPv6 descartam silenciosamente em vez de serem recusadas — as tentativas de conexão então expiram em vez de falhar, e a solicitação nunca é concluída.
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse",
        "--ipv4"
      ]

Estratégias de Transporte

O MCP Remote suporta diferentes estratégias de transporte ao conectar a um servidor MCP. Isso permite que você controle se ele usa transporte Server-Sent Events (SSE) ou HTTP, e em que ordem tenta cada um.

Especifique a estratégia de transporte com o sinalizador --transport:

npx mcp-remote https://example.remote/server --transport sse-only

Estratégias disponíveis:

  • http-first (padrão): Tenta o transporte HTTP primeiro, recorre ao SSE se o HTTP falhar com erro 404
  • sse-first: Tenta o transporte SSE primeiro, recorre ao HTTP se o SSE falhar com erro 405
  • http-only: Usa apenas o transporte HTTP, falha se o servidor não o suportar
  • sse-only: Usa apenas o transporte SSE, falha se o servidor não o suportar

Eras de Protocolo (servidores de 2026-07-28)

A revisão 2026-07-28 do MCP aposentou o handshake initialize e a sessão por trás dele. Um servidor que o implementa atende solicitações sem estado, cada uma carregando sua própria versão de protocolo e capacidades, e se anuncia por meio de server/discover em vez de responder a um handshake.

A maioria dos hosts de desktop ainda fala a era 2025-11-25. A matriz de compatibilidade da especificação coloca esse par — cliente legado, servidor moderno — na única célula que simplesmente falha, porque um cliente legado não tem como avançar. A correção que ela nomeia é um cliente de dupla era, que é o que mcp-remote se torna com --protocol auto:

npx mcp-remote https://example.remote/mcp --protocol auto

Modos disponíveis:

  • legacy (padrão): envia o initialize do cliente diretamente, exatamente como todas as versões anteriores fizeram. Nada é sondado.
  • auto: gasta um server/discover no primeiro handshake. Se um servidor 2026-07-28 responder, mcp-remote responde ao handshake do cliente local por conta própria e reescreve toda solicitação posterior na era moderna — _meta por solicitação, com cabeçalho MCP-Protocol-Version correspondente. Se qualquer outra coisa responder, o handshake sai inalterado e nada muda.

Está desativado por padrão porque todo servidor existente hoje é legado, e a sondagem é uma ida e volta que essas conexões não precisam.

As duas superfícies modernas sem equivalente 2025-11-25 também são conectadas:

  • Notificações de mudança. A era moderna só envia notifications/tools/list_changed e amigos por um fluxo subscriptions/listen que o cliente abre. Um cliente da era 2025 nunca abre um, então mcp-remote o abre em nome do cliente — pedindo exatamente as notificações que o servidor disse que pode enviar — e repassa cada uma na forma que essa era espera.
  • Solicitações de múltiplas idas e voltas. Quando um servidor responde com input_required, pedindo amostragem, elicitação ou raízes no meio da solicitação, mcp-remote desempacota as perguntas incorporadas e as apresenta ao cliente como as solicitações comuns iniciadas pelo servidor que ele já entende, então tenta novamente a solicitação original com as respostas e um eco byte-exato do requestState do servidor. O cliente nunca é informado de que isso aconteceu: ele ainda está esperando a única solicitação que enviou, e é com isso que ele é respondido. Limitado a 10 rodadas. Uma pergunta que este proxy não pode fazer a um cliente da era de 2025 — qualquer coisa fora de amostragem, elicitação e raízes, ou uma elicitação em modo URL, ou uma que o cliente nunca declarou suportar — é reportada como erro em vez de ser descartada.

Três métodos que a era moderna aposentou são honrados pelo mcp-remote em si, em vez de serem encaminhados a um servidor que não os possui mais, porque as capacidades entregues ao cliente ainda os anunciam:

  • resources/subscribe / resources/unsubscribe tornam-se entradas no stream subscriptions/listen, que é reaberto sempre que o conjunto muda.
  • logging/setLevel é registrado e carregado como o io.modelcontextprotocol/logLevel por requisição que o substituiu — sem o qual um servidor moderno não envia logs nenhum.

Metadados Estáticos de Cliente OAuth

O MCP Remote suporta fornecer metadados estáticos de cliente OAuth em vez de usar os padrões do mcp-remote. Isso é útil ao conectar-se a servidores OAuth que esperam IDs específicos de cliente/software ou escopos.

Forneça os metadados do cliente como uma string JSON ou como um caminho de arquivo prefixado com @ usando a flag --static-oauth-client-metadata:

npx mcp-remote https://example.remote/server --static-oauth-client-metadata '{ "scope": "space separated scopes" }'
# uses node readfile, so you probably want to use absolute paths if you're not sure what the cwd is
npx mcp-remote https://example.remote/server --static-oauth-client-metadata '@/Users/username/Library/Application Support/Claude/oauth_client_metadata.json'

O que você fornece é mesclado sobre os padrões, então é assim que você fixa um valor que o mcp-remote negociaria de outra forma. token_endpoint_auth_method é escolhido a partir do token_endpoint_auth_methods_supported do servidor de autorização: none quando o servidor aceita clientes públicos, caso contrário client_secret_post, caso contrário client_secret_basic. Substitua-o quando o servidor precisar de algo diferente:

npx mcp-remote https://example.remote/server --static-oauth-client-metadata '{ "token_endpoint_auth_method": "client_secret_post" }'

Informações Estáticas de Cliente OAuth

Conforme a especificação, os servidores são encorajados, mas não obrigados, a suportar registro dinâmico de cliente OAuth.

Para esses servidores, o MCP Remote suporta fornecer informações estáticas de cliente OAuth em vez disso. Isso é útil ao conectar-se a servidores OAuth que exigem clientes pré-registrados.

Forneça os metadados do cliente como uma string JSON ou como um caminho de arquivo prefixado com @ usando a flag --static-oauth-client-info:

export MCP_REMOTE_CLIENT_ID=xxx
export MCP_REMOTE_CLIENT_SECRET=yyy
npx mcp-remote https://example.remote/server --static-oauth-client-info "{ \"client_id\": \"$MCP_REMOTE_CLIENT_ID\", \"client_secret\": \"$MCP_REMOTE_CLIENT_SECRET\" }"
# uses node readfile, so you probably want to use absolute paths if you're not sure what the cwd is
npx mcp-remote https://example.remote/server --static-oauth-client-info '@/Users/username/Library/Application Support/Claude/oauth_client_info.json'

Documentos de Metadados de ID de Cliente

SEP-991 permite que um servidor de autorização aceite uma URL HTTPS como o client_id, onde essa URL serve um documento JSON descrevendo o cliente. Servidores que suportam isso anunciam "client_id_metadata_document_supported": true em seus metadados de servidor de autorização, e nenhum registro dinâmico é necessário.

Aponte o mcp-remote para o seu documento com --client-metadata-url:

npx mcp-remote https://example.remote/server --client-metadata-url https://client.example.com/.well-known/oauth-client-metadata

A URL deve usar HTTPS e ter um caminho — uma origem nua é rejeitada. Se o servidor não anunciar suporte, o mcp-remote registra dinamicamente como de costume, então a flag é segura para deixar no lugar.

O documento que você hospeda deve listar o redirect_uri que o mcp-remote enviará, que contém a porta de callback OAuth. Passar esta flag torna essa porta estrita: o mcp-remote usa a porta derivada da URL do servidor (ou a que você passar explicitamente) e falha em vez de mover-se silenciosamente para outra, então o redirect_uris no seu documento permanece correto. Execute uma vez para ver a porta que ele escolheu, ou escolha-a você mesmo:

npx mcp-remote https://example.remote/server 3334 --client-metadata-url https://client.example.com/.well-known/oauth-client-metadata

Entrando Sem um Usuário

Alguns servidores não são protegidos em nome de uma pessoa — um servidor MCP interno alcançado por um trabalho agendado, por exemplo, onde não há usuário para consentir e nenhum navegador para consentir. Para esses, o --client-credentials usa a concessão de Credenciais de Cliente OAuth: o cliente apresenta suas próprias credenciais e recebe um token para si mesmo.

npx mcp-remote https://example.remote/mcp \
  --client-credentials \
  --static-oauth-client-info '{"client_id":"my-client","client_secret":"${MCP_CLIENT_SECRET}"}'

As credenciais vêm de --static-oauth-client-info, que aceita JSON inline ou @path/to/file.json. ${ENV_VAR} placeholders são expandidos a partir do ambiente em ambas as formas, então o segredo não precisa estar em uma linha de comando onde todos os outros processos na máquina podem lê-lo. Nada registra o valor expandido.

O endpoint de token, o escopo e o indicador resource RFC 8707 são descobertos e aplicados da mesma forma que para todos os outros fluxos, e client_secret_basic ou client_secret_post é escolhido a partir do que o servidor de autorização anuncia. Nenhum token de atualização está envolvido: as credenciais são a coisa durável, então um token expirado é substituído pedindo outro da mesma forma que o primeiro foi obtido.

Se um servidor interno não publica metadados de descoberta RFC 9728 ou RFC 8414/OIDC, forneça seu endpoint de token conhecido explicitamente. Isso pula a descoberta e é aceito apenas com --client-credentials:

npx mcp-remote https://example.remote/mcp \
  --client-credentials \
  --token-endpoint https://auth.example.com/oauth/token \
  --static-oauth-client-info '{"client_id":"my-client","client_secret":"${MCP_CLIENT_SECRET}"}' \
  --static-oauth-client-metadata '{"scope":"mcp.read mcp.write","token_endpoint_auth_method":"client_secret_basic"}'

O endpoint explícito deve usar HTTPS, exceto para um endpoint de loopback HTTP. Credenciais e fragmentos de URL são recusados na URL do endpoint, e mudar o endpoint seleciona um cache de token separado. A descoberta também é pulada na inicialização a frio e em novas tentativas de 401. Tokens são renovados antes da expiração usando as mesmas credenciais de cliente; se a renovação falhar, o token atual é enviado até que o servidor o recuse. Com um endpoint explícito, scope é omitido a menos que configurado com --static-oauth-client-metadata ou nomeado no desafio 401 do servidor, e resource é omitido a menos que definido com --resource.

Entrando Sem um Navegador

O fluxo padrão precisa de um navegador nesta máquina e uma porta de loopback para redirecionar de volta — o que um trabalho cron, uma sessão SSH ou um contêiner não tem. Se o seu servidor de autorização suportar a Concessão de Autorização de Dispositivo OAuth, o --device-code move o navegador para qualquer máquina em que você esteja realmente sentado:

npx mcp-remote https://example.remote/server --device-code

O mcp-remote imprime um código curto e uma URL, então faz polling até você aprová-lo:

To authorize this client, visit:
  https://auth.example.com/activate

And enter the code: WDJB-MJHT

Waiting for approval...

A saída vai para o stderr, que os clientes MCP capturam em seus próprios logs — então em uma execução headless, é nesse log que você lê o código. Isso só precisa acontecer uma vez: o token de atualização que volta é armazenado como qualquer outro, e execuções posteriores são não interativas.

Nenhum servidor de callback é iniciado e nenhuma porta é vinculada, então este também é o fluxo a usar quando a porta de loopback está indisponível.

O servidor deve anunciar device_authorization_endpoint em seus metadados de servidor de autorização; o mcp-remote falha com uma mensagem clara em vez de cair em um navegador que não está lá. Note que servidores que oferecem esta concessão frequentemente esperam um cliente pré-registrado — combine-o com --static-oauth-client-info se o registro dinâmico for recusado.

Persistência de Sessão em Balanceador de Carga

Sessões MCP vivem em um único backend, então um servidor atrás de um balanceador de carga precisa que cada requisição de um cliente alcance o mesmo nó. AWS ALB, Azure Load Balancer e outros fazem isso com um cookie que o cliente deve enviar de volta.

O mcp-remote mantém cookies que o servidor MCP define e os reenvia em requisições posteriores, incluindo do stream SSE para os POSTs que o seguem. Nada para configurar. Cookies são mantidos em memória durante a vida do processo, nunca gravados em disco, e apenas enviados de volta para a origem exata que os definiu — Domain é ignorado, então nada viaja para outro host.

Um Cookie que você passa você mesmo com --header sempre vence.

Para desligar:

npx mcp-remote https://example.remote/server --disable-cookies

Usando o Token de ID como Credencial Bearer

Por padrão, o mcp-remote envia o token de acesso OAuth, que diz o que o chamador tem permissão para fazer. Alguns servidores em vez disso verificam quem é o chamador: eles validam um token de ID OIDC contra um endpoint JWKS e leem reivindicações de identidade como sub e email dele. AWS Cognito na frente do Bedrock AgentCore funciona assim, e rejeita o token de acesso completamente.

Passe --use-id-token para enviar o token de ID em vez disso:

npx mcp-remote https://example.remote/server --use-id-token

Apenas a credencial apresentada ao servidor MCP muda — o token de atualização e o fluxo de renovação não são tocados. A renovação segue a reivindicação exp do próprio token de ID em vez da vida útil do token de acesso, já que o token de ID é o que realmente vai para a rede.

Um token de ID só é emitido quando openid está entre os escopos solicitados. Se o seu servidor não anunciá-lo, peça-o explicitamente:

npx mcp-remote https://example.remote/server --use-id-token --static-oauth-client-metadata '{ "scope": "openid email" }'

Claude Desktop

Documentação Oficial

Para adicionar um servidor MCP ao Claude Desktop, você precisa editar o arquivo de configuração localizado em:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Se ele ainda não existir, talvez você precise habilitá-lo em Configurações > Desenvolvedor.

Reinicie o Claude Desktop para aplicar as mudanças no arquivo de configuração. Após reiniciar, você deve ver um ícone de martelo no canto inferior direito da caixa de entrada.

Cursor

Documentação Oficial. O arquivo de configuração está localizado em ~/.cursor/mcp.json.

A partir da versão 0.48.0, o Cursor suporta servidores SSE sem autenticação diretamente. Se o seu servidor MCP estiver usando o protocolo oficial de autorização OAuth do MCP, você ainda precisa adicionar um servidor "command" e chamar mcp-remote.

Windsurf

Documentação Oficial. O arquivo de configuração está localizado em ~/.codeium/windsurf/mcp_config.json.

Construindo Servidores MCP Remotos

Para instruções sobre como construir e implantar servidores MCP remotos, incluindo atuar como um cliente OAuth válido, veja os seguintes recursos:

Em particular, veja:

Para mais informações sobre testar esses servidores, veja também:

Conhece mais recursos que gostaria de compartilhar? Por favor, adicione-os a este Readme e envie um PR!

Solução de Problemas

Limpe seu diretório ~/.mcp-auth

mcp-remote armazena todas as informações de credenciais dentro de ~/.mcp-auth (ou onde quer que seu MCP_REMOTE_CONFIG_DIR aponte). Se você está tendo problemas persistentes, tente executar:

rm -rf ~/.mcp-auth

Depois reinicie seu cliente MCP.

As credenciais são armazenadas sob mcp-remote-v1, que nomeia o layout do armazenamento em vez da versão do pacote, então atualizar o mcp-remote não faz mais você sair da sessão. Versões antes desta mudança mantinham um diretório separado por versão — se você tiver diretórios ~/.mcp-auth/mcp-remote-0.x.y sobrando, eles contêm tokens antigos e podem ser excluídos.

Verifique sua versão do Node

Certifique-se de que a versão do Node que você tem instalada é 18 ou superior. O Claude Desktop usará a versão do sistema do Node, mesmo se você tiver uma versão mais nova instalada em outro lugar.

Reinicie o Claude

Ao modificar o claude_desktop_config.json, pode ser útil reiniciar completamente o Claude

Certificados de VPN

Você pode encontrar problemas se estiver atrás de uma VPN; você pode tentar definir a variável de ambiente NODE_EXTRA_CA_CERTS para apontar para o arquivo de certificado CA. Se estiver usando claude_desktop_config.json, isso pode parecer:

{
 "mcpServers": {
    "remote-example": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://remote.mcp.server/sse"
      ],
      "env": {
        "NODE_EXTRA_CA_CERTS": "{your CA certificate file path}.pem"
      }
    }
  }
}

Verifique os logs

  • Siga os logs do Claude Desktop em tempo real
  • MacOS / Linux:
    tail -n 20 -F ~/Library/Logs/Claude/mcp*.log
  • Para bash no WSL:
    tail -n 20 -f "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log"
  • Powershell:
    Get-Content "C:\Users\YourUsername\AppData\Local\Claude\Logs\mcp.log" -Wait -Tail 20

Depuração

Logs de Depuração

Para solucionar problemas complexos, especialmente com atualização de tokens ou problemas de autenticação, use a flag --debug:

"args": [
  "mcp-remote",
  "https://remote.mcp.server/sse",
  "--debug"
]

Isso cria logs detalhados em ~/.mcp-auth/{server_hash}_debug.log com timestamps e informações completas sobre cada etapa do processo de conexão e autenticação. Quando você encontrar problemas com atualização de tokens, problemas de suspensão/retomada do laptop ou problemas de autenticação, forneça esses logs ao buscar suporte.

Erros de Autenticação

Se você encontrar o seguinte erro, retornado pela URL /callback:

Authentication Error
Token exchange failed: HTTP 400

Você pode executar rm -rf ~/.mcp-auth para limpar qualquer estado e tokens armazenados localmente.

Modo "Cliente"

Execute o seguinte na linha de comando (não de um servidor MCP):

npx -p mcp-remote@latest mcp-remote-client https://remote.mcp.server/sse

Isso executará todo o fluxo de autorização e tentará listar as ferramentas e recursos na URL remota. Tente isso após executar rm -rf ~/.mcp-auth para ver se credenciais obsoletas são o seu problema; caso contrário, esperamos que o problema fique mais óbvio nesses logs do que nos do seu cliente MCP.

Agradecimentos

Glen Maddern é o autor original do mcp-remote. Ele construiu o mcp-remote em um dos blocos de construção mais populares do ecossistema MCP.