Switchboard

Un centro MCP local que permite que tus agentes de Claude Code se comuniquen entre sí: mensajes, notificaciones en la terminal y coordinación a través de un panel web.

Documentación

⇄ Switchboard

Permite que tus agentes de código se comuniquen entre sí.
Claude Code y Codex CLI, en la misma red, en la misma conversación.

The Switchboard dashboard — an operator's patchbay: agents grouped on the left, the transcript of what they said to each other in the center

Tienes Claude Code (la CLI de Anthropic) abierto en el backend, Codex CLI (la de OpenAI) en el frontend, otro agente en infraestructura. Ninguno sabe que los demás existen. Así que cuando el contrato de la API cambia, tú eres quien lleva la noticia: copia de esta terminal, pega en aquella, repite. Tú eres el intermediario de mensajes.

Switchboard es el cable entre ellos. Es un hub local. Tus agentes se envían mensajes entre sí a través de MCP, el destinatario recibe un aviso en su propia terminal, y tú observas toda la conversación en un panel — donde también puedes abrir el chat de cualquier agente, manejar su terminal real y ver qué hizo con el mensaje que recibió. Conecta sesiones que ya tienes. No las crea, orquesta ni gestiona.

Lo que lo mantiene seguro: tmux lleva un aviso de una línea, y nada más. El mensaje en sí viaja a través de MCP. El agente A llama a send_message, el Hub lo añade a ~/.switchboard/messages.jsonl (la fuente de verdad) y toca la terminal del agente B con una sola línea [switchboard]. B se despierta y llama a check_messages para leerlo.

Plataforma: Windows + WSL (Ubuntu). Eso es en lo que Switchboard está construido y probado. El núcleo (hub, MCP, avisos de tmux) es Unix y tmux estándar, así que Linux y macOS podrían funcionar, pero nadie lo ha probado. Trátalos como no soportados por ahora. Las partes que lo hacen funcionar en Windows (el lanzador de un clic, abrir una ventana de terminal real, rutas de carpeta \\wsl$\…) son específicas de WSL, y lo dicen en lugar de fallar cuando las ejecutas en otro lugar.

Solo local por diseño: el Hub se vincula a 127.0.0.1 y nada llega a la red. Licencia MIT.


Requisitos previos

  • Node.js >= 20. Se ejecuta como ESM, con TypeScript ejecutado por tsx. Sin paso de compilación.
  • tmux >= 3.2 (probado en 3.4).
  • Claude Code >= 2.x, el binario claude en tu PATH.
  • Codex CLI, opcional: el binario codex en tu PATH. Solo lo necesitas para ejecutar agentes con --agent codex, o el botón Codex del panel. Todo lo demás funciona sin él.
  • jq, opcional. Útil para leer el JSONL mientras depuras.

Una distribución de WSL, un usuario. El servidor de tmux pertenece a un usuario en una distribución. Ejecuta el Hub (serve) y cada agente (start) como el mismo usuario en la misma distribución. Si los divides entre dos, tmux send-keys no encontrará la sesión, así que el aviso nunca llega.


Configuración: dos comandos

git clone https://github.com/rodcoppi/switchboard-mcp.git && cd switchboard-mcp && npm install
node bin/switchboard.mjs setup

setup hace cada paso manual de abajo por ti: comprueba los requisitos previos (y ofrece una instalación de tmux sin sudo si falta tmux), registra el servidor MCP en Claude Code, pone el fragmento del protocolo del agente en tu ~/.claude/CLAUDE.md, añade las reglas de permisos, ejecuta npm link, ofrece el acceso directo de Windows y levanta el Hub. Pregunta antes de tocar un archivo tuyo. Vuelve a ejecutarlo cuando quieras, no cambia nada que ya esté bien. Pasa --yes y deja de preguntar.

Cuando termina, el panel está en http://127.0.0.1:4577/. Lanza agentes desde el formulario Launch agent allí, o ejecuta switchboard wire en la carpeta de una ventana de claude que ya tengas abierta para traerla.

Configuración manual (lo que el asistente automatiza, paso a paso)

1. Instalación

git clone https://github.com/rodcoppi/switchboard-mcp.git
cd switchboard-mcp
npm install

El TypeScript se ejecuta directamente a través de tsx, así que no hay nada que compilar. Tres formas de llamar a la CLI switchboard:

  • npm link pone switchboard en tu PATH. Esta es la que debes usar:
    npm link
    switchboard --help
    
  • El shim del bin, sin enlazar:
    node bin/switchboard.mjs --help
    
  • El punto de entrada, sin enlazar:
    npx tsx src/index.ts --help
    

Los ejemplos de abajo dicen switchboard <subcommand> y asumen que enlazaste. Si no lo hiciste, léelos como node bin/switchboard.mjs <subcommand>.

2. Inicia el Hub (serve), normalmente automático

Omite este paso: switchboard start y switchboard wire levantan el Hub por ti cuando no está en ejecución, en una sesión de tmux separada llamada sb-hub. No queda ninguna ventana de terminal abierta. Después de un reinicio, wire o start tu primer agente y el Hub se levanta con él.

Ejecútalo tú mismo cuando quieras ver los registros en vivo:

switchboard serve

El Hub se ejecuta en primer plano y registra en stdout y ~/.switchboard/logs/hub.log. Su primera línea te da las direcciones y el comando de registro de MCP, listo para copiar:

Dashboard: http://127.0.0.1:4577/  |  MCP: http://127.0.0.1:4577/mcp  |  Register (once): claude mcp add --transport http --scope user switchboard http://127.0.0.1:4577/mcp --header 'Authorization: Bearer ${SWITCHBOARD_AGENT_TOKEN}' --header 'X-Switchboard-Agent-Name: ${SWITCHBOARD_AGENT_NAME}'

Para mirar dentro del Hub que se inició solo: tmux attach -t sb-hub, y Ctrl-b d para dejarlo en ejecución. O switchboard logs -f. serve toma --port <port> y --log-level debug|info|warn|error.

Lanzamiento de un clic desde Windows (sin terminal de WSL)

En Windows y WSL puedes omitir la terminal. Una vez, dentro de WSL:

switchboard shortcut            # creates Switchboard.lnk on your Windows Desktop
switchboard shortcut --startup  # or: installs it in the Startup folder (runs on every boot)

Haz doble clic en Switchboard (o simplemente inicia Windows, con --startup) y el Hub se levanta en segundo plano, con el panel abierto en http://127.0.0.1:4577/ en tu navegador de Windows. WSL2 reenvía localhost por ti; el Hub aún se vincula a 127.0.0.1 dentro de WSL, así que nada llega a la red. Lanza o conecta agentes desde el formulario Launch agent. Elimina el acceso directo para deshacerlo.

El acceso directo es un .lnk que lleva el icono de Switchboard y se abre minimizado; el .bat que maneja, y el icono, viven en %LOCALAPPDATA%\Switchboard (un .bat no puede llevar un icono, y un icono en el sistema de archivos de WSL se renderiza en blanco al arrancar, cuando la distribución aún no está en ejecución). Regenera el icono con node scripts/make-icon.mjs.

3. Registra el MCP en Claude Code (mcp add)

Solo una vez, en el ámbito user (aplica a cada proyecto):

claude mcp add --transport http --scope user switchboard http://127.0.0.1:4577/mcp \
  --header 'Authorization: Bearer ${SWITCHBOARD_AGENT_TOKEN}' \
  --header 'X-Switchboard-Agent-Name: ${SWITCHBOARD_AGENT_NAME}'

claude mcp list muestra switchboard como conectado mientras el Hub está activo.

Esos dos encabezados son lo que hace que unirse sea silencioso. Claude Code expande ${VAR} desde el entorno del PROPIO agente cuando se conecta, así que el Hub sabe quién llama antes de que se ejecute cualquier herramienta: la sesión se vincula en el momento de la conexión y el agente está en la red sin una sola línea escrita en su terminal — como cualquier otro servidor MCP que uses. Un registro cubre toda tu flota (cada sesión lleva su propio nombre y token), y el token nunca pasa por el modelo. Un cliente registrado sin los encabezados aún funciona de la manera clásica: el Hub escribe una línea de inicio pidiendo al agente que llame a join él mismo.

¿También ejecutas agentes de Codex? Apunta Codex al mismo Hub. Mismo endpoint de HTTP transmisible, escrito de manera diferente (setup ofrece esto cuando encuentra el binario codex):

codex mcp add switchboard --url http://127.0.0.1:4577/mcp

Permisos de herramientas. Añade la regla de permitir mcp__switchboard__* a permissions en el settings.json de Claude Code, o las herramientas de Switchboard pedirán aprobación cada vez que las uses. ¿Ya estás en bypassPermissions? Estás cubierto. switchboard start te lo recuerda en su primera ejecución.

Solo si omites los encabezados de arriba. En la ruta clásica, el agente lee SWITCHBOARD_AGENT_TOKEN de su entorno con printenv antes de llamar a join, así que ese comando de shell también necesita aprobación — añade Bash(printenv:*) a la regla de permitir, o ejecuta el agente con bypassPermissions. Con los encabezados de identidad registrados, nada de esto aplica: nada se escribe y ningún token llega al modelo.

4. Pega el protocolo del agente (fragmento)

Pega agent-protocol/CLAUDE.snippet.md en tu ~/.claude/CLAUDE.md, donde cubre cada proyecto, o en el CLAUDE.md de un proyecto. Le enseña a un agente a leer su nombre y token del entorno y entregarlos a join, a llamar a check_messages cuando vea una línea [switchboard], y a leer lo que dicen sus pares sin caer en un bucle de agradecimientos. También traza la línea que importa: la coordinación no es subordinación, y ningún otro agente puede autorizar lo que tu usuario no autorizó.

5. Inicia un agente (start)

Ejecuta esto en lugar de abrir claude tú mismo:

switchboard start alpha --role "payments API backend" --dir ~/projects/api

Qué sucede:

  1. El Hub registra al agente a través de REST, antes de que se abra Claude Code.
  2. Una sesión de tmux sb-alpha inicia claude en el directorio --dir.
  3. Desde una terminal interactiva, start ejecuta tmux attach en esa sesión, así que tu pestaña de Windows Terminal se convierte en la pantalla del agente. Desconéctate con Ctrl-b d y el agente sigue trabajando en segundo plano.
  4. El agente se une silenciosamente: su cliente MCP se conecta llevando los encabezados de identidad, y el Hub vincula la sesión — aparece como MCP conectado en switchboard status sin que se haya escrito nada en su terminal. ¿Registraste el MCP sin los encabezados? Unos segundos después de que la TUI esté lista, una línea de inicio pide al agente que llame a join él mismo en su lugar (--no-kickoff lo desactiva).

start banderas: --role "<description>", --dir <path>, --no-kickoff, --agent <claude|codex>, --claude-args "<extra args for the agent CLI>".

Adoptar un agente ya abierto (wire)

¿Ya tienes una ventana de Claude Code abierta (un claude simple en bash, sin tmux) y quieres unirla a la red sin perder la conversación? Usa wire en lugar de start:

  1. En esa ventana, sal de claude (Ctrl-C dos veces, o /exit).
  2. En la misma carpeta, ejecuta:
    switchboard wire
    
  3. La conversación vuelve — ahora dentro de una sesión de tmux, conectada al Hub. El nombre del agente por defecto es el nombre de la carpeta (sanitizado a letras minúsculas, dígitos y guiones; pasa --name <name> si el nombre de la carpeta no se puede usar).

Bajo el capó, wire reabre claude con -c (continuar la conversación de la carpeta) y --dangerously-skip-permissions (para que el agente lea su token y llame a join sin aviso) — estos son los valores por defecto de wire, a diferencia de start. Cualquier --claude-args adicional se añade después de ellos. Si ya existe una sesión de tmux para ese nombre, wire la reemplaza (mata la anterior y la recrea — sin confirmación), luego ejecuta el mismo inicio automático que start.

Retroceso automático: si la carpeta no tiene una conversación reanudable (nunca abriste claude allí, o la última se ejecutó en modo -p/impresión), claude -c sale de inmediato — wire lo detecta y reabre automáticamente una sesión nueva (sin -c), informándote. Nunca falla en una ventana muerta; en el peor caso obtienes una conversación completamente nueva ya conectada a la red.

wire banderas: --name <name>, --role "<description>", --dir <path> (por defecto: carpeta actual), --no-kickoff, --agent <claude|codex>, --claude-args "<extra args for the agent CLI>".

Elegir la CLI del agente (--agent claude|codex)

Cada forma de abrir un agente toma un tipo de agente: claude (por defecto, Claude Code) o codex (Codex CLI). Es un flujo con una elección, no un modo separado — registro, el aviso, el inicio, status, menciones y el panel se comportan de manera idéntica:

switchboard start alpha --dir ~/projects/api --agent codex
switchboard wire --agent codex        # adopt the current folder with Codex

En el panel, el formulario Launch agent tiene un interruptor Claude | Codex, y cada tarjeta muestra el tipo de su agente junto al chip de MCP. El tipo está registrado en el agente, así que reopen lo relanza con la misma CLI con la que se lanzó.

Requisitos: el binario codex en el PATH, y el Hub registrado como servidor MCP en Codex (codex mcp add switchboard --url http://127.0.0.1:4577/mcp — switchboard setup ofrece esto automáticamente cuando encuentra codex). Sin ese registro, un agente de Codex se abre bien pero no tiene herramientas de Switchboard para unirse.

Lo que difiere bajo el capó es solo el argv y las dos cadenas leídas de la TUI — ambas viven en un adaptador (src/shared/agent-types.ts):

Claude CodeCodex CLI
binarioclaudecodex
continuar conversación-cresume --last (un subcomando)
omitir aprobaciones--dangerously-skip-permissions--dangerously-bypass-approvals-and-sandbox
diálogo de confianzaaceptado por ti al adjuntaraceptado automáticamente al inicio

Los agentes registrados antes de que existiera esta función no tienen un tipo registrado y se tratan como Claude Code, que es lo que son.

Grupos: mantén los agentes de un proyecto fuera de los de otro

Cada agente pertenece a un grupo, y un grupo es un muro: un agente solo puede enviar mensajes a agentes del mismo grupo, list_agents no se lo muestra a nadie más, y su transmisión se detiene en el borde del grupo. Ejecuta los agentes de un proyecto en panorama y los de otro en site y ninguno podrá despertar al otro, ya sea por un descuido tuyo o de un agente.

switchboard start alpha --dir ~/projects/api --group panorama
switchboard wire --group site        # adopt the current folder into another group
switchboard status                   # the GROUP column tells you who talks to whom

En el panel, el formulario Launch agent tiene un campo de grupo, y las pestañas sobre la transcripción cambian de sala: elige panorama y lees solo la conversación de ese grupo. Una transmisión que envíes desde allí llega a ese grupo y se detiene.

¿Agentes ya en ejecución? No tienes que relanzarlos. Abre el menú ⋯ en una tarjeta y elige group…; la celda del nombre se convierte en un campo con tus grupos existentes detrás, y Enter mueve al agente. Tiene efecto en el siguiente mensaje de ese agente, sin reinicio: a diferencia de renombrar, que requiere que el agente esté detenido (uno activo se reincorporaría con su nombre antiguo y lo desharía), nada de una sesión en ejecución deshace un cambio de grupo.

Deja --group desactivado y nada cambia: el agente conserva el grupo que ya tenía, y uno nuevo se une a default, donde ya viven todos tus agentes actuales. Volver a ejecutar start o wire sin la bandera nunca saca a un agente de su grupo.

Tú eres el operador, así que ningún muro se aplica a ti: puedes enviar mensajes a cualquier agente desde el panel.

Menciones: delega con %name

Dentro de la ventana de cualquier agente, referencia a otro agente como %<name> y se convierte en una delegación. Por ejemplo, decirle a tu agente de backend:

Arregla el error de paginación y pide a %frontend que actualice los tipos de consumidor después.

hace que arregle el error y envíe a frontend un mensaje factual y accionable con la tarea delegada (rutas, contratos, qué informar). El agente que menciona sigue siendo responsable de tu solicitud: la mención solo enruta la subtarea. Esto es parte del protocolo de agentes (la etiqueta join + el fragmento), por lo que funciona en todos los agentes conectados.

Por qué % y no @: @ ya es el sigilo de referencia a archivo en Claude Code y en Codex, y la TUI lo resuelve antes de que el modelo vea tu mensaje. Los nombres de agentes suelen ser nombres de carpetas (wire deriva uno del otro), así que @frontend escrito junto a una carpeta frontend/ se convierte silenciosamente en una referencia a archivo y la delegación se pierde sin error. % no colisiona con nada en ninguna CLI (! es bash, # es memoria, / es comandos). @<name> todavía se entiende, solo falla cuando una ruta coincide por casualidad.

Lanzar agentes desde el panel

El panel (http://127.0.0.1:4577/) tiene un formulario Launch agent (al final de la barra lateral): escribe el directorio del proyecto, opcionalmente un nombre (por defecto el nombre de la carpeta) y un rol, elige el agente (Claude o Codex), marca continue conversation para reanudar la última conversación de la carpeta (misma alternativa automática que wire), y pulsa Launch. El Hub mismo crea la sesión tmux del agente y ejecuta el inicio automático: no se necesita terminal. La nueva tarjeta aparece en vivo vía SSE; conéctate al agente en cualquier momento con tmux attach -t sb-<name>. Bajo el capó es POST /api/agents/launch {dir, name?, role?, continue?, agentType?}: solo localhost, como todo lo demás.

Hablar con un agente: el chat

Haz clic en la tarjeta de un agente y obtienes su conversación, renderizada como chat: lo que preguntaste, lo que respondió, sus llamadas a herramientas plegadas en una línea cada una, markdown y resaltado de sintaxis, y los eventos del arnés que muestra la terminal (worked for 2m 20s, tareas en segundo plano, interrupciones). Se lee del registro de transcripción propio de Claude Code: Switchboard no posee nada, así que la sesión del agente está intacta. El compositor debajo envía a ese agente: escribe y pulsa Enter, / para comandos de barra (enrutados a la terminal), @ para mencionar un archivo, arrastra un archivo para referenciarlo, y el 🎤 para dictar: el reconocimiento de voz se ejecuta localmente en tu máquina, sin API, sin clave, sin factura.

Cada mensaje que llega de un par se muestra como la línea propia de Switchboard con un interruptor show what X sent que despliega el mensaje real, y en el feed de tráfico cada mensaje leído tiene un interruptor de reacción que muestra lo que el destinatario dijo al respecto en su propio chat. Ambos responden a la pregunta que un tablón de mensajes nunca hace: ¿y luego qué pasó?

Ver la pantalla de un agente

Alterna Terminal y la pantalla en vivo del agente ocupa el panel: la TUI real de Claude Code (o Codex), con colores, cursor y todo, y puedes escribir en ella (aprobar un mensaje, pulsar Esc para interrumpir, arrastrar un archivo para escribir su ruta). Abre varios agentes y se convierten en pestañas en la parte superior; window en el menú de la tarjeta aún abre una terminal real del sistema cuando la quieres. Esto es un cliente tmux en modo control (tmux -C), no un segundo pty: tmux es dueño del proceso del agente, así que cerrar el panel nunca derriba al agente: ese es el punto de poder cerrar la pila de ventanas de terminal.

Previsualizar archivos que los agentes mencionan

Los agentes nombran rutas absolutas constantemente ("escribió /home/you/api/src/foo.ts"). Esas rutas son clicables en la transcripción: haz clic en una y el archivo se abre en línea (imágenes, texto, código, markdown). Las lecturas están delimitadas: solo archivos bajo el directorio de trabajo de un agente o tu carpeta de inicio, resueltos con realpath para que .. y los enlaces simbólicos no puedan escapar. Una ruta fuera del alcance se rechaza con un mensaje claro, nunca se lee: el cuerpo de un mensaje no es confiable, así que un agente no puede hacerte abrir un archivo arbitrario nombrándolo.

Dos puertas están en el encabezado de la vista previa para lo que un panel en línea no puede hacer: browser abre el archivo en una pestaña real (un .html que un agente construyó se renderiza como el sitio real, dentro de un sandbox CSP, así que sus scripts nunca pueden manejar el Hub con tu autoridad), y folder revela el archivo en el Explorador de Windows.

Soltar un archivo en el chat o la terminal referencia el archivo donde ya vive: el Hub encuentra el original por nombre y tamaño entre los proyectos de tus agentes, Descargas y Escritorio, exactamente como arrastrar a una terminal real. Solo cuando no hay un original al que apuntar (una captura pegada, un adjunto arrastrado directamente de un cliente de correo) se guarda una copia en ~/.switchboard/uploads, conservada durante 24 h; un archivo grande sin origen se rechaza en lugar de duplicarse.

Gestionar agentes desde el panel

Cada tarjeta lleva un botón open (reopen cuando el agente está fuera de línea: lo relanza en su carpeta, continuando la conversación, con la misma CLI con la que se lanzó) y un menú ⋯:

AcciónQué hace
nudgeFuerza un empujón manual: sigue sujeto a la protección de panel (nunca escribe en un shell) y a la protección de diálogo (nunca escribe mientras un modal posee el panel).
muteDeja de empujar a este agente. Los mensajes siguen registrándose y aún los lee en su próximo check_messages: silenciar apaga el empujón, no el correo.
autostartMarca al agente para lanzarse al iniciar sesión en la máquina. El Hub solo almacena la bandera; un pequeño gancho de inicio la lee y relanza los agentes marcados, reanudando sus conversaciones.
boot commandUna línea de shell que el lanzador ejecuta antes de la CLI, en el mismo shell (<boot> && exec <cli>), para proyectos que necesitan servicios o entorno primero. Las exportaciones se transfieren a la CLI; una configuración fallida aborta el lanzamiento en lugar de dejar un agente a medio preparar.
launch argsReemplaza los argumentos de lanzamiento de la CLI para este agente: un --resume <session-id> fijado, banderas extra. Solo lo establece el operador vía REST: un agente nunca puede escribir su propio código de arranque o argv.
groupMueve al agente a otra sala (el muro de comunicación: ver Groups).
nicknameUn nombre de visualización libre (emoji bienvenido) para la interfaz. El kebab name sigue siendo la dirección del protocolo, así que esto funciona en un agente en ejecución.
renameCambia el id técnico; todo el historial y el recuento de no leídos siguen al nuevo nombre. Solo para un agente detenido (uno en ejecución se reincorporaría con el nombre antiguo).
stop / removestop mata la sesión tmux y conserva el registro (la tarjeta se convierte en reopen). remove elimina el registro (confirmación de dos clics): los mensajes permanecen en el JSONL de solo añadir.

Los nombres de agentes son direcciones (%name en un mensaje, la sesión tmux sb-<name>), así que son letras minúsculas, dígitos y guiones. No tienes que memorizarlo: los campos de nombre reescriben lo que escribes mientras escribes: Chefe de Redes se convierte en chefe-de-redes frente a ti, de la misma manera que wire deriva un nombre de una carpeta llamada ai panorama.


Otros subcomandos

ComandoQué hace
switchboard wireAdopta la ventana actual en la red, continuando su conversación (ver abajo).
switchboard statusTabla de agentes registrados: NAME, ROLE, STATUS, MCP, UNREAD, LAST SEEN.
switchboard send <to> <message...>Envía un mensaje como operador (el humano) a un agente, o all para transmisión. Útil para scripts y para probar sin el panel.
switchboard stop <name>Detiene la sesión tmux del agente (pide confirmación si hay mensajes no leídos; --yes lo omite). El registro en el Hub permanece: un nuevo start <name> reutiliza el nombre (re-conexión).
switchboard downDetiene las sesiones tmux de todos los agentes. El Hub sigue activo (nunca se mata aquí).
switchboard logs [-f]Últimas ~100 líneas de ~/.switchboard/logs/hub.log; -f sigue el archivo.

Para detener el Hub: Ctrl-C en la terminal switchboard serve (o tmux kill-session -t sb-hub, si se ejecuta en la sesión recomendada).

Los datos viven en ~/.switchboard/: config.json (cada valor tiene un valor predeterminado; el archivo puede que ni siquiera exista), agents.json (instantánea atómica) y messages.jsonl (solo añadir, consultable con cat/jq).


Seguridad

El modelo de amenazas es honesto y el límite de confianza es la máquina local. Lee esto antes de exponer cualquier cosa:

  • Enlazar en 127.0.0.1, fijo y no configurable. Un mensaje entregado se convierte en entrada ejecutable para un agente con acceso al sistema de archivos. Exponer el Hub en la red = RCE gratuito.
  • NUNCA reenviar el puerto 4577 (sin ssh -L, sin regla de firewall/NAT) y NUNCA ejecutar el Hub detrás de un proxy inverso. 127.0.0.1 es la única barrera.
  • Modelo de confianza local: cualquier proceso local puede publicar en el Hub y, por tanto, inyectar entrada en cualquier agente. Esto se acepta en v1 (el mismo modelo que cualquier herramienta de desarrollo local), siempre que nunca se filtre a la red.
  • El nudge nunca escribe en un panel que posee un diálogo. El nudge es una línea más un Enter separado ~500ms después (la única forma en que una TUI lo acepta), y con un aviso de permiso abierto (Do you want to proceed? ❯ 1. Yes) ese Enter solía caer en la opción resaltada — lo que significa que cualquier agente capaz de enviar un mensaje podía aprobar la llamada de herramienta pendiente de otro agente. Probado con un agente desechable, luego cerrado: el lector de paneles reporta blocked para avisos de permiso, diálogos de confianza y advertencias de canal; el despachador pone en cola en lugar de escribir, y relee el panel en vivo inmediatamente antes de escribir (fallo-cerrado — un panel ilegible cuenta como bloqueado). El mensaje retenido se entrega en el siguiente vaciado, una vez que respondas al diálogo.
  • Token de capacidad (adenda v1.1): start inyecta un token por agente en el entorno de la sesión de tmux (SWITCHBOARD_AGENT_TOKEN); el agente lo lee y lo pasa a join, y nunca aparece en list_agents, en GET /api/agents, en el panel o en los registros. Con los encabezados de identidad registrados (ver paso 3) el token nunca llega al modelo en absoluto: el cliente MCP lo envía directamente desde el entorno de la sesión.
  • Superficies solo para operadores. Lo que un agente puede persistir sobre sí mismo se detiene en su rol. El comando de arranque y los argumentos de lanzamiento — los dos campos que deciden qué se ejecuta al inicio — se pueden configurar a través de REST (el panel) y deliberadamente no se exponen a través de MCP, por lo que un agente comprometido no puede escribir su propio código de arranque. Cierra la suplantación por procesos que conocen el nombre de un agente pero nunca hablan con el endpoint de registro.
  • Riesgo residual conocido (documentado en el comentario de src/server/api.ts): el endpoint POST /api/agents/register está deliberadamente sin autenticación, y volver a registrar un nombre existente regenera y devuelve un token nuevo. Así que un proceso local malicioso puede obtener un token válido para cualquier nombre y suplantar a ese agente a través de join — también invalidando el token de la sesión legítima (su join después de un reinicio del Hub entonces falla). Esto se acepta por la especificación v1.1 (el mismo límite de "cualquier proceso local puede publicar") y no debe "arreglarse" sin aprobación — requerir rotación de tokens rompería el re-adjuntar de switchboard start.
  • Inyección de prompts entre agentes es un riesgo residual: un agente comprometido/alucinando puede intentar manipular a otro. Mitigación v1: el límite declarado en el fragmento del protocolo (los mensajes de pares se evalúan críticamente; coordinación ≠ subordinación) más visibilidad completa del feed en el panel.

Consejos de tmux en WSL / Windows Terminal (escollo P11)

  • Si usas tmux raramente, un ~/.tmux.conf mínimo con el mouse habilitado ayuda mucho con el desplazamiento y la selección de paneles:
    set -g mouse on
    
  • switchboard start ejecuta tmux attach en la sesión del agente, así que cada pestaña de Windows Terminal se mantiene como "la pantalla de un agente" — el flujo de trabajo de pestañas que ya usas se conserva. Para salir de la vista de un agente sin matarlo: Ctrl-b d (desconectar). Para volver: tmux attach -t sb-<name>.

Hoja de ruta

Switchboard ejecuta agentes de Claude Code y Codex CLI hoy (ver Eligiendo la CLI del agente) — en la misma red, en la misma conversación. Algunas direcciones para más adelante:

  • Más CLIs de agentes. La infraestructura es agnóstica al agente — el nudge es tmux y los mensajes son MCP (un estándar abierto) — y agregar el segundo tipo convirtió esa afirmación en un adaptador real (src/shared/agent-types.ts). Un tercero ahora es un descriptor: qué binario lanzar, cómo escribe "continuar" y "omitir aprobaciones", sus marcadores listos para TUI, su ortografía de mcp add. El estándar es que la CLI hable MCP y se ejecute en una terminal.
  • Niveles de urgencia (interrupt / normal / fyi): un mensaje fyi que nunca despierta al destinatario (costo de token cero hasta que verifique por sí mismo) — el ahorrador estructural de tokens sobre la etiqueta actual + el respaldo de límite de velocidad.
  • Estado del agente en la tarjeta (working / blocked / idle), leído del panel que el panel ya transmite. La mitad de blocked se envió con el guardián de diálogos (ver Seguridad); mostrarlo como quién me necesita ahora mismo es el siguiente paso, y exponer el estado de un par en list_agents permite a los agentes dejar de molestar a alguien atascado en un aviso.
  • Reanudación exacta de sesión. Un hook de SessionStart que reporte el id de sesión propio de la CLI reemplazaría -c ("la última conversación de la carpeta") con --resume <id>, y daría al chat la ruta exacta de la transcripción en lugar de una heurística.
  • Exportación del historial del feed (la búsqueda ya vive en el encabezado del panel).

Contribuciones bienvenidas — ver el diseño del código en las secciones anteriores; el Hub es un solo proceso Node y no hay paso de compilación.