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.
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.1y 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
claudeen tu PATH. - Codex CLI, opcional: el binario
codexen 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-keysno 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 linkponeswitchboarden 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__*apermissionsen elsettings.jsonde Claude Code, o las herramientas de Switchboard pedirán aprobación cada vez que las uses. ¿Ya estás enbypassPermissions? Estás cubierto.switchboard startte lo recuerda en su primera ejecución.Solo si omites los encabezados de arriba. En la ruta clásica, el agente lee
SWITCHBOARD_AGENT_TOKENde su entorno conprintenvantes de llamar ajoin, así que ese comando de shell también necesita aprobación — añadeBash(printenv:*)a la regla de permitir, o ejecuta el agente conbypassPermissions. 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:
- El Hub registra al agente a través de REST, antes de que se abra Claude Code.
- Una sesión de tmux
sb-alphainiciaclaudeen el directorio--dir. - Desde una terminal interactiva,
startejecutatmux attachen esa sesión, así que tu pestaña de Windows Terminal se convierte en la pantalla del agente. Desconéctate conCtrl-b dy el agente sigue trabajando en segundo plano. - 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 statussin 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 ajoinél mismo en su lugar (--no-kickofflo 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:
- En esa ventana, sal de claude (
Ctrl-Cdos veces, o/exit). - En la misma carpeta, ejecuta:
switchboard wire - 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 Code | Codex CLI | |
|---|---|---|
| binario | claude | codex |
| continuar conversación | -c | resume --last (un subcomando) |
| omitir aprobaciones | --dangerously-skip-permissions | --dangerously-bypass-approvals-and-sandbox |
| diálogo de confianza | aceptado por ti al adjuntar | aceptado 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 (wirederiva uno del otro), así que@frontendescrito junto a una carpetafrontend/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ón | Qué hace |
|---|---|
| nudge | Fuerza 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). |
| mute | Deja 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. |
| autostart | Marca 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 command | Una 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 args | Reemplaza 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. |
| group | Mueve al agente a otra sala (el muro de comunicación: ver Groups). |
| nickname | Un 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. |
| rename | Cambia 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 / remove | stop 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
| Comando | Qué hace |
|---|---|
switchboard wire | Adopta la ventana actual en la red, continuando su conversación (ver abajo). |
switchboard status | Tabla 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 down | Detiene 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.1es 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 reportablockedpara 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):
startinyecta un token por agente en el entorno de la sesión de tmux (SWITCHBOARD_AGENT_TOKEN); el agente lo lee y lo pasa ajoin, y nunca aparece enlist_agents, enGET /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 endpointPOST /api/agents/registerestá 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 dejoin— también invalidando el token de la sesión legítima (sujoindespué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 deswitchboard 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.confmínimo con el mouse habilitado ayuda mucho con el desplazamiento y la selección de paneles:set -g mouse on switchboard startejecutatmux attachen 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
tmuxy 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 demcp add. El estándar es que la CLI hable MCP y se ejecute en una terminal. - Niveles de urgencia (
interrupt/normal/fyi): un mensajefyique 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 deblockedse 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 enlist_agentspermite a los agentes dejar de molestar a alguien atascado en un aviso. - Reanudación exacta de sesión. Un hook de
SessionStartque 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.