Claude Platform Docs
MessagesTunnel MCP

Risolvere i problemi dei tunnel MCP

Diagnostica i problemi di connettività, TLS, validazione IP e instradamento OAuth in uno stack di tunnel.

Una richiesta attraverso il tunnel può fallire in uno di tre livelli; diagnosticali in ordine: la connessione in uscita verso il tunnel edge, il TLS interno da Anthropic al tuo proxy, quindi l'instradamento e la validazione IP verso il server MCP upstream.

Riferimento rapido

SintomoCausaSoluzione
Il tunnel non compare nel selettore + MCP Server dell'agenteIl selettore elenca solo i tunnel nel workspace della sessione che hanno almeno un certificato attivo.Registra un certificato CA, oppure apri la sessione nel workspace in cui è stato creato il tunnel.
Il chiamante vede HTTP 500; cloudflared registra No ingress rules were definedcloudflared non ha una destinazione locale.Aggiungi --url http://localhost:8080 e network_mode: "service:mcp-proxy" al servizio cloudflared.
Il proxy registra no route for hosttunnel_domain non corrisponde al dominio assegnato, oppure config.yaml è stato modificato senza riavviare.Imposta tunnel_domain sul dominio esatto mostrato nella pagina di dettaglio del tunnel, quindi riavvia il proxy (docker compose restart mcp-proxy).
Il proxy registra IP validation failed: <ip> is not a private addressIl server MCP upstream si risolve al di fuori di RFC1918.Vedi Validazione IP upstream.
Il proxy termina con cannot unmarshal !!seq into map[string]stringroutes è una lista YAML.Usa routes: { name: http://host:port }.
Il proxy termina con open /data/tls.key: permission deniedLa chiave è 0600; il container del proxy viene eseguito come non-root.chmod 644 data/tls.key.
curl https://<proxy>:8080 fallisce con wrong version numberPrevisto; il listener è WebSocket in chiaro. Il TLS avviene all'interno dello stream WS.Verifica invece tramite un Managed Agent o la Messages API.

Le sezioni seguenti trattano i guasti che richiedono più di una correzione di una sola riga.

OAuth fallisce dietro una allowlist di IP di origine

I flussi OAuth falliscono quando la allowlist di IP di origine del tuo server di autorizzazione impedisce al backend di Anthropic di raggiungere /token, /register e gli endpoint di discovery. Se preferisci non inserire nella allowlist gli intervalli di egress di Anthropic, puoi instradare le chiamate OAuth backend-to-backend attraverso il tunnel, mantenendo l'endpoint /authorize rivolto al browser sul tuo hostname pubblico esistente.

  1. Aggiungi una route del proxy per il server di autorizzazione

    routes:
      mcp: http://your-mcp-server:8080
      auth: http://your-auth-server:8080

    Riavvia il proxy dopo aver modificato routes (docker compose restart mcp-proxy, oppure helm upgrade).

  2. Servi metadati di discovery con endpoint separati

    La risposta /.well-known/oauth-authorization-server del tuo server di autorizzazione dovrebbe puntare authorization_endpoint al tuo hostname esistente già presente nella allowlist e tutto il resto al 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"]
    }
  3. Punta il server MCP all'issuer del tunnel

    La risposta /.well-known/oauth-protected-resource del tuo server MCP dovrebbe fare riferimento all'hostname del tunnel come proprio server di autorizzazione:

    {
      "resource": "https://mcp.<tunnel-domain>",
      "authorization_servers": ["https://auth.<tunnel-domain>"]
    }

Con questa configurazione, il browser dell'utente raggiunge /authorize sul tuo hostname esistente (che la tua allowlist già consente), mentre il backend di Anthropic raggiunge /token, /register e i documenti di discovery attraverso il tunnel.

Errori di autenticazione del componente di setup

Il componente di setup (Job Helm o servizio setup di Compose) si autentica alla Tunnels API scambiando un JWT OIDC tramite la tua regola di federazione. Quando lo scambio fallisce, consulta Risolvere i problemi di uno scambio fallito nel riferimento di Workload Identity Federation; le modalità di errore (subject, audience, issuer, JWKS, durata) sono le stesse.

Cause specifiche dei tunnel:

  • L'audience predefinita del chart è api.anthropic.com (senza schema). Se l'audience della tua regola è https://api.anthropic.com, imposta api.wif.audience in modo che corrisponda.
  • Un 403 dalla Tunnels API dopo uno scambio riuscito significa che lo scope della regola non include workspace:manage_tunnels, oppure che il service account della regola non è membro del workspace del tunnel. Imposta lo scope e aggiungi il service account al workspace.

Su Helm, il componente di setup viene eseguito come Job hook di pre-install. In caso di errore, il Job viene lasciato per l'ispezione (kubectl logs job/mcp-tunnel-setup -n mcp-tunnel). Helm non gestisce le risorse hook, quindi eliminalo prima di riprovare:

helm uninstall mcp-tunnel -n mcp-tunnel
kubectl -n mcp-tunnel delete job mcp-tunnel-setup

Il tunnel non si connette

Controlla prima i log di cloudflared. Cause comuni:

  • Il TUNNEL_TOKEN è mancante, scaduto o copiato in modo errato.
  • Un firewall sta bloccando il traffico TCP/UDP in uscita sulla porta 7844 verso il tunnel edge.

cloudflared potrebbe anche registrare avvisi sulle dimensioni del buffer di ricezione UDP; si tratta di un suggerimento di ottimizzazione QUIC, non di un errore.

Errori di certificato

Quando Anthropic rifiuta il certificato del proxy durante il TLS interno, il proxy registra tls handshake failed. Verifica che:

  • Il certificato del server non sia scaduto.
  • Il Subject Alternative Name del certificato corrisponda a *.<tunnel-domain>.
  • La CA firmataria sia registrata presso Anthropic per questo tunnel.

Consulta i requisiti dei certificati per le regole di validazione complete.

Validazione IP upstream

Per la protezione da SSRF, il proxy per impostazione predefinita si connette solo a indirizzi negli intervalli privati RFC1918 (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16). Per la connessione dal proxy all'upstream è supportato solo IPv4. (L'intervallo di egress da cloudflared all'edge in Requisiti di rete è un hop diverso.)

Se il proxy registra IP validation failed: <ip> is not a private address, l'hostname upstream si è risolto al di fuori di tale insieme. Su Kubernetes, alcune distribuzioni gestite allocano il Service CIDR al di fuori di RFC1918; se kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' restituisce un indirizzo al di fuori degli intervalli privati, individua il Service CIDR del tuo cluster e aggiungilo.

Se l'indirizzo è legittimo, aggiungi il CIDR più ristretto che lo copre a upstream.allowed_ips. Impostare allowed_ips sostituisce il valore predefinito RFC1918 anziché estenderlo, quindi includi gli intervalli privati usati dagli altri tuoi server MCP upstream:

config/mcp-proxy.yaml
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

Was this page helpful?