Implantar túneis MCP com Helm
Instale a pilha de túnel em um cluster Kubernetes usando o chart Helm da Anthropic.
O chart Helm da Anthropic instala a pilha de túnel como um único Deployment e a anexa ao seu túnel: um que o hook de configuração do chart cria para você, ou um túnel existente que você criou no Console.
Antes de começar
Você precisa de:
- Um túnel. Com acesso programático, o hook de configuração do chart cria um para você quando você não fornece um ID de túnel; para anexar a um túnel existente, crie-o no Console e anote o ID do túnel (
tnl_...). O provisionamento manual sempre começa a partir de um túnel criado no Console; você também precisará do token do túnel e do domínio do túnel. - Uma forma de o chart se autenticar na API de Tunnels.
- Acesso programático (recomendado). O componente de configuração se autentica por meio de "Workload Identity Federation" (federação de identidade de carga de trabalho), busca o token do túnel, gera uma CA, registra-a na Anthropic e armazena tudo em um Secret. Você precisará de uma regra de federação com escopo
workspace:manage_tunnels. - Manual. Pule o acesso programático. Você vai obter o token do túnel no Console, gerar uma CA e um certificado de servidor por conta própria, registrar a CA no Console e fornecer as credenciais ao cluster como Secrets.
- Acesso programático (recomendado). O componente de configuração se autentica por meio de "Workload Identity Federation" (federação de identidade de carga de trabalho), busca o token do túnel, gera uma CA, registra-a na Anthropic e armazena tudo em um Secret. Você precisará de uma regra de federação com escopo
- Um cluster Kubernetes no qual você possa implantar com
helmekubectl. A aba Sem acesso programático também usaopenssl(1.1.1 ou posterior). - Conectividade de rede de saída do cluster para
api.anthropic.com(443 TCP) e para a borda do túnel (7844 TCP e UDP). Consulte os requisitos de rede completos. - Um ou mais servidores MCP em execução e acessíveis a partir do cluster nos endereços que você configurará em
gateway.config.routes. Se você ainda não tiver um, use o servidor de exemplo.
Opcional: Usar um servidor MCP de exemplo
Se você não tiver um servidor MCP disponível para testes, use este servidor mínimo:
kubectl create namespace mcp-tunnel --dry-run=client -o yaml | kubectl apply -f -
kubectl -n mcp-tunnel apply -f - <<'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: hello-mcp-src
data:
hello_server.py: |
from mcp.server.fastmcp import FastMCP
mcp = FastMCP("hello-server", host="0.0.0.0", port=9000)
@mcp.tool()
def hello(name: str = "world") -> str:
"""Say hello to someone."""
return f"Hello, {name}!"
if __name__ == "__main__":
mcp.run(transport="streamable-http")
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-mcp
spec:
replicas: 1
selector:
matchLabels: { app: hello-mcp }
template:
metadata:
labels: { app: hello-mcp }
spec:
containers:
- name: hello-mcp
image: python:3.13-slim
command: ["sh", "-c", "pip install --quiet mcp && python /app/hello_server.py"]
volumeMounts:
- { name: src, mountPath: /app }
ports:
- { containerPort: 9000 }
volumes:
- name: src
configMap: { name: hello-mcp-src }
---
apiVersion: v1
kind: Service
metadata:
name: hello-mcp
spec:
selector: { app: hello-mcp }
ports:
- { port: 9000, targetPort: 9000 }
EOFAs etapas de instalação a seguir indicam onde adicionar a rota correspondente.
Instalar
O componente de configuração troca o token de ServiceAccount projetado do cluster por meio da sua regra de federação, busca o token do túnel, gera uma CA e um certificado de servidor e registra a CA na Anthropic. Um CronJob diário renova o certificado de servidor conforme necessário, de modo que você não manipula nenhum segredo manualmente.
Configurar Workload Identity Federation para o cluster
Siga Usar WIF com Kubernetes para registrar o emissor OIDC do seu cluster e criar uma regra de federação. O componente de configuração é executado sob sua própria ServiceAccount no namespace da release; o nome exato segue a convenção
fullnamedo Helm, portanto, para qualquer nome de release diferente demcp-tunnel, executehelm template <release> ... | grep -A2 'kind: ServiceAccount'para confirmá-lo antes de criar a regra. O restante deste guia assume o nome de releasemcp-tunnelno namespacemcp-tunnel, onde a ServiceAccount émcp-tunnel-setup.Campo Valor Subject system:serviceaccount:mcp-tunnel:mcp-tunnel-setupAudience api.anthropic.com(o padrão do chart; sem esquema)Scope workspace:manage_tunnelsSe o túnel estiver em um workspace diferente do workspace padrão da organização, também adicione a conta de serviço da regra a esse workspace (a API de Tunnels autoriza com base nas associações de workspace da conta de serviço).
Anote o ID da regra (
fdrl_...); você o definirá comoapi.wif.federationRuleId.Obter os valores padrão
helm show values \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 > values.yamlConfigurar a anexação do túnel e as rotas
Edite
values.yamle defina as chavesapi.wif.*com o ID da regra de federação e o ID da organização, além de uma entradaroutespara cada servidor MCP upstream:values.yamlapi: wif: federationRuleId: "fdrl_..." organizationId: "00000000-0000-0000-0000-000000000000" # Set when the tunnel is in a non-default workspace and the # rule's service account is a member of that workspace. # workspaceId: "wrkspc_..." tunnel: # Leave empty to have the setup hook create a tunnel during install. # Set to attach to an existing tunnel from the Console. id: "" # Increment to rotate the tunnel token on the next upgrade. # See the "Rotate the tunnel token" section. tokenVersion: "1" gateway: config: routes: docs: http://docs-mcp.internal:8080 search: http://search-mcp.internal:8080Com essas rotas, o Claude alcança os servidores em
docs.<your-tunnel-domain>esearch.<your-tunnel-domain>. Algumas distribuições gerenciadas de Kubernetes alocam o CIDR de Service fora dos intervalos privados padrão; se suas rotas apontam para Services dentro do cluster, adicionegateway.config.upstream.allowed_ipsaqui conforme Validação de IP upstream.Revisar os manifestos renderizados
Renderize o chart e revise a saída de acordo com as práticas de verificação da sua organização:
helm template mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ -n mcp-tunnel \ -f values.yaml > rendered.yamlInstalar
helm install mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ --namespace mcp-tunnel --create-namespace \ -f values.yamlO componente de configuração é executado como um Job de hook pre-install do Helm, portanto
helm installbloqueia até que ele seja concluído. Em caso de sucesso, o Helm exclui o Job automaticamente. Sehelm installfalhar com um erro de hook, consulte Falhas de autenticação do componente de configuração.Quando
tunnel.idestá vazio, o componente de configuração cria o túnel no workspace que sua regra de federação tem como alvo (o workspace padrão da organização, a menos que você definaapi.wif.workspaceId) e armazena o ID e o domínio dele no Secretmcp-tunnel. Encontre o domínio de que você precisará para a verificação na página de detalhes do túnel, que você abre a partir da página MCP tunnels (platform.claude.com/settings/workspaces/default/mcp-tunnels) no Console. No seletor de workspace na barra lateral, selecione o workspace que contém o túnel. Você também pode ler o domínio a partir do Secret:kubectl -n mcp-tunnel get secret mcp-tunnel \ -o jsonpath='{.data.tunnel-domain}' | base64 -dExecutar novamente o componente de configuração (durante atualizações ou rotação de token) reutiliza o ID do túnel armazenado neste Secret; ele nunca cria um segundo túnel.
Neste modo (setup.enabled: false), o chart não faz chamadas de API; o componente de configuração não é executado e não há CronJob de renovação de certificado. Use este caminho se você preferir não configurar Workload Identity Federation.
Obter o token e o domínio do túnel
Gerar uma CA e um certificado de servidor
O proxy escuta em WebSocket simples, com TLS interno transportado dentro desse fluxo usando o certificado que você gera aqui. O SAN do certificado de servidor deve incluir
*.<tunnel-domain>conforme os requisitos de certificado.export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE mkdir -p mcp-tunnel/data cd mcp-tunnel # CA autoassinada. Extensões explícitas para que satisfaça os requisitos # de certificado independentemente dos padrões do openssl.cnf da distro. openssl req -x509 -newkey rsa:2048 -nodes \ -keyout data/ca.key -out data/ca.crt \ -days 3650 -subj "/CN=mcp-tunnel-ca" \ -addext "basicConstraints=critical,CA:TRUE" \ -addext "keyUsage=critical,keyCertSign,cRLSign" \ -addext "subjectKeyIdentifier=hash" # Arquivo de extensões para o certificado do servidor. Usar -extfile (em vez de # -copy_extensions, que é exclusivo do OpenSSL 3.0+) mantém isso funcionando no # OpenSSL 1.1.x. cat > data/tls.ext <<EOF subjectAltName = DNS:${TUNNEL_DOMAIN},DNS:*.${TUNNEL_DOMAIN} authorityKeyIdentifier = keyid,issuer extendedKeyUsage = serverAuth EOF # Certificado do servidor assinado pela CA openssl req -newkey rsa:2048 -nodes \ -keyout data/tls.key -out /tmp/server.csr \ -subj "/CN=${TUNNEL_DOMAIN}" openssl x509 -req -in /tmp/server.csr \ -CA data/ca.crt -CAkey data/ca.key -CAcreateserial \ -out data/tls.crt -days 90 \ -extfile data/tls.extRegistre
data/ca.crtno Console. Mantenhadata/ca.keyem algum lugar durável e seguro; você precisará dele para assinar um novo certificado de servidor no momento da renovação.Criar os dois Secrets
O chart lê chaves específicas; os nomes dos Secrets são configuráveis, mas as chaves não. O comando de criação de namespace a seguir não tem efeito se o namespace já existir (por exemplo, da etapa do servidor MCP de exemplo).
kubectl create namespace mcp-tunnel --dry-run=client -o yaml | kubectl apply -f - kubectl -n mcp-tunnel create secret generic mcp-tunnel-token \ --from-literal=tunnel-token='eyJ...' kubectl -n mcp-tunnel create secret generic mcp-tunnel-cert \ --from-file=tls.crt=data/tls.crt \ --from-file=tls.key=data/tls.keyObter os valores padrão
helm show values \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 > values.yamlConfigurar valores para provisionamento manual
Edite
values.yamle defina as seguintes chaves:values.yamlsetup: enabled: false external: tunnelTokenSecretName: mcp-tunnel-token # must contain key: tunnel-token serverCertSecretName: mcp-tunnel-cert # must contain keys: tls.crt, tls.key gateway: config: # Required when setup.enabled is false. Replace the placeholder with # the $TUNNEL_DOMAIN value you exported earlier. When setup.enabled # is true the chart injects this from the Secret as a -tunnel-domain # flag instead. tunnel_domain: YOUR_TUNNEL_DOMAIN_HERE routes: docs: http://docs-mcp.internal:8080 search: http://search-mcp.internal:8080Algumas distribuições gerenciadas de Kubernetes alocam o CIDR de Service fora dos intervalos privados padrão; se suas rotas apontam para Services dentro do cluster, adicione
gateway.config.upstream.allowed_ipsaqui conforme Validação de IP upstream.Revisar os manifestos renderizados
helm template mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ -n mcp-tunnel \ -f values.yaml > rendered.yamlInstalar
helm install mcp-tunnel \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 \ --namespace mcp-tunnel --create-namespace \ -f values.yaml
Verificar a implantação
Verifique de ponta a ponta a partir do lado da Anthropic: use https://<route>.<your-tunnel-domain>/<path> em uma sessão de Managed Agent ou em uma requisição da Messages API, onde <route> é uma chave de gateway.config.routes e <path> é o caminho em que o servidor MCP upstream atende. Com o servidor MCP de exemplo, isso é https://echo.<your-tunnel-domain>/mcp. Consulte Usar os servidores MCP tunelados para os formatos de requisição.
Se isso falhar, verifique os logs do pod (kubectl -n mcp-tunnel logs deploy/mcp-tunnel -c mcp-proxy e -c cloudflared) e consulte Solução de problemas.
Configuração opcional
Restringir a saída com NetworkPolicy
A entrada no pod do proxy é negada por padrão (networkPolicy.ingress.enabled: true). Para restringir adicionalmente a saída do pod, defina networkPolicy.egress.enabled: true e preencha networkPolicy.egress.mcpServers com seletores de rótulo de pod ou intervalos CIDR que cubram seus servidores MCP upstream. A saída do cloudflared para a borda do túnel é permitida separadamente por meio de networkPolicy.egress.cloudflaredEgressCIDRs.
Ajustar o proxy
Os campos em gateway.config.* são repassados ao arquivo de configuração do proxy. Ajustes comuns incluem upstream.allowed_ips, log_level e upstream.tls. Consulte a referência de configuração do proxy para a lista completa de campos. O chart sempre define listen_addr, tls.cert_file e tls.key_file; defini-los em gateway.config não tem efeito.
Fornecer seu próprio token OIDC
Por padrão, o chart projeta um token de ServiceAccount do Kubernetes para o componente de configuração. Para usar um token de um provedor de identidade diferente (como SPIFFE, Vault ou um sidecar de SDK de nuvem), monte-o com setup.extraVolumes e setup.extraVolumeMounts. Em seguida, aponte api.wif.tokenFile para o caminho de montagem. O chart define ANTHROPIC_IDENTITY_TOKEN_FILE para esse caminho, e o componente de configuração lê o token a partir dali.
Atualizações
Sempre passe --version para helm upgrade para não obter inesperadamente um chart mais recente.
Atualizar a partir do chart 1.x
O chart 2.0.0 move o ID do túnel de api.wif.tunnelId para tunnel.id. Antes de atualizar, edite seu values.yaml: mova o valor tnl_... para tunnel.id e remova api.wif.tunnelId. Deixar tunnel.id sem definição é seguro (o componente de configuração reutiliza o ID do túnel já armazenado no Secret mcp-tunnel ao ser executado novamente), mas a movimentação explícita mantém seu values.yaml preciso. Atualize também o escopo da sua regra de federação de org:manage_tunnels para workspace:manage_tunnels no Console.
Alterar a configuração
Para alterações rotineiras, como rotas, número de réplicas ou NetworkPolicy:
helm upgrade mcp-tunnel \
oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
--version 2.0.2 \
-n mcp-tunnel \
-f values.yamlRotacionar o token do túnel
Com acesso programático, incremente tunnel.tokenVersion em values.yaml e atualize com --set setup.force=true. O componente de configuração só é executado novamente em atualizações quando forçado:
helm upgrade mcp-tunnel \
oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
--version 2.0.2 \
-n mcp-tunnel \
-f values.yaml \
--set setup.force=trueO componente de configuração se autentica com Workload Identity Federation; não há token de API para revogar.
Sem acesso programático, clique em Rotate token na página de detalhes do túnel no Console e, em seguida, atualize o Secret mcp-tunnel-token:
kubectl -n mcp-tunnel create secret generic mcp-tunnel-token \
--from-literal=tunnel-token='eyJ...' --dry-run=client -o yaml | kubectl apply -f -
kubectl -n mcp-tunnel rollout restart deploy/mcp-tunnelRenovação de certificado
O chart fornece automação, mas você continua responsável por monitorar a expiração e confirmar que a renovação seja concluída.
Com acesso programático, a renovação de certificado é automática. O chart implanta um CronJob (nomeado a partir do fullname do Helm, com o sufixo -cert-renew) que executa setup renew-cert diariamente (em serverCert.cronSchedule, padrão 0 0 * * * UTC). O job não tem efeito a menos que o certificado esteja dentro de serverCert.renewBefore da expiração (padrão 30 dias). A renovação é local: o job assina um novo certificado com a CA já armazenada no Secret, não faz chamadas de API e precisa apenas do RBAC do Kubernetes que o chart concede. O proxy recarrega o certificado dinamicamente a partir da montagem do Secret, portanto não é necessário reiniciar o Deployment.
Sem acesso programático, não há CronJob. De dentro do diretório mcp-tunnel/ que você manteve após a instalação, assine um novo certificado de servidor com a CA existente (não gere a CA novamente):
export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE
openssl req -new -key data/tls.key -out /tmp/server.csr \
-subj "/CN=${TUNNEL_DOMAIN}"
openssl x509 -req -in /tmp/server.csr \
-CA data/ca.crt -CAkey data/ca.key -CAcreateserial \
-out data/tls.crt -days 90 -extfile data/tls.ext
kubectl -n mcp-tunnel create secret generic mcp-tunnel-cert \
--from-file=tls.crt=data/tls.crt --from-file=tls.key=data/tls.key \
--dry-run=client -o yaml | kubectl apply -f -O proxy recarrega o certificado dinamicamente a partir da montagem do Secret.
Próximos passos
Anexe um servidor MCP upstream a um Managed Agent ou à Messages API.
Orientações de hardening, rotação de credenciais e resposta a violações.
Diagnostique problemas de conectividade, TLS e roteamento.
Was this page helpful?