Claude Media
CLAUDE_CODE_MESSAGING_SOCKETをhookやBashから使う方法

CLAUDE_CODE_MESSAGING_SOCKETをhookやBashから使う方法

Claude Codeがhookやbashコマンドに自動で渡す受信箱ソケットのパスと、own-child配信の認証手順をまとめます。

このTipsでできること

Claude Codeはセッション間メッセージングを有効にしたセッションで、受信箱ソケットのパスをCLAUDE_CODE_MESSAGING_SOCKETという環境変数にして、hookとBashコマンドへ自動で渡します。この変数を使うと、hookスクリプトや外部プロセスから「いま動いているこのセッション」の受信箱へ直接書き込めます。v2.1.224以降のClaude Codeが対象です。

セットで渡されるCLAUDE_CODE_MESSAGING_TOKEN(v2.1.228以降)は、そのソケットへ書き込むプロセスが本当にこのセッションの子プロセスであることを証明するための認証トークンです。この2つの変数を組み合わせて使う場面と、プラットフォームごとの落とし穴を扱います。

やり方

変数の中身を確認する

セッション内で/statusを実行すると、Peer addressの行にuds:が付いたパスで受信箱ソケットの場所が表示されます。同じパスがhookやBashコマンドにはCLAUDE_CODE_MESSAGING_SOCKETとして渡ります。メッセージング機能を有効にして起動したセッションでは、SessionStartを含むどのhookが動くよりも前にこの変数がエクスポートされます。

詳しい理由を見るには--debugを付けて起動します。

claude --debug

ソケットを用意できなかった場合の理由がログに残ります。ソケット自体はmacOSとLinux(WSL 2を含む)ではUnixドメインソケット、ネイティブWindowsでは名前付きパイプです。作業ディレクトリを使えない場合、Claude Codeは/tmp/cc-socks-<uid>というユーザー専用のディレクトリにソケットを作ります。

hookスクリプトから自セッションの受信箱に接続する

CLAUDE_CODE_MESSAGING_SOCKETとCLAUDE_CODE_MESSAGING_TOKENはどちらもClaude Codeが起動時に自動でエクスポートする値で、settingsファイルのenvブロックで上書きすることはできません。読み取り専用の値として、hookのシェル内でそのまま参照します。メッセージ本文のペイロード形式は公式ドキュメントに明記されていないため、以下のサンプルは本文を送らず、認証行だけを送って接続を成立させるところまでに絞っています(本文の扱いは後述の「メッセージ本文の形式は公式に説明なし」節を参照します)。

hooks/notify-self.sh
#!/bin/bash
SOCK="$CLAUDE_CODE_MESSAGING_SOCKET"
TOKEN="$CLAUDE_CODE_MESSAGING_TOKEN"
 
if [ -z "$SOCK" ]; then
  # メッセージングが無効、または受信箱を用意できなかったセッション
  exit 0
fi
 
# own-child(自セッションの子プロセス)であることを示す認証行を
# 接続の最初の1行として送る
printf '{"type":"auth","token":"%s"}\n' "$TOKEN" | nc -U "$SOCK"

送信先は自セッションの受信箱なので、Claude Code側はこの接続を「別セッションからのピアメッセージ」ではなくown-child(自セッションの子プロセスからの接続)として扱います。own-childと判定されると、この後に本文を送ったとしても、通常のピアメッセージが受ける承認待ちを経由しません。

プラットフォーム別の検証方法を把握する

own-childかどうかの判定方法はOSによって違います。

環境検証方法CLAUDE_CODE_MESSAGING_TOKENが必要か
Linux(WSL 2含む)検証方法プロセス証跡。子プロセスが終了した後でも検証できるCLAUDE_CODE_MESSAGING_TOKENが必要か不要(証跡があれば)
macOS検証方法プロセス証跡。ただし送信プロセスが動いている間だけCLAUDE_CODE_MESSAGING_TOKENが必要か送信後に終了する場合は必要
コンテナ内(Claude CodeがPID 1で動く場合)検証方法プロセス証跡が取れないCLAUDE_CODE_MESSAGING_TOKENが必要か必須
ネイティブWindows検証方法プロセス証跡なしCLAUDE_CODE_MESSAGING_TOKENが必要か必須(認証行がないと接続ごと切断)

macOSでプロセスがすでに終了していたり、コンテナ内でClaude CodeがプロセスID 1として動いていたりすると、プロセス証跡自体が存在しません。この場合にトークンで検証できなければ、Claude Codeはメッセージを「権限を主張しないメッセージ」と同じ扱いにし、bypassPermissionsなどで通常の確認をスキップしているセッションでも承認待ちにします。ネイティブWindowsでは認証行が必須で、有効な認証行から始まらない接続はそのまま切断されます。なお、ネイティブWindowsでセッション間メッセージング自体を使うにはClaude Code v2.1.234以降が必要です。

-p(headless)セッションとbareモードの違い

claude -pで起動したheadlessセッションも、対話セッションと同じように受信箱ソケットを用意し、CLAUDE_CODE_MESSAGING_SOCKETをエクスポートします。長時間動く-pワーカーへ外部から進捗確認のメッセージを送りたいときに使えます。一方、hookやスキル、MCPサーバーなどの自動読み込みを省いて起動を速くする--bareモードではソケットを用意しません。bareモードのスクリプトでCLAUDE_CODE_MESSAGING_SOCKETを参照しても値は空になるので、事前に空文字チェックを入れておく必要があります。

連投すると絞られる

同じ送信元から短時間に同じ内容を繰り返し送ると、受信側のセッションはそれを間引きます。Claude Codeは受信セッション側で送信元ごとの繰り返しをレート制限し、短い時間内に届いた同一の繰り返しは破棄し、Claudeが読める未読メッセージは最大50件までしかキューに積みません。監視スクリプトをwhileループで回して毎秒このソケットに書き込むような実装は、途中から配信されなくなるので避けます。

crossSessionInboundをrefuseにしても変数は残る

セッション側でcrossSessionInboundをrefuseに設定していても、Claude Codeは受信箱ソケットの用意そのものはやめません。CLAUDE_CODE_MESSAGING_SOCKETはいつも通りhookとBashコマンドへエクスポートされます。変わるのは配信結果だけで、ソケットに届いたメッセージはClaudeへ渡されずにすべて破棄されます。「受信を止めたつもりが、変数自体は消えていない」という状態になるため、受信を完全に止めたい場合は変数の有無ではなく、そのセッションに適用されている設定ファイルのcrossSessionInboundの値を確認します。

関連するバージョンの変遷

このソケット周りの挙動は、公開後も何度か手直しが入っています。

バージョン変更内容
v2.1.224変更内容セッション間メッセージングとともにCLAUDE_CODE_MESSAGING_SOCKETが導入
v2.1.228変更内容一部の環境で「インストールまたはアップグレード後の最初のセッション」で受信箱が用意されない不具合を修正
v2.1.228変更内容own-child配信の認証手段としてCLAUDE_CODE_MESSAGING_TOKENを追加
v2.1.232変更内容共有/tmp上のソケット用ディレクトリを堅牢化。あらかじめ仕込まれたシンボリックリンクや他ユーザーのディレクトリを拒否するように変更(この変更がuser namespaceやrootlessコンテナ内で副作用を起こす)
v2.1.243変更内容v2.1.232の堅牢化がuser namespaceとrootlessコンテナ内でメッセージング自体をエラーを出さずに無効化していた不具合を修正
v2.1.243変更内容ソケットへの接続で完全な1行を30秒以内に送らないと接続を閉じる、という現行の挙動に変更
v2.1.248変更内容Amazon Bedrock・AWS版Claude Platform・Google CloudのAgent Platform・Microsoft Foundry、およびfeature-flag取得をオフにしたセッションでも同一マシン内のメッセージングが使えるように

v2.1.232の堅牢化は、シンボリックリンクを使ったなりすましを防ぐための正当な変更でしたが、副作用としてuser namespaceやrootlessコンテナで動くセッションのメッセージングを気づかないうちに止めていました。v2.1.243より前のバージョンをコンテナで使っている場合、CLAUDE_CODE_MESSAGING_SOCKETが空になっていないか確認する価値があります。

Bedrock・AWS版Claude Platform・Google CloudのAgent Platform・Microsoft Foundryといった各プロバイダー経由でClaude Codeを動かしている場合は、同一マシン内のメッセージングであってもv2.1.248より前では対応していません。この変数を参照するスクリプトをCIやセルフホスト環境に組み込む前に、そこで動くClaude Codeのバージョンとプロバイダーの組み合わせをclaude --versionで確認しておきます。

補足

サンドボックス内のBashから届かせる

サンドボックス化したBashコマンドがこのソケットに書き込めるかどうかは、サンドボックスのUnixソケット設定で決まります。sandbox.network.allowAllUnixSocketsとsandbox.network.allowUnixSockets(いずれもsandbox設定の項目)が対象です。既定の制限が掛かっていると、サンドボックス内のBashからはCLAUDE_CODE_MESSAGING_SOCKETのパスが見えていても接続できません。

接続は完成した1行を送ってから開く

Claude Codeは、接続してから30秒以内に完全な1行を受け取れないと、その接続を閉じます。時間のかかるコマンドの出力を先に変数へキャプチャしてから、認証行を送る接続を開きます。

RESULT=$(long_running_check.sh)
printf '{"type":"auth","token":"%s"}\n' "$CLAUDE_CODE_MESSAGING_TOKEN" | nc -U "$CLAUDE_CODE_MESSAGING_SOCKET"

この順序を守れば、コマンドの実行中に30秒のタイムアウトへ引っかかることを避けられます。

メッセージ本文の形式は公式に説明なし

認証行{"type":"auth","token":"<token>"}の書式は公式ドキュメントに明記されていますが、その後に続けるメッセージ本文のペイロード形式は公式ドキュメントに例示がありません。この変数の主な用途は、Claude自身が呼ぶSendMessageツールを経由せずに、外部のhookやスクリプトから同じ受信箱へ直接届けることです。正確な本文フォーマットが必要な場面では、まずSendMessage側の挙動(別記事で解説)で意図した配信ができないか確認するのが安全です。

想定される使い方: バックグラウンドで走らせたコマンドの完了を知らせる

典型的な使い方は、Bashの&でバックグラウンドに投げた長時間コマンドが終わったタイミングで、自セッションの受信箱へ完了を知らせる接続を送ることです(本文フォーマットは公式に例示がないため、確実に検証できるのは前節までの認証行を送るところまでです)。Claude Codeにも、別セッションが次にアイドルになったときに通知を受け取れる機能(セッション間メッセージングの記事で解説)がありますが、それは対象がv2.1.236以降・同一マシン上のセッション限定です。これに対してCLAUDE_CODE_MESSAGING_SOCKETを直接使う方法は、hookやBashコマンドという「セッションの外側で動くプロセス」から任意のタイミングで書き込める点が違います。テスト実行やデプロイスクリプトのように、Claude Codeのターンとは非同期に完了するプロセスと相性が良い方法です。

この変数を使うべき場面の早見表

シーン使う方法補足
Claude自身が別セッションへ判断して送る使う方法SendMessageツール(Claudeが自動で呼ぶ)補足利用者が変数を直接触る必要はない
hookやBashから自セッションの受信箱に書き込む使う方法CLAUDE_CODE_MESSAGING_SOCKET + CLAUDE_CODE_MESSAGING_TOKEN補足own-child判定が通れば承認待ちを経由しない
受信箱のアドレスを目視で確認する使う方法/statusのPeer address行補足uds:接頭辞付きで表示される
サンドボックス化したBashから届かせる使う方法sandbox.network.allowUnixSockets設定補足既定では届かないことがある

よくあるつまずき

  • settingsのenvブロックで上書きしようとして反映されない: CLAUDE_CODE_MESSAGING_SOCKETとCLAUDE_CODE_MESSAGING_TOKENはどちらもClaude Codeが起動時に決める値で、envブロックからの設定を受け付けません。
  • コンテナ内で認証行を省いて接続が承認待ちのまま止まる: PID 1で動くコンテナはプロセス証跡を取れないため、認証行なしの接続はown-childと判定されず、通常のピアメッセージと同じ承認待ちになります。
  • --debugを付けずに「受信箱がない」原因を探して時間を使う: ソケットを用意できなかったセッションは/statusのPeer address行にunavailableと理由が出ますが、詳しい失敗の中身は--debugログにしか残りません。
  • v2.1.232〜v2.1.242のコンテナで変数が空になる: user namespaceやrootlessコンテナで動かしている場合、v2.1.232のソケットディレクトリ堅牢化が原因でメッセージングごと気づかないうちに止まることがあります。v2.1.243以降へ上げれば直ります。

まとめ

CLAUDE_CODE_MESSAGING_SOCKETは、Claude Codeがv2.1.224以降でhookとBashコマンドへ自動的に渡す受信箱ソケットのパスです。CLAUDE_CODE_MESSAGING_TOKEN(v2.1.228以降)と組み合わせて認証行を送れば、外部プロセスから自セッションの受信箱へown-childとして直接配信できます。プロセス証跡が取れないmacOSの終了後・コンテナ・ネイティブWindowsでは、このトークンが唯一の検証手段になる点を押さえておきます。

この記事を共有:XはてブLinkedIn