# Instrucciones para el agente: MCP tunnels: conecta servidores privados con la plataforma Claude

Pega este texto a tu agente (Claude Code, Codex, OpenCode, Hermes o el que uses) y dile «ayúdame a montarlo». Son los pasos para ponerlo en marcha; el porqué de cada pieza está en la guía completa.

- Dificultad: intermedio
- Guía completa: https://lab.wisd.ai/hub/mcp-tunnels

---

## Para el agente: cómo acompañar al usuario

1. Pregunta primero para qué lo quiere. Si su objetivo no necesita algún paso, sáltalo.
2. Antes de instalar, comprueba lo que ya tiene (versiones, claves, sistema operativo).
3. Avanza un paso cada vez: explica en una frase qué vas a hacer y deja que el usuario lo ejecute o lo apruebe.
4. Tras cada paso, comprueba que funcionó antes de seguir. Si falla, para y explica el error.
5. No inventes comandos ni opciones: si la documentación del proyecto contradice estos pasos, manda la documentación.
6. Al terminar, haz una prueba real con el objetivo del usuario y dile dónde profundizar.

---

## Pasos de configuración

### Paso 1: crea el túnel

Comprueba que Docker con Compose funciona, que OpenSSL ≥1.1.1 está en PATH y que el equipo tiene salida a Internet. Solicita acceso si tu cuenta no lo tiene. En la consola de Claude, abre MCP tunnels, selecciona el espacio de trabajo y crea un túnel con aprovisionamiento manual.

### Paso 2: prepara certificados y servicios

Esta es la ruta macOS/Linux del [inicio rápido oficial](https://platform.claude.com/docs/en/agents-and-tools/mcp-tunnels/quickstart). Sustituye el dominio por el de tu túnel y carga `TUNNEL_TOKEN` desde tu entorno privado. Ejecuta los bloques en la misma terminal, en este orden:

```bash
mkdir -p mcp-tunnel/{config,data}
cd mcp-tunnel
export TUNNEL_DOMAIN=YOUR_TUNNEL_DOMAIN_HERE   # dominio copiado de la consola
# Carga TUNNEL_TOKEN desde tu entorno privado antes de continuar.
```

```bash
openssl req -x509 -newkey rsa:2048 -nodes \
  -keyout data/ca.key -out data/ca.crt \
  -days 3650 -subj "/CN=mcp-tunnel-ca" \
  -addext "basicConstraints=critical,CA:TRUE" \
  -addext "keyUsage=critical,keyCertSign,cRLSign" \
  -addext "subjectKeyIdentifier=hash"

cat > data/tls.ext <<EOF
subjectAltName = DNS:${TUNNEL_DOMAIN},DNS:*.${TUNNEL_DOMAIN}
authorityKeyIdentifier = keyid,issuer
extendedKeyUsage = serverAuth
EOF

openssl req -newkey rsa:2048 -nodes \
  -keyout 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

chmod 644 data/tls.key
```

En la ficha del túnel de la consola pulsa Add certificate y sube `data/ca.crt`. Después crea `hello_server.py`, la configuración del proxy y Compose:

```bash
cat > hello_server.py <<'EOF'
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")
EOF
```

```bash
cat > config/mcp-proxy.yaml <<EOF
listen_addr: ":8080"
tunnel_domain: ${TUNNEL_DOMAIN}
tls:
  cert_file: /data/tls.crt
  key_file: /data/tls.key
routes:
  echo: http://hello-mcp:9000
EOF

cat > docker-compose.yaml <<'EOF'
services:
  mcp-proxy:
    image: us-docker.pkg.dev/anthropic-public-registry/images/mcp-proxy@sha256:d243d30642d39857a0579e465cb3b9bf3ae7c1141e83143bb6856777a31467a5
    volumes:
      - ./config/mcp-proxy.yaml:/etc/mcp-gateway/config.yaml:ro
      - ./data:/data:ro
    restart: unless-stopped

  cloudflared:
    image: cloudflare/cloudflared@sha256:0e56c13c7058fcef9c4f0e7d83372f82330548dbf8f8b366f3d8b506526d93b2
    command: tunnel --no-autoupdate run --url http://localhost:8080
    environment:
      - TUNNEL_TOKEN
    network_mode: "service:mcp-proxy"
    restart: unless-stopped

  hello-mcp:
    image: python:3.13-slim
    working_dir: /app
    volumes:
      - ./hello_server.py:/app/hello_server.py:ro
    command: sh -c "pip install --quiet mcp && python hello_server.py"
    restart: unless-stopped
EOF
```

Python 3.13 y el SDK MCP se instalan dentro del contenedor de ejemplo. Las imágenes del proxy y cloudflared quedan fijadas por huella; no hace falta Python en el equipo anfitrión.

### Paso 3: arranca el ejemplo

Desde el directorio `mcp-tunnel` preparado en el paso anterior, con esos archivos completos y `TUNNEL_DOMAIN` y `TUNNEL_TOKEN` definidos en la terminal, el comando oficial es:

```bash
docker compose up -d
```

En Sessions crea un agente, añade el servidor del túnel con subdominio `echo` y ruta `mcp`, y pide: «Usa hello para saludar a tunnel». La respuesta esperada es `Hello, tunnel!`.

## Comprobación

Confirma en los registros una ruta configurada y conexiones de cloudflared registradas. En la consola debe aparecer una llamada a la herramienta y su respuesta.

## Si algo falla

Comprueba acceso a la vista previa, rol, certificado de CA y conectividad saliente. Usa la página Troubleshooting de MCP tunnels; evita publicar el servicio para sortear un error del túnel.
