Desplegar túneles MCP con Helm
Instala la pila del túnel en un clúster de Kubernetes usando el chart de Helm de Anthropic.
El chart de Helm de Anthropic instala la pila del túnel como un único Deployment y la conecta a tu túnel: uno que el hook de configuración del chart crea por ti, o un túnel existente que creaste en la Console.
Antes de comenzar
Necesitas:
- Un túnel. Con acceso programático, el hook de configuración del chart crea uno por ti cuando no proporcionas un ID de túnel; para conectarte a un túnel existente en su lugar, créalo en la Console y registra el ID del túnel (
tnl_...). El aprovisionamiento manual siempre parte de un túnel creado en la Console; también necesitarás su token de túnel y su dominio de túnel. - Una forma de que el chart se autentique ante la API de Tunnels.
- Acceso programático (recomendado). El componente de configuración se autentica mediante Workload Identity Federation, obtiene el token del túnel, genera una CA, la registra con Anthropic y almacena todo en un Secret. Necesitarás una regla de federación con alcance
workspace:manage_tunnels. - Manual. Omite el acceso programático. Obtendrás el token del túnel desde la Console, generarás tú mismo una CA y un certificado de servidor, registrarás la CA en la Console y proporcionarás las credenciales al clúster como Secrets.
- Acceso programático (recomendado). El componente de configuración se autentica mediante Workload Identity Federation, obtiene el token del túnel, genera una CA, la registra con Anthropic y almacena todo en un Secret. Necesitarás una regla de federación con alcance
- Un clúster de Kubernetes en el que puedas desplegar con
helmykubectl. La pestaña Sin acceso programático también usaopenssl(1.1.1 o posterior). - Conectividad de red saliente desde el clúster hacia
api.anthropic.com(443 TCP) y el borde del túnel (7844 TCP y UDP). Consulta los requisitos de red completos. - Uno o más servidores MCP en ejecución y accesibles desde el clúster en las direcciones que configurarás bajo
gateway.config.routes. Si aún no tienes uno, usa el servidor de ejemplo.
Opcional: Usa un servidor MCP de ejemplo
Si no tienes un servidor MCP disponible para pruebas, usa 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 }
EOFLos pasos de instalación que siguen indican dónde agregar la ruta correspondiente.
Instalar
El componente de configuración intercambia el token proyectado del ServiceAccount del clúster a través de tu regla de federación, obtiene el token del túnel, genera una CA y un certificado de servidor, y registra la CA con Anthropic. Un CronJob diario renueva el certificado de servidor según sea necesario, por lo que no manejas ningún secreto a mano.
Configura Workload Identity Federation para el clúster
Sigue Usar WIF con Kubernetes para registrar el emisor OIDC de tu clúster y crear una regla de federación. El componente de configuración se ejecuta bajo su propio ServiceAccount en el namespace del release; el nombre exacto sigue la convención
fullnamede Helm, así que para cualquier nombre de release distinto demcp-tunnel, ejecutahelm template <release> ... | grep -A2 'kind: ServiceAccount'para confirmarlo antes de crear la regla. El resto de esta guía asume el nombre de releasemcp-tunnelen el namespacemcp-tunnel, donde el ServiceAccount esmcp-tunnel-setup.Campo Valor Subject system:serviceaccount:mcp-tunnel:mcp-tunnel-setupAudience api.anthropic.com(el valor predeterminado del chart; sin esquema)Scope workspace:manage_tunnelsSi el túnel está en un workspace distinto del predeterminado de la organización, agrega también la cuenta de servicio de la regla como miembro de ese workspace en Settings > Workspaces (la API de Tunnels autoriza según las membresías de workspace de la cuenta de servicio).
Anota el ID de la regla (
fdrl_...); lo establecerás comoapi.wif.federationRuleId.Obtén los valores predeterminados
helm show values \ oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \ --version 2.0.2 > values.yamlConfigura la conexión del túnel y las rutas
Edita
values.yamly establece las clavesapi.wif.*con el ID de la regla de federación y el ID de la organización, además de una entrada enroutespara 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:8080Con estas rutas, Claude alcanza los servidores en
docs.<your-tunnel-domain>ysearch.<your-tunnel-domain>. Algunas distribuciones administradas de Kubernetes asignan el CIDR de Services fuera de los rangos privados estándar; si tus rutas apuntan a Services dentro del clúster, agregagateway.config.upstream.allowed_ipsaquí según Validación de IP upstream.Revisa los manifiestos renderizados
Renderiza el chart y revisa la salida de acuerdo con las prácticas de verificación de tu organización:
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.yamlInstala
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.yamlEl componente de configuración se ejecuta como un Job de hook pre-install de Helm, por lo que
helm installse bloquea hasta que se completa. Si tiene éxito, Helm elimina el Job automáticamente. Sihelm installfalla con un error de hook, consulta Fallos de autenticación del componente de configuración.Cuando
tunnel.idestá vacío, el componente de configuración crea el túnel en el workspace al que apunta tu regla de federación (el workspace predeterminado de la organización a menos que establezcasapi.wif.workspaceId) y almacena su ID y dominio en el Secretmcp-tunnel. Encuentra el dominio que necesitarás para la verificación en la página de detalle del túnel en la Console bajo Manage > MCP tunnels, o léelo desde el Secret:kubectl -n mcp-tunnel get secret mcp-tunnel \ -o jsonpath='{.data.tunnel-domain}' | base64 -dVolver a ejecutar el componente de configuración (durante actualizaciones o rotación del token) reutiliza el ID de túnel almacenado en este Secret; nunca crea un segundo túnel.
Verifica el despliegue
Verifica de extremo a extremo desde el lado de Anthropic: usa https://<route>.<your-tunnel-domain>/<path> en una sesión de Managed Agent o en una solicitud a la API de Messages, donde <route> es una clave de gateway.config.routes y <path> es la ruta en la que sirve el servidor MCP upstream. Con el servidor MCP de ejemplo, es https://echo.<your-tunnel-domain>/mcp. Consulta Usa los servidores MCP tunelizados para ver las formas de las solicitudes.
Si eso falla, revisa los logs del pod (kubectl -n mcp-tunnel logs deploy/mcp-tunnel -c mcp-proxy y -c cloudflared) y consulta Solución de problemas.
Configuración opcional
Restringe el tráfico saliente con NetworkPolicy
El tráfico entrante al pod del proxy se deniega de forma predeterminada (networkPolicy.ingress.enabled: true). Para restringir adicionalmente el tráfico saliente del pod, establece networkPolicy.egress.enabled: true y completa networkPolicy.egress.mcpServers con selectores de etiquetas de pod o rangos CIDR que cubran tus servidores MCP upstream. El tráfico saliente desde cloudflared hacia el borde del túnel se permite por separado mediante networkPolicy.egress.cloudflaredEgressCIDRs.
Ajusta el proxy
Los campos bajo gateway.config.* se pasan directamente al archivo de configuración del proxy. Los ajustes comunes incluyen upstream.allowed_ips, log_level y upstream.tls. Consulta la referencia de configuración del proxy para ver la lista completa de campos. El chart siempre establece listen_addr, tls.cert_file y tls.key_file; establecerlos en gateway.config no tiene efecto.
Proporciona tu propio token OIDC
De forma predeterminada, el chart proyecta un token de ServiceAccount de Kubernetes para el componente de configuración. Para usar un token de un proveedor de identidad diferente (como SPIFFE, Vault o un sidecar de SDK de nube), móntalo con setup.extraVolumes y setup.extraVolumeMounts. Luego apunta api.wif.tokenFile a la ruta de montaje. El chart establece ANTHROPIC_IDENTITY_TOKEN_FILE en esa ruta, y el componente de configuración lee el token desde allí.
Actualizaciones
Pasa siempre --version a helm upgrade para no obtener inesperadamente un chart más reciente.
Actualiza desde el chart 1.x
El chart 2.0.0 mueve el ID del túnel de api.wif.tunnelId a tunnel.id. Antes de actualizar, edita tu values.yaml: mueve el valor tnl_... a tunnel.id y elimina api.wif.tunnelId. Dejar tunnel.id sin establecer es seguro (el componente de configuración reutiliza el ID de túnel ya almacenado en el Secret mcp-tunnel al volver a ejecutarse), pero el movimiento explícito mantiene tu values.yaml preciso. Actualiza también el alcance de tu regla de federación de org:manage_tunnels a workspace:manage_tunnels en la Console.
Cambia la configuración
Para cambios rutinarios como rutas, número de réplicas o 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.yamlRota el token del túnel
Con acceso programático, incrementa tunnel.tokenVersion en values.yaml y actualiza con --set setup.force=true. El componente de configuración solo se vuelve a ejecutar en actualizaciones cuando se fuerza:
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=trueEl componente de configuración se autentica con Workload Identity Federation; no hay ningún token de API que revocar.
Sin acceso programático, haz clic en Rotate token en la página de detalle del túnel en la Console, y luego actualiza el 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-tunnelRenovación de certificados
El chart proporciona automatización, pero sigues siendo responsable de monitorear el vencimiento y confirmar que la renovación se complete.
Con acceso programático, la renovación de certificados es automática. El chart despliega un CronJob (nombrado según el fullname de Helm, con el sufijo -cert-renew) que ejecuta setup renew-cert diariamente (en serverCert.cronSchedule, predeterminado 0 0 * * * UTC). El job no tiene efecto a menos que el certificado esté dentro de serverCert.renewBefore de su vencimiento (predeterminado 30 días). La renovación es local: el job firma un nuevo certificado con la CA ya almacenada en el Secret, no realiza llamadas a la API y solo necesita el RBAC de Kubernetes que el chart otorga. El proxy recarga en caliente el certificado desde el montaje del Secret, por lo que no se necesita reiniciar el Deployment.
Sin acceso programático no hay CronJob. Desde dentro del directorio mcp-tunnel/ que conservaste después de la instalación, firma un nuevo certificado de servidor con la CA existente (no regeneres la CA):
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 -El proxy recarga en caliente el certificado desde el montaje del Secret.
Próximos pasos
Conecta un servidor MCP upstream a un Managed Agent o a la API de Messages.
Guía de endurecimiento, rotación de credenciales y respuesta ante brechas.
Diagnostica problemas de conectividad, TLS y enrutamiento.
Was this page helpful?