「編集のたびに自動でフォーマットしたい」「.env や package-lock.json は絶対に書き換えさせたくない」「危険な rm -rf は止めたい」——こうした「必ずこうなってほしい」を、AIの気まぐれに頼らず確実に実現するのが Claude Code hooks(フック)だ。フックは Claude Code のライフサイクルの要所で自動実行されるシェルコマンドで、プラグインの構成要素にもなる。
本記事では、フックとは何か・イベント一覧・設定方法・入出力の契約・使い方・安全性を、公式ドキュメントに基づいて整理する。先に要点を3つ。① フックは「ハーネス(Claude Code 本体)が実行する確定的な処理」——モデルが「やろうと判断する」のを待たずに必ず走る。② settings.json にイベント名→マッチャ→コマンドの形で書く。③ PreToolUse などは終了コード2やJSONで“ブロック”できる——保護ファイル編集や危険コマンドを止められる。
ライフサイクルの要所で“必ず”走る
— モデルの判断ではなく、ハーネスが確定的に実行する
SessionStart
セッション開始。出力をコンテキストに注入
UserPromptSubmit
プロンプト送信時 [ブロック可]
PreToolUse
ツール実行の直前=門番 [ブロック可]
PostToolUse
ツール成功後=自動整形/監査に
Stop
応答終了時=テスト合格まで続行など [ブロック可]
各点で あなたのシェルコマンドが走る。PreToolUse で危険な操作を門前払い、PostToolUse で自動整形——が定番。
1. Claude Code hooks(フック)とは
公式ドキュメントの定義はこうだ:「フックは、Claude Code のライフサイクルの特定の時点で実行される、ユーザー定義のシェルコマンド。Claude Code の振る舞いに対する“確定的な制御”を提供し、特定の動作を(LLMが選ぶのではなく)常に起こるようにする」。プロジェクトのルールを強制したり、繰り返し作業を自動化したり、既存ツールと連携させたりするのに使う。
核心は 「決定論(determinism)」だ。「テストを流して」とお願いしても、モデルが流すかは“判断”次第。だが フックなら、ハーネスが必ず実行する——気まぐれが入らない。現在はコマンド(command)以外に HTTP・MCPツール・LLMプロンプト・サブエージェント検証といった種類も増えているが、まずは 「シェルコマンドを要所で必ず走らせる仕組み」と捉えれば十分だ。
2. フックイベント一覧
イベントは「ライフサイクルのどこで発火するか」を表す。まずは定番の9つを押さえよう(“ブロック可”=終了コード2やJSONでその動作を止められる)。
| イベント | 発火タイミング | ブロック |
|---|---|---|
| SessionStart | セッション開始・再開時(stdout はコンテキストに注入) | 不可 |
| UserPromptSubmit | プロンプト送信時、Claude が処理する前 | 可 |
| PreToolUse | ツール呼び出しの直前(主要な門番) | 可 |
| PostToolUse | ツール成功後(※実行自体は取り消せない) | 可 |
| Notification | 通知(入力/許可待ち等)時 | 不可 |
| Stop | Claude が応答を終えるとき(ブロック=続行) | 可 |
| SubagentStop | サブエージェントが終了したとき | 可 |
| SessionEnd | セッション終了時 | 不可 |
| PreCompact | コンテキスト圧縮の前 | 可 |
2026年の公式ドキュメントでは、これ以外にも PermissionRequest・PostToolUseFailure・ConfigChange・FileChanged・WorktreeCreate など多数のイベントが追加されている。ただしイベント名はバージョンで増減しうるので、本記事では安定している定番9つ+次章の契約を軸にする(最新の全リストは公式で確認を)。
3. 設定方法
フックは settings.json の "hooks" キーに書く。配置場所でスコープが決まる:ユーザー(~/.claude/settings.json)/プロジェクト(.claude/settings.json・git共有可)/ローカル(.claude/settings.local.json)/管理ポリシー(組織)/プラグインの hooks/hooks.json。JSONの形はこうだ。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
構造は 「hooks → イベント名 → { matcher, hooks:[...] } の配列 → 各フックは type+command」。マッチャは対象ツール名を指定し、"*"(または省略)で全一致、"Edit|Write" のように | 区切り、その他の記号は正規表現(例 mcp__memory__.*)。大文字小文字は区別される。なお /hooks コマンドで設定済みフックを一覧できるが 読み取り専用——追加・変更は settings.json を直接編集する。全無効化は "disableAllHooks": true。
4. 入出力の契約
フックは 標準入力(stdin)にJSONを受け取り、終了コードまたは標準出力のJSONで結果を返す。
入力(stdin):session_id・transcript_path・cwd・hook_event_name などが共通。ツール系イベントは tool_name・tool_input(例 {"command":"rm -rf /tmp/build"})、UserPromptSubmit は prompt が加わる。終了コード:0=成功(一部イベントでは stdout がコンテキストに追加される。ただし PreToolUse の0は“承認”ではなく通常の許可フローに従う)、2=ブロック(stderr が Claude に渡され、修正の材料になる。このとき JSON出力は無視される)。
# PreToolUse の構造化JSON出力で「拒否」する例(stdout に出す)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "DBへの書き込みは禁止です"
}
}
# 共通フィールド: continue(false で完全停止) / decision:"block"+reason /
# additionalContext(Claudeへ追記) / updatedInput(引数を書換)
最重要の原則:「フックは制限を“きつく”できるが“緩く”はできない」。allow を返してもプロンプトを省くだけで、どのスコープの deny ルール(管理設定含む)も常に優先される。PreToolUse の deny は bypassPermissions / --dangerously-skip-permissions でもブロックする。権限設計の考え方は 権限モードとセキュリティも参照。
5. 使い方の例
公式が挙げる定番ユースケースを、設定とセットで。
定番の自動化
PostToolUse+Edit|Write で prettier / linter を自動実行。PreToolUse で .env・.git/ 等への編集を exit 2 でブロック。PreToolUse で rm -rf 等を検知し deny を返す。SessionStart の stdout で 規約やメモを毎回読み込ませる(圧縮後も)。Notification でデスクトップ通知、PostToolUse でコマンド履歴を記録。Stop でテストが通るまで止めない(合格まで続行させる)。
補足:Claude は Bash 経由でもファイルを変えられる。全変更を捕捉したいなら、ターン毎に作業ツリーを走査する Stop フックを足す。
6. 安全性
フックは強力だが、あなたの権限で任意のシェルコマンドを自動実行する——ここを軽視してはいけない。
⚠️ 公式の警告
「フックは任意のシェルコマンドを自動実行する。設定したフックの安全性の責任は完全にあなたにある。自己責任で使うこと」。フックはファイル読取・コード改変・データ持ち出し・任意コマンド実行が可能——完全に信頼できるものだけを設定する。
起動時スナップショット(重要な安全機構):フック設定はセッション開始時に固定され、セッション中の設定変更は反映されない。悪意あるプロンプトやツール出力がフック設定を書き換えるのを防ぐためだ。変更は新しいセッションで反映する。
実務上は、入力を必ず検証・クォートする(jq で取り出す/未クォート変数は追加引数やシェル構文になり得る)、絶対パス・${CLAUDE_PROJECT_DIR} を使う、.env・.ssh 等の機微ファイルは触らない、ツール出力を eval しない、が鉄則。フックは制御端末を持たない(/dev/tty 不可)。組織では管理者が allowManagedHooksOnly でフックを制限できる。
まとめ
Claude Code hooks(フック)は、ライフサイクルの要所で自動実行されるユーザー定義のシェルコマンドで、「必ずこうなる」をモデルの判断に頼らず確定的に実現する仕組みだ。定番イベントは SessionStart / UserPromptSubmit / PreToolUse / PostToolUse / Notification / Stop / SubagentStop / SessionEnd / PreCompact の9つ(PreToolUse 等はブロック可=保護ファイルや危険コマンドを止められる)。設定は settings.json の "hooks" に イベント→マッチャ→type+command の形で書く。
入出力は stdin にJSON、終了コード0(成功)/2(ブロック)、または stdout の構造化JSON。原則は 「制限はきつくできるが緩くできない」(deny は常に優先)。定番ユースケースは 自動整形・保護ファイル防御・危険コマンド阻止・コンテキスト再注入・監査・終了前テスト。ただし 任意コード実行ゆえ、信頼できるフックだけ・入力は検証/クォートを徹底し、設定は起動時に固定される点を理解しておく。関連:プラグイン、MCP、Claude Codeエラー集。
FAQ
Q. フックは何のための機能ですか?
A. 「必ずこうしてほしい」を確定的に自動化する機能です。「編集後に整形」「保護ファイルは書き換えさせない」「危険な rm -rf は止める」「終了前にテストを通す」などを、AIの判断に頼らずハーネスが必ず実行します。フックは ライフサイクルの要所で走るシェルコマンドで、settings.json に設定します。
Q. どんなイベント(タイミング)がありますか?
A. 定番は SessionStart(開始)・UserPromptSubmit(送信時)・PreToolUse(ツール直前)・PostToolUse(ツール後)・Notification(通知)・Stop(応答終了)・SubagentStop・SessionEnd(終了)・PreCompact(圧縮前)の9つです。このうち PreToolUse・UserPromptSubmit・Stop・PreCompact 等はブロック可能で、操作を止められます。2026年版では他にも多くのイベントが追加されていますが、名前はバージョンで変わりうるので最新は公式で確認してください。
Q. 保護したいファイルや危険なコマンドを止められますか?
A. はい。PreToolUse フックで止められます。スクリプトで tool_input のファイルパスやコマンドを調べ、.env や rm -rf 等にマッチしたら 終了コード2(または JSON で permissionDecision:"deny")を返せばブロックされます。重要なのは deny は常に優先され、bypassPermissions でも止まること。フックは「制限をきつくする」方向にしか効きません。
Q. 設定を変えたのに反映されません。
A. これは仕様(安全機構)です。フック設定は セッション開始時にスナップショットとして固定され、セッション中の変更は反映されません。これは、悪意あるプロンプトやツール出力がフック設定を勝手に書き換えるのを防ぐためです。新しいセッションを開始すれば反映されます。なお /hooks は一覧の読み取り専用で、追加・変更は settings.json を直接編集します。
Q. フックは安全ですか?
A. 無条件には安全ではありません。フックは あなたの権限で任意のシェルコマンドを実行するため、公式も「自己責任で」と明記しています。信頼できるフックだけを設定し、入力は jq で検証・クォート、絶対パスを使い、.env・.ssh 等は触らない、ツール出力を eval しないのが鉄則です。組織では管理者が allowManagedHooksOnly でフックを制限できます。