Claude Platform Docs
MessaggiTunnel MCP

Distribuire i tunnel MCP con Helm

Installa lo stack del tunnel su un cluster Kubernetes utilizzando il chart Helm di Anthropic.

Il chart Helm di Anthropic installa lo stack del tunnel come un singolo Deployment e lo collega al tuo tunnel: uno che l'hook di configurazione del chart crea per te, oppure un tunnel esistente che hai creato nella Claude Console.

Prima di iniziare

Ti servono:

  • Un tunnel. Con l'accesso programmatico, l'hook di configurazione del chart ne crea uno per te quando non fornisci un ID del tunnel; per collegarti invece a un tunnel esistente, crealo nella Console e annota l'ID del tunnel (tnl_...). Il provisioning manuale parte sempre da un tunnel creato nella Console; ti servono anche il suo token del tunnel e il dominio del tunnel.
  • Un modo per consentire al chart di autenticarsi presso la Tunnels API.
  • Un cluster Kubernetes su cui puoi effettuare il deployment con helm e kubectl. La scheda Senza accesso programmatico utilizza anche openssl (1.1.1 o successivo).
  • Connettività di rete in uscita dal cluster verso api.anthropic.com (443 TCP) e l'edge del tunnel (7844 TCP e UDP). Consulta i requisiti di rete completi.
  • Uno o più server MCP in esecuzione e raggiungibili dal cluster agli indirizzi che configurerai in gateway.config.routes. Se non ne hai ancora uno, usa il server di esempio.

Facoltativo: usa un server MCP di esempio

Se non hai un server MCP disponibile per i test, usa questo server minimale:

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 }
EOF

I passaggi di installazione che seguono indicano dove aggiungere la route corrispondente.

Installazione

Il componente di configurazione scambia il token ServiceAccount proiettato del cluster tramite la tua regola di federazione, recupera il token del tunnel, genera una CA e un certificato del server e registra la CA presso Anthropic. Un CronJob giornaliero rinnova il certificato del server quando necessario, quindi non devi gestire manualmente alcun segreto.

  1. Configura Workload Identity Federation per il cluster

    Segui Usare WIF con Kubernetes per registrare l'issuer OIDC del tuo cluster e creare una regola di federazione. Il componente di configurazione viene eseguito con un proprio ServiceAccount nel namespace della release; il nome esatto segue la convenzione fullname di Helm, quindi per qualsiasi nome di release diverso da mcp-tunnel, esegui helm template <release> ... | grep -A2 'kind: ServiceAccount' per verificarlo prima di creare la regola. Il resto di questa guida presuppone il nome di release mcp-tunnel nel namespace mcp-tunnel, dove il ServiceAccount è mcp-tunnel-setup.

    CampoValore
    Subjectsystem:serviceaccount:mcp-tunnel:mcp-tunnel-setup
    Audienceapi.anthropic.com (il valore predefinito del chart; senza schema)
    Scopeworkspace:manage_tunnels

    Se il tunnel si trova in un workspace diverso da quello predefinito dell'organizzazione, aggiungi anche il service account della regola a quel workspace (la Tunnels API autorizza in base alle appartenenze ai workspace del service account).

    Annota l'ID della regola (fdrl_...); lo imposterai come api.wif.federationRuleId.

  2. Recupera i valori predefiniti

    helm show values \
      oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
      --version 2.1.0 > values.yaml
  3. Configura il collegamento al tunnel e le route

    Modifica values.yaml e imposta le chiavi api.wif.* con l'ID della regola di federazione e l'ID dell'organizzazione, oltre a una voce routes per ciascun server MCP upstream:

    values.yaml
    api:
      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:8080

    Con queste route, Claude raggiunge i server su docs.<your-tunnel-domain> e search.<your-tunnel-domain>. Alcune distribuzioni Kubernetes gestite allocano il CIDR dei Service al di fuori degli intervalli privati standard; se le tue route puntano a Service interni al cluster, aggiungi qui gateway.config.upstream.allowed_ips come descritto in Convalida degli IP upstream.

  4. Esamina i manifest renderizzati

    Esegui il rendering del chart ed esamina l'output secondo le pratiche di verifica della tua organizzazione:

    helm template mcp-tunnel \
      oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
      --version 2.1.0 \
      -n mcp-tunnel \
      -f values.yaml > rendered.yaml
  5. Installa

    helm install mcp-tunnel \
      oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
      --version 2.1.0 \
      --namespace mcp-tunnel --create-namespace \
      -f values.yaml

    Il componente di configurazione viene eseguito come Job hook pre-install di Helm, quindi helm install resta bloccato finché non viene completato. In caso di successo, Helm elimina automaticamente il Job. Se helm install fallisce con un errore dell'hook, consulta Errori di autenticazione del componente di configurazione.

    Quando tunnel.id è vuoto, il componente di configurazione crea il tunnel nel workspace a cui punta la tua regola di federazione (il workspace predefinito dell'organizzazione, a meno che tu non imposti api.wif.workspaceId) e memorizza il suo ID e il suo dominio nel Secret mcp-tunnel. Trova il dominio che ti servirà per la verifica nella pagina dei dettagli del tunnel, che apri dalla pagina Tunnel MCP (platform.claude.com/settings/workspaces/default/mcp-tunnels) nella Console. Nel selettore dei workspace nella barra laterale, seleziona il workspace che contiene il tunnel. Puoi anche leggere il dominio dal Secret:

    kubectl -n mcp-tunnel get secret mcp-tunnel \
      -o jsonpath='{.data.tunnel-domain}' | base64 -d

    La riesecuzione del componente di configurazione (durante gli aggiornamenti o la rotazione del token) riutilizza l'ID del tunnel memorizzato in questo Secret; non crea mai un secondo tunnel.

Verifica il deployment

Esegui una verifica end-to-end dal lato di Anthropic: usa https://<route>.<your-tunnel-domain>/<path> in una sessione di Managed Agent o in una richiesta alla Messages API, dove <route> è una chiave di gateway.config.routes e <path> è il percorso su cui il server MCP upstream risponde. Con il server MCP di esempio, è https://echo.<your-tunnel-domain>/mcp. Consulta Usare i server MCP tramite tunnel per la struttura delle richieste.

Se la verifica fallisce, controlla i log del pod (kubectl -n mcp-tunnel logs deploy/mcp-tunnel -c mcp-proxy e -c cloudflared) e consulta la Risoluzione dei problemi.

Configurazione facoltativa

Limita il traffico in uscita con NetworkPolicy

Il traffico in ingresso verso il pod del proxy è negato per impostazione predefinita (networkPolicy.ingress.enabled: true). Per limitare anche il traffico in uscita dal pod, imposta networkPolicy.egress.enabled: true e popola networkPolicy.egress.mcpServers con selettori di etichette dei pod o intervalli CIDR che coprano i tuoi server MCP upstream. Il traffico in uscita da cloudflared verso l'edge del tunnel è consentito separatamente tramite networkPolicy.egress.cloudflaredEgressCIDRs.

Ottimizza il proxy

I campi in gateway.config.* vengono passati al file di configurazione del proxy. Le modifiche comuni includono upstream.allowed_ips, log_level e upstream.tls. Consulta il riferimento sulla configurazione del proxy per l'elenco completo dei campi. Il chart imposta sempre listen_addr, tls.cert_file e tls.key_file; impostarli in gateway.config non ha alcun effetto.

Fornisci il tuo token OIDC

Per impostazione predefinita, il chart proietta un token ServiceAccount di Kubernetes per il componente di configurazione. Per usare un token di un diverso provider di identità (come SPIFFE, Vault o un sidecar di un SDK cloud), montalo con setup.extraVolumes e setup.extraVolumeMounts. Quindi fai puntare api.wif.tokenFile al percorso di montaggio. Il chart imposta ANTHROPIC_IDENTITY_TOKEN_FILE su quel percorso e il componente di configurazione legge il token da lì.

Aggiornamenti

Passa sempre --version a helm upgrade per non scaricare inaspettatamente un chart più recente.

Aggiornamento dal chart 1.x

Il chart 2.0.0 sposta l'ID del tunnel da api.wif.tunnelId a tunnel.id. Prima di aggiornare, modifica il tuo values.yaml: sposta il valore tnl_... in tunnel.id e rimuovi api.wif.tunnelId. Lasciare tunnel.id non impostato è sicuro (il componente di configurazione riutilizza alla riesecuzione l'ID del tunnel già memorizzato nel Secret mcp-tunnel), ma lo spostamento esplicito mantiene accurato il tuo values.yaml. Aggiorna inoltre nella Console l'ambito della tua regola di federazione da org:manage_tunnels a workspace:manage_tunnels.

Modifica la configurazione

Per modifiche di routine come route, numero di repliche o NetworkPolicy:

helm upgrade mcp-tunnel \
  oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
  --version 2.1.0 \
  -n mcp-tunnel \
  -f values.yaml

Ruota il token del tunnel

Con l'accesso programmatico, incrementa tunnel.tokenVersion in values.yaml ed esegui l'aggiornamento con --set setup.force=true. Il componente di configurazione viene rieseguito durante gli aggiornamenti solo se forzato:

helm upgrade mcp-tunnel \
  oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
  --version 2.1.0 \
  -n mcp-tunnel \
  -f values.yaml \
  --set setup.force=true

Il componente di configurazione si autentica con Workload Identity Federation; non c'è alcun token API da revocare.

Senza accesso programmatico, fai clic su Rotate token nella pagina dei dettagli del tunnel nella Console, quindi aggiorna il 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-tunnel

Rinnovo del certificato

Il chart fornisce l'automazione, ma resti responsabile del monitoraggio della scadenza e della conferma del completamento del rinnovo.

Con l'accesso programmatico, il rinnovo del certificato è automatico. Il chart distribuisce un CronJob (denominato in base al fullname di Helm, con suffisso -cert-renew) che esegue setup renew-cert ogni giorno (secondo serverCert.cronSchedule, predefinito 0 0 * * * UTC). Il job non ha effetto a meno che il certificato non si trovi entro serverCert.renewBefore dalla scadenza (predefinito 30 giorni). Il rinnovo è locale: il job firma un nuovo certificato con la CA già memorizzata nel Secret, non effettua chiamate API e necessita solo dell'RBAC di Kubernetes concesso dal chart. Il proxy ricarica a caldo il certificato dal mount del Secret, quindi non è necessario riavviare il Deployment.

Senza accesso programmatico non esiste alcun CronJob. Dall'interno della directory mcp-tunnel/ che hai conservato dopo l'installazione, firma un nuovo certificato del server con la CA esistente (non rigenerare 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 -

Il proxy ricarica a caldo il certificato dal mount del Secret.

Passaggi successivi

Was this page helpful?