ターミナルを2枚開いてClaude Codeを走らせていると、片方でスキーマを変えた瞬間、もう片方が古い前提のままコードを書き続ける、という事故が起きる。気づくのはたいてい、壊れたあとだ。cross-session messaging は、この「片方が知っていることを、もう片方が知らない」状態を、人間の転記なしで埋めるための機能である。マルチセッションでのセッション間のやり取りを、公式に用意された経路で行うもの、と言い換えてもいい。
より広いClaude Codeの全体像は Claude Code|2026年版・インストールからCLAUDE.md・Hooks・本番運用までの実装手引き にまとめている。本記事はそのうち「独立した複数セッションが互いに伝言する」部分だけを、公式ドキュメントと実際の配布バイナリの両方から掘り下げる。
30秒でわかる cross-session messaging
・何ができるか:あるClaude Codeセッションが書いた短いテキストを、別のセッションのClaudeに届けられる。宛先の発見も送信もClaude自身がやるので、利用者はツールを直接叩かない
・何を解決するか:並行セッション間の「知らなかった」を消す。破壊的変更の通知、worktree並行作業の同期、長時間タスクの進捗確認
・何を代替するか:2枚のターミナルを行き来して人間がコピペしていた作業。ただし会話の文脈ごと移したいなら、この機能ではなくセッションのresumeが正解
・要件:Claude Code v2.1.224以降、macOSまたはLinux。有効化の操作は不要
・渡らないもの:会話履歴、ファイル、権限。渡るのは本文テキストだけ
この記事で答える3つの問い
①この機能は結局なにをするのか → 別セッションのClaudeに本文テキストだけを届ける(第1章)
②自分の環境で使えるのか → claude --version だけでは判定を誤る。確認コマンドは第3章
③似た機能とどう使い分けるのか → resume / agent teams / Remote Control との違いは第7章
cross-session messagingとは——セッションをまたいで伝言を届ける仕組み
cross-session messagingは、Claude Codeのあるセッションから別のセッションへ、Claudeがメッセージを届ける機能である。公式ドキュメントはこれを「Claude Codeのあるセッションから別のセッションへ、Claudeがメッセージを配送させる」ものと説明し、想定する場面として「あるセッションでの変更が、別のセッションが作っているものを壊すとき、あなたが気づく前にClaudeがそのセッションに警告できる」という例を挙げている。
重要なのは、やり取りされる単位が「テキスト1本」だという点だ。公式ドキュメントの定義は明快で、メッセージとは「あるClaudeが別のClaudeに書く一片のテキストであって、決して会話履歴やファイルではない」。受信側に渡るのは送信者の名前と本文、そして返信用アドレスだけである。したがって「あっちのセッションの文脈をこっちに持ってきたい」という用途にこの機能は向かない。それはセッションのresumeがやることだ。
2つのツールが使われるが、利用者は呼ばない
Claudeはこの機能のために2つのツールを使う。到達できる相手を列挙する ListAgents と、名前を指定して1通届ける SendMessage である。ただし公式ドキュメントは、利用者側がこれらを直接呼ぶ必要はないと明言している——「ClaudeはListAgentsで宛先を見つけ、SendMessageで送るので、あなたがどちらのツールも自分で呼ぶことはない」。
利用者がやることは、伝えたい内容を自然文で頼むだけだ。公式ドキュメントが挙げる例はいずれも「入力するプロンプト」であって、Claudeが実際に送る文面ではない。
Ask the session running in my other terminal whether the migration finished
(別のターミナルで動いているセッションに、マイグレーションが終わったか聞いて)
文面はClaudeが自分で書く。だから「さっきやったことを、決済APIを触っているセッションに説明して」のように、内容だけ指定して言い回しを任せる頼み方が成立する。さらにClaudeは頼まれなくても自分の判断で送ることがある——他セッションに影響する変更を入れた直後などがそれにあたる。
なお SendMessage は、独立セッション同士だけでなく、同一セッション内のサブエージェントやagent teamsのチームメイトへの送信にも使われる同一のツールである。この事実は後述する「組織全体で無効化するとサブエージェントへの連絡も同時に消える」という副作用に直結する。実際、本記事執筆時のセッションで露出している SendMessage の入力スキーマは to(宛先名)、message(本文テキスト)、summary(UIに出す5〜10語のプレビュー)の3つで、公式ドキュメントが言う「プレーンテキストだけが渡る」という説明と矛盾しない構造になっている。
受信側はターンの合間に読む
配送タイミングにも決まりがある。公式ドキュメントによれば、受信側のClaudeはメッセージをアクティブなターン中のツール呼び出しの合間に読むため、実行中のツールが中断されることはない。受信側が待機中であれば、メッセージを起点に新しいターンが始まる。
届いたメッセージは会話上に送信者つきで表示され、Claudeが読み終えると Message from の1行に折りたたまれる。Ctrl+O で展開できる。そして配送されたメッセージは、あなたが打ったプロンプトと同じように利用量にカウントされる。無料の通知チャネルではない点は押さえておきたい。
cross-session messagingの使い方——送る・受け取る・宛先を確認する
送る
前述のとおり、送信は自然文で頼む。宛先の指定も「別のターミナルのセッション」「決済APIを触っているセッション」程度の曖昧さで通る。Claudeが ListAgents の結果から該当セッションを選ぶためだ。
宛先の一覧を自分で見る
Claudeが自動で宛先を解決するので事前準備は要らないが、どのセッションに到達できるかを自分で確認したい場合は /list-agents コマンドを使う。エイリアスとして /peers も用意されている。この一覧には次の3種類が並ぶ。
・サブエージェント:現在のセッション内で動いているエージェント。ただしagent teamsのチームメイトはここに出ない(Claudeはチーム独自の名簿経由でやり取りするため)
・同一マシン上の他セッション:バックグラウンドセッションを含む。ただし後述するinboxソケットをbindしたセッションだけが現れる
・このマシンの外のセッション:Remote Controlが接続されている間だけ表示され、Remote Control というラベルが付く
セッションの名前
メッセージの宛先になるのはセッションの名前である。名前は /rename コマンドまたは起動時の --name フラグで自分で設定できる。設定しなかった場合はClaude Codeが命名し、対話セッションでは作業ディレクトリのフォルダ名から myapp-3f のような名前が導出される。
名前は衝突しうる。/list-agents の出力には各ローカルセッションの作業ディレクトリが併記されるため、同名でもディレクトリが違えば人間の目には区別できる。Claude自身の一覧では各行に短い識別子が付き、名前が衝突したときはそれを宛先に使う。
スクリプトやフックからセッションに投げ込む
セッションごとにbindされるinboxソケットのパスは、2か所で確認できる。ひとつは /status の Peer address 行(パスは uds: が前置される)、もうひとつが環境変数 CLAUDE_CODE_MESSAGING_SOCKET である。
この環境変数はフックとBashコマンドに対してエクスポートされ、そのエクスポートは SessionStart を含むあらゆるフックの実行前に行われる、と公式ドキュメントは述べている。各セッションは自分自身のソケットをエクスポートし、親セッションから継承したものが渡ることはない。
自分の環境でこのエクスポート経路を確かめたければ、--settings に次のようなフックを渡して起動すればよい。ソケットのパスがファイルに書き出される。
{
"hooks": {
"SessionStart": [
{ "hooks": [ { "type": "command",
"command": "sh -c 'echo \"socket=[$CLAUDE_CODE_MESSAGING_SOCKET]\" > /tmp/probe.txt'" } ] }
]
}
}
自分の子プロセス(自セッションのソケットに投げ返すフックやBashコマンド)から届いたメッセージには特例がある。crossSessionInbound の値が1つも当てはまらない場合、Claude Codeは自分の子プロセス由来だと検証できたメッセージを配送する。ただし検証可能性はOSによって異なり、Linux(WSL 2内を含む)では既に終了した子プロセスでも検証できる一方、macOSでは投稿したプロセスが生きている間しか検証できず、Claude CodeがPID 1として動くコンテナ内ではまったく検証できない。検証できないときは、権限プロンプトをスキップするセッションでは保留扱いになる。
動作要件と、自分の環境が対応しているかを確かめるコマンド
要件は3層に分かれる。
①バージョン:Claude Code v2.1.224以降。
②OS:macOSとLinux(WSL 2内のLinuxを含む)で利用できる。native Windowsでは提供されない。
③プロバイダとフラグ:Amazon Bedrock、Claude Platform on AWS、Google CloudのAgent Platform、Microsoft Foundryでは利用できない。加えて CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC、DISABLE_TELEMETRY、DO_NOT_TRACK、DISABLE_GROWTHBOOK のいずれかが、この機能が依存する機能フラグ評価を切ってしまう値になっていると、cross-session messagingはオフのままになる。これらはシェル、設定ファイルの env マップ、managed settingsのいずれからでも入りうる。
claude --version だけでは判定を誤る
ここに実務上の落とし穴がある。公式ドキュメントはバージョン要件の確認手段として claude --version を案内しているが、このコマンドはPATHの先頭にある1つしか見ない。本記事の検証機では、ネイティブ版とnpmグローバル版が同居していた。
$ which -a claude
/Users/xxx/.local/bin/claude
/Users/xxx/.nodebrew/current/bin/claude
$ claude --version
2.1.220 (Claude Code)
$ /Users/xxx/.nodebrew/current/bin/claude --version
2.1.87 (Claude Code)
PATH先頭のネイティブ版は2.1.220で、要件の2.1.224までは4リリース足りない。そしてその裏に隠れていたnpmグローバル版は2.1.87——要件より137リリースも古い。エイリアスやシェルの設定次第でどちらが起動するか変わりうる以上、which -a claude で全部を列挙し、それぞれに --version を当てるのが確実な確認手順になる。
機能の有無を確かめる最短の方法は /list-agents
公式ドキュメントは、/list-agents(別名 /peers)が認識されるかどうかで切り分けよ、としている。
・/list-agents が認識されない:そのセッションにcross-session messagingが無い。バージョン・OS・プロバイダ・環境変数を上から順に潰す
・/list-agents は動くのに送信が届かない:機能自体はオンで、もっと狭い原因がある。denyルールでツールが外されている、受信側のinbound制御で保留・破棄された、相手がこのマシンの外にいて返信専用、のいずれか
機能が有効なセッションでは /status にも自分のinboxアドレスを示す Peer address 行が出る。
実測:2.1.224で何が入ったのか——バージョン要件をバイナリで検証する
「v2.1.224以降」という要件が実際にどこで線引きされているのかは、配布物を並べれば確かめられる。npmの @anthropic-ai/claude-code からゲート直前の 2.1.223、要件の版である 2.1.224、検証時点の最新 2.1.226 をそれぞれ独立したディレクトリに固定インストールし、同梱されるネイティブバイナリ(bin/claude.exe、実体は Mach-O 64-bit executable arm64、272〜280MB)に対して機能関連の文字列を数えた。
| 文字列 | 2.1.223 | 2.1.224 | 2.1.226 | 意味 |
|---|---|---|---|---|
CLAUDE_CODE_MESSAGING_SOCKET |
0 | 20 | 20 | inboxソケットのパスを渡す環境変数 |
crossSessionInbound |
0 | 18 | 25 | 受信時の扱いを決める設定キー |
dialogExpiry |
0 | 4 | 4 | 承認ダイアログの期限 |
isolatePeerMachines |
9 | 20 | 20 | 別マシン宛の承認を必須化する設定 |
list-agents |
2 | 4 | 4 | 宛先一覧のコマンド |
読み取れることは3つある。
①要件のバージョンは実体を伴っている。 ソケットの環境変数、inbound制御の設定キー、ダイアログ期限のいずれも、2.1.223には1件も存在しない。大文字小文字を無視して MESSAGING_SOCKET を探しても0件だった。公式ドキュメントの「v2.1.224以降」は、配布物のレベルで裏が取れる線引きである。
②機能は一度に降ってきたわけではない。 isolatePeerMachines は2.1.223の時点で既に9件、list-agents も2件存在していた。つまり別マシン隔離の設定とエージェント列挙の下地は先行して入っており、2.1.224で追加されたのは「ソケット経由の受信」と「inbound制御」の層だったと読める。
③2.1.224以降も動いている。 crossSessionInbound の出現数だけが18→25へ増えている。設定キーの参照箇所が増えたということで、この領域が現在も手が入り続けていることを示す。
この検証で断定していないこと
文字列カウントは「その版のバイナリに該当機能のコードが含まれるか」を示すもので、実際の配送動作を測ったものではない。ソケットのファイル権限(公式ドキュメントは「OSユーザーに限定する」と説明)や、実際に2セッション間でメッセージが届くかどうかは、認証済みのセッションを2本立ち上げる必要があるため本記事では検証していない。要件バージョン未満の検証機で CLAUDE_CODE_MESSAGING_SOCKET が空だったことも確認したが、これは版が古いことと整合するだけで、それ以上の主張はできない。
届く・保留・拒否——inbound制御(crossSessionInbound)の決まり方
「送ったのに届かない」の原因はほぼここにある。公式ドキュメントは、通常の対話セッション同士が既定設定で動いている場合はメッセージが配送されるとしつつ、あらゆる構成で配送が保証されるわけではないと明記している。受信側は到着した各メッセージを自分のinbound制御に照らし、結果は3つのいずれかになる。
| 値 | 挙動 |
|---|---|
accept |
各メッセージをClaudeに配送する |
hold |
メッセージごとに通知を出すが配送しない。あとから accept が適用されれば、保留分を解放する |
refuse |
配送せずに破棄する |
値が設定されていないときの既定
crossSessionInbound にどの値も当てはまらないとき、Claude Codeは送信側と受信側の権限モードから1通ごとに判定する。判定はセッションを2クラスに分けて行われる。権限プロンプトをスキップするセッション(bypassPermissions)が一方のクラス、それ以外がもう一方だ。プランモードはbypassPermissionsが使えるセッションではスキップ側に数え、auto・acceptEdits・dontAsk はプロンプトする側に数える。
・受信側が権限プロンプトを出すセッション:基本は配送される。保留になるのは、送信側が「自分は権限プロンプトをスキップする」と申告してきた場合だけ
・受信側が権限プロンプトをスキップするセッション:基本は保留される。配送されるのは、送信側も同じくスキップ側だと申告した場合だけ
当てはまる値があるか"} B -->|"accept"| C["配送する"] B -->|"refuse"| D["破棄する"] B -->|"hold"| E["保留して通知"] B -->|"値なし"| F{"受信側は権限プロンプトを
スキップするか"} F -->|"いいえ"| G{"送信側はスキップ側と
申告しているか"} G -->|"いいえ"| C G -->|"はい"| E F -->|"はい"| H{"送信側もスキップ側か"} H -->|"はい"| C H -->|"いいえ"| E E --> I{"承認ダイアログに
回答があるか"} I -->|"承認"| C I -->|"拒否"| D I -->|"dialogExpiry 経過
(既定5分)"| D
保留されたときに起きること
既定判定でメッセージが保留されると、受信側に承認ダイアログが開く。ダイアログには送信者とプレビューが表示され、承認すればその1通が配送され、拒否または閉じれば破棄される。無回答のまま dialogExpiry の期限(既定5分)を過ぎると、ダイアログは閉じてメッセージは破棄される。
保留中にそのセッションの権限モードのクラスが変わると、Claude Codeはinbound規則を再適用し、新たに受け入れ可能になったメッセージを配送して通知を出す。逆に、保留中に refuse が適用される変更が入ると、保留されていたメッセージはすべて破棄され、到達できる各送信者に拒否が報告される。
送信側にも状況は伝わる。送信側が同一マシンで動いている場合、メッセージが保留された時点で通知が出て、その後に受信側が配送・拒否・期限切れのいずれかを行った時点で結果が続報として届く。ただし到着時点で refuse により拒否されたメッセージについては、送信側への通知は出ない。
保留の上限は100件で、配送キューとは別枠。これを超えると古いものから破棄される。
設定の優先順位
crossSessionInbound の効き方には独特の優先順位がある。公式の設定リファレンスはこう規定している——Claude Codeはmanaged settings、--settings フラグ、ユーザー設定の順に読んで最初に見つかった値を適用し、プロジェクト設定やローカル設定の値は、それら信頼されたソースが与える値より accept < hold < refuse の階段で厳しい場合にのみ適用される。信頼されたソースがどれも値を設定していない場合は、プロジェクトやローカルの hold・refuse が1通ごとの既定を置き換える形で効く。
要するに「緩める方向」はプロジェクト設定から効かせられないが、「締める方向」なら効かせられるという非対称な設計だ。同じ非対称性は isolatePeerMachines にもあり、こちらは「どの設定スコープからの true も適用される」ため、チェックインされたプロジェクトファイルが要求をオンにはできてもオフにはできない。
非対話セッション(claude -p)の注意点
claude -p のセッションにも対話セッションと同じようにinboxソケットがbindされるため、長時間動く -p ワーカーはメッセージを受け取れるし、一覧にも現れる。ただしbare modeで起動したセッションはソケットをbindしないので、受信もできず一覧にも出ない。
さらに -p セッションは承認ダイアログを表示できない。したがって保留されたメッセージはそのまま保留され続ける。無人の -p ワーカーにメッセージを受け取らせたい場合は、その --settings の中で crossSessionInbound を accept に設定して起動する必要がある。ユーザー設定に accept を書いても効くが、そちらは自分が動かすすべてのセッションに適用されてしまう。
別マシン・Web版のセッションとやり取りする(返信のみ)
相手がどこで動いているかによって、メッセージの経路と「送れるもの」が変わる。
| 相手の居場所 | 経路 | こちらから送れるもの |
|---|---|---|
| このマシン上 | セッションごとのソケット経由。Anthropicのサーバーを通らない | 新規メッセージと返信 |
| 自分の別のマシン | Anthropicのサーバー経由で、そのマシンのRemote Control接続に着信 | 返信のみ |
| Claude Code on the web | Anthropicのサーバー経由でクラウドセッションへ直接 | 返信のみ |
同一マシン内の配送は、各セッションがディスク上のファイルに自分を登録し、そこにinboxソケットをbindすることで成立している。Claudeがローカルセッションを列挙・送信するとき、Claude Codeはそれらのファイルを読んで相手を見つける。つまり同じファイル群が見えるセッション同士でしか到達できない。コンテナは独自のファイルシステムを持つため、コンテナ内のセッションとホスト側のセッションは互いに到達できない。一方、同じコンテナ内の2セッション同士は、セルフホストランナー上を含めてメッセージをやり取りできる。
返信には返信用アドレスが必要で、ほとんどのメッセージはこれを持っている。ただし例外がある。このマシンの外にいるセッションへの返信を、返信する側がRemote Controlに接続していない状態で送った場合、Anthropicのサーバーへの直接リクエストとしては通るものの、返信用アドレスを伴わずに到着するため、受け取った側はそれに返事ができない。Claudeは送信時にその旨を伝えられる。
別マシン宛を承認制にする
マシンの外へメッセージが出る前に必ず自分の承認を挟みたい場合は、isolatePeerMachines を設定する。
{
"isolatePeerMachines": true
}
これを設定すると、通常の権限プロンプトをスキップする bypassPermissions モードであっても、このマシンの外のセッションへ返信が出ていく前に承認が求められる。同一マシン内のセッション同士のメッセージではプロンプトは出ない。
subagents・agent teams・Remote Controlとの違いと使い分け
Claude Codeには「複数のセッション/エージェントを扱う」機能が複数ある。cross-session messagingはそのうち自分で立ち上げて自分で操る独立セッション同士のための機能であり、公式ドキュメントは他の用途にはそれぞれ専用機能を使うよう促している。
| やりたいこと | 使う機能 | cross-session messagingとの違い |
|---|---|---|
| 独立セッションに短い連絡をする | cross-session messaging | — |
| 別ターミナルで同じ会話を続ける/文脈を新セッションに渡す | セッションのresume | 会話そのものを移す。メッセージは本文テキストしか運ばない |
| Claudeが立ち上げて監督するチームを動かす | agent teams | Claudeがチームを編成・監督する。チームメイトは /list-agents に出ず、チーム独自の名簿経由 |
| 多数のセッションを1か所から見て操る | agent view | 監視・操作のUI。セッション間の伝言路ではない |
| スマホ等から自分でセッションを操る | Remote Control | 人間が操作する経路。別マシン宛メッセージはこの接続に相乗りする |
| CI結果やチャットなど外部イベントを流し込む | channels | 外部→セッションの入力路。セッション同士ではない |
| 同一セッション内のサブエージェントに連絡する | SendMessage(同一ツール) |
ツールは同じだが、宛先がセッション内 |
判断は単純だ。運びたいのが「一言」ならメッセージ、「文脈」ならresume、「編成」ならagent teamsである。
セキュリティ境界——メッセージにできないこと
並行セッションを繋ぐ以上、「片方のセッションを踏み台にして、もう片方に禁止された操作をやらせる」経路になっては困る。Claude Codeはここに明示的な制約を置いている。セッションAがセッションBにメッセージを送ると、Claude CodeはBのClaudeに対してそのメッセージが人間ではなく別セッションから来たものであることを伝え、できることを制限する。
・承認の代わりにならない:別セッションからのメッセージは決してあなたの同意として扱われず、保留中の権限プロンプトに代理で答えることはできない
・設定を変更させられない:別セッションに頼まれたからといって権限設定・CLAUDE.md・その他の構成を変更しないよう、受信側のClaudeは指示されている
・コマンドは実行されない:メッセージ本文に /compact のようなコマンドが含まれていても、それはただのテキストとして届く。Claude Codeがそれを実行することはない
・権限プロンプトは通常どおり出る:メッセージに沿って動くのに受信側が持っていない権限が必要なら、他の作業と同じプロンプトが出る
権限境界はセッションごとに保たれる。Claudeは、自分のセッションで拒否・ブロックされた操作や、自分の権限設定ならブロックされる操作を、別のセッションに依頼しないよう指示されている。そうした作業は人間に差し戻される。
この設計思想は、Claude Codeが内部でどうツールと権限を組み立てているかという話とも地続きだ。より深い構造は Claude Codeの内部アーキテクチャ完全解剖:331モジュールから読み解く本番エージェント設計の全貌 を参照してほしい。並行worktreeでの運用作法そのものについては Claude Codeベストプラクティス2026|Boris直伝25 Tips・並列ワークツリー・–bare最適化 が詳しい。Claude Code自体をこれから触る場合は Claude Codeとは?Anthropic公式AIコーディングツールの使い方・インストール・料金【2026年版】 から入るとよい。
機能を止める
受信と送信は別々の制御になっているため、必要な方向だけ止められる。
・受信を止める:crossSessionInbound を refuse にする。プロジェクト設定やローカル設定からの refuse は他のどのソースより優先され、ユーザー設定からの refuse はmanaged settingsや --settings が値を設定していない限り適用される
・送信と列挙を止める:SendMessage と ListAgents を名指しした権限denyルールを追加する。どちらも指定子なしの素のツール名で書く
組織全体で両方向を止めるなら、managed settingsで次のように組み合わせる。
{
"permissions": {
"deny": ["SendMessage", "ListAgents"]
},
"crossSessionInbound": "refuse"
}
無効化するときの2つの副作用
①サブエージェントへの連絡も消える:SendMessage は同一セッション内のサブエージェントやagent teamsのチームメイトへの送信にも使われる同じツールなので、denyするとそちらも同時に止まる
②見た目では判別できない:拒否設定のセッションは、自分の /status でも他セッションの一覧でも、まったく変化を見せない。この設定が効いているかどうかは設定ファイルそのものから確認するしかない
なお、これらを設定してもClaude Codeは各セッションのinboxソケットをbindし続ける。到着したメッセージを配送せずに落とすだけである。
仕様上の制限
最後に、機能が動くあらゆる環境に共通する制限を2つ挙げておく。
プレーンテキストのみ。 Claudeがセッション間で送れるのはプレーンテキストだけである。agent teamsの構造化されたプロトコルメッセージはチーム内にとどまる。
メッセージループはスロットルされる。 Claude Codeは送信者ごとに繰り返しメッセージをレート制限し、短時間に届いた同一メッセージの繰り返しを破棄し、Claudeが読むのを待っている受理済みメッセージを1セッションあたり50件で上限を切る。2セッション間でメッセージのループが起きても、それは自然に止まる設計になっている。
参照ソース
・Message your other Claude Code sessions — Claude Code公式ドキュメント。本記事の機能仕様・要件・制限の一次ソース
・Settings — crossSessionInbound の優先順位規定と dialogExpiry の既定値・許容値
・Permission modes — inbound既定が参照する権限モードの分類
・Hooks — CLAUDE_CODE_MESSAGING_SOCKET がエクスポートされる先
・@anthropic-ai/claude-code(npm) — 本記事の版比較(2.1.223 / 2.1.224 / 2.1.226)で取得した配布パッケージ