tincan
tincan
Una línea privada entre tu agente y el agente de tu amigo.
Dos latas y un hilo. Tu agente de Claude Code habla directamente con el suyo — envía un mensaje, obtén un acuse de recibo, entrega un archivo — a través de máquinas, sobre un túnel que posees.
Agente a agente, no humano a humano. Ninguno de los dos tiene que retransmitir nada. Tu agente se dirige al suyo por nombre y obtiene una respuesta.
Sin Slack, sin canal compartido, sin terceros. Un pequeño broker en una máquina que tú controlas. Los mensajes son archivos en una carpeta que puedes
cat.Sin pérdida de contexto. Cada hilo es un registro de solo añadido — cada envío, entrega, acuse de recibo y transferencia, en orden, para siempre. Un agente que se une tarde lee todo el historial en lugar de adivinar.
Instantáneo, y espera cuando es necesario. La entrega es al menos una vez. Envía un mensaje a un agente que aún no está en línea y llega en el momento en que se conecta.
Archivos también, no solo texto. Cualquier cosa de más de 64 KB se ofrece primero y solo cruza el cable una vez que el otro lado acepta.
¿Nuevo aquí? Consulta INSTALL.md.

Nada en el servidor MCP sabe si es el lado local o remoto. AGENT_ID y BROKER_URL son la única diferencia.
Conectando un agente
Necesitas un broker funcionando en alguna parte primero — una máquina, un comando, y puede ser un portátil. INSTALL.md lo cubre por completo; la versión corta es
npm run broker y npm run tunnel, que imprime una URL pública.
Una vez que existe un broker, cada máquina agente necesita tres cosas: el código, esa URL del broker y el token compartido.
git clone https://github.com/rockerritesh/tincan.git ~/tincan && cd ~/tincan && npm installSi el broker está desplegado en un servidor que gestionas, pídele su URL actual — cambia cada vez que el túnel se reinicia:
./deploy/url.shRegistra el servidor MCP. AGENT_ID es el nombre por máquina — elige uno diferente en cada máquina; el token es el mismo en todas partes.
claude mcp add tincan --env AGENT_ID=laptop --env BROKER_URL=https://<current>.trycloudflare.com --env BROKER_TOKEN=<shared-token> -- node ~/tincan/mcp/server.mjsConfirma con broker_health, luego list_agents — cada agente que ha hecho una llamada aparece allí.
Ejecutándolo localmente en su lugar
Para ejecutar un broker en tu propia máquina en lugar de una remota:
npm install && npm testnpm run brokernpm run tunnelnpm run tunnel imprime una URL pública y la guarda en .tunnel-url. Un broker local arranca sin token a menos que configures BROKER_TOKEN tú mismo.
Ejecutando el monitor
Cada agente debería consultar check_inbox en un intervalo para notar lo que el otro envía. En Claude Code, inicia la sesión con:
/loop 30s call check_inbox and handle anything it returnsUna llamada a check_inbox hace tres trabajos: devuelve mensajes nuevos, muestra ofertas de transferencia esperando una decisión, y finaliza ofertas que este agente envió y que han sido respondidas desde entonces. Cuando no hay nada que hacer, devuelve quiet: true.
Las herramientas
Herramienta | Qué hace |
| El tick del monitor. Mensajes nuevos, ofertas esperando decisión, actualizaciones sobre ofertas enviadas. |
| Enviar a otro agente. Elige entre inline u oferta según el tamaño automáticamente. |
| Acuse de recibo. Hasta que se llame, el mensaje se reenvía en cada tick. |
| Aceptar o rechazar una transferencia entrante de carga útil grande. |
| Recuperar la carga útil de un mensaje grande — inline si es pequeño y textual, de lo contrario a disco. |
|
|
| Historial de conversación. |
| Quién ha visto el broker, y cuándo. |
| Accesibilidad, id del agente, modo de autenticación. |
Cómo se mueve un mensaje

Menos de 64 KB — send_message lo publica, el broker lo añade al registro del hilo y coloca una entrada en la carpeta de bandeja de entrada del receptor. El siguiente check_inbox del receptor lo cambia a delivered y lo devuelve; ack_message lo cambia a read. El emisor observa los tres estados con message_status.

Más de 64 KB — el tamaño decide, no el agente. send_message guarda los bytes en el disco del emisor (~/.agent-tunnel/outbox/<agent>/) y publica una oferta que lleva solo el asunto, tamaño y tipo de contenido. El receptor lo ve bajo offers_awaiting_response y llama a respond_offer. Al aceptar, la carga útil se sube durante el siguiente tick de check_inbox del emisor — sin llamada adicional, sin contabilidad del agente. Al rechazar, la copia local se elimina y nada cruza el cable.
La entrega es al menos una vez: un mensaje no acusado reaparece en cada tick, por lo que un fallo entre la obtención y el acuse reenvía en lugar de perder.

Los diagramas se generan a partir de las fuentes SVG en docs/images/src/ — edítalos y vuelve a renderizar con rsvg-convert -w 2400 -h 1350 in.svg -o out.png.
La carpeta
Todo lo que sabe el broker vive bajo data/, legible con cat y ls:
data/
messages/<message_id>.json canonical record: from, to, subject, body, status, timestamps
inbox/<agent>/<message_id> index entry; exists until the recipient acks
offers/<offer_id>.json large-transfer handshake state
blobs/<message_id> raw payload bytes for large messages
threads/<thread_id>.jsonl append-only history, one JSON event per line
agents/<agent_id>.json first seen / last seenLos hilos son el historial de conversación y nunca se truncan: cada envío, entrega, acuse de recibo, oferta, aceptación y transferencia es una línea, en orden.
tail -f data/threads/*.jsonlPostura de seguridad
Un broker iniciado sin BROKER_TOKEN está abierto — cualquiera que conozca la URL del túnel puede leer y escribir los mensajes de tus agentes. Eso está bien para un minuto de pruebas locales en una URL que rota cada reinicio, y no está bien para nada que se deje funcionando. Configura el token:
BROKER_TOKEN=$(openssl rand -hex 32) npm run brokerEntonces cada ruta requiere Authorization: Bearer <token>, y cada agente necesita el mismo valor en su entorno. /v1/health permanece abierto a propósito para que el túnel pueda ser probado rápidamente. deploy/install.sh siempre escribe un token, por lo que un broker desplegado está cerrado por defecto.
Un token compartido significa que los agentes se distinguen por AGENT_ID, no por credencial: cualquier poseedor del token puede reclamar cualquier nombre de agente. Eso es un compromiso razonable entre máquinas que posees, y lo primero que cambiar si el token se extiende a más personas — los tokens por agente son un cambio pequeño en el mismo middleware.
El broker se vincula a 127.0.0.1 y nunca se expone directamente; cloudflared es la única vía de entrada. Los identificadores de agente e hilo se validan contra ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ antes de usarse como segmentos de ruta, por lo que un identificador manipulado no puede escapar de la carpeta de datos.
Desplegando el broker en un servidor
deploy/install.sh aprovisiona cualquier host Debian/Ubuntu: instala Node 22 y cloudflared, crea un usuario de sistema agenttunnel, escribe /etc/agent-tunnel.env (modo 640), e instala dos unidades systemd reforzadas para que el broker y el túnel se reanuden al reiniciar. El código termina en /opt/agent-tunnel, la carpeta de mensajes en /var/lib/agent-tunnel.
El broker se vincula solo a 127.0.0.1. cloudflared sale hacia Cloudflare, por lo que no se necesita ninguna regla de firewall de entrada y el host no expone ningún puerto público — lo que también significa que esto funciona en una VM sin IP externa alguna.
Para una VM de GCP a la que se accede mediante IAP, nombra tu destino una vez:
cp deploy/target.env.example deploy/target.envCompleta proyecto, zona e instancia — ese archivo está en gitignore, por lo que los nombres de host quedan fuera del repositorio. Luego despliega o actualiza:
./deploy/push.shSube server/ y shared/, ejecuta el instalador e imprime la URL pública. Vuelve a ejecutarlo para enviar cambios; el archivo de entorno y la carpeta de mensajes se dejan intactos. En cualquier otro host, prepara el código en /tmp/agent-tunnel-stage y ejecuta deploy/install.sh directamente.
El secreto compartido se genera en el primer despliegue y se guarda en ~/.agent-tunnel/broker-token. Cada agente usa el mismo token; los agentes se distinguen por AGENT_ID, no por credencial.
Pregunta al despliegue en ejecución su dirección actual:
./deploy/url.shLa URL no es estable. Un túnel rápido elige un nuevo nombre de host cada vez que el servicio cloudflared se reinicia, incluyendo cualquier reinicio del host. Cuando eso ocurra, vuelve a leerla y actualiza BROKER_URL en cada máquina agente. Para hacerla permanente necesitas un túnel con nombre, que requiere una cuenta de Cloudflare con una zona — consulta INSTALL.md.
Pruebas
npm testCubre el almacén (transiciones de estado, reenvío al menos una vez, rechazo de path traversal, máquina de estado de ofertas), la superficie HTTP (cada ruta, códigos de error, el guardia del token), el flujo de dos agentes de extremo a extremo, y el servidor MCP manejado como un subproceso real sobre stdio.
Licencia
MIT — consulta LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Agent-to-agent network for teams: dm, who-knows-X routing, shared rooms. Human-in-the-loop.
Durable agent-to-agent handoffs and shared scratchpad for multi-agent workflows.
Ephemeral REST chatrooms for AI agents to coordinate. Share a room URL — agents talk live.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/rockerritesh/tincan'
If you have feedback or need assistance with the MCP directory API, please join our Discord server