Claude Code の hook は、ツールの実行前、権限の確認が必要になったとき、Claude が応答を終えたときなど、セッション中の決まったタイミングで Claude Code が自動的に実行するコマンドです(HTTP 呼び出しや prompt など、ほかのハンドラー種別もあります)。hook は ~/.claude/settings.json などの設定ファイルの hooks キーに定義します。各 hook はイベントに関する JSON を stdin で受け取り、終了コードまたは stdout に出力する JSON オブジェクトで応答できます。これにより、ログの記録、通知、操作のブロック、ユーザーに代わっての応答などが可能になります。
01hook の構成
hook の設定は 3 つの階層で構成されます。
- hook イベント:
PreToolUseやStopなど。 - matcher グループ:「Bash ツールのときだけ」のように、発火する条件を絞り込みます。
- 1 つ以上の hook ハンドラー:実際に実行される処理です。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/path/to/lint-check.sh"
}
]
}
]
}
}
この例では、Claude がファイルを書き込み・編集した後に lint スクリプトを実行します。別のイベントを追加するには、同じ hooks オブジェクト内に兄弟キーを追加します。
02hook の配置場所
~/.claude/settings.jsonすべてのプロジェクトいいえ(自分のマシンのみ).claude/settings.json1 つのプロジェクトはい(コミット可能).claude/settings.local.json1 つのプロジェクトいいえhooks/hooks.jsonプラグインが有効な間はい異なるファイルの hook は置き換えられるのではなく、すべて合算されます。Claude Code で /hooks と入力すると、有効なすべての hook とその定義元を確認できます。
対話セッションでは、フォルダーのワークスペース信頼ダイアログを承認するまで、Claude Code は自分で定義したものも含めて hook を実行しません。
03ハンドラーの種類
ほとんどの hook は、シェルコマンドを実行する "type": "command" です。ほかに 4 種類あります。
http:イベントの JSON を URL に POST し、レスポンスボディを読み取ります。mcp_tool:設定済みの MCP サーバーのツールを呼び出します。prompt:Claude モデルにシングルターンで問い合わせ、JSON 形式の判定を読み取ります。agent:判定前にファイルを読み込めるサブエージェントを起動します(実験的機能)。
command hook はユーザーの権限をすべて持った状態で実行されます。macOS と Linux では sh -c、Windows では Git Bash(または PowerShell)を介して実行されます。"async": true を追加するとバックグラウンドで実行されますが、その場合は判定を返せなくなります。
04matcher
matcher は、イベントのどの発生時に hook を実行するかを決めます。照合対象はイベントによって異なり、ツールイベントではツール名、Notification では通知の種類、SessionStart ではセッションの開始方法などになります。
"*"、""、または matcher の省略は、すべてにマッチします。- 英字、数字、
_、-、スペース、|、,だけで構成される場合は完全一致の名前として扱われます。Edit|Writeはどちらのツールにもマッチします。 - それ以外は JavaScript の正規表現として扱われるため、
mcp__memory__.*は 1 つの MCP サーバーのすべてのツールにマッチします。
matcher は大文字と小文字を区別します。Stop や UserPromptSubmit など、一部のイベントは matcher を無視します。ツールイベントでは、"Bash(git *)" のような権限ルールを if フィールドに指定すると、個々のハンドラーをさらに絞り込めます。
05入力:hook が受け取るデータ
すべての hook は stdin で JSON を受け取ります。session_id、transcript_path、cwd、hook_event_name などの共通フィールドに加え、イベント固有のフィールドが含まれます。たとえば Bash 呼び出しに対する PreToolUse hook では、tool_name と tool_input.command も渡されます。jq などの JSON パーサーで読み取れます。
#!/bin/bash
input=$(cat)
cmd=$(jq -r '.tool_input.command // empty' <<<"$input")
echo "Claude wants to run: $cmd" >> ~/claude-commands.log
exit 0
06出力:終了コードと JSON
hook から Claude Code へ結果を返す方法は 2 つあります。
終了コード 0 は成功です。2 はブロッキングエラーで、ブロック可能なイベントではアクションが中止され、stderr の内容がその理由として扱われます。それ以外のコード(よく使われる 1 も含む)は非ブロッキングエラーとなり、アクションはそのまま実行され、hook エラーの通知が表示されます。hook でルールを強制したい場合は、1 ではなく 2 で終了してください。
stdout への JSON 出力 より細かく制御したい場合は、0 で終了し、JSON オブジェクトを 1 つ出力します。Claude を完全に停止する continue: false のように、どのイベントでも使えるフィールドもあります。一方、イベントごとに異なるフィールドもあり、Stop では decision: "block" と reason を使い、PreToolUse と PermissionRequest では hookSpecificOutput の中に判定を入れます。stdout にはそれ以外を出力しないでください。シェルプロファイルから余計な行が 1 行でも出力されると、Claude Code は JSON を読み取れなくなります。
07すべての hook イベント
SessionStartセッションの開始または再開時不可(コンテキストを追加)Setup--init-only で起動したとき、または -p と併せて --init / --maintenance で起動したときいいえInstructionsLoadedCLAUDE.md または .claude/rules/*.md ファイルの読み込み時いいえUserPromptSubmitprompt を送信した後、Claude がそれを受け取る前はいUserPromptExpansion入力したコマンドが prompt に展開されるときはいPreToolUseツール呼び出しの前はいPermissionRequestツール呼び出しに権限の判断が必要なときJSON で許可または拒否PermissionDeniedauto モードがツール呼び出しを拒否したときいいえPostToolUseツール呼び出しの成功後不可(ツールは実行済み)PostToolUseFailureツール呼び出しの失敗後いいえPostToolBatch並列ツール呼び出しのバッチ完了後、次のモデル呼び出しの前はいNotificationClaude Code が通知を送るときいいえMessageDisplayClaude の返答テキストの表示中不可(表示内容は変更可能)SubagentStart / SubagentStopサブエージェントの開始時または終了時SubagentStop のみTaskCreated / TaskCompletedタスクの作成時または完了時はいStopClaude が応答を終えたとき可(Claude に処理を続行させる)StopFailureターンが API エラーで終了したときいいえTeammateIdleエージェントチームのメンバーがアイドル状態になる直前はいConfigChangeセッション中に設定ファイルが変更されたときはいCwdChanged作業ディレクトリが変更されたときいいえDirectoryAdded/add-dir でディレクトリが追加されたときいいえFileChanged監視対象のファイルがディスク上で変更されたときいいえWorktreeCreate / WorktreeRemoveworktree の作成時または削除時はいPreCompact / PostCompactコンテキスト圧縮の前後PreCompact のみPreModelSwitch / PostModelSwitchモデルの切り替え前後PreModelSwitch のみElicitation / ElicitationResultMCP サーバーが入力を求めたとき、およびそれに回答した後はいSessionEndセッションが終了したときいいえAnthropic はイベントを随時追加しているため、最新の一覧や各イベントの入力フィールドはhooks リファレンスで確認してください。
08通知に関係するイベント
通知してほしい場面のほとんどは、次の 4 つのイベントでカバーできます。
Stop:「Claude の処理が完了した」ことを知らせます。Stop hook ガイドを参照してください。Notification:「Claude が入力を待っている」ことを知らせます。permission_promptやidle_promptなどの種類があります。Notification hook ガイドを参照してください。PermissionRequest:許可が必要になった瞬間に通知を受けたり、その場で応答したりできます。PermissionRequest ガイドを参照してください。AskUserQuestionツールに対するPreToolUse:Claude の選択式の質問を確認したり回答したりできます。スマートフォンから質問に回答する方法を参照してください。
そのまま貼り付けて使えるデスクトップ向けの設定は、Claude Code の完了時に通知を受け取る方法から始めてください。
09Claude Code Notifier の位置づけ
Claude Code Notifier は、すべてこれらの hook の上に構築されています。無料のコマンドラインツール ccn は Mac、Windows、Linux で動作します。インストールすると ~/.claude/settings.json に 7 つの hook エントリ(いずれも ccn hook を実行)が追加され、元のファイルのバックアップが一度だけ作成されます。ccn はイベントごとに数ミリ秒だけ実行されてすぐに終了するため、常駐するプロセスはありません。
単体ではデスクトップ通知を表示します。iPhone または Android アプリとペアリングすると、同じ hook を通じて回答を送り返せます。許可の承認・拒否、質問への回答、Claude が止まった後の次の指示の送信などが可能です。本ツールは独立したプロダクトであり、Anthropic が提供しているものではありません。ログや lint だけが目的なら、自分で数行書くほうがシンプルです。詳しくはccn のページをご覧ください。
10よくある質問
Claude を待たずに hook をテストするには?
サンプルの JSON をスクリプトにパイプで渡し、終了コードを確認します:echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh; echo $?。その後、Claude Code で /hooks を実行し、正しいイベントに登録されているか確認してください。
hook が実行されないのはなぜですか?
よくある原因は、settings.json の JSON が不正(末尾のカンマやコメント)、matcher が完全に一致していない(大文字・小文字を区別します)、スクリプトに実行権限がない、フォルダをまだ信頼済みにしていない、などです。claude --debug で Claude Code を起動し、デバッグログで何が実行されたか確認してください。詳しい一覧はトラブルシューティングのチェックリストにあります。
すべての hook を一時的に無効にするには?
設定ファイルで "disableAllHooks": true を設定します。1 回の実行だけスキップしたい場合は、--settings '{"disableAllHooks": true}' を付けて Claude Code を起動してください。特定の hook だけを無効にするスイッチはないため、その場合はエントリを削除します。なお、どちらの方法でも組織の managed settings で設定された hook は無効にできません。
hook のデフォルトのタイムアウトは?
command、HTTP、MCP ツールの hook は 10 分(600 秒)、prompt hook は 30 秒、agent hook は 60 秒です。一部のイベントではより短いデフォルト値が使われます。どのハンドラーでも timeout を秒単位で指定できます。