結論​(即答)​: Claude Code hooksとは

Claude Code hooks​(フック)は、​Claude Code が​セッション中の​決まった​場面で​自動的に​実行する​処理です。​設定ファイルに​「どの​場面で​(イベント)」​「何を​(ハンドラー)」​動かすかを​書いておくと、​Claude の​判断を​待たずに​プログラムが​動きます。

場面を​表すイベントは、​2026年10月20日時点の​公式リファレンスで​33種類あります。​全部を​覚える​必要は​ありません。​業務で​最初に​使うのは、​起動時の​ SessionStart、​ツール実行前の​ PreToolUse、​ツール実行後の​ PostToolUse、​応答終了時の​ Stop の​4つです。

できる​ことは​3つに​分かれます。

  • 止める​: 危険な​コマンドの​実行を​拒否する。​テストが​通るまで​ Claude を​終わらせない
  • 足す: 起動時に​前回の​作業メモを​読み込ませる。​ツールの​結果に​注意書きを​添える
  • 記録する​: 会話の​要約を​ノートに​残す。​ファイルの​変更を​通知する

当社は​ Obsidian へ​作業記録を​自動で​貯める​目的で​導入し、​2026年10月20日時点で​33イベントの​うち14イベントを​常用しています。​形式は​すべて​シェルコマンド型​(command)で、​本体は​ Node.js の​短い​スクリプトです。

出典: Claude Code 公式ドキュメント​「フック リファレンス」​(2026年10月20日確認。​当社の​確認環境は​ Claude Code v2.1.304)

CLAUDE.md や​ permissions との​違い

CLAUDE.md に​書いた​指示は、​Claude が​読んで​従う​「お願い」です。​長い​会話では​読み落とされる​ことがあります。​hooks は​プログラムが​実行するので、​場面が​来る​たびに​動きます。

permissions​(権限ルール)は、​ツールごとに​「許可する、​拒否する、​確認する」を​決める​仕組みです。​hooks は​その前後に​任意の​処理を​挟む仕組みで、​PreToolUse から​許可や​拒否を​返すこともできます。​公式リファレンスも、​許可と​拒否​そのものは​権限システムで​決め、​hooks は​その​補助と​して​使う​よう​書いています。

hooksの​種類は​「いつ​動くか」と​「何が​動くか」の​2軸で​分かれる

hooks を​分類する​軸は​2つあります。​1つ目は​イベントで、​どの​場面で​動くかを​表します​(33種類)。​2つ目は​ハンドラーの​形式で、​何が​処理を​行うかを​表します​(5種類)。​設定は​「イベント → matcher​(絞り込み)​→ ハンドラー」の​3階層で​書きます。

Claude Code hooks の発火順 セッションの開始で SessionStart、終了で SessionEnd が1回ずつ発火する。その間はターンがくり返され、各ターンは UserPromptSubmit で始まり Stop(API エラー時は StopFailure)で終わる。ターンの中ではツール呼び出しがくり返され、PreToolUse、PermissionRequest、ツール実行、PostToolUse または PostToolUseFailure、PostToolBatch の順に発火する。圧縮、サブエージェント、モデル切り替え、MCP の入力要求、設定やファイルの変更、通知は起きたときだけ割り込む。緑の枠のイベントは終了コード2か JSON で処理を止められ、白い枠のイベントは情報を足すか記録するだけで止められない。 セッションに1回 ターンに1回/ツール呼び出しごと セッションに1回 SessionStart ターン(ユーザーの発言ごとにくり返す) UserPromptSubmit ツール呼び出し(1ターンに何回も) PreToolUse PermissionRequest JSON でのみ拒否 ツール実行 PostToolUse PostToolUseFailure PostToolBatch Stop StopFailure ← API エラーのとき SessionEnd 場面に応じて割り込むイベント(起きたときだけ) PreCompact PostCompact SubagentStart SubagentStop PreModelSwitch PostModelSwitch Elicitation ElicitationResult ConfigChange FileChanged など Notification InstructionsLoaded 止められる(終了コード2 か JSON) 止められない(情報を足す、記録する) ツールの実行そのもの
図: Claude Code hooks の発火順。セッションに1回、ターンに1回、ツール呼び出しごとの3段階に分かれ、緑の枠のイベントは処理を止められる

公式リファレンスは、​イベントの​頻度を​3段階に​分けています。

頻度 イベント
セッションに​1回 SessionStart、​SessionEnd
ターン​(ユーザーの​1回の​発言と​ Claude の​応答)に​1回 UserPromptSubmit、​Stop、​StopFailure
ツール呼び出しごと PreToolUse、​PostToolUse

残りの​イベントは、​サブエージェントの​起動、​コンテキストの​圧縮、​モデルの​切り​替えなど、​その​出来事が​起きたときだけ​発火します。

全3​3イベントの​一覧表​(発火タイミング、​matcherの​対象、​ブロック可否)

表の​「ブロック」は、​終了コード2または​ JSON で​処理を​止められるかを​表します。​「matcher の​対象」は、​その​イベントの​中で​さらに​絞り込める​条件です。

セッションの​開始と​終了

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
SessionStart セッションの​開始と​再開 開始方法​(startup、​resume、​clear、​compact、​fork) 不可 前回の​作業メモや​環境変数の​注入
Setup --init-only、​または​ -p と​ --init か​ --maintenance で​起動したとき トリガー​(init、​maintenance) 不可 CI や​スクリプトでの​1回限りの​準備
InstructionsLoaded CLAUDE.md や​ .claude/rules/*.md が​読み込まれたとき 読み込み理由​(session_start、​path_glob_match など) 不可 どの​指示が​読まれたかの​監査
SessionEnd セッションの​終了 終了理由​(clear、​resume、​logout、​prompt_input_exit、​other) 不可 後片付け、​ログの​確定

ユーザー入力と​応答

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
UserPromptSubmit プロンプトの​送信直後、​Claude が​処理する​前 なし 可 入力の​検査、​文脈の​追加
UserPromptExpansion スラッシュコマンドが​プロンプトに​展開されるとき コマンド名 可 特定コマンドの​禁止や​差し替え
MessageDisplay Claude の​応答テキストが​表示されている​間 なし 不可 表示テキストの​置換​(タイムアウト10秒)
Stop Claude が​応答を​終えるとき なし 可 作業記録の​保存、​終了条件の​検査
StopFailure API エラーで​ターンが​終わったとき エラー種別​(rate_limit、​overloaded、​billing_error など) 不可 障害の​記録と​通知

ツール呼び出しと​権限

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
PreToolUse ツール呼び出しの​実行前 ツール名​(Bash、​Edit|Write、mcp__.*​ など) 可 危険な​操作の​拒否、​入力の​書き換え
PermissionRequest ツール呼び出しが​権限の​確認を​必要と​するとき ツール名 可​(JSON の​ decision のみ。​終了コード2は​無効) 確認ダイアログの​自動応答
PermissionDenied オートモード​(auto mode)が​ツール呼び出しを​拒否したとき ツール名 不可 再試行の​許可​(retry)
PostToolUse ツール呼び出しが​成功した​後 ツール名 不可 フォーマッターや​テストの​実行、​結果への​注記
PostToolUseFailure ツール呼び出しが​失敗した​後 ツール名 不可 失敗の​記録、​復旧の​ヒント
PostToolBatch 並列ツール呼び出しの​一括完了後、​次の​モデル呼び出しの​前 なし 可 バッチ全体を​見た​検査

サブエージェントと​タスク

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
SubagentStart サブエージェントの​生成時 エージェント種別 不可 サブエージェントへの​文脈注入
SubagentStop サブエージェントの​終了時 エージェント種別 可 成果物の​検査、やり直しの​指示
TaskCreated TaskCreate で​タスクが​作られたとき なし 可 タスクの​命名規則の​強制
TaskCompleted タスクが​完了に​されるとき なし 可 完了条件の​検査
TeammateIdle エージェントチームの​チームメイトが​待機に​入るとき なし 可 残作業の​割り​当て

環境、​設定、​ファイル

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
ConfigChange セッション中に​設定ファイルや​スキルが​変わったとき 変更元​(user_settings、​project_settings、​local_settings、​policy_settings、​skills) 可​(policy_settings を​除く) 想定外の​設定変更の​拒否
CwdChanged 作業ディレクトリが​変わったとき なし 不可 direnv のような​環境変数の​切り​替え
DirectoryAdded /add-dir などで​ディレクトリが​追加されたとき 追加方法​(slash_command、​register_repo_root) 不可 追加先の​案内
FileChanged 監視対象の​ファイルが​ディスク上で​変わったとき 監視する​ファイル名​(.envrc|.env のように​列挙) 不可 設定ファイル変更時の​再読み込み
WorktreeCreate worktree が​作られるとき なし 可​(失敗させる) worktree の​作り方を​自前の​手順に​差し替える
WorktreeRemove hooks が​作った​ worktree が​削除されるとき なし 可​(失敗させる) 後片付け

圧縮、​モデル、​MCP、​通知

イベント 発火タイミング matcher の​対象 ブロック 主な​用途
PreCompact コンテキスト圧縮の​前 圧縮の​きっかけ​(manual、​auto) 可 圧縮前の​引き継ぎメモの​保存
PostCompact コンテキスト圧縮の​後 圧縮の​きっかけ​(manual、​auto) 不可 圧縮後の​文脈の​補充
PreModelSwitch モデルの​切り​替えを​適用する​前 切り​替え先の​モデル名 可 高価な​モデルへの​切り​替え確認
PostModelSwitch モデルが​切り​替わった​後 切り​替え先の​モデル名 不可 モデル変更の​記録
Elicitation MCP サーバーが​ユーザー入力を​求めたとき MCP サーバー名 可 フォームの​自動入力
ElicitationResult ユーザーが​ MCP の​入力要求に​答えた​後 MCP サーバー名 可 送信前の​値の​検査
Notification Claude Code が​通知を​出すとき 通知種別​(permission_prompt、​idle_prompt、​agent_completed など) 不可 デスクトップ通知、​チャットへの​連携

出典: 公式リファレンスの​「フック ライフサイクル」​「Matcher パターン」​「イベントごとの​終了コード 2 動作」の​各表​(2026年10月20日確認)

止められるのは​「まだ​起きていない​こと」だけ

33イベントの​うち、​終了コード2で​処理を​止められるのは​16イベントです。​PermissionRequest は​終了コード2では​止まらず、​JSON の​ decision でだけ拒否できます。​合わせて​17イベントで、​hooks から​結果を​変えられます。

分かれ目は、​イベントが​「まだ​起きていない​こと」を​表すか​「すでに​起きた​こと」を​表すかです。​PreToolUse は​ツール呼び出しの​前なので​止められます。​PostToolUse は​ツールが​動いた​後なので​止められません。​SessionStart や​ PostModelSwitch も​同じ​理由で​止められません。

止められる​イベント 終了コード2で​起きる​こと
PreToolUse ツール呼び出しを​拒否する
UserPromptSubmit プロンプトを​ Claude に​渡さない
UserPromptExpansion コマンドの​展開を​止める
Stop Claude を​終わらせず、​会話を​続けさせる
SubagentStop サブエージェントを​終わらせない
TeammateIdle チームメイトを​待機させず、​作業を​続けさせる
TaskCreated タスクの​作成を​取り消す
TaskCompleted タスクを​完了に​しない
PostToolBatch 次の​モデル呼び出しの​前に​ループを​止める
ConfigChange 設定変更を​適用しない​(policy_settings を​除く)
PreCompact コンテキスト圧縮を​止める
PreModelSwitch モデルの​切り​替えを​取り消す
Elicitation MCP の​入力要求を​辞退し、​ダイアログを​出さない
ElicitationResult 回答を​送らず、​辞退に​変える
WorktreeCreate worktree の​作成を​失敗に​する
WorktreeRemove ディレクトリが​残っていれば​削除を​失敗に​する

止められない​イベントにも​使い道は​あります。​PostToolUse は​ Claude に​見せる​結果を​ updatedToolOutput で​置き換えられ、​PermissionDenied は​ retry: true で​再試行を​促せ、​SessionStart は​ additionalContext で​文脈を​足せます。​「止める」以外の​出力は、​後の​「終了コードと​JSON出力の​読み方」で​扱います。

注意点が​2つあります。​1つは、​タイムアウトした​フックは​止める​役目を​果たさない​ことです。​PreToolUse の​フックが​時間切れに​なると、​ツール呼び出しは​通常の​権限フローで​続きます。​時間切れでも​止めたいときは​ onFailure: "block" を​付けます​(PreModelSwitch だけは​時間切れで​切り​替えが​止まります)。

もう​1つは​ Stop の​安全弁です。​Stop の​フックが​続行の​指示​(終了コード2か​ decision: "block")を​8回連続で​返すと、​Claude Code は​それを​無視して​停止します。​Claude が​ツールを​呼ぶと​回数は​0に​戻り、​上限は​環境変数 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP で​変えられます。

出典: 公式リファレンス​「イベントごとの​終了コード 2 動作」​「タイムアウト」​「Stop」​(2026年10月20日確認)

ハンドラーの​形式は​5種類​(command、​http、​mcp_tool、​prompt、​agent)

イベントが​決まったら、​何に​処理を​させるかを​ type で​選びます。

形式 何が​動くか 結果の​返し方 既定の​タイムアウト 向く​用途
command シェルコマンド。​入力は​標準入力の​ JSON 終了コードと​標準出力の​ JSON 600秒 ほぼ​すべて。​速く、​モデルの​呼び出しが​増えない
http 指定 URL への​ POST。​入力は​リクエスト本体の​ JSON レスポンス本体の​ JSON 600秒 社内サーバーでの​一元的な​検査
mcp_tool 設定済み MCP サーバーの​ツール ツールの​テキスト出力​(command の​標準出力と​同じ​扱い) 600秒 MCP に​実装済みの​処理の​再利用
prompt Claude への​1回の​問い​合わせ {"ok": true/false, "reason": "..."} 30秒 「終わって​よいか」のような​判断
agent ファイルを​読める​サブエージェント​(最大50ターン) 同上 60秒 テストを​実際に​走らせて​確かめる​検査​(実験的機能)

当社は​ command だけを​使っています。​prompt と​ agent は​モデルの​呼び出しが​増える​ため、​その​分だけ​遅くなり、​利用枠も​消費します。​判断が​要る​検査でも、​まずは​シェルスクリプトで​書けないかを​考えます。

command には​書き方が​2つあります。args​ を​付けると​ exec 形式に​なり、​シェルを​介さずに​引数が​そのまま​渡ります。args​ を​付けないと​シェル形式に​なり、sh -c​ を​通ります​(Windows では​ Git Bash か​ PowerShell)。​パスを​含むコマンドは​ exec 形式の​ほうが​安全です。

長い​処理は​ "async": true で​バックグラウンドで​走らせられます。​Claude は​結果を​待たずに​進み、​処理が​終わると​ additionalContext や​ systemMessage が​次の​ターンで​届きます。​ただし非同期の​フックは​処理を​止められません。​止めたい​対象が​すでに​終わっている​ためです。

出典: 公式リファレンス​「フック ハンドラー フィールド」​「プロンプト ベースの​フック」​「エージェント ベースの​フック」​「バックグラウンドで​フックを​実行」​(2026年10月20日確認)

settings.jsonの​書き方と​置き場所

置き場所で​効く​範囲が​決まる

置き場所 効く​範囲 共有の​しかた
~/.claude/settings.json その​ PC の​すべての​プロジェクト 共有しない​(PC ローカル)
.claude/settings.json その​プロジェクトだけ リポジトリに​コミットして​共有する
.claude/settings.local.json その​プロジェクトだけ 共有しない​(gitignore の​対象)
管理ポリシー設定 組織全体 管理者が​配布する
プラグインの​ hooks/hooks.json プラグインが​有効な​間 プラグインに​同梱
スキルの​フロントマター スキルを​呼んだ後、​セッションの​残りの​間 スキルの​ファイルで​定義
サブエージェントの​フロントマター その​サブエージェントの​実行中 サブエージェントの​ファイルで​定義

複数の​場所に​ある​ hooks は​置き換えではなく​合算されます。​プロジェクトの​設定が​ユーザーの​設定を​消すことは​ありません。​チームで​共有したい​規則は​ .claude/settings.json に、​自分だけで​使う​記録用の​フックは​ ~/.claude/settings.json に​置く​分け方が​基本です。

構造は​3階層

設定は​「イベント → matcher で​絞った​グループ → ハンドラーの​配列」の​3階層です。​次は​公式リファレンスに​ある​例で、rm -rf​ を​含む Bash コマンドを​拒否する​ PreToolUse の​設定です。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(rm *)",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh",
            "args": []
          }
        ]
      }
    ]
  }
}

呼ばれる​スクリプトは、​標準入力の​ JSON から​コマンドを​取り出し、rm -rf​ を​含むときだけ拒否を​返します。

#!/bin/bash
# .claude/hooks/block-rm.sh
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
  jq -n '{
    hookSpecificOutput: {
      hookEventName: "PreToolUse",
      permissionDecision: "deny",
      permissionDecisionReason: "Destructive command blocked by hook"
    }
  }'
else
  exit 0
fi

matcher の​書き方

matcher の​値 判定 例
"*"、""、​省略 すべてに​一致 "matcher": "*"、​または​ matcher を​書かない
英数字、_、-、​空白、,、|​ だけ 完全一致。|​ か​ , で​複数指定 Bash、Edit|Write
それ以外の​文字を​含む JavaScript の​正規表現​(前後の​固定なし) mcp__memory__.*、^Edit$

正規表現は​値の​どこかに​一致すれば​通ります。Edit.*​ は​ NotebookEdit にも​一致するので、​完全に​一致させたいときは​ ^Edit$ と​書きます。​matcher を​持たない​イベント​(Stop、​UserPromptSubmit など)に​ matcher を​書いても​無視されます。

ハンドラーの​共通フィールド

フィールド 意味
type command、​http、​mcp_tool、​prompt、​agent の​いずれか​(必須)
if 権限ルールの​構文で​さらに​絞る​("Bash(git *)"、"Edit(*.ts)")。​ツール名で​絞れる​5イベント​(PreToolUse、​PermissionRequest、​PermissionDenied、​PostToolUse、​PostToolUseFailure)でだけ​効き、​1つの​フックに​1条件
timeout 中断までの​秒数
statusMessage 実行中に​スピナーへ​出す文言
once 初回の​成功後に​フックを​外す。​スキルの​フロントマターでだけ​有効

設定した​ hooks は、​Claude Code の​中で​ /hooks と​打つと​一覧できます。​全部を​一時的に​無効に​するには​設定の​ disableAllHooks を​ true にします​(管理ポリシーの​フックは​無効に​なりません)。

出典: 公式リファレンス​「設定」の​各節​(2026年10月20日確認)

終了コードと​JSON出力の​読み方

フックは​2つの​経路で​ Claude Code に​結果を​伝えます。​終了コードと、​標準出力に​書く​ JSON です。

終了コードは​0、​2、​それ以外の​3通り

終了コード 意味
0 成功。​標準出力が​ { で​始まる​ JSON なら​解釈して​適用する。​文字列だけなら、​一部の​イベントで​ Claude の​文脈に​足される
2 止める。​標準エラー出力の​文章が​理由と​して​使われる​(止められる​イベントのみ)
それ以外 止めない​失敗。​処理は​続き、​エラーだけ​表示される。onFailure: "block"​ を​付けた​フックは​失敗でも​止める

JSON で​返せる​共通フィールド

フィールド 働き
continue false で​ Claude の​処理を​完全に​止める。​イベント固有の​判定より​優先
stopReason continue: false のときユーザーに​出す文言
systemMessage ユーザーに​見せる​注意書き
terminalSequence デスクトップ通知や​ベルなどの​端末制御​(対話セッションのみ)
hookSpecificOutput イベント固有の​出力。hookEventName​ が​必須

イベント固有の​出力は​ hookSpecificOutput に​まとめます。​よく​使うのは​次の​3つです。

  • permissionDecision(PreToolUse)​: allow、​deny、​ask、​defer の​いずれか。​複数の​フックが​違う​答えを​返したら​ deny、​defer、​ask、​allow の​順で​強い​ほうが​勝つ
  • updatedInput(PreToolUse、​PermissionRequest)​: ツールへの​入力を​丸ごと​差し替える
  • additionalContext(多くの​イベント)​: Claude の​文脈に​文章を​足す。​上限は​10,000文字。​超えると​全文が​ファイルに​保存され、​Claude には​その​パスと​先頭2,000文字だけが​渡る

入力で​受け取る​共通フィールド

フックは​標準入力​(http ならリクエスト本体)で​ JSON を​受け取ります。​どの​イベントにも​ session_id、transcript_path​(会話ログの​パス)、cwd、hook_event_name​ が​入り、​ツール系なら​ tool_name と​ tool_input、​Stop なら​ last_assistant_message のように​イベント固有の​項目が​足されます。​サブエージェントの​中で​動いたときは​ agent_id と​ agent_type も​入ります。

標準出力には​ JSON 以外を​出さないようにします。​シェルの​起動時メッセージが​混ざるだけで​ JSON の​解釈に​失敗し、​終了コード0でも​「止めない​失敗」と​して​扱われます。

出典: 公式リファレンス​「フック入出力」​(2026年10月20日確認)

まず​入れる​なら、​この​4つ​(当社の​運用例)

導入の​経緯は​冒頭のとおりです。​当社の​設定は​ ~/.claude/settings.json に​14イベントを​登録したもので、​組み立て方は​ AIデータ基盤の​作り方​(2/3)​再現手順 に​載せています。

その​経験から、​最初に​入れる​価値が​高い順に​4つを​挙げます。

1. PreToolUse で​危険な​コマンドを​止める

対象は​ Bash、​条件は​ rm -rf や​ git push --force のような​取り返しの​つかない​操作です。rm -rf​ に​ついては​「settings.jsonの​書き方と​置き場所」の​ block-rm.sh が​そのまま​使え、git push --force​ は​同じ​スクリプトに​条件を​1行足すだけです。​拒否の​理由は​ Claude に​渡るので、​Claude は​別の​方法を​探します。

2. Stop で​作業記録を​自動保存する

Stop は​応答の​たびに​発火し、​入力の​ last_assistant_message に​最後の​応答が​入ります。​当社は​これを​デイリーノートの​決まった​位置に​追記しています。​失敗しても​会話を​止めないよう、​例外は​ログに​落として​終了コード0で​返します。

3. SessionStart で​前回の​文脈を​読み込ませる

additionalContext に​文章を​返すと、​起動直後の​ Claude が​それを​読んだ​状態で​始まります。​当社は​並行する​複数の​会話の​直近の​発言を​注入し、​「さっきの​あれ」が​別の​会話でも​通じるように​しています。​プラグインが​同じ​仕組みを​使うことも​あり、​当社の​環境では​ Vercel の​プラグインが​ SessionStart で​自身の​使い方の​案内を​毎回注入しています。

4. PostToolUse で​フォーマッターや​テストを​回す

matcher を​ Edit|Write にし、​ファイルが​書かれる​たびに​整形や​テストを​走らせます。​時間の​かかる​テストは​ "async": true に​して​ Claude を​待た​せず、​結果は​次の​ターンで​受け取ります。

書くときの​約束

  • 記録用の​フックは、​失敗しても​会話を​止めない​(例外は​捕捉して​ログに​残し、​終了コード0で​返す)
  • ノートや​ログへの​書き込みは​追記だけにし、​既存の​行を​書き換えない
  • スクリプトは​絶対パスで​指し、​シェル変数は​ "$VAR" のように​引用符で​囲む
  • .env や​鍵の​ファイルには​触らない

出典: 当社の​設定​(2026年10月20日確認)、​AIデータ基盤の​作り方​(2/3)​再現手順、​公式リファレンス​「セキュリティ ベストプラクティス」

つまずきやすい点と​制限

信頼していない​フォルダの​フックも​動く​ことがある

対話セッションでは、​フォルダを​信頼するかの​確認に​応じるまで​設定ファイルの​フックは​動きません。​一方、-p​ で​動かす非対話モードや​ SDK からの​実行では​ダイアログが​出ず、​リポジトリに​コミットされた​ .claude/settings.json の​フックが​そのまま​動きます。​他人の​リポジトリを​ claude -p で​動かす前には、.claude/​ の​中身を​確認するか、--bare​ で​起動するか、--settings '{"disableAllHooks": true}'​ で​無効にします。

タイムアウトの​既定値は​イベントで​違う

command、​http、​mcp_tool は​600秒、​prompt は​30秒、​agent は​60秒です。​ただし UserPromptSubmit、​PreModelSwitch、​PostModelSwitch では​ command、​http、​mcp_tool も​30秒、​MessageDisplay は​10秒に​下がります。​SessionEnd は​全フックで​1.5秒の​予算を​共有し、​個別に​ timeout を​書くと​最大60秒まで​延びます。

PreToolUse は​ @ 指定の​ファイル読み込みでは​発火しない

プロンプトに​ @ファイル名 と​書いた​読み込みは、​ツール呼び出しではないので​ PreToolUse を​通りません。​ファイルの​読み取りを​ hooks で​守る​つもりなら、​この​抜け道を​前提に​設計します。​公式リファレンスは​回避策と​して​環境変数 CLAUDE_CODE_DISABLE_FILE_MENTIONS=1 を​挙げています。

止めた​プロンプトは​消えない

UserPromptSubmit で​プロンプトを​止めても、​原文は、​止めたときに​表示される​メッセージと、​ディスク上の​会話ログに​残ります。suppressOriginalPrompt​ は、​表示される​メッセージから​原文を​外すだけです。​機密情報の​流出防止を​ hooks で​止める​ことに​頼るわけには​いきません。

非同期フックは​ -p では​終了時に​打ち切られる

"async": true の​フックの​結果が​届くのは、​セッションが​動いている​間だけです。​非対話モードでは、​セッション終了時に​まだ​走っている​非同期フックは​強制終了されます。​セッションより​長く​続けたい​処理は、​フックから​切り離した​別プロセスと​して​起動します。

Windows の​ PowerShell では​変数の​書き方に​注意

PowerShell の​フックで​ $CLAUDE_PROJECT_DIR と​裸で​書くと、​未定義の​変数と​して​ $null に​なります。${CLAUDE_PROJECT_DIR}​ か​ $env:CLAUDE_PROJECT_DIR を​使います。

動かないときの​調べ方

まず​ /hooks で​読み込まれているかを​見ます。​次に​ claude --debug で​起動すると、​ログが​ ~/.claude/debug/<session-id>.txt に​出ます。​v2.1.296 以降は、​フックごとに​ Hooks: PostToolUse:Write [...] finished with status 0 (31ms) のような​1行が​残り、​遅いフックも​見つけられます。

出典: 公式リファレンス​「セキュリティに​関する​考慮事項」​「タイムアウト」​「フックを​デバッグ」​(2026年10月20日確認)

よく​ある​質問

hooks を​使うと​料金は​かかりますか?

command、​http、​mcp_tool の​フックは​ Claude の​モデルを​呼ばないので、​フック自体は​ Claude の​利用枠を​使いません。​ただし additionalContext で​足した​文章は​次の​呼び出しの​入力に​含まれます。​prompt と​ agent は​モデルを​呼びます。​agent は​最大50ターン動くので、​頻繁に​発火する​イベントには​向きません。

CLAUDE.md に​書くのと​何が​違いますか?

CLAUDE.md は​ Claude が​読む指示で、​従うか​どうかは​ Claude の​判断です。​hooks は​プログラムが​実行するので、​Claude の​判断を​介さずに​動きます。​「毎回起こしたい​こと」は​ hooks、​「状況に​応じて​判断して​ほしい​こと」は​ CLAUDE.md に​書きます。

チームで​共有するには​どこに​書きますか?

プロジェクトの​ .claude/settings.json に​書いて​コミットします。​個人の​ PC だけで​動かしたいものは​ ~/.claude/settings.json か​ .claude/settings.local.json です。

サブエージェントの​中でも​動きますか?

動きます。​設定ファイル、​管理ポリシー、​プラグインの​フックは​サブエージェントの​中でも​発火し、​入力に​ agent_id と​ agent_type が​入るので、​本体の​会話と​区別できます。

プラグインや​スキルにも​ hooks を​持たせられますか?

持たせられます。​プラグインは​ hooks/hooks.json、​スキルと​サブエージェントは​フロントマターに​書きます。​スキルの​フックは​ once: true で​初回だけ動かせます。

設定したのに​動かないときは​どこを​見ますか?

まず​ /hooks に​出ているかを​確かめます。​出ていなければ、​フォルダの​信頼、​JSON の​構文、​置き場所を​疑います。​出ているのに​動かないなら​ claude --debug の​ログで​ matcher の​一致を​見ます。​終了コード0で​ JSON を​返しているのに​効かないときは、​標準出力に​ JSON 以外の​文字が​混ざっていないかを​確かめます。

MCP と​ hooks は​どう​違いますか?

MCP は​ Claude に​新しい​ツール​(外部​サービスの​操作など)を​与える​仕組みで、​使うか​どうかは​ Claude が​決めます。​hooks は​ Claude の​動作の​前後に​処理を​挟む仕組みで、​Claude の​判断を​待ちません。​両者は​組み合わせられ、mcp_tool​ 形式を​使えば、​フックから​ MCP の​ツールを​呼べます。

関連リンク

Obsidian 連携や​ Claude Fable 5.1 の​記事など、​関連する​他の​リサーチは​この​下の​一覧に​あります。