Les tunnels MCP sont en aperçu de recherche. Demandez l'accès pour les essayer.
Une requête passant par le tunnel peut échouer à l'une des trois couches ; diagnostiquez-les dans l'ordre : la connexion sortante vers le tunnel edge, le inner TLS d'Anthropic vers votre proxy, puis le routage et la validation d'IP vers le serveur MCP en amont.
| Symptôme | Cause | Correctif |
|---|---|---|
| Le tunnel n'apparaît pas dans le sélecteur + MCP Server de l'agent | Le sélecteur ne liste que les tunnels de l'espace de travail de la session qui possèdent au moins un certificat actif. | Enregistrez un certificat CA, ou ouvrez la session dans l'espace de travail où le tunnel a été créé. |
L'appelant voit une erreur HTTP 500 ; cloudflared journalise No ingress rules were defined | cloudflared n'a pas de cible locale. | Ajoutez --url http://localhost:8080 et network_mode: "service:mcp-proxy" au service cloudflared. |
Le proxy journalise no route for host | tunnel_domain ne correspond pas au domaine attribué, ou config.yaml a été modifié sans redémarrage. | Définissez tunnel_domain sur le domaine exact affiché sur la page de détails du tunnel, puis redémarrez le proxy (docker compose restart mcp-proxy). |
Le proxy journalise IP validation failed: <ip> is not a private address | Le serveur MCP en amont se résout en dehors de RFC1918. | Voir Validation d'IP en amont. |
Le proxy se termine avec cannot unmarshal !!seq into map[string]string | routes est une liste YAML. | Utilisez routes: { name: http://host:port }. |
Le proxy se termine avec open /data/tls.key: permission denied | La clé est en 0600 ; le conteneur du proxy s'exécute en tant qu'utilisateur non-root. | chmod 644 data/tls.key. |
curl https://<proxy>:8080 échoue avec wrong version number | Comportement attendu ; l'écouteur est un WebSocket en clair. Le TLS s'effectue à l'intérieur du flux WS. | Vérifiez plutôt via un Managed Agent ou l'API Messages. |
Les sections suivantes couvrent les échecs qui nécessitent plus qu'un correctif d'une seule ligne.
Les flux OAuth échouent lorsque la liste d'autorisation d'IP source de votre serveur d'autorisation empêche le backend d'Anthropic d'atteindre /token, /register et les points de terminaison de découverte. Si vous préférez ne pas ajouter les plages de sortie d'Anthropic à votre liste d'autorisation, vous pouvez router les appels OAuth de backend à backend via le tunnel tout en conservant le point de terminaison /authorize destiné au navigateur sur votre nom d'hôte public existant.
Ajouter une route de proxy pour le serveur d'autorisation
routes:
mcp: http://your-mcp-server:8080
auth: http://your-auth-server:8080Redémarrez le proxy après avoir modifié routes (docker compose restart mcp-proxy, ou helm upgrade).
Servir des métadonnées de découverte à points de terminaison séparés
La réponse /.well-known/oauth-authorization-server de votre serveur d'autorisation doit pointer authorization_endpoint vers votre nom d'hôte existant autorisé et tout le reste vers le tunnel :
{
"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"]
}Pointer le serveur MCP vers l'émetteur du tunnel
La réponse /.well-known/oauth-protected-resource de votre serveur MCP doit référencer le nom d'hôte du tunnel comme son serveur d'autorisation :
{
"resource": "https://mcp.<tunnel-domain>",
"authorization_servers": ["https://auth.<tunnel-domain>"]
}Avec cette configuration, le navigateur de l'utilisateur atteint /authorize sur votre nom d'hôte existant (que votre liste d'autorisation permet déjà), tandis que le backend d'Anthropic atteint /token, /register et les documents de découverte via le tunnel.
Le composant de configuration (Job Helm ou service setup de Compose) s'authentifie auprès de l'API Tunnels en échangeant un JWT OIDC via votre règle de fédération. Lorsque l'échange échoue, consultez Dépanner un échange échoué dans la référence Workload Identity Federation ; les modes d'échec (subject, audience, issuer, JWKS, durée de vie) sont les mêmes.
Causes spécifiques aux tunnels :
api.anthropic.com (sans schéma). Si l'audience de votre règle est https://api.anthropic.com, définissez api.wif.audience pour qu'elle corresponde.403 de l'API Tunnels après un échange réussi signifie que la portée de la règle n'inclut pas org:manage_tunnels, ou que le compte de service de la règle n'est pas membre de l'espace de travail du tunnel. Définissez la portée et ajoutez le compte de service à l'espace de travail.Sur Helm, le composant de configuration s'exécute en tant que Job de hook pre-install. En cas d'échec, le Job est conservé pour inspection (kubectl logs job/mcp-tunnel-setup -n mcp-tunnel). Helm ne gère pas les ressources de hook, supprimez-le donc avant de réessayer :
helm uninstall mcp-tunnel -n mcp-tunnel
kubectl -n mcp-tunnel delete job mcp-tunnel-setupVérifiez d'abord les journaux de cloudflared. Causes courantes :
TUNNEL_TOKEN est manquant, expiré ou copié incorrectement.cloudflared peut également journaliser des avertissements concernant les tailles de tampon de réception UDP ; il s'agit d'une indication de réglage QUIC, pas d'une erreur.
Lorsqu'Anthropic rejette le certificat du proxy pendant le inner TLS, le proxy journalise tls handshake failed. Vérifiez que :
*.<tunnel-domain>.Consultez les exigences relatives aux certificats pour les règles de validation complètes.
Pour la protection contre les attaques SSRF, le proxy ne compose par défaut que des adresses dans les plages privées RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Seul IPv4 est pris en charge pour la connexion du proxy vers l'amont. (La plage de sortie de cloudflared vers l'edge dans Exigences réseau est un saut différent.)
Si le proxy journalise IP validation failed: <ip> is not a private address, le nom d'hôte en amont s'est résolu en dehors de cet ensemble. Sur Kubernetes, certaines distributions gérées allouent le CIDR de Service en dehors de RFC1918 ; si kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' renvoie une adresse en dehors des plages privées, recherchez le CIDR de Service de votre cluster et ajoutez-le.
Si l'adresse est légitime, ajoutez le CIDR couvrant le plus étroit à upstream.allowed_ips. Définir allowed_ips remplace la valeur par défaut RFC1918 plutôt que de l'étendre, incluez donc les plages privées que vos autres serveurs MCP en amont utilisent :
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 onlyÉvitez 0.0.0.0/0 en dehors des tests locaux ; cela désactive entièrement la protection SSRF.
Was this page helpful?