Módulo 7: Remote Control y CLAUDE.md para Equipos

2. Remote Control — Setup, Sesiones y Control desde Dispositivos Móviles

2. Remote Control — Setup, Sesiones y Control desde Dispositivos Móviles

Descripción

Hasta ahora, supervisar Claude Code significa estar frente a tu terminal. Si un Agent Team está corriendo un refactor de 40 minutos, tienes dos opciones: quedarte mirando la pantalla o irte y perder visibilidad completa de lo que está pasando. Remote control cambia esa dinámica — te permite conectarte a sesiones activas de Claude Code desde otro dispositivo para monitorear progreso, ver qué archivos se están editando, y mantener el control sin estar físicamente en tu computador.

Esta cápsula cubre el setup técnico completo: cómo habilitar remote control, cómo conectar dispositivos, cómo monitorear sesiones en tiempo real, y las consideraciones de seguridad que necesitas antes de exponer sesiones a acceso remoto. Al terminar, podrás lanzar un Agent Team en tu máquina, irte, y revisar el estado desde tu teléfono.

Estado experimental (marzo 2026): Remote control es una feature en desarrollo activo en Claude Code. Las APIs y comandos descritos en esta cápsula están basados en la documentación y funcionalidad disponible a marzo de 2026. Verifica la disponibilidad actual en docs.anthropic.com/en/docs/claude-code antes de implementar. Algunos comandos pueden haber cambiado de nombre o requerir flags adicionales.


Entendiendo Remote Control

El modelo conceptual

Remote control no crea una nueva sesión — se conecta a una sesión existente. Tu Claude Code sigue corriendo en tu máquina. El remote control es una ventana de lectura (y opcionalmente, escritura) a esa sesión desde otro lugar.

Tu máquina (donde corre Claude Code)
┌─────────────────────────────────────┐
│  Claude Code Session (activa)       │
│  ├── Agent Team corriendo           │
│  ├── Hooks activos                  │
│  └── SDK scripts ejecutándose       │
│                                     │
│  Remote Control Server (local)      │
│  └── Expone API para conexiones     │
└──────────────┬──────────────────────┘
               │ (conexión segura)
               │
┌──────────────┴──────────────────────┐
│  Tu teléfono / otro dispositivo     │
│  ├── Ver estado de sesión           │
│  ├── Ver archivos editados          │
│  ├── Aprobar/rechazar operaciones   │
│  └── Enviar comandos                │
└─────────────────────────────────────┘

Qué puedes hacer remotamente

CapacidadDescripciónRequiere
MonitorearVer estado actual de la sesión, archivos editados, comandos ejecutadosSolo lectura
Aprobar/RechazarResponder a PermissionRequest de hooksEscritura limitada
Ver Agent TeamEstado de cada teammate — en progreso, completado, fallidoSolo lectura
Enviar mensajeEnviar instrucción adicional a la sesiónEscritura
InterrumpirCancelar la ejecución actualEscritura

Acceso remoto: métodos disponibles

Claude Code ofrece múltiples formas de acceso remoto:

Método 1: claude.ai Web Interface
  → Conectar sesión de Claude Code a la interfaz web
  → Requiere cuenta Anthropic autenticada
  → Mejor para monitoreo visual

Método 2: CLI desde otro terminal/máquina
  → Conectarse via SSH + claude session commands
  → Mejor para developers que prefieren terminal

Método 3: SDK API (programático)
  → Usar el SDK desde scripts para consultar estado
  → Mejor para dashboards custom y automatización

Habilitando Remote Control

Paso 1: Verificar soporte

claude --version

claude --help | grep -i remote

Si remote no aparece en la ayuda, tu versión puede no soportar esta feature aún. Actualiza:

npm update -g @anthropic-ai/claude-code

Paso 2: Configurar el acceso remoto

La configuración de remote control se hace a nivel de settings del proyecto o del usuario:

{
  "remote": {
    "enabled": true,
    "require_auth": true,
    "allowed_operations": ["monitor", "approve", "reject", "interrupt"],
    "session_visibility": "authenticated"
  }
}

Guarda esto en .claude/settings.json (nivel proyecto) o ~/.claude/settings.json (nivel usuario).

Paso 3: Iniciar una sesión con remote control habilitado

claude --remote

# O con configuración explícita:
claude --remote --remote-port 3500

Cuando la sesión arranca con --remote, Claude Code:

  1. Inicia el servidor de remote control en un puerto local
  2. Genera un token de autenticación temporal
  3. Muestra la URL y el token para conectar
Remote control enabled.
Connect URL: https://claude.ai/remote/session/abc123
Auth token: rc_tk_xxxxxxxxxxxxxxxx

Paso 4: Conectar desde otro dispositivo

Desde el navegador web:

Abre la URL proporcionada, ingresa el token de autenticación, y verás el dashboard de la sesión en tiempo real.

Desde otra terminal (mismo equipo o SSH):

claude remote connect --session abc123 --token rc_tk_xxxxxxxxxxxxxxxx

Desde el SDK (programático):

import subprocess
import json

result = subprocess.run(
    ["claude", "remote", "status", "--session", "abc123",
     "--token", "rc_tk_xxxxxxxxxxxxxxxx",
     "--output-format", "json"],
    capture_output=True, text=True
)

status = json.loads(result.stdout)
print(f"Estado: {status['state']}")
print(f"Archivos editados: {status['files_changed']}")
print(f"Operaciones pendientes: {status['pending_approvals']}")

Monitoreo de Sesiones en Tiempo Real

Estado de la sesión

Una vez conectado, puedes consultar el estado de la sesión:

claude remote status --session abc123 --output-format json

Respuesta típica:

{
  "session_id": "abc123",
  "state": "running",
  "started_at": "2026-03-13T10:30:00Z",
  "running_for_ms": 125000,
  "current_task": "Refactoring authentication module",
  "tools_used": 42,
  "files_changed": [
    "src/auth/login.py",
    "src/auth/middleware.py",
    "tests/test_auth.py"
  ],
  "pending_approvals": [],
  "agent_team": {
    "team_lead": {
      "state": "coordinating",
      "current_task": "Reviewing teammate outputs"
    },
    "teammates": [
      {
        "name": "auth-specialist",
        "state": "working",
        "task": "Implementing JWT refresh"
      },
      {
        "name": "test-writer",
        "state": "waiting",
        "task": "Waiting for auth changes"
      }
    ]
  },
  "cost_usd": 0.0234,
  "errors": []
}

Monitoreo continuo

Para monitorear en tiempo real (similar a tail -f):

claude remote watch --session abc123 --interval 5

Este comando imprime el estado cada 5 segundos. Es especialmente útil para operaciones largas donde quieres un heartbeat constante.

Script de monitoreo con Python

Para un dashboard más personalizado:

#!/usr/bin/env python3
"""Monitor remoto de sesiones de Claude Code."""

import subprocess
import json
import time
import sys


def get_session_status(session_id, token):
    result = subprocess.run(
        ["claude", "remote", "status",
         "--session", session_id,
         "--token", token,
         "--output-format", "json"],
        capture_output=True, text=True
    )
    if result.returncode != 0:
        return None
    return json.loads(result.stdout)


def display_status(status):
    print(f"\033[2J\033[H")  # clear screen
    print(f"{'='*50}")
    print(f"Session: {status['session_id']}")
    print(f"Estado: {status['state']}")
    print(f"Tiempo: {status['running_for_ms'] // 1000}s")
    print(f"Costo: ${status.get('cost_usd', 0):.4f}")
    print(f"{'='*50}")

    if status.get('agent_team'):
        team = status['agent_team']
        print(f"\nAgent Team:")
        print(f"  Lead: {team['team_lead']['state']}")
        for tm in team.get('teammates', []):
            icon = "🔄" if tm['state'] == 'working' else "⏳"
            print(f"  {icon} {tm['name']}: {tm['task']}")

    if status.get('pending_approvals'):
        print(f"\n⚠️  APROBACIONES PENDIENTES:")
        for approval in status['pending_approvals']:
            print(f"  → {approval['operation']}: {approval['description']}")

    if status.get('files_changed'):
        print(f"\nArchivos ({len(status['files_changed'])}):")
        for f in status['files_changed'][-5:]:
            print(f"  📄 {f}")


def main():
    if len(sys.argv) < 3:
        print("Uso: python monitor.py <session_id> <token>")
        sys.exit(1)

    session_id = sys.argv[1]
    token = sys.argv[2]

    print("Conectando al remote control...")

    while True:
        status = get_session_status(session_id, token)
        if status is None:
            print("Error obteniendo estado. Reintentando...")
            time.sleep(10)
            continue

        display_status(status)

        if status['state'] in ('completed', 'error', 'cancelled'):
            print(f"\nSesión terminada: {status['state']}")
            break

        time.sleep(5)


if __name__ == "__main__":
    main()

Monitoreo de Agent Teams Remotamente

Ver estado del equipo

Cuando un Agent Team está activo, el remote control expone el estado de cada teammate:

claude remote team-status --session abc123 --output-format json
{
  "team_lead": {
    "state": "coordinating",
    "tasks_assigned": 4,
    "tasks_completed": 2,
    "tasks_in_progress": 1,
    "tasks_pending": 1
  },
  "teammates": [
    {
      "name": "backend-dev",
      "state": "working",
      "current_task": "Implement user CRUD",
      "files_touched": ["src/api/users.py", "src/models/user.py"],
      "started_at": "2026-03-13T10:32:00Z"
    },
    {
      "name": "test-writer",
      "state": "completed",
      "completed_task": "Write unit tests for auth",
      "files_touched": ["tests/test_auth.py"],
      "duration_ms": 45000
    },
    {
      "name": "docs-writer",
      "state": "idle",
      "waiting_for": "backend-dev to complete user CRUD"
    }
  ],
  "task_board": {
    "total": 4,
    "completed": 2,
    "in_progress": 1,
    "pending": 1
  }
}

Escenarios de monitoreo real

Escenario 1: Refactor nocturno

Lanzas un refactor grande antes de irte a dormir:

claude --remote -p "Refactoriza el módulo de pagos: \
  extrae la lógica de Stripe a un adapter pattern, \
  agrega tests unitarios para cada adapter, \
  actualiza la documentación" \
  --allowedTools "Read,Write,Edit,Grep,Glob,Bash"

Desde tu teléfono, periódicamente chequeas:

  • ¿Cuántos archivos lleva editados?
  • ¿Ha encontrado errores?
  • ¿Necesita alguna aprobación?

Escenario 2: CI con aprobación

Un pipeline de CI usa Claude Code para generar un changelog y crear un PR. El script necesita aprobación antes de pushear:

result = subprocess.run(
    ["claude", "--remote", "-p",
     "Genera el changelog del sprint y crea un PR",
     "--output-format", "json"],
    capture_output=True, text=True,
    cwd="/path/to/project"
)

Recibes una notificación en tu teléfono: "Claude quiere ejecutar git push origin release/v2.3.0". Apruebas o rechazas.


Seguridad en Remote Control

Autenticación

Cada sesión de remote control genera un token único. Sin el token, no hay acceso:

Token format: rc_tk_[32 caracteres alfanuméricos]
Validez: solo durante la vida de la sesión
Scope: una sesión específica

Principios de seguridad

PrincipioImplementación
Autenticación obligatoriaToken único por sesión, no reutilizable
Scope mínimoEl token solo da acceso a esa sesión, no a otras
Expiración automáticaEl token expira cuando la sesión termina
Conexiones limitadasMáximo N dispositivos conectados simultáneamente
Operaciones auditadasToda acción remota se registra en logs

Configuración de seguridad avanzada

{
  "remote": {
    "enabled": true,
    "require_auth": true,
    "max_connections": 3,
    "allowed_operations": ["monitor", "approve", "reject"],
    "log_remote_actions": true,
    "session_visibility": "authenticated",
    "auto_disconnect_idle_minutes": 30
  }
}

Qué NO hacer con remote control

❌ No compartas el token en canales no seguros (Slack público, email sin cifrar)
❌ No habilites remote control sin require_auth en redes compartidas
❌ No des acceso de escritura si solo necesitas monitoreo
❌ No dejes sesiones con remote control activo sin supervisión por horas
❌ No uses remote control sobre redes WiFi públicas sin VPN

Casos de Uso Avanzados

Uso 1: Batch jobs de fin de semana

Configuras un script que lanza 5 tareas secuenciales el viernes por la noche:

#!/usr/bin/env python3
"""Batch de tareas para el fin de semana."""

import subprocess
import json

tasks = [
    "Actualiza todas las dependencias de pip y resuelve conflictos",
    "Agrega type hints a todos los archivos en src/core/",
    "Genera docstrings para funciones sin documentación en src/api/",
    "Crea tests de integración para los endpoints de /users",
    "Actualiza el README.md con la documentación actual",
]

for i, task in enumerate(tasks, 1):
    print(f"\n[{i}/{len(tasks)}] Ejecutando: {task[:50]}...")

    result = subprocess.run(
        ["claude", "--remote", "-p", task,
         "--output-format", "json",
         "--allowedTools", "Read,Write,Edit,Grep,Glob,Bash"],
        capture_output=True, text=True,
        timeout=1800
    )

    if result.returncode == 0:
        output = json.loads(result.stdout)
        print(f"  Costo: ${output.get('cost_usd', 0):.4f}")
    else:
        print(f"  Error: {result.stderr[:100]}")

El sábado por la mañana, revisas desde tu teléfono: ¿cuántas tareas completó? ¿Alguna falló? ¿Cuánto costó el batch total?

Uso 2: Monitoreo de Agent Team en reunión

Mientras estás en una reunión, tu Agent Team está implementando una feature. Con remote control:

  1. Abres el dashboard en tu teléfono bajo la mesa
  2. Ves que el backend-dev teammate completó su tarea
  3. El test-writer está corriendo pero encontró 2 tests fallidos
  4. El team lead reasignó una subtarea
  5. Hay una aprobación pendiente para un npm publish — la rechazas porque falta code review

Todo sin abrir tu laptop.

Uso 3: Pair programming remoto con agentes

Tu compañero de equipo está corriendo Claude Code y quiere que revises lo que el agente está haciendo. Te comparte el session ID y el token. Tú te conectas desde tu máquina y ves la sesión en tiempo real. Si el agente va por un camino incorrecto, puedes enviar un mensaje redireccionando el trabajo.


Troubleshooting

"Remote control no aparece en claude --help"

Causa: Tu versión de Claude Code no soporta remote control, o la feature está detrás de un feature flag.

Solución:

npm update -g @anthropic-ai/claude-code
claude --version

claude config list | grep remote

Si el feature flag no está habilitado, consulta la documentación oficial para instrucciones de opt-in.

"Connection refused al conectar remotamente"

Causa: El servidor de remote control no está corriendo, el puerto está ocupado, o un firewall bloquea la conexión.

Solución:

# Verificar que la sesión está activa
claude remote list

# Verificar que el puerto está escuchando
lsof -i :3500

# Si el puerto está ocupado, usar otro
claude --remote --remote-port 3501

"Token expired o invalid"

Causa: El token se generó para una sesión que ya terminó, o se copió incorrectamente.

Solución:

# Listar sesiones activas con sus tokens
claude remote list --show-tokens

# Regenerar token para una sesión activa
claude remote refresh-token --session abc123

"Remote control funciona lento"

Causa: El intervalo de polling es muy frecuente, o la conexión de red tiene alta latencia.

Solución:

# Aumentar el intervalo de polling
claude remote watch --session abc123 --interval 15

# Reducir la verbosidad del output
claude remote status --session abc123 --compact

"No puedo ver el estado del Agent Team"

Causa: Agent Teams es una feature experimental que puede no exponer estado via remote control en todas las versiones.

Solución: Verifica que la versión de Claude Code soporta remote team-status. Si no está disponible, usa remote status que muestra un resumen general sin desglose por teammate.


Comparación: Terminal vs Remote Control

AspectoTerminal LocalRemote Control
PresenciaDebes estar frente al computadorCualquier dispositivo con red
LatenciaInstantáneaDepende de la conexión (1-5s típico)
CapacidadesTodasMonitoreo + aprobación + interrupción
SeguridadImplícita (acceso físico)Token + autenticación
Múltiples observadoresNo (un terminal)Sí (múltiples dispositivos)
Ideal paraDesarrollo activo, debuggingSupervisión, operaciones largas
Agent TeamsFull control del team leadVista del estado, aprobación
HooksSe ejecutan localmenteSe monitorean remotamente
SDK scriptsEjecución localEjecución local + monitoreo remoto
CostoSin overheadMínimo overhead de servidor

Regla práctica: Usa terminal local para desarrollo activo (cuando estás iterando rápidamente). Usa remote control para supervisión pasiva (cuando lanzas un trabajo y te vas).


Ejercicios

Ejercicio 1: Setup básico de remote control (Fácil)

Inicia una sesión de Claude Code con remote control habilitado. Desde otro terminal en la misma máquina, conéctate y consulta el estado de la sesión.

Ver solución

Terminal 1 — Iniciar sesión:

claude --remote

Anota el session ID y el token que se muestran.

Terminal 2 — Conectar:

claude remote status --session <SESSION_ID> --token <TOKEN> --output-format json | jq .

Deberías ver el estado actual de la sesión: running, idle, o waiting.

Si --remote no está disponible en tu versión:

claude -p "Di 'remote control test exitoso'" --output-format json > /tmp/session-test.json
cat /tmp/session-test.json | jq .state

Ejercicio 2: Script de monitoreo simple (Fácil)

Escribe un script bash que consulte el estado de una sesión cada 10 segundos y lo imprima en formato legible.

Ver solución

scripts/simple-monitor.sh:

#!/bin/bash

SESSION_ID=$1
TOKEN=$2

if [ -z "$SESSION_ID" ] || [ -z "$TOKEN" ]; then
    echo "Uso: ./simple-monitor.sh <session_id> <token>"
    exit 1
fi

while true; do
    clear
    echo "=== Remote Monitor ==="
    echo "Session: $SESSION_ID"
    echo "Time: $(date +%H:%M:%S)"
    echo "========================"

    STATUS=$(claude remote status \
        --session "$SESSION_ID" \
        --token "$TOKEN" \
        --output-format json 2>/dev/null)

    if [ $? -ne 0 ]; then
        echo "Error conectando. Reintentando..."
        sleep 10
        continue
    fi

    STATE=$(echo "$STATUS" | jq -r '.state')
    COST=$(echo "$STATUS" | jq -r '.cost_usd // 0')
    FILES=$(echo "$STATUS" | jq -r '.files_changed | length')

    echo "Estado: $STATE"
    echo "Costo: \$$COST"
    echo "Archivos: $FILES"

    if [ "$STATE" = "completed" ] || [ "$STATE" = "error" ]; then
        echo "Sesión terminada."
        break
    fi

    sleep 10
done
chmod +x scripts/simple-monitor.sh
./scripts/simple-monitor.sh abc123 rc_tk_xxxxx

Ejercicio 3: Configuración de seguridad (Medio)

Escribe una configuración de settings.json que habilite remote control con las siguientes restricciones:

  • Máximo 2 conexiones simultáneas
  • Solo operaciones de monitoreo y aprobación (no envío de mensajes)
  • Desconexión automática después de 15 minutos de inactividad
  • Logging de todas las acciones remotas
Ver solución

.claude/settings.json:

{
  "remote": {
    "enabled": true,
    "require_auth": true,
    "max_connections": 2,
    "allowed_operations": ["monitor", "approve", "reject"],
    "log_remote_actions": true,
    "session_visibility": "authenticated",
    "auto_disconnect_idle_minutes": 15
  }
}

La clave está en allowed_operations: al no incluir "message" ni "interrupt", los observadores remotos solo pueden ver y aprobar/rechazar, no enviar instrucciones nuevas ni detener la ejecución. Esto es ideal para escenarios donde un senior monitorea el trabajo de un agente sin intervenir directamente.

Ejercicio 4: Monitor de Agent Team con Python (Medio)

Escribe un script Python que monitoree un Agent Team remotamente y genere un reporte cuando todos los teammates hayan terminado.

Ver solución

scripts/team-monitor.py:

#!/usr/bin/env python3
"""Monitorea un Agent Team y genera reporte al terminar."""

import subprocess
import json
import time
import sys
from datetime import datetime


def get_team_status(session_id, token):
    result = subprocess.run(
        ["claude", "remote", "team-status",
         "--session", session_id,
         "--token", token,
         "--output-format", "json"],
        capture_output=True, text=True
    )
    if result.returncode != 0:
        return None
    return json.loads(result.stdout)


def all_done(status):
    if not status or not status.get("teammates"):
        return False
    return all(
        tm["state"] in ("completed", "error")
        for tm in status["teammates"]
    )


def generate_report(history):
    report = []
    report.append(f"# Agent Team Report")
    report.append(f"Generated: {datetime.now().isoformat()}")
    report.append(f"")

    if not history:
        report.append("No data collected.")
        return "\n".join(report)

    final = history[-1]
    report.append(f"## Summary")
    report.append(f"- Total teammates: {len(final.get('teammates', []))}")

    completed = sum(1 for t in final.get("teammates", [])
                    if t["state"] == "completed")
    errors = sum(1 for t in final.get("teammates", [])
                 if t["state"] == "error")

    report.append(f"- Completed: {completed}")
    report.append(f"- Errors: {errors}")
    report.append(f"")

    report.append(f"## Teammates")
    for tm in final.get("teammates", []):
        report.append(f"### {tm['name']}")
        report.append(f"- State: {tm['state']}")
        report.append(f"- Files: {', '.join(tm.get('files_touched', []))}")
        report.append(f"")

    return "\n".join(report)


def main():
    if len(sys.argv) < 3:
        print("Uso: python team-monitor.py <session_id> <token>")
        sys.exit(1)

    session_id, token = sys.argv[1], sys.argv[2]
    history = []

    print("Monitoreando Agent Team...")
    while True:
        status = get_team_status(session_id, token)
        if status:
            history.append(status)
            teammates = status.get("teammates", [])
            for tm in teammates:
                icon = {"working": "🔄", "completed": "✅",
                        "error": "❌", "idle": "⏳"}.get(tm["state"], "?")
                print(f"  {icon} {tm['name']}: {tm['state']}")

            if all_done(status):
                print("\nTodos los teammates terminaron.")
                break

        time.sleep(10)

    report = generate_report(history)
    report_path = f"team-report-{datetime.now():%Y%m%d-%H%M%S}.md"
    with open(report_path, "w") as f:
        f.write(report)
    print(f"Reporte: {report_path}")


if __name__ == "__main__":
    main()

Ejercicio 5: Simulación de remote control local (Difícil)

Sin acceso a remote control real, simula el patrón usando dos procesos: uno que ejecuta Claude Code con SDK headless y escribe su estado a un archivo JSON, y otro que lee ese archivo periódicamente como "monitor remoto."

Ver solución

Proceso 1 — Ejecutor (scripts/executor.sh):

#!/bin/bash

STATE_FILE="/tmp/claude-remote-sim.json"

update_state() {
    cat > "$STATE_FILE" << EOF
{
  "state": "$1",
  "task": "$2",
  "timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
  "files_changed": $3
}
EOF
}

update_state "starting" "Initializing session" "[]"
sleep 2

update_state "running" "Analyzing codebase" "[]"

RESULT=$(claude -p "Lista los archivos Python en el directorio actual" \
    --output-format json \
    --allowedTools "Bash,Glob" 2>/dev/null)

if [ $? -eq 0 ]; then
    update_state "completed" "Task finished" "[\"analysis-result.json\"]"
else
    update_state "error" "Task failed" "[]"
fi

echo "Ejecución terminada. Estado final en $STATE_FILE"

Proceso 2 — Monitor (scripts/local-monitor.sh):

#!/bin/bash

STATE_FILE="/tmp/claude-remote-sim.json"

echo "Esperando sesión..."
while [ ! -f "$STATE_FILE" ]; do
    sleep 1
done

echo "Sesión encontrada. Monitoreando..."
while true; do
    clear
    echo "=== REMOTE MONITOR (simulado) ==="
    echo "$(date +%H:%M:%S)"
    echo "================================="

    if [ -f "$STATE_FILE" ]; then
        STATE=$(cat "$STATE_FILE" | jq -r '.state')
        TASK=$(cat "$STATE_FILE" | jq -r '.task')
        FILES=$(cat "$STATE_FILE" | jq -r '.files_changed | length')
        echo "Estado: $STATE"
        echo "Tarea: $TASK"
        echo "Archivos: $FILES"
    fi

    if [ "$STATE" = "completed" ] || [ "$STATE" = "error" ]; then
        echo ""
        echo "Sesión terminada: $STATE"
        break
    fi

    sleep 3
done

Uso:

chmod +x scripts/executor.sh scripts/local-monitor.sh

# Terminal 1:
./scripts/executor.sh

# Terminal 2 (simultáneo):
./scripts/local-monitor.sh

Este patrón es exactamente lo que remote control hace internamente: un proceso escribe estado, otro lo lee. La diferencia es que remote control lo hace sobre la red en lugar de un archivo local.

Ejercicio 6: Dashboard multi-sesión (Difícil)

Diseña un script Python que monitoree múltiples sesiones de Claude Code simultáneamente y las muestre en un dashboard consolidado con el estado de cada una.

Ver solución

scripts/multi-monitor.py:

#!/usr/bin/env python3
"""Dashboard multi-sesión de Claude Code."""

import subprocess
import json
import time
import sys


def get_status(session_id, token):
    try:
        result = subprocess.run(
            ["claude", "remote", "status",
             "--session", session_id,
             "--token", token,
             "--output-format", "json"],
            capture_output=True, text=True, timeout=10
        )
        if result.returncode == 0:
            return json.loads(result.stdout)
    except (subprocess.TimeoutExpired, json.JSONDecodeError):
        pass
    return {"session_id": session_id, "state": "unreachable"}


def display_dashboard(sessions_status):
    print("\033[2J\033[H")
    print(f"{'='*60}")
    print(f"  CLAUDE CODE MULTI-SESSION DASHBOARD")
    print(f"  {time.strftime('%H:%M:%S')}")
    print(f"{'='*60}\n")

    for status in sessions_status:
        sid = status.get("session_id", "?")[:8]
        state = status.get("state", "unknown")
        cost = status.get("cost_usd", 0)
        files = len(status.get("files_changed", []))
        pending = len(status.get("pending_approvals", []))

        icon = {
            "running": "🔄", "completed": "✅",
            "error": "❌", "unreachable": "⚠️"
        }.get(state, "?")

        print(f"  {icon} {sid}  |  {state:<12} | "
              f"${cost:.4f} | {files} files | "
              f"{pending} approvals")

    print(f"\n{'='*60}")


def main():
    sessions = []
    for i in range(1, len(sys.argv), 2):
        if i + 1 < len(sys.argv):
            sessions.append({
                "id": sys.argv[i],
                "token": sys.argv[i + 1]
            })

    if not sessions:
        print("Uso: python multi-monitor.py <id1> <tok1> [<id2> <tok2> ...]")
        sys.exit(1)

    while True:
        statuses = [get_status(s["id"], s["token"]) for s in sessions]
        display_dashboard(statuses)

        if all(s.get("state") in ("completed", "error", "unreachable")
               for s in statuses):
            print("Todas las sesiones terminaron.")
            break

        time.sleep(10)


if __name__ == "__main__":
    main()

Resumen

  • Remote control permite conectarte a sesiones activas de Claude Code desde otros dispositivos — tu teléfono, otro computador, o un script remoto
  • Se habilita con --remote al iniciar una sesión, que genera un token de autenticación y una URL de conexión
  • Las capacidades remotas incluyen monitorear estado, aprobar/rechazar operaciones, ver Agent Teams, y interrumpir ejecución
  • El monitoreo en tiempo real muestra archivos editados, comandos ejecutados, costo acumulado, y estado de cada teammate
  • La seguridad se basa en tokens por sesión, límite de conexiones, y configuración de operaciones permitidas
  • Tres métodos de acceso: web interface (visual), CLI remoto (terminal), SDK programático (scripts)
  • Remote control es ideal para operaciones largas, batch jobs, y supervisión de Agent Teams sin presencia física
  • El patrón interno es simple: un proceso escribe estado, otro lo lee — remote control hace esto sobre la red
  • Estado experimental (marzo 2026): verifica disponibilidad actual en la documentación oficial antes de implementar

Recursos Adicionales

  1. Claude Code Overview (Anthropic Docs) — Contexto general de Claude Code
  2. Claude Code CLI Reference — Flags de CLI incluyendo --remote
  3. Claude Code Settings — Configuración de remote control en settings.json
  4. Claude Code Hooks — Hooks que se monitorean via remote control
  5. Claude Code Best Practices — Buenas prácticas de seguridad
  6. Claude Code Tips and Tricks — Tips para automatización y monitoreo
  7. Claude Code Agent Teams — Agent Teams que se monitorean remotamente
  8. Anthropic API Security — Principios de seguridad de Anthropic

Siguiente cápsula: En la cápsula 03 diseñarás approval flows remotos — cómo definir qué operaciones necesitan aprobación humana, configurar gates de aprobación con hooks PermissionRequest, aprobar desde tu teléfono con timeouts configurables, y definir políticas para cuando nadie aprueba a tiempo. Pasas de monitorear (cápsula 02) a controlar activamente (cápsula 03).