Claude Platform Docs
MessagesMCP-Tunnel

Fehlerbehebung bei MCP-Tunneln

Diagnostiziere Probleme mit Konnektivität, TLS, IP-Validierung und OAuth-Routing in einem Tunnel-Stack.

Eine Anfrage durch den Tunnel kann auf einer von drei Ebenen fehlschlagen; diagnostiziere sie der Reihe nach: die ausgehende Verbindung zum Tunnel-Edge, das innere TLS von Anthropic zu deinem Proxy, dann Routing und IP-Validierung in Richtung des Upstream-MCP-Servers.

Kurzreferenz

SymptomUrsacheLösung
Tunnel erscheint nicht in der + MCP Server-Auswahl des AgentenDie Auswahl listet nur Tunnel im Workspace der Sitzung auf, die mindestens ein aktives Zertifikat haben.Registriere ein CA-Zertifikat oder öffne die Sitzung in dem Workspace, in dem der Tunnel erstellt wurde.
Aufrufer sieht HTTP 500; cloudflared protokolliert No ingress rules were definedcloudflared hat kein lokales Ziel.Füge --url http://localhost:8080 und network_mode: "service:mcp-proxy" zum cloudflared-Service hinzu.
Proxy protokolliert no route for hosttunnel_domain stimmt nicht mit der zugewiesenen Domain überein, oder config.yaml wurde ohne Neustart bearbeitet.Setze tunnel_domain auf die exakte Domain, die auf der Tunnel-Detailseite angezeigt wird, und starte dann den Proxy neu (docker compose restart mcp-proxy).
Proxy protokolliert IP validation failed: <ip> is not a private addressDer Upstream-MCP-Server wird außerhalb von RFC1918 aufgelöst.Siehe Upstream-IP-Validierung.
Proxy beendet sich mit cannot unmarshal !!seq into map[string]stringroutes ist eine YAML-Liste.Verwende routes: { name: http://host:port }.
Proxy beendet sich mit open /data/tls.key: permission deniedDer Schlüssel ist 0600; der Proxy-Container läuft nicht als Root.chmod 644 data/tls.key.
curl https://<proxy>:8080 schlägt mit wrong version number fehlErwartet; der Listener ist Klartext-WebSocket. TLS findet innerhalb des WS-Streams statt.Überprüfe stattdessen über einen Managed Agent oder die Messages API.

Die folgenden Abschnitte behandeln Fehler, die mehr als eine einzeilige Lösung erfordern.

OAuth schlägt hinter einer Quell-IP-Allowlist fehl

OAuth-Flows schlagen fehl, wenn die Quell-IP-Allowlist deines Autorisierungsservers das Backend von Anthropic daran hindert, /token, /register und die Discovery-Endpunkte zu erreichen. Wenn du die Egress-Bereiche von Anthropic lieber nicht auf die Allowlist setzen möchtest, kannst du die Backend-zu-Backend-OAuth-Aufrufe durch den Tunnel leiten, während der browserseitige /authorize-Endpunkt auf deinem bestehenden öffentlichen Hostnamen bleibt.

  1. Füge eine Proxy-Route für den Autorisierungsserver hinzu

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

    Starte den Proxy nach dem Bearbeiten von routes neu (docker compose restart mcp-proxy oder helm upgrade).

  2. Stelle Discovery-Metadaten mit aufgeteilten Endpunkten bereit

    Die /.well-known/oauth-authorization-server-Antwort deines Autorisierungsservers sollte authorization_endpoint auf deinen bestehenden, auf der Allowlist stehenden Hostnamen verweisen lassen und alles andere auf den 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. Verweise den MCP-Server auf den Tunnel-Issuer

    Die /.well-known/oauth-protected-resource-Antwort deines MCP-Servers sollte den Tunnel-Hostnamen als ihren Autorisierungsserver referenzieren:

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

Mit dieser Konfiguration ruft der Browser des Nutzers /authorize auf deinem bestehenden Hostnamen auf (was deine Allowlist bereits erlaubt), während das Backend von Anthropic /token, /register und die Discovery-Dokumente durch den Tunnel erreicht.

Authentifizierungsfehler der Setup-Komponente

Die Setup-Komponente (Helm-Job oder Compose-setup-Service) authentifiziert sich bei der Tunnels API, indem sie ein OIDC-JWT über deine Föderationsregel austauscht. Wenn der Austausch fehlschlägt, siehe Fehlerbehebung bei einem fehlgeschlagenen Austausch in der Referenz zur Workload Identity Federation; die Fehlermodi (Subject, Audience, Issuer, JWKS, Lebensdauer) sind dieselben.

Tunnel-spezifische Ursachen:

  • Die Standard-Audience des Charts ist api.anthropic.com (ohne Schema). Wenn die Audience deiner Regel https://api.anthropic.com ist, setze api.wif.audience entsprechend.
  • Ein 403 von der Tunnels API nach einem erfolgreichen Austausch bedeutet, dass der Scope der Regel workspace:manage_tunnels nicht enthält oder der Service-Account der Regel kein Mitglied des Workspace des Tunnels ist. Setze den Scope und füge den Service-Account zum Workspace hinzu.

Bei Helm läuft die Setup-Komponente als Pre-Install-Hook-Job. Bei einem Fehler bleibt der Job zur Untersuchung bestehen (kubectl logs job/mcp-tunnel-setup -n mcp-tunnel). Helm verwaltet keine Hook-Ressourcen, lösche ihn also vor einem erneuten Versuch:

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

Tunnel verbindet sich nicht

Prüfe zuerst die cloudflared-Logs. Häufige Ursachen:

  • Das TUNNEL_TOKEN fehlt, ist abgelaufen oder wurde falsch kopiert.
  • Eine Firewall blockiert ausgehendes TCP/UDP auf Port 7844 zum Tunnel-Edge.

cloudflared protokolliert möglicherweise auch Warnungen zu UDP-Empfangspuffergrößen; dies ist ein QUIC-Tuning-Hinweis, kein Fehler.

Zertifikatsfehler

Wenn Anthropic das Zertifikat des Proxys während des inneren TLS ablehnt, protokolliert der Proxy tls handshake failed. Überprüfe, dass:

  • Das Serverzertifikat nicht abgelaufen ist.
  • Der Subject Alternative Name des Zertifikats mit *.<tunnel-domain> übereinstimmt.
  • Die signierende CA bei Anthropic für diesen Tunnel registriert ist.

Siehe die Zertifikatsanforderungen für die vollständigen Validierungsregeln.

Upstream-IP-Validierung

Zum SSRF-Schutz wählt der Proxy standardmäßig nur Adressen in den privaten RFC1918-Bereichen (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) an. Für die Verbindung vom Proxy zum Upstream wird nur IPv4 unterstützt. (Der Egress-Bereich von cloudflared zum Edge in den Netzwerkanforderungen ist ein anderer Hop.)

Wenn der Proxy IP validation failed: <ip> is not a private address protokolliert, wurde der Upstream-Hostname außerhalb dieser Menge aufgelöst. Auf Kubernetes weisen einige verwaltete Distributionen den Service-CIDR außerhalb von RFC1918 zu; wenn kubectl get svc kubernetes -n default -o jsonpath='{.spec.clusterIP}' eine Adresse außerhalb der privaten Bereiche zurückgibt, ermittle den Service-CIDR deines Clusters und füge ihn hinzu.

Wenn die Adresse legitim ist, füge den engsten abdeckenden CIDR zu upstream.allowed_ips hinzu. Das Setzen von allowed_ips ersetzt den RFC1918-Standard, anstatt ihn zu erweitern, schließe also die privaten Bereiche ein, die deine anderen Upstream-MCP-Server verwenden:

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?