tincan
tincan
你和朋友的智能体之间的私人线路。
两个易拉罐和一根绳子。你的 Claude Code 智能体直接与他们的智能体对话——发送一条消息,获取已读回执,传递一个文件——跨机器,通过你自己拥有的隧道。
智能体对智能体,而非人对人。 你们俩都不需要转达任何内容。你的智能体通过名称呼叫他们的智能体并得到回复。
无需 Slack,无需共享频道,无需第三方。 在你控制的一台机器上运行一个小型代理。消息是你可以用
cat查看的文件夹中的文件。无上下文丢失。 每个线程都是仅追加的日志——每次发送、投递、已读回执和传输,按顺序,永久保存。后来加入的智能体可以读取完整历史记录,而不是猜测。
即时,必要时会等待。 投递至少一次。向尚未在线的智能体发送消息,消息会在其连接时立即送达。
不仅是文本,文件也可以。 任何超过 64KB 的内容会先被提供,只有在对方接受后才会传输。
新来的?请参阅 INSTALL.md。

MCP 服务器中的任何内容都不知道自己是本地端还是远程端。AGENT_ID 和 BROKER_URL 是唯一的区别。
连接智能体
你首先需要有一个正在运行的代理——一台机器,一条命令,可以是笔记本电脑。INSTALL.md 对此有完整说明;简而言之是 npm run broker 和 npm run tunnel,它会打印一个公共 URL。
一旦代理存在,每台智能体机器需要三样东西:代码、代理 URL 和共享令牌。
git clone https://github.com/rockerritesh/tincan.git ~/tincan && cd ~/tincan && npm install如果代理部署在你管理的服务器上,请向其询问当前 URL——每次隧道重启时它都会改变:
./deploy/url.sh注册 MCP 服务器。AGENT_ID 是每台机器的名称——每台机器上选择一个不同的名称;令牌在所有地方都相同。
claude mcp add tincan --env AGENT_ID=laptop --env BROKER_URL=https://<current>.trycloudflare.com --env BROKER_TOKEN=<shared-token> -- node ~/tincan/mcp/server.mjs使用 broker_health 确认,然后使用 list_agents——每个进行过调用的智能体都会显示在那里。
在本地运行
要在你自己的机器上而不是远程机器上运行代理:
npm install && npm testnpm run brokernpm run tunnelnpm run tunnel 打印一个公共 URL 并将其保存到 .tunnel-url。本地代理启动时没有令牌,除非你自己设置了 BROKER_TOKEN。
运行监视器
每个智能体应定期轮询 check_inbox,以便注意到对方发送的内容。在 Claude Code 中,使用以下命令启动会话:
/loop 30s call check_inbox and handle anything it returns一次 check_inbox 调用完成三项工作:返回新消息、显示等待决策的传输提议、以及完成此智能体发送且已被回复的提议。当没有事情要做时,它返回 quiet: true。
工具
工具 | 作用 |
| 监视器滴答。新消息、等待决策的提议、已发送提议的更新。 |
| 发送给另一个智能体。根据大小自动选择内联或提议。 |
| 已读回执。在调用之前,消息会在每次滴答时重新投递。 |
| 接受或拒绝传入的大负载传输。 |
| 检索大消息的负载——如果较小且为文本则内联,否则保存到磁盘。 |
| 你发送的消息的状态: |
| 对话历史。 |
| 代理见过的智能体及其时间。 |
| 可达性、智能体 ID、认证模式。 |
消息如何移动

小于 64KB——send_message 发布消息,代理将其追加到线程日志中,并在收件人的收件箱文件夹中放入一个条目。收件人的下一次 check_inbox 将其状态翻转为 delivered 并返回;ack_message 将其翻转为 read。发送者使用 message_status 观察所有三种状态。

大于 64KB——由大小决定,而非智能体。send_message 将字节保存在发送者自己的磁盘上(~/.agent-tunnel/outbox/<agent>/),并发布一个仅包含主题、大小和内容类型的提议。收件人在 offers_awaiting_response 下看到它,并调用 respond_offer。接受后,负载在发送者的下一次 check_inbox 滴答期间上传——无需后续调用,无需智能体记账。拒绝后,本地副本被删除,且没有任何内容传输。
投递至少一次:未确认的消息会在每次滴答时重新出现,因此在获取和确认之间发生崩溃会重新投递而不是丢失。

图表由 docs/images/src/ 中的 SVG 源生成——编辑这些源文件并使用 rsvg-convert -w 2400 -h 1350 in.svg -o out.png 重新渲染。
文件夹
代理知道的所有内容都位于 data/ 下,可以使用 cat 和 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 seen线程是对话历史记录,永远不会被截断:每次发送、投递、已读回执、提议、接受和传输都是一行,按顺序排列。
tail -f data/threads/*.jsonl安全态势
未设置 BROKER_TOKEN 启动的代理是开放的——任何知道隧道 URL 的人都可以读取和写入你的智能体的消息。这对于在每次重启都会更换 URL 的本地测试一分钟来说没问题,但对于任何持续运行的情况则不行。设置令牌:
BROKER_TOKEN=$(openssl rand -hex 32) npm run broker然后每个路由都需要 Authorization: Bearer <token>,并且每个智能体都需要在其环境中使用相同的值。/v1/health 故意保持开放,以便可以对隧道进行冒烟测试。deploy/install.sh 始终写入一个令牌,因此部署的代理默认是关闭的。
一个共享令牌意味着智能体通过 AGENT_ID 区分,而不是通过凭据:任何持有令牌的人都可以声称任何智能体名称。在你自己的机器之间,这是一个合理的权衡;如果令牌传播范围更广,首先需要更改的就是这个——每个智能体使用单独的令牌是对同一中间件的一个小改动。
代理绑定 127.0.0.1,从不直接暴露;cloudflared 是唯一的入口。智能体和线程 ID 在使用前会通过 ^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$ 进行验证,因此精心构造的 ID 无法逃逸数据文件夹。
将代理部署到服务器
deploy/install.sh 可以配置任何 Debian/Ubuntu 主机:它安装 Node 22 和 cloudflared,创建一个 agenttunnel 系统用户,写入 /etc/agent-tunnel.env(模式 640),并安装两个加固的 systemd 单元,以便代理和隧道在重启后都能恢复。代码位于 /opt/agent-tunnel,消息文件夹位于 /var/lib/agent-tunnel。
代理仅绑定 127.0.0.1。cloudflared 向外拨号到 Cloudflare,因此不需要入站防火墙规则,主机不暴露任何公共端口——这也意味着它可以在没有外部 IP 的虚拟机上工作。
对于通过 IAP 访问的 GCP 虚拟机,只需指定一次目标:
cp deploy/target.env.example deploy/target.env填写项目、区域和实例——该文件被 gitignore,因此主机名不会出现在仓库中。然后部署或升级:
./deploy/push.sh它上传 server/ 和 shared/,运行安装程序,并打印公共 URL。重新运行以推送更改;环境文件和消息文件夹保持不变。在任何其他主机上,将代码暂存到 /tmp/agent-tunnel-stage 并直接运行 deploy/install.sh。
共享密钥在首次部署时生成,并保存在 ~/.agent-tunnel/broker-token。每个智能体使用相同的令牌;智能体通过 AGENT_ID 区分,而不是通过凭据。
向正在运行的部署询问其当前地址:
./deploy/url.shURL 不是稳定的。 快速隧道在 cloudflared 服务每次重启时(包括主机重启)都会选择一个新的主机名。发生这种情况时,重新读取它并更新每台智能体机器上的 BROKER_URL。要使其永久化,你需要一个命名隧道,这需要一个带有区域的 Cloudflare 账户——请参阅 INSTALL.md。
测试
npm test涵盖存储(状态转换、至少一次重新投递、路径遍历拒绝、提议状态机)、HTTP 表面(每个路由、错误代码、令牌门控)、端到端的双智能体流程,以及作为真实子进程通过 stdio 驱动的 MCP 服务器。
许可证
MIT——请参阅 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