Claude Codeのhooksは、種類を把握しないまま書くと「効かせたつもりが効いていない」事故につながります。hooksは自動化4層の1つで、全体像は『AIエージェントの自動化|hooks・定期実行・常駐の役割分担』で扱いました。本記事は公式ドキュメントの全30種類を発火タイミングで整理し、逆引きする判断基準を示します。個別実装は別記事へ送り、一覧と選び方に絞ります。

検証環境:claude-opus-5 / Claude Code v2.1.x / macOS 15 / 2026-07-29検証。

01結論:Claude Codeのhooksは30種類|まず「発火条件」で絞り込む

結論は3点です。

  1. hooksは常駐しません。対応するイベントが起きるまで、スクリプトは1行も動きません。
  2. 本記事では30種類を5グループへ整理します(グループ名は次章の一覧表で示します。この分類は本記事の独自編集です。公式ドキュメントはイベントを「セッションに1回」「ターンに1回」「ツール呼び出しごと」という3つの発火頻度でしか説明していません)。
  3. 選ぶ基準は「いつ発火するか」と「実行や継続をブロックできるか」の2軸です。外すと発火しない・止められないhooksを作ります。

危険コマンドの遮断は『Claude CodeのPreToolUseフック|危険コマンド遮断のコード例』にコードつきでまとめています。

02Claude Code hooksの全イベント一覧|30種を5グループで見る

Claude Code公式ドキュメントの「Hook lifecycle」表を数えると、hooksイベントは30種類です(2026-07-29に公式ドキュメントを取得して実数を確認)。

Claude Code hooksの発火順、30種を1本の時間軸に配置した俯瞰図 Claude Codeの1セッションを貫く時間軸に沿って、Setup、SessionStart、UserPromptSubmit、PreToolUse、PostToolUse/Failure、PostToolBatch、Stop、SessionEndの8段が交互に並ぶ。上にはサブエージェントの並走、下にはPreCompact等の割り込みが破線で添えられ、本線から外れた発火があることを示す。30種のイベントのうち17種はブロック可能、13種は不可であることもあわせて示す。 TIMELINE Claude Code hooks 30種、発火順の全体像 時間の経過 Setup UserPromptSubmit PostToolUse/Failure Stop SessionStart PreToolUse PostToolBatch SessionEnd サブエージェント並走 割り込み:PreCompact等 30 種類のイベント 30種中17種はブロック可能・13種は不可。発火順とブロック可否の2軸で選ぶ。
Claude Codeの1セッションを貫く時間軸に30種のhooksを発火順で並べた俯瞰図
グループイベント名発火タイミングブロック可否
セッションの生死・環境Setup--init-only起動時、または-p --init/--maintenance時に1回不可(context注入のみ)
セッションの生死・環境SessionStartセッション開始・--resume/--continue/clear後・compaction後・fork後不可(additionalContextinitialUserMessagewatchPathssessionTitlereloadSkillsの5フィールドのみ返せる)
セッションの生死・環境SessionEndセッション終了時不可(後始末専用・1.5秒の共有予算)
セッションの生死・環境PreCompactコンテキスト圧縮の直前可(decision: blockで圧縮を止める)
セッションの生死・環境PostCompactコンテキスト圧縮の完了後不可(ログ用途)
セッションの生死・環境ConfigChange設定ファイル変更を検知した時可(policy_settings以外は変更を止められる)
セッションの生死・環境CwdChanged作業ディレクトリが変わった時(cd実行等)不可(環境連携の副作用専用)
セッションの生死・環境InstructionsLoadedCLAUDE.mdや.claude/rules/*.mdが読み込まれた時不可(ログ用途)
セッションの生死・環境FileChanged監視対象ファイルがディスク上で変化した時不可(副作用専用)
セッションの生死・環境WorktreeCreateworktreeが作成される時実質可(0以外の終了コードで作成が失敗する)
セッションの生死・環境WorktreeRemoveworktreeが削除される時不可(後始末専用)
プロンプト処理・応答終了UserPromptSubmitユーザーがプロンプトを送信し、処理される直前可(decision: blockで送信自体を消せる)
プロンプト処理・応答終了UserPromptExpansionコマンドやスキルがプロンプトへ展開される時可(decision: blockで展開を止める)
プロンプト処理・応答終了StopClaudeが応答を終える時可(decision: blockで終了させず継続させる)
プロンプト処理・応答終了StopFailureAPI側エラーでターンが終わった時不可(ログ・後始末専用)
ツール実行PreToolUseツール呼び出しの直前可(permissionDecision: allow/deny/ask/defer)
ツール実行PermissionRequestツール呼び出しに許可判定が要る時可(decision.behavior: allow/deny)
ツール実行PermissionDenied自動モードの分類器が拒否した直後不可(retry指示のみ・exit codeとstderrは無視)
ツール実行PostToolUseツール呼び出しが成功した後可(decision: blockまたはupdatedToolOutputで結果を書き換え)
ツール実行PostToolUseFailureツール呼び出しが失敗した後可(decision: blockで後続を止める)
ツール実行PostToolBatch並列ツール呼び出しが全解決後、次のモデル呼び出し前可(decision: blockでループを止める)
サブエージェント・タスクSubagentStartサブエージェントが生成された時不可(context注入のみ)
サブエージェント・タスクSubagentStopサブエージェントが完了した時可(decision: blockで完了させず継続させる)
サブエージェント・タスクTaskCreatedタスクが作成された時可(continue: falseまたはexit code 2で作成を巻き戻す)
サブエージェント・タスクTaskCompletedタスクが完了扱いになった時可(continue: falseまたはexit code 2で完了を止める)
サブエージェント・タスクTeammateIdleエージェントチームの一員がアイドルになる直前可(アイドル化・継続そのものも止められる)
通知・MCP連携NotificationClaude Codeが通知を送る時不可(副作用専用)
通知・MCP連携MessageDisplayアシスタントのメッセージ文が画面表示されている間不可(画面表示のみdisplayContentで差し替え可)
通知・MCP連携ElicitationMCPサーバーが入力を要求した時可(action: accept/decline/cancel)
通知・MCP連携ElicitationResultユーザー応答をMCPサーバーへ返す直前可(action: accept/decline/cancelで応答を差し替え)

30種類のうち、ブロック可否が「可」なのは17種類、「不可」は13種類です(2026-07-29実測)。「不可」の多くはヒント注入かログ・副作用専用の設計です。

30種類を全部使う必要はありません。取り消せない操作に近いイベント(PreToolUse・SessionStart等)から優先登録し、観測用途は後回しにする優先順位づけが実務で機能します。

03hooksでツール実行を制御する|PreToolUse・PermissionRequest・PostToolUseの境界

ツール実行グループの6種類は名前が似て混同しやすい領域です。判断軸は「呼び出しの前か後か」と「誰の判断を経由するか」です。

PreToolUseはツール実行の直前に発火しpermissionDecisionallowdenyaskdeferで返します。deferは「判断しない」の意味で通常の権限フロー(permissions設定やユーザー確認)に処理を戻すだけで、自律度を下げる値ではありません。

PermissionRequestはPreToolUseとは別の入り口です。許可判定が要る局面で発火し、hookSpecificOutput.decision.behaviorallowdenyを返します。

{
  "hookSpecificOutput": {
    "hookEventName": "PermissionRequest",
    "decision": {
      "behavior": "deny",
      "updatedInput": {}
    }
  }
}

PermissionDeniedは自動モードの分類器が拒否した直後に発火します。exit codestderrは無視され、retryフィールドだけが意味を持ちます(出典: Claude Code公式ドキュメント)。

PostToolUse・PostToolUseFailure・PostToolBatchは実行後の3種です。成功時はPostToolUse、失敗時はPostToolUseFailure、並列ツール群の全解決後・次呼び出し直前はPostToolBatchが発火します。PostToolUseはupdatedToolOutputで結果を書き換えられ、機密マスキングや要約に向きます。

04hooksでセッションと環境を制御する|SessionStart・ConfigChange・FileChangedの境界

セッションの生死・環境グループの11種類は「開始・終了」と「セッション中の環境変化の検知」の2層に分かれます。

SessionStartはsourceフィールド(startupresumeclearcompactforkの5パターン)で発火元を区別できます。返せるフィールドは5つです。

  • additionalContext:文脈を注入
  • initialUserMessage:最初のプロンプトを設定
  • watchPaths:監視対象ファイルを指定
  • sessionTitle:セッション名を設定
  • reloadSkills:スキルを再読み込み
{
  "hookSpecificOutput": {
    "hookEventName": "SessionStart",
    "additionalContext": "必読ルールの要約テキスト",
    "reloadSkills": true
  }
}

起動のたびに必読ルールを自動で読み込ませる実装は、専用の手順記事で扱う予定です。本記事ではSessionStartが「ブロックできない・文脈注入専用」という一点を押さえてください。

ConfigChange・CwdChanged・InstructionsLoaded・FileChangedはセッション外側の変化検知層です。唯一ブロック可能なConfigChangeはdecision: blockで止まり(policy_settings除く)、残り3種は環境同期・ログ用途です。

05どのhooksイベントを使うか|やりたいことから逆引きする判断基準

「何をしたいか」から使うイベントを引く表です。

やりたいこと使うイベント判定の返し方
危険な操作を実行前に止めたいPreToolUsepermissionDecision: "deny"
起動時に必読ルールを注入したいSessionStartadditionalContext
実行結果を書き換えたい(マスキング等)PostToolUseupdatedToolOutput
応答を終える前にもう1周させたいStopdecision: "block"
設定ファイルの変更を検知して止めたいConfigChangedecision: "block"(policy_settings除く)
.envのようなファイルの変化だけ監視したいFileChangedmatcherにファイル名を列挙(副作用専用)
サブエージェント完了時に集計処理を挟みたいSubagentStopdecision: "block"またはadditionalContext
MCPからの入力要求に自動で応答したいElicitationaction: "accept"/"decline"/"cancel"
『何をしたいか』からhooksイベントを選ぶ4段の判定フロー やりたいことからhooksイベントを選ぶ判定フローの図。①実行前に止めたいかがYesならPreToolUseかPermissionRequestへ進み、つまずきは気づきにくさ。②開始時に文脈注入したいかがYesならSessionStartへ進み、つまずきは効かないこと。③結果を書き換えたいかがYesなら成功時はPostToolUse、失敗時はPostToolUseFailureへ進み、つまずきは効きすぎること。④観測だけでよいかがYesならConfigChange等へ進み、つまずきは気づけないこと。すべてNoなら一覧表で個別に確認する。 DECISION 『何をしたいか』からイベントを逆引きする判定フロー ①取り消せない操作を実行前に止めたいか ②セッション開始時に文脈注入したいか ③結果や応答を書き換えたいか ④観測だけでよいか いいえ→次の問いへ 無ければ一覧表で個別確認 はい PreToolUse /PermissionRequest つまずき:気づきにくい はい SessionStart つまずき:効かない(ブロック不可) はい PostToolUse/Failure つまずき:効きすぎる(誤爆) はい ConfigChange等(観測専用) つまずき:気づけない 4問はすべて「前か後か」と「誰の判断を経由するか」で分かれる。
「何をしたいか」からhooksイベントへ逆引きする判定フロー図

判断に迷う場合は、上から順に「取り消せない操作か」「ブロックしたいか」「観測だけでよいか」の3問を自分に投げてください。

06hooksの設定方法と入出力の共通スキーマ|settings.jsonへの登録

hooksを書ける場所は6箇所あります(出典: Claude Code公式ドキュメント)。

置き場所有効範囲共有可否
~/.claude/settings.json全プロジェクト不可(個人設定)
.claude/settings.json単一プロジェクト可(Gitでコミット)
.claude/settings.local.json単一プロジェクト不可(gitignore対象)
Managed policy settings組織全体可(管理者のみ変更)
プラグインのhooks/hooks.jsonプラグイン有効時可(同梱配布)
スキル・エージェントのfrontmatter動作中のみ可(ファイル内に記述)
同じhookイベントを複数の置き場所に重複登録すると何が起こるか hookイベントを登録できる6つの置き場所(User設定・Project設定・Local設定・Managed・Plugin配布・Skill/Agent)から、同じイベントが重複登録された時の挙動を示す図。コマンドとargsが完全一致していれば重複排除されて1回だけ実行され、一致しなければ全て並列実行される。あわせてallowManagedHooksOnlyが有効な時はManaged以外の5箇所のhookが無効化され発火しなくなることも示す。 BRANCH 同じhookが複数箇所に重複登録された時の挙動 置き場所(6箇所) User設定 Project設定 Local設定 Managed(組織) Plugin配布 Skill/Agent コマンド+argsが完全一致か? はい 重複排除 1回だけ実行 いいえ 全て並列実行 (重複起動に注意) allowManagedHooksOnly有効時→ Managed以外の5箇所は無効化(発火しない) 6箇所に置けても、動くかは「コマンド+argsの完全一致」の1点で決まる。
同じhookイベントが複数の置き場所(User/Project/Local/Managed等6箇所)に重複登録された時の挙動を示す図

チーム共有hooksは.claude/settings.jsonに書いてGitで共有し、個人の一時的な上書きはLocalへ置きます。permissionsのallow・ask・denyとhooksの配分は『Claude Codeの権限設定|allow・ask・denyの配分と設定例』で扱っています。

matcherの書き方は3パターンです(出典: Claude Code公式ドキュメント)。*・空文字・省略は全件一致、英数字・_-・空白・,|だけの文字列は完全一致かリスト指定です。ハイフンが完全一致に含まれるのはv2.1.195以降のみで、それ以前はcode-reviewerも正規表現扱いとなりsenior-code-reviewerに誤爆します。それ以外を含むと正規表現評価です(例:Bash=完全一致/Edit|Write=リスト/mcp__memory__.*=正規表現)。

FileChangedとStopFailureは例外です。英数字・_|のみが完全一致となり、ハイフン・空白・カンマを含めると他のイベントより先に正規表現として評価されます。

hookの実行方式(type)は5種類です(出典: Claude Code公式ドキュメント)。シェルコマンドcommand・URLへPOSTするhttp・MCPツールを呼ぶmcp_toolが基本です。モデルにYes/No判定させるprompt・検証用サブエージェントのagentが加わります。デフォルトタイムアウトはcommandhttpmcp_toolが600秒、promptが30秒、agentが60秒です。

全イベントの入力フィールドはsession_idtranscript_pathcwdhook_event_namepermission_modeです。サブエージェント内ではagent_idagent_typeも加わります。

{
  "session_id": "abc123",
  "transcript_path": "/path/to/transcript.jsonl",
  "cwd": "/current/working/directory",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse"
}

出力側の共通フィールドはcontinuestopReasonsuppressOutputsystemMessageです。固有判定はhookSpecificOutput内に書きます。

07hooksでつまずきやすい点|設定と実装がずれる3つの落とし穴

落とし穴1:matcherに*を書いて、意図せず正規表現になる。 *は完全一致の文字集合に含まれず、Bash*は「直前の文字の0回以上の繰り返し」を意味する正規表現になり、想定と違う一致を生みます。

落とし穴2:SessionEndの合計予算1.5秒を知らずに重い処理を書く。 SessionEndは複数登録しても合計1.5秒の共有予算しかありません(出典: Claude Code公式ドキュメント)。timeout指定で最大60秒まで延びますが、既定値のままログ送信やAPI呼び出しを書くと打ち切られます。

落とし穴3:PermissionDeniedをPreToolUseと同じ感覚で実装する。 exit code 2はPreToolUseで効きますが、PermissionDeniedでは無視され、読むのはretryフィールドだけです。

matcherとtypeの挙動はイベントをまたいで統一されていません。公式ドキュメントを都度確認し、類推で実装しないことが要です。

08hooksを整えるチェックリスト

  • 実行前に止めたい操作をPreToolUseのdeny対象として洗い出したか
  • 使うイベントを「発火タイミング」と「ブロックできるか」の2軸で選んだか
  • matcherに*など正規表現化する文字を意図せず混ぜていないか
  • settings.jsonのどの置き場所(User/Project/Local/Managed等)に書くか決めたか
  • 短いデフォルトタイムアウト(UserPromptSubmit 30秒・MessageDisplay 10秒・SessionEnd 1.5秒)を把握したか
  • /hooksコマンドで登録内容を確認したか
  • PreToolUseの詳しい実装は専用記事へ委ね、判断基準だけを使ったか

09FAQ

Claude Code hooksは常駐しているプロセスですか

いいえ。対応するイベントが起きた時だけ新規プロセスとして起動し、判定を返すと終了します。時刻起点の処理は別の層が担当します。

PreToolUseとPermissionRequestは何が違いますか

PreToolUseは呼び出し直前に必ず発火しpermissionDecisionallowdenyaskdeferを返します。PermissionRequestは許可判定が要る局面のみで発火しdecision.behaviorallowdenyだけの狭い入り口です。

hooksのイベント一覧はどこで確認できますか

Claude Codeで/hooksと入力すると、登録済みイベントとmatcherを読み取り専用で一覧できます(出典: Claude Code公式ドキュメント)。設定ファイルは本記事の一覧表を参照してください。

hooksがdeferを返すと何が起きますか

そのフックは判断をせず、通常の権限フロー(permissions設定やユーザー確認)に処理を戻します。exit 0で出力が無い場合と同じ扱いです。

hooksをどのイベントから設定し始めるべきですか

取り消せない操作に近いイベントからです。PreToolUseで危険な操作をdenyにする設計の優先度が最も高いです。