Claude Code Hooks完全ガイド — 9種類のHookと用途別の使い分け早見表
Claude Code Hooksは、ツール実行・セッション開始終了・ユーザー入力・通知などのイベントに任意のbashコマンドを差し込む仕組みです。9種類の発火タイミング、設定ファイルの構造、用途別使い分け、よくあるつまずきまでを完全網羅します。
Claude Code Hooksは、ツール実行・セッション開始終了・ユーザー入力・通知などのイベントに任意のbashコマンドを差し込む仕組みです。手作業で繰り返している「保存後の整形」「危険コマンドの遮断」「完了通知」をClaude Codeの動作と一体化させて自動化できます。
本記事では9種類のHook全種類、settings.json の構造、用途別の使い分け、よくあるつまずきと回避策までを完全網羅します。具体的なレシピ例はClaude Code Hooks実例カタログで扱っているので、本記事は「全体像 + 仕様 + 設計判断」に集中します。
Claude Code Hooksとは
- Claude Codeが起動するイベントに合わせ、ユーザーが定義したbashコマンドを実行する仕組み
- 設定ファイル
~/.claude/settings.json(ユーザーグローバル)または<project>/.claude/settings.json(プロジェクト固有)に登録する - イベントJSONが標準入力(stdin)で渡されるので、
jqで必要な値を取り出して任意の処理を行う - exit code 0で許可、非ゼロで処理停止 / ブロックの動作を制御できるHookがある(
PreToolUse等) - 自動テスト・自動整形・危険操作の遮断・完了通知・ログ収集など、運用面の摩擦を消す用途で広く使われる
入門の最初の一歩はClaude Code Hooks入門 — 最初のHookを5ステップで動かすを参照してください。本記事は「全体像を一覧で把握し、自分の用途にどのHookを選べばよいかを判断する」段階に来た方を対象としています。
9種類のHook一覧と発火タイミング
Claude Codeが現時点でサポートするHookは次の9種類です。設定ファイルの hooks.<event 名> キーに配列で登録します。
| Event名 | 発火タイミング | 主な用途 | 標準入力JSONの主要キー |
|---|---|---|---|
PreToolUse | ツール呼び出しの直前 | 危険コマンドの遮断、許可確認、ログ | tool_name / tool_input |
PostToolUse | ツール呼び出しの直後 | フォーマッタ実行、テスト、正規化 | tool_name / tool_input / tool_response |
UserPromptSubmit | ユーザーがプロンプトを送信した時 | プロンプトの記録、入力バリデーション | prompt |
SessionStart | Claude Codeセッションを開始した時 | 環境変数の読込、初期化、コンテキスト注入 | session_id / cwd |
SessionEnd | セッションを正常終了した時 | サマリ書き出し、計測の終端処理 | session_id |
Stop | メインエージェントが停止した時 | 完了通知、結果ログの保存 | session_id |
SubagentStop | サブエージェントが停止した時 | サブエージェント完了通知、結果集約 | session_id / agent_name |
Notification | ClaudeがOS通知を発火した時 | OS通知の再発火、Slack連携 | notification_type / message |
PreCompact | コンテキスト圧縮の直前 | スナップショット保存、圧縮前の重要情報の退避 | session_id |
これら9種類は「ツール実行系」「セッションライフサイクル系」「ユーザー入力系」「通知系」の4グループに整理できます。次の節で用途別の使い分けを見ていきます。
どのHookを選ぶか — 用途別使い分け早見表
実運用で「この用途にはHookを使うべきか、使うなら何を選ぶか」の判断を素早く下せるよう、よくある運用ニーズと推奨Hookの対応をまとめます。
| 運用ニーズ | 推奨Hook | 設計の要点 |
|---|---|---|
| ファイル保存後に自動整形(Prettier / Biome / Ruff等) | PostToolUse(matcher: Edit|Write) | tool_response.file_path を jq で取得し、ファイル種別に応じて整形コマンドを呼び分ける |
| 危険コマンド(rm -rf等)の遮断 | PreToolUse(matcher: Bash) | tool_input.command を grep でチェックし、危険パターンに一致したらexit 2で停止 |
| Secretsを含むファイルへの書き込みを遮断 | PreToolUse(matcher: Write|Edit) | tool_input.file_path が .env* / *credentials* のときexit 2 |
| ユーザー指示の履歴ロギング | UserPromptSubmit | prompt をJSONLでファイルにappendする単純な構造で十分 |
| セッション開始時にプロジェクト固有の環境変数を注入 | SessionStart | ~/.claude/env-project-*.sh を切替でsource、cwd で判別 |
| 長時間タスク完了のOS通知 / Slack連携 | Stop または Notification | notification_type === "task_complete" を見て発火、terminal-notifier / Slack Webhookを叩く |
| サブエージェント完了結果の集約 | SubagentStop | agent_name で振り分け、結果JSONLを集約用ディレクトリに保存 |
| コンテキスト圧縮前の重要メモ退避 | PreCompact | 圧縮で消えると困る決定事項を .claude/snapshots/ に書き出す |
| 自動テスト実行(編集後に該当ファイルのテストだけ走らせる) | PostToolUse(matcher: Edit|Write) | tool_response.file_path からjest / pytestの対象ファイルを推測し、--findRelatedTests 等を起動 |
| Push前の差分チェック / lint | PreToolUse(matcher: Bash、commandが git push を含む時) | matcherで Bash を選び、tool_input.command をgrepして条件hitしたときだけ走らせる |
選び方の原則は次のとおりです。
- 読みたいだけなら
Post*系を選ぶ:PostToolUse/Stop/SubagentStop/SessionEndは処理結果を観察して副作用(整形、通知、ログ)を起こす用途 - 止めたいなら
Pre*系を選ぶ:PreToolUse/UserPromptSubmit/PreCompactはexit 2で「やらせない」判断ができる用途 BashmatcherとEdit|Writematcherを使い分ける:Bashは「コマンド文字列を見て判断」、Edit/Writeは「ファイルパスを見て判断」が基本
設定ファイルの構造
Hooksは次のような構造で登録します。settings.json のスキーマはClaude Code設定ファイル完全ガイドで扱っているので、本記事はHooksに絞ります。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_response.file_path' | xargs -I{} echo \"edited: {}\" >> ~/.claude/edit.log"
}
]
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -qE '(^|;|&&|\\|\\|)\\s*rm\\s+-rf\\s+/' && echo 'blocked: rm -rf /' >&2 && exit 2 || exit 0"
}
]
}
]
}
}主要キーの意味:
| キー | 役割 |
|---|---|
hooks.<event 名> | Event名(PreToolUse 等)別の配列。複数登録すれば全て直列実行される |
matcher | eventの対象を絞る正規表現。PreToolUse / PostToolUse は tool_name に対するマッチ |
hooks[].type | 現状は "command" のみ。将来別タイプが増える可能性に備えたフィールド |
hooks[].command | 実行するbash文字列。stdinでevent JSONが渡される |
exit codeの意味もEvent別に異なります。
| Event | exit 0 | exit 1 | exit 2 |
|---|---|---|---|
PreToolUse | 許可 | 警告(stderr表示) | ブロック(ツール実行を停止) |
PostToolUse | 続行 | 警告 | 続行(ブロック効果なし、Postなので) |
UserPromptSubmit | 許可 | 警告 | プロンプト送信を停止 |
Stop / SubagentStop | 終了続行 | 警告 | 続行(ブロック効果なし) |
Notification | 続行 | 警告 | 続行 |
SessionStart / SessionEnd / PreCompact | 続行 | 警告 | 続行 |
「止める」効果があるのは実質的に PreToolUse と UserPromptSubmit の2種だけです。これは設計判断として重要で、観察 / 副作用と「拒否」を仕組みで区別している姿勢が見えます。
各Hookの実用例(深掘り誘導)
具体的な設定例9件はClaude Code Hooks実例カタログで扱っています。本記事の早見表から自分の用途を絞り込み、対応するレシピをそちらで参照してください。代表例を3つだけ抜粋して紹介します。
例1:PostToolUseでMarkdown保存後に日本語スペースを自動正規化
本サイト(Claude Media)が実運用しているレシピです。media/content/*.mdx を編集した直後に normalize-ja-spaces.ts を走らせ、日本語と英数字の間のスペースを除去します。執筆者(人間 / Claude Code)が意識しなくてもCIで落ちない状態が自動で保たれます。
例2:PreToolUseで .env への書き込みを遮断
tool_input.file_path が .env / .env.local / credentials.json 等のパターンに一致したらexit 2でブロックします。Secretsを誤ってコミットする事故を構造的に防げます。
例3:Stopで長時間タスクの完了通知
Stop eventを契機に terminal-notifier(macOS)やSlack Webhookを叩き、長時間タスクが終わった瞬間を見逃さないようにします。複数ターミナルで並列にClaude Codeを動かしている運用では効果が大きくなります。
よくあるつまずきと回避策
Hooksの運用で実際に踏みやすい落とし穴を7つ集めました。
つまずき1:matcher の正規表現がtool_nameと完全一致しないと発火しない
PreToolUse / PostToolUse の matcher は tool_name に対する正規表現マッチです。Edit ではなく EditFile のようにtool名を誤記すると静かにスキップされます。発火しないときはまず matcher: ""(空)で受けて、stdinの tool_name を確認するのが定石です。
つまずき2:commandの中で \ のエスケープが効かずJSON構文が壊れる
settings.json はJSONなので、bashの \$ や \\ のエスケープをJSONのエスケープと混同しがちです。複雑なcommandは別ファイルにシェルスクリプトとして書き、command: "bash ~/.claude/hooks/pretooluse-guard.sh" のように呼び出す構成にすると保守しやすくなります。
つまずき3:exit 2でブロックしたつもりが、Post系では効かない
PostToolUse でexit 2を返してもツールの実行自体は既に終わっているため、止める効果はありません。「やらせない」のは PreToolUse / UserPromptSubmit のみと覚えるのが安全です。
つまずき4:stdinのJSON構造がeventごとに違う
tool_input / tool_response / prompt / notification_type など、eventごとにstdinのJSON構造は異なります。実装前に command: "tee /tmp/hook-debug.json >/dev/null" のようなpeek用hookを一時的に登録して構造を確認するのが近道です。
つまずき5:hookのcommandが非同期で走らない
各hookは直列実行で完了を待つので、長時間処理(数十秒のlintやtest)をhook内に書くとClaude Codeの体感応答が悪化します。短時間で済む処理に限定するか、nohup ... & でバックグラウンド化して即exit 0を返す設計にします。
つまずき6:~/.claude/settings.json とプロジェクト .claude/settings.json の優先順位
プロジェクト固有設定はユーザーグローバル設定に加算(マージ)されます。同じEventを両方で登録すると両方とも実行されます。意図せず2重実行されないよう、用途別に「グローバル」「プロジェクト」のどちらに置くかを決めておきます。
つまずき7:Bash matcherでgit commitを遮断したら、Claude Codeが動けなくなる
PreToolUse matcher: Bash で git commit を含むcommandをブロックすると、レビュー用のcommitすら止まります。意図と違う遮断にならないよう、grep -E '\\s+git\\s+push\\s+' のようにpushのみに限定するなど、特定のリスク行動に絞った正規表現を使います。
まとめ
Claude Code Hooksは「観察」「副作用」「拒否」の3機能を9種類のイベントに分散させた仕組みです。用途に合ったHookを選ぶ判断軸は次のとおりです。
- 観察 / 副作用なら
Post*系 +Stop/SubagentStop/Notification - 拒否 / 入力チェックなら
Pre*系 +UserPromptSubmit - セッション境界の処理なら
SessionStart/SessionEnd/PreCompact
実運用に乗せる前に、本記事の早見表で「自分の用途にどのHookが向くか」を確定し、具体的なコード例はClaude Code Hooks実例カタログでコピペ可能なレシピを参照してください。設定ファイル全体の構造はClaude Code設定ファイル完全ガイドを、サブエージェントとの連携はClaude Code Sub-agent完全ガイドを併せてご覧ください。
Hooksは導入難度が低く、効果が運用全体に長く効く投資対効果の良い領域です。最初の1個から組み始め、運用の摩擦を消すたびにレシピを増やしていく形が安定して続けやすいでしょう。
関連する記事
Claude Code をもっと見る →Claude Code設定ファイル完全ガイド — settings.jsonの全項目とpermissions設計
Claude Code Hooks実例カタログ — 9つのユースケース別レシピと避けたい落とし穴
Claude Code設定ガイド — settings.jsonの主要フィールド・環境変数・実戦レシピ
Claude Code MCPサーバー完全ガイド — 自作手順から人気サーバーまで網羅
Claude Codeの/goalコマンド — 完了条件を渡して目標達成まで自走させる仕組み
Claude Codeのメモリ三層構造 — CLAUDE.md/Settings/Skillsの使い分け
Claude Codeとは — Anthropicのエージェント型AIコーディングCLI完全ガイド
Claude Code Hooksの設定方法 — 初めて書く人の完全手順