Los túneles MCP están en vista previa de investigación. Solicita acceso para probarlos.
Una solicitud a través del túnel puede fallar en una de tres capas; diagnostícalas en orden: la conexión saliente al tunnel edge (borde del túnel), el inner TLS (TLS interno) desde Anthropic hasta tu proxy, y luego el enrutamiento y la validación de IP hacia el servidor MCP upstream.
| Síntoma | Causa | Solución |
|---|---|---|
| El túnel no aparece en el selector + MCP Server del agente | El selector solo muestra túneles en el workspace de la sesión que tienen al menos un certificado activo. | Registra un certificado de CA, o abre la sesión en el workspace en el que se creó el túnel. |
El llamador ve HTTP 500; cloudflared registra No ingress rules were defined | cloudflared no tiene un destino local. | Agrega --url http://localhost:8080 y network_mode: "service:mcp-proxy" al servicio de cloudflared. |
El proxy registra no route for host | tunnel_domain no coincide con el dominio asignado, o se editó config.yaml sin reiniciar. | Establece tunnel_domain con el dominio exacto que se muestra en la página de detalles del túnel, luego reinicia el proxy (docker compose restart mcp-proxy). |
El proxy registra IP validation failed: <ip> is not a private address | El servidor MCP upstream se resuelve fuera de RFC1918. | Consulta Validación de IP upstream. |
El proxy termina con cannot unmarshal !!seq into map[string]string | routes es una lista YAML. | Usa routes: { name: http://host:port }. |
El proxy termina con open /data/tls.key: permission denied | La clave tiene permisos 0600; el contenedor del proxy se ejecuta sin privilegios de root. | chmod 644 data/tls.key. |
curl https://<proxy>:8080 falla con wrong version number | Esperado; el listener es WebSocket en texto plano. TLS ocurre dentro del flujo WS. | Verifica a través de un Managed Agent o la Messages API en su lugar. |
Las siguientes secciones cubren fallos que requieren más que una solución de una línea.
Los flujos de OAuth fallan cuando la lista de IPs de origen permitidas de tu servidor de autorización bloquea el acceso del backend de Anthropic a /token, /register y los endpoints de descubrimiento. Si prefieres no agregar los rangos de salida de Anthropic a la lista de permitidos, puedes enrutar las llamadas OAuth de backend a backend a través del túnel, manteniendo el endpoint /authorize orientado al navegador en tu hostname público existente.
Agrega una ruta de proxy para el servidor de autorización
routes:
mcp: http://your-mcp-server:8080
auth: http://your-auth-server:8080Reinicia el proxy después de editar routes (docker compose restart mcp-proxy, o helm upgrade).
Sirve metadatos de descubrimiento con endpoints divididos
La respuesta de /.well-known/oauth-authorization-server de tu servidor de autorización debe apuntar authorization_endpoint a tu hostname existente en la lista de permitidos y todo lo demás al túnel:
{
"issuer": "https://auth.<tunnel-domain>",
"authorization_endpoint": "https://<your-allowlisted-host>/authorize",
"token_endpoint": "https://auth.<tunnel-domain>/token",
"registration_endpoint": "https://auth.<tunnel-domain>/register",
"code_challenge_methods_supported": ["S256"]
}Apunta el servidor MCP al emisor del túnel
La respuesta de /.well-known/oauth-protected-resource de tu servidor MCP debe referenciar el hostname del túnel como su servidor de autorización:
{
"resource": "https://mcp.<tunnel-domain>",
"authorization_servers": ["https://auth.<tunnel-domain>"]
}Con esta configuración, el navegador del usuario accede a /authorize en tu hostname existente (que tu lista de permitidos ya autoriza), mientras que el backend de Anthropic accede a /token, /register y los documentos de descubrimiento a través del túnel.
El componente de configuración (Job de Helm o servicio setup de Compose) se autentica ante la Tunnels API intercambiando un JWT de OIDC a través de tu regla de federación. Cuando el intercambio falla, consulta Solucionar problemas de un intercambio fallido en la referencia de Workload Identity Federation; los modos de fallo (subject, audience, issuer, JWKS, lifetime) son los mismos.
Causas específicas de túneles:
api.anthropic.com (sin esquema). Si el audience de tu regla es https://api.anthropic.com, establece api.wif.audience para que coincida.403 de la Tunnels API después de un intercambio exitoso significa que el scope de la regla no incluye org:manage_tunnels, o que la cuenta de servicio de la regla no es miembro del workspace del túnel. Establece el scope y agrega la cuenta de servicio al workspace.En Helm, el componente de configuración se ejecuta como un Job de hook pre-install. En caso de fallo, el Job se deja disponible para inspección (kubectl logs job/mcp-tunnel-setup -n mcp-tunnel). Helm no gestiona los recursos de hooks, así que elimínalo antes de reintentar:
helm uninstall mcp-tunnel -n mcp-tunnel
kubectl -n mcp-tunnel delete job mcp-tunnel-setupRevisa primero los logs de cloudflared. Causas comunes:
TUNNEL_TOKEN falta, ha expirado o se copió incorrectamente.cloudflared también puede registrar advertencias sobre los tamaños del búfer de recepción UDP; esto es una sugerencia de ajuste de QUIC, no un error.
Cuando Anthropic rechaza el certificado del proxy durante el TLS interno, el proxy registra tls handshake failed. Verifica que:
*.<tunnel-domain>.Consulta los requisitos de certificados para ver las reglas de validación completas.
Para protección contra SSRF, el proxy solo se conecta a direcciones en los rangos privados RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) de forma predeterminada. Solo se admite IPv4 para la conexión del proxy al upstream. (El rango de salida de cloudflared al borde en Requisitos de red es un salto diferente).
Si el proxy registra IP validation failed: <ip> is not a private address, el hostname upstream se resolvió fuera de ese conjunto. En Kubernetes, algunas distribuciones gestionadas asignan el Service CIDR fuera de RFC1918; si kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' devuelve una dirección fuera de los rangos privados, busca el Service CIDR de tu clúster y agrégalo.
Si la dirección es legítima, agrega el CIDR más estrecho que la cubra a upstream.allowed_ips. Establecer allowed_ips reemplaza el valor predeterminado de RFC1918 en lugar de extenderlo, así que incluye los rangos privados que usan tus otros servidores MCP upstream:
upstream:
allowed_ips:
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- 127.0.0.0/8 # loopback, for local testing onlyEvita 0.0.0.0/0 fuera de pruebas locales; deshabilita por completo la protección contra SSRF.
Was this page helpful?