Yyatmita

複数の Claude Code を1本の broker でつないだ——AI 司令部と部下が「実際に喋る」ようになった運用記

前篇で立てた司令部は、まだ頭の中の組織図だった。claude-peers(同一マシンの複数 Claude Code をつなぐ MCP)で配線したら、セッション同士がメッセージを送り合うようになった。導入・β channel・二層プロトコル・運用3日目の実用感の記録

自分のエージェント基盤を組む#agent-stack#claude-peers#claude-code#mcp#workflow
← 前の記事: Claude Code の deep-research を解剖する — エージェント基盤に持ち帰る7つの設計判断

この記事は「AI エージェント基盤」シリーズの一篇です。Claude が書いています(題材は筆者自身の運用の実話)。前篇は「方向性を相談するプロジェクトを立てた話」

司令部はあったが、まだ「頭の中」にしかなかった

前篇で、複数プロジェクトの方向性を決めるためだけの司令部(GHQ)を立てた話を書いた。何を・なぜ・どの順でやるかを決める場所をひとつ作ったら、発散していたプロジェクト群がまとまりだした——という話だ。

ただ、正直に続きを書くと、あの時点の司令部は まだ「頭の中の組織図」 でしかなかった。司令部がいて、その下に各プロジェクトがいる、という絵は描けている。でも実体は、私が複数のターミナルで Claude Code を別々に開いているだけ。司令部セッションが「これは yatmita でやって」と決めても、その意図を yatmita のセッションに運ぶのは、結局 私が手でコピペする しかなかった。

司令部の決定を片方の窓からコピーして、もう片方の窓に貼る。返事をまたコピーして戻す。組織図は綺麗なのに、配線が人力。指揮官と部下のあいだに電話線が無くて、伝令(私)が走って紙を渡している状態だった。

この記事は、その電話線を引いた話だ。使ったのは claude-peers という MCP で、主役はこのツールの紹介と、3日ほど運用してみての所感になる。

claude-peers とは何か

claude-peers は、同じマシンで動いている複数の Claude Code セッション同士がメッセージをやり取りするための MCP だ。仕組みはいたってシンプルで、

  • ローカルに小さな broker(仲介プロセス)が立ち上がり、
  • メッセージは SQLite に保存され、
  • 各セッションは MCP のツール経由でそこへ読み書きする。

最初の1セッションが起動したときに broker が自動で立ち上がり、後片付けも自動。外に出ていく通信は無く、すべて localhost で完結する。

セッションに生えるツールは4つだけだ。

ツール役割
send_message相手の peer ID 宛にメッセージを送る
set_summary「自分が今何をしているか」を1〜2文で broadcast する
list_peers今いる他のセッションと、それぞれの summary を一覧する
check_messages自分宛の新着を取りに行く

運用で効くのは、この4つを settings.jsonpermissions.allow に入れてしまうことだ。そうすると送受信のたびに承認を求められなくなり、セッション同士が approve 無しで会話できる。指揮官と部下のあいだの電話を、いちいち私が「かけていいですか?」と聞かれずに繋げる、ということ。

// ~/.claude/settings.json (抜粋)
"permissions": {
  "allow": [
    "mcp__claude-peers__send_message",
    "mcp__claude-peers__set_summary",
    "mcp__claude-peers__list_peers",
    "mcp__claude-peers__check_messages"
  ]
}
brokerlocalhost + SQLite GHQ セッション司令部 yatmita セッションサイト・記事 promotion-hq セッションプロモ manginus セッションマンガ制作

落とし穴: 通常起動だと、メッセージは届かない

ここが最初に転んだところで、かつ一番大事な注意点でもある。

普通に claude で起動したセッションは、他の peer からメッセージが来ても気づけない。正確には、メッセージ自体は broker の SQLite に保存される。でもそれが「今会話している Claude のセッションに割り込んで通知される」という動きが、通常起動では効かない。check_messages で自分から取りに行く分にはいいが、相手が一方的に送ってきた緊急の用件は、こちらが偶然 polling しない限り素通りしてしまう。

実際にこれで一度ひやりとした。あるセッション間で「これは公開していいか?」という人間の判断を仰ぐメッセージが投げられたのに、受け手が気づかないまま別の作業を続け、メッセージが宙に浮きかけた。最終的には SQLite を直接覗いて拾い出したが、運用に乗せる前に気づけてよかった、という類のヒヤリだった。

これを解決するのが、Claude Code の 開発中の channel 機能 だ。起動時にフラグを付ける。

claude --dangerously-load-development-channels server:claude-peers

このフラグを付けて起動したセッションには、peer からのメッセージが 届いた瞬間に割り込み通知される。伝令が走らなくても、相手の発言が肩を叩いてくれる。前篇でいう「司令部の一声が部下に即座に届く」が、ようやく物理的に成立する。

毎回打つのは面倒なので、fish の関数にしてある。

function claudepeers --description 'Launch claude with claude-peers channel notification'
    claude --dangerously-load-development-channels server:claude-peers $argv
end

$argv を素通しにしてあるので、claudepeers -c で会話を引き継いで再起動、といった使い方もそのまま効く。新しい部下を起こすときは、tmux で窓を割って、その窓で claudepeers を叩くだけ。

このフラグは β だという但し書き

フラグ名が --dangerously- で始まっていることからも分かる通り、これは Claude Code の 開発中・未公開の機能 だ。正直に書いておくと、

  • Anthropic 側で予告なく挙動が変わったり、無くなったりし得る。
  • セッションが文脈を圧縮(compact)している最中は、通知を受け取れないことがある。
  • だから「本番の重要連絡をこれ一本に頼る」のは危うい。

セキュリティ面の不安は薄い(通信は localhost 限定で外に出ない)が、安定性は保証されていない。私は「自分ひとりの開発機で、消えても致命的でない連絡に使う」という線で割り切って使っている。人に配る構成ではない。

「誰が今、何をしているか」が一覧になる

運用に乗せてみて地味に効いたのが set_summary だ。各セッションが起動直後に、自分の素性と今やっていることを1行で broadcast しておく。接頭辞だけ規約で揃えてある。

  • [GHQ] スプリント編成中。各 repo に Issue を配り終えた
  • [yatmita] アクセス解析の対話中。次に記事 Issue に着手予定
  • [manginus] EP の英訳チェックを回している

すると司令部が list_peers を叩くだけで、艦隊の現況が一望できる。「promotion-hq は今ふさがっている」「yatmita は手が空きそう」が分かる。組織図が静止画ではなく、今まさに何が動いているかのダッシュボードになった瞬間で、ここで初めて「複数のセッションを率いている」という感覚が出てきた。

正本は Issue、peers はあくまで「通知」

もうひとつ、運用設計で決めたことがある。peers で全部やろうとしない、というルールだ。

peers のメッセージは速いが、揮発する。セッションを閉じれば文脈は消えるし、β の通知は前述の通り取りこぼし得る。だから「判断」と「経過」は peers に置かない。それらは GitHub の Issue に書く。peers で流すのは「Issue に書いたよ/コメントしたよ」という 通知のメタ情報だけ にした。

永続["永続レイヤー(正本)"] 永続["永続レイヤー(正本)"] 「ここに書いた」と知らせる 読みに行く GitHub Issue判断・経過・DoD peers メッセージ「書いたよ」の一声

司令部が判断したら Issue にコメントを残し、peers で「コメント置いた」と一声かける。受け手は通知で気づき、Issue を読みに行って着手する。速さは揮発レイヤー、記録は永続レイヤー ——この二段構えにしてから、「peers で言ったから済んだことにする」という後から辿れない事故が起きなくなった。

実をいうと、いま書いているこの記事も同じ経路で発注されている。司令部が記事の Issue を立て、peers で私に「書いて」と通知し、私が Issue を読んで着手した。書いている最中にも司令部から「そのデータの見せ方はこう気をつけろ」と peers で軌道修正が飛んできた。電話線を引いたら、ちゃんと電話がかかってくるようになった、という感じだ。

回してみた3日間の、正直な感触

ここまで仕組みと運用の話を書いてきたが、成果が出たという話ではないことは明記しておく。これは運用を始めて3日目のメモで、効果測定はまだこれからだ。便利になったのは「私が伝令として窓のあいだを往復する手間」であって、プロジェクトが前に進んだかどうかは別の指標で見ないといけない。

そのうえで、感触を正直に書くと——

  • 良かった: 設計レビュー(Issue コメント)→ 通知 → 数分で往復、というサイクルが回る。複数 repo を同時に走らせていても、現況が list_peers で掴めるので、頭の中で「今どこが動いているか」を保持し続けなくてよくなった。
  • 癖がある: β の通知は万能ではない。compact 中は届かないし、起動フラグを忘れた窓は「いるのに聞こえていない」状態になる。最初は何度か「返事が来ない」で混乱した。
  • AI 側が滑る瞬間もある: 司令部役の AI が、計画表に書いてある「推奨」を、まるで確定済みの指示のように部下へ流してしまったり、手の空いたセッションに埋め合わせの仕事を作りかけたり——という小さな脱線は起きる。ただ、これは人間の一言ですぐ止まる(「その話、私は知らないよ」で着手前に停止した)。前篇で書いた「対外アクションは人間承認・停止ルールを置く」という設計が、ここでも普通に効いている。細かい話なので深追いはしないが、配線して速くなった分、変な方向にも速く進みかけるのは確かで、人間が intent を握り続ける前提は変わらない。

まとめ

  • 前篇で立てた司令部は、配線が人力(私のコピペ)だった。claude-peers でセッション同士を直結したら、組織図が「実際に喋る組織」になった。
  • ツールは broker + SQLite + 4つの MCP ツールというシンプルな構成。permissions.allow に入れて approve 無しで会話させるのが運用のコツ。
  • ただし通常起動では通知が届かない。--dangerously-load-development-channels で channel push を有効化する必要があるが、これは β・自己責任 の機能(compact 中は届かない・予告なく変わり得る・配布には不適)。
  • 速さは peers(揮発)、記録は Issue(永続)の 二層プロトコル にすると、後から辿れる。
  • 3日目の所感としては手間が減った段階で、成果はこれから。配線が速い分、AI も人間も「速く間違える」余地は増えるので、停止ルールと人間承認は外さない。

電話線は引けた。次は、この回線で実際にプロジェクトがどれだけ前に出たのかを、もう少し回してから書こうと思う。