Claude Platform Docs
СообщенияТуннели MCP

Развёртывание туннелей MCP с помощью Helm

Установите стек туннеля в кластер Kubernetes с помощью Helm-чарта Anthropic.

Helm-чарт Anthropic устанавливает стек туннеля как единый Deployment и подключает его к вашему туннелю: либо к тому, который создаёт для вас хук настройки чарта, либо к существующему туннелю, созданному вами в Claude Console.

Перед началом работы

Вам понадобится:

  • Туннель. При программном доступе хук настройки чарта создаёт туннель для вас, если вы не указали ID туннеля; чтобы вместо этого подключиться к существующему туннелю, создайте его в Console и запишите ID туннеля (tnl_...). Ручная подготовка всегда начинается с туннеля, созданного в Console; вам также понадобятся его токен туннеля и домен туннеля.
  • Способ аутентификации чарта в Tunnels API.
  • Кластер Kubernetes, в который вы можете выполнять развёртывание с помощью helm и kubectl. На вкладке Без программного доступа также используется openssl (версии 1.1.1 или новее).
  • Исходящее сетевое подключение из кластера к api.anthropic.com (443 TCP) и к периметру туннеля (7844 TCP и UDP). См. полные сетевые требования.
  • Один или несколько серверов MCP, запущенных и доступных из кластера по адресам, которые вы настроите в gateway.config.routes. Если у вас его ещё нет, используйте пример сервера.

Необязательно: использование примера сервера MCP

Если у вас нет сервера MCP для тестирования, используйте этот минимальный сервер:

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

В последующих шагах установки указано, где добавить соответствующий маршрут.

Установка

Компонент настройки обменивает проецируемый токен ServiceAccount кластера через ваше правило федерации, получает токен туннеля, генерирует CA и серверный сертификат и регистрирует CA в Anthropic. Ежедневный CronJob при необходимости обновляет серверный сертификат, поэтому вам не нужно обращаться с секретами вручную.

  1. Настройте Workload Identity Federation для кластера

    Следуйте инструкциям Использование WIF с Kubernetes, чтобы зарегистрировать OIDC-издателя вашего кластера и создать правило федерации. Компонент настройки работает под собственным ServiceAccount в пространстве имён релиза; точное имя формируется по соглашению Helm fullname, поэтому для любого имени релиза, отличного от mcp-tunnel, выполните helm template <release> ... | grep -A2 'kind: ServiceAccount', чтобы проверить его перед созданием правила. Далее в этом руководстве предполагается имя релиза mcp-tunnel в пространстве имён mcp-tunnel, где ServiceAccount называется mcp-tunnel-setup.

    ПолеЗначение
    Subjectsystem:serviceaccount:mcp-tunnel:mcp-tunnel-setup
    Audienceapi.anthropic.com (значение чарта по умолчанию; без схемы)
    Scopeworkspace:manage_tunnels

    Если туннель находится в рабочем пространстве, отличном от рабочего пространства организации по умолчанию, также добавьте сервисный аккаунт правила в это рабочее пространство (Tunnels API выполняет авторизацию на основе членства сервисного аккаунта в рабочих пространствах).

    Запишите идентификатор правила (fdrl_...); вы укажете его в api.wif.federationRuleId.

  2. Получите значения по умолчанию

    helm show values \
      oci://us-docker.pkg.dev/anthropic-public-registry/charts/mcp-tunnel \
      --version 2.1.0 > values.yaml
  3. Настройте подключение к туннелю и маршруты

    Отредактируйте values.yaml и задайте ключи api.wif.* с идентификатором правила федерации и идентификатором организации, а также запись routes для каждого вышестоящего сервера MCP:

    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

    С этими маршрутами Claude обращается к серверам по адресам docs.<your-tunnel-domain> и search.<your-tunnel-domain>. Некоторые управляемые дистрибутивы Kubernetes выделяют Service CIDR вне стандартных частных диапазонов; если ваши маршруты указывают на Services внутри кластера, добавьте здесь gateway.config.upstream.allowed_ips, как описано в разделе Проверка IP-адресов вышестоящих серверов.

  4. Проверьте сгенерированные манифесты

    Сгенерируйте чарт и проверьте результат в соответствии с практиками проверки вашей организации:

    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. Установите

    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

    Компонент настройки запускается как Job pre-install-хука Helm, поэтому helm install блокируется до его завершения. При успешном выполнении Helm автоматически удаляет Job. Если helm install завершается ошибкой хука, см. Ошибки аутентификации компонента настройки.

    Если tunnel.id пуст, компонент настройки создаёт туннель в рабочем пространстве, на которое нацелено ваше правило федерации (рабочее пространство организации по умолчанию, если вы не задали api.wif.workspaceId), и сохраняет его идентификатор и домен в Secret mcp-tunnel. Домен, который понадобится вам для проверки, можно найти на странице сведений о туннеле, которая открывается со страницы MCP tunnels (platform.claude.com/settings/workspaces/default/mcp-tunnels) в Console. В селекторе рабочих пространств на боковой панели выберите рабочее пространство, содержащее туннель. Вы также можете прочитать домен из Secret:

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

    Повторный запуск компонента настройки (во время обновлений или ротации токена) повторно использует идентификатор туннеля, сохранённый в этом Secret; второй туннель никогда не создаётся.

Проверка развёртывания

Выполните сквозную проверку со стороны Anthropic: используйте https://<route>.<your-tunnel-domain>/<path> в сеансе Managed Agent или в запросе к Messages API, где <route> — ключ из gateway.config.routes, а <path> — путь, по которому обслуживает запросы вышестоящий сервер MCP. Для примера сервера MCP это https://echo.<your-tunnel-domain>/mcp. Форматы запросов см. в разделе Использование туннелированных серверов MCP.

Если проверка не удалась, просмотрите журналы пода (kubectl -n mcp-tunnel logs deploy/mcp-tunnel -c mcp-proxy и -c cloudflared) и обратитесь к разделу Устранение неполадок.

Дополнительная настройка

Ограничение исходящего трафика с помощью NetworkPolicy

Входящий трафик к поду прокси по умолчанию запрещён (networkPolicy.ingress.enabled: true). Чтобы дополнительно ограничить исходящий трафик пода, задайте networkPolicy.egress.enabled: true и заполните networkPolicy.egress.mcpServers селекторами меток подов или диапазонами CIDR, охватывающими ваши вышестоящие серверы MCP. Исходящий трафик от cloudflared к периметру туннеля разрешается отдельно через networkPolicy.egress.cloudflaredEgressCIDRs.

Настройка прокси

Поля в gateway.config.* передаются в файл конфигурации прокси. Типичные настройки включают upstream.allowed_ips, log_level и upstream.tls. Полный список полей см. в справочнике по конфигурации прокси. Чарт всегда задаёт listen_addr, tls.cert_file и tls.key_file; их указание в gateway.config не имеет эффекта.

Использование собственного токена OIDC

По умолчанию чарт проецирует токен Kubernetes ServiceAccount для компонента настройки. Чтобы использовать токен от другого поставщика удостоверений (например, SPIFFE, Vault или sidecar облачного SDK), смонтируйте его с помощью setup.extraVolumes и setup.extraVolumeMounts. Затем укажите путь монтирования в api.wif.tokenFile. Чарт задаёт ANTHROPIC_IDENTITY_TOKEN_FILE равным этому пути, и компонент настройки считывает токен оттуда.

Обновления

Всегда передавайте --version в helm upgrade, чтобы неожиданно не получить более новую версию чарта.

Обновление с чарта 1.x

Чарт 2.0.0 переносит идентификатор туннеля из api.wif.tunnelId в tunnel.id. Перед обновлением отредактируйте ваш values.yaml: перенесите значение tnl_... в tunnel.id и удалите api.wif.tunnelId. Оставить tunnel.id незаданным безопасно (при повторном запуске компонент настройки повторно использует идентификатор туннеля, уже сохранённый в Secret mcp-tunnel), но явный перенос сохраняет точность вашего values.yaml. Также измените в Console область вашего правила федерации с org:manage_tunnels на workspace:manage_tunnels.

Изменение конфигурации

Для рутинных изменений, таких как маршруты, количество реплик или 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

Ротация токена туннеля

При программном доступе увеличьте tunnel.tokenVersion в values.yaml и выполните обновление с --set setup.force=true. Компонент настройки повторно запускается при обновлениях только принудительно:

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

Компонент настройки проходит аутентификацию с помощью Workload Identity Federation; токена API, который нужно отзывать, нет.

Без программного доступа нажмите Rotate token на странице сведений о туннеле в Console, затем обновите 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

Обновление сертификата

Чарт обеспечивает автоматизацию, но вы по-прежнему отвечаете за отслеживание срока действия и подтверждение завершения обновления.

При программном доступе обновление сертификата выполняется автоматически. Чарт развёртывает CronJob (названный по Helm fullname с суффиксом -cert-renew), который ежедневно запускает setup renew-cert (по расписанию serverCert.cronSchedule, по умолчанию 0 0 * * * UTC). Задание ничего не делает, если до истечения срока действия сертификата остаётся больше serverCert.renewBefore (по умолчанию 30 дней). Обновление выполняется локально: задание подписывает новый сертификат с помощью CA, уже сохранённого в Secret, не выполняет вызовов API и нуждается только в Kubernetes RBAC, который предоставляет чарт. Прокси выполняет горячую перезагрузку сертификата из смонтированного Secret, поэтому перезапуск Deployment не требуется.

Без программного доступа CronJob отсутствует. Находясь в каталоге mcp-tunnel/, сохранённом после установки, подпишите новый серверный сертификат существующим CA (не генерируйте 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 -

Прокси выполняет горячую перезагрузку сертификата из смонтированного Secret.

Следующие шаги

Was this page helpful?