Skip to main content
Glama

tincan

エージェントと友達のエージェントをつなぐプライベートライン。

二つの缶と一本の紐。あなたのClaude Codeエージェントが、相手のエージェントと直接通信します——メッセージを送り、既読通知を受け取り、ファイルを渡す——すべて、あなたが所有するトンネルを通じて、マシンを越えて。

  • エージェント同士、人間同士ではない。 どちらも中継する必要はありません。あなたのエージェントは相手のエージェントを名前で呼び、回答を得ます。

  • Slackも共有チャンネルもサードパーティも不要。 あなたが管理するマシン上の小さなブローカーが一つ。メッセージはcatで読めるフォルダ内のファイルです。

  • コンテキストロスなし。 すべてのスレッドは追記専用のログです——すべての送信、配信、既読通知、転送が、順序通り、永遠に保持されます。遅れて参加したエージェントは推測する代わりに全履歴を読みます。

  • 即時、必要なときは待機もする。 配信は最低1回保証されます。まだオンラインでないエージェントにメッセージを送ると、接続した瞬間に届きます。

  • テキストだけでなくファイルも。 64KBを超えるものは最初に提案され、相手側が承諾した場合にのみ転送されます。

初めてですか? INSTALL.mdをご覧ください。

tincan アーキテクチャ — 2台のマシン、1つのブローカー、そして発信するトンネル

MCPサーバー内の何も、自分がローカル側かリモート側かを認識しません。唯一の違いはAGENT_IDとBROKER_URLです。

エージェントの接続

まずどこかでブローカーを実行する必要があります——1台のマシン、1つのコマンドで、ラップトップでも構いません。INSTALL.mdで完全にカバーされていますが、短く言うとnpm run brokerとnpm run tunnelで、公開URLが表示されます。

ブローカーが存在すれば、各エージェントマシンには3つのものが必要です:コード、そのブローカー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 test
npm run broker
npm run tunnel

npm run tunnelは公開URLを表示し、.tunnel-urlに保存します。ローカルブローカーは、自分でBROKER_TOKENを設定しない限り、トークンなしで起動します。

Related MCP server: Session Multiplayer

モニターの実行

各エージェントは、相手が送信したものに気づくよう、定期的にcheck_inboxをポーリングする必要があります。Claude Codeでは、セッションを次のように開始します:

/loop 30s call check_inbox and handle anything it returns

1回のcheck_inbox呼び出しで3つの仕事をします:新しいメッセージを返す、決定待ちの転送提案を提示する、このエージェントが送信した提案のうち後に回答されたものを完了させる。何もすることがない場合はquiet: trueを返します。

ツール一覧

ツール

機能

check_inbox

モニターのティック。新しいメッセージ、決定待ちの提案、送信済み提案の更新情報。

send_message

別のエージェントに送信。サイズに応じて自動でインラインと提案を選択。

ack_message

既読通知。呼び出されるまで、メッセージは毎回のティックで再配信される。

respond_offer

受信した大容量ペイロード転送の提案を受け入れるか拒否する。

fetch_payload

大きなメッセージのペイロードを取得——小さくテキストの場合はインライン、そうでなければディスクへ。

message_status

自分が送信したものの状態:queued → delivered → read。

list_threads / read_thread

会話履歴。

list_agents

ブローカーが確認したエージェントとその時刻。

broker_health

到達可能性、エージェントID、認証モード。

メッセージの流れ

送信、配信、既読——送信者が監視できるレシート

64KB未満 —— send_messageで投稿すると、ブローカーがスレッドログに追記し、受信者のインボックスフォルダにエントリを入れます。受信者の次のcheck_inboxでdeliveredに変わり、メッセージを返します;ack_messageでreadに変わります。送信者はmessage_statusで3つの状態すべてを監視できます。

提案ハンドシェイク——受信者が承諾するまで何も転送されない

64KB超 —— サイズが判断し、エージェントは判断しません。send_messageはバイトを送信者自身のディスク(~/.agent-tunnel/outbox/<agent>/)に保持し、件名、サイズ、コンテンツタイプのみを含む提案を投稿します。受信者はoffers_awaiting_responseでそれを確認し、respond_offerを呼び出します。承諾されると、ペイロードは送信者の次のcheck_inboxティック時にアップロードされます——追加の呼び出しもエージェントの簿記も不要。拒否されると、ローカルコピーは削除され、何も転送されません。

配信は最低1回保証:未確認のメッセージは毎回のティックで再表示されるため、取得と確認の間にクラッシュしても、失われることなく再配信されます。

メッセージと提案の状態遷移、どちらも前方のみ

図は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

スレッドは会話履歴であり、決して切り詰められません:すべての送信、配信、既読通知、提案、承諾、転送が1行ずつ、順序通りに記録されます。

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は常にトークンを書き込むため、デプロイされたブローカーはデフォルトで閉じられています。

共有トークン1つということは、エージェントは資格情報ではなくAGENT_IDで区別されることを意味します:トークンの保持者は誰でも任意のエージェント名を名乗れます。これは自分が所有するマシン間では妥当なトレードオフであり、トークンが広がった場合に最初に変更すべき点です——エージェントごとのトークンは同じミドルウェアへの小さな変更で実現できます。

ブローカーは127.0.0.1にバインドされ、直接公開されることはありません;cloudflaredだけが唯一の経路です。エージェントIDとスレッド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)を書き込み、2つの強化されたsystemdユニットをインストールして、ブローカーとトンネルが再起動後も復帰するようにします。コードは/opt/agent-tunnelに、メッセージフォルダは/var/lib/agent-tunnelに配置されます。

ブローカーは127.0.0.1のみにバインドします。cloudflaredはCloudflareに発信するため、受信ファイアウォールルールは不要で、ホストは公開ポートを公開しません——つまり、外部IPがまったくないVMでも動作します。

IAP経由で到達するGCP VMの場合、ターゲットを一度指定します:

cp deploy/target.env.example deploy/target.env

プロジェクト、ゾーン、インスタンスを入力——そのファイルはgitignoreされているため、ホスト名はリポジトリ外に残ります。その後、デプロイまたはアップグレード:

./deploy/push.sh

server/とshared/をアップロードし、インストーラーを実行し、公開URLを表示します。変更を送信するために再実行してください;envファイルとメッセージフォルダはそのまま残ります。他のホストでは、コードを/tmp/agent-tunnel-stageにステージングし、deploy/install.shを直接実行してください。

共有秘密鍵は初回デプロイ時に生成され、~/.agent-tunnel/broker-tokenに保持されます。すべてのエージェントは同じトークンを使用します;エージェントは資格情報ではなくAGENT_IDで区別されます。

実行中のデプロイに現在のアドレスを尋ねる:

./deploy/url.sh

URLは安定していません。 クイックトンネルは、cloudflaredサービスが再起動するたび(ホストの再起動を含む)に新しいホスト名を選びます。その場合は、再読み取りして各エージェントマシンのBROKER_URLを更新してください。永続的にするには名前付きトンネルが必要であり、ゾーンを持つCloudflareアカウントが必要です——INSTALL.mdを参照してください。

テスト

npm test

ストア(状態遷移、最低1回の再配信、パストラバーサル拒否、提案状態遷移)、HTTPサーフェス(すべてのルート、エラーコード、トークンゲート)、2エージェントのエンドツーエンドフロー、そして実際のサブプロセスとしてstdio経由で駆動されるMCPサーバーをカバーしています。

ライセンス

MIT — LICENSEを参照。

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables AI agents to communicate directly through a mesh network, supporting group chats, message exchange, and invite-only access with prompt injection protection.
    29 npm
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables AI coding agents in different harnesses, projects, or machines to share encrypted peer-to-peer rooms and exchange messages directly, without any central server or account.
    8
    3
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables already-running AI coding agents on the same project to register, discover one another, and exchange durable direct messages so they can share progress and avoid conflicting work.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables AI coding agents to communicate directly with each other across machines, with support for rooms, pairing, and encrypted messaging.
    1 npm
    7
    MIT