本文へスキップ
Claude Media
Claude Code Hooks完全ガイド — 9種類のHookと用途別の使い分け早見表

Claude Code Hooks完全ガイド — 9種類のHookと用途別の使い分け早見表

Claude Code Hooksは、ツール実行・セッション開始終了・ユーザー入力・通知などのイベントに任意のbashコマンドを差し込む仕組みです。9種類の発火タイミング、設定ファイルの構造、用途別使い分け、よくあるつまずきまでを完全網羅します。

読了目安 約12

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
SessionStartClaude Codeセッションを開始した時環境変数の読込、初期化、コンテキスト注入session_id / cwd
SessionEndセッションを正常終了した時サマリ書き出し、計測の終端処理session_id
Stopメインエージェントが停止した時完了通知、結果ログの保存session_id
SubagentStopサブエージェントが停止した時サブエージェント完了通知、結果集約session_id / agent_name
NotificationClaudeが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_pathjq で取得し、ファイル種別に応じて整形コマンドを呼び分ける
危険コマンド(rm -rf等)の遮断PreToolUse(matcher: Bash)tool_input.commandgrep でチェックし、危険パターンに一致したらexit 2で停止
Secretsを含むファイルへの書き込みを遮断PreToolUse(matcher: Write|Edit)tool_input.file_path.env* / *credentials* のときexit 2
ユーザー指示の履歴ロギングUserPromptSubmitprompt をJSONLでファイルにappendする単純な構造で十分
セッション開始時にプロジェクト固有の環境変数を注入SessionStart~/.claude/env-project-*.sh を切替でsource、cwd で判別
長時間タスク完了のOS通知 / Slack連携Stop または Notificationnotification_type === "task_complete" を見て発火、terminal-notifier / Slack Webhookを叩く
サブエージェント完了結果の集約SubagentStopagent_name で振り分け、結果JSONLを集約用ディレクトリに保存
コンテキスト圧縮前の重要メモ退避PreCompact圧縮で消えると困る決定事項を .claude/snapshots/ に書き出す
自動テスト実行(編集後に該当ファイルのテストだけ走らせる)PostToolUse(matcher: Edit|Write)tool_response.file_path からjest / pytestの対象ファイルを推測し、--findRelatedTests 等を起動
Push前の差分チェック / lintPreToolUse(matcher: Bash、commandが git push を含む時)matcherで Bash を選び、tool_input.command をgrepして条件hitしたときだけ走らせる

選び方の原則は次のとおりです。

  1. 読みたいだけなら Post* 系を選ぶ:PostToolUse / Stop / SubagentStop / SessionEnd は処理結果を観察して副作用(整形、通知、ログ)を起こす用途
  2. 止めたいなら Pre* 系を選ぶ:PreToolUse / UserPromptSubmit / PreCompact はexit 2で「やらせない」判断ができる用途
  3. Bash matcherと Edit|Write matcherを使い分ける: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 等)別の配列。複数登録すれば全て直列実行される
matchereventの対象を絞る正規表現。PreToolUse / PostToolUsetool_name に対するマッチ
hooks[].type現状は "command" のみ。将来別タイプが増える可能性に備えたフィールド
hooks[].command実行するbash文字列。stdinでevent JSONが渡される

exit codeの意味もEvent別に異なります。

Eventexit 0exit 1exit 2
PreToolUse許可警告(stderr表示)ブロック(ツール実行を停止)
PostToolUse続行警告続行(ブロック効果なし、Postなので)
UserPromptSubmit許可警告プロンプト送信を停止
Stop / SubagentStop終了続行警告続行(ブロック効果なし)
Notification続行警告続行
SessionStart / SessionEnd / PreCompact続行警告続行

「止める」効果があるのは実質的に PreToolUseUserPromptSubmit の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 / PostToolUsematchertool_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: Bashgit commit を含むcommandをブロックすると、レビュー用のcommitすら止まります。意図と違う遮断にならないよう、grep -E '\\s+git\\s+push\\s+' のようにpushのみに限定するなど、特定のリスク行動に絞った正規表現を使います。

まとめ

Claude Code Hooksは「観察」「副作用」「拒否」の3機能を9種類のイベントに分散させた仕組みです。用途に合ったHookを選ぶ判断軸は次のとおりです。

  1. 観察 / 副作用なら Post* 系 + Stop / SubagentStop / Notification
  2. 拒否 / 入力チェックなら Pre* 系 + UserPromptSubmit
  3. セッション境界の処理なら SessionStart / SessionEnd / PreCompact

実運用に乗せる前に、本記事の早見表で「自分の用途にどのHookが向くか」を確定し、具体的なコード例はClaude Code Hooks実例カタログでコピペ可能なレシピを参照してください。設定ファイル全体の構造はClaude Code設定ファイル完全ガイドを、サブエージェントとの連携はClaude Code Sub-agent完全ガイドを併せてご覧ください。

Hooksは導入難度が低く、効果が運用全体に長く効く投資対効果の良い領域です。最初の1個から組み始め、運用の摩擦を消すたびにレシピを増やしていく形が安定して続けやすいでしょう。

この記事を共有:XLinkedIn