創刊準備号 · 2026年秋English · RSS
AgentKoji

Claude Codeのhooks早見表

Claude Codeのhookのイベントは33個で、16個はexit 2で止められます。イベントとexit codeを表で引けます。

要点(TL;DR)

  • hooksは、Claude Codeの決まった時点で自動で動くコマンド、HTTPエンドポイント、MCPツール、プロンプト、サブエージェントです。公式ドキュメントにはイベントが33個あります。
  • exit 0は成功、exit 2は止められるイベントでは処理を止めます。それ以外の終了コードで正しいJSONも出さない場合は止めないエラーで、onFailureをblockにしたときだけ止まります。
  • ツールの呼び出しを実行の前に止めるなら、PreToolUseでexit 2にするか、permissionDecisionでdenyを返します。

hooks は、Claude Code の決まった時点で自動で動く、利用者が書いたシェルのコマンド、HTTP のエンドポイント、MCP のツール、LLM のプロンプト、サブエージェントです。ターミナル、IDE の拡張、デスクトップアプリ、クラウドのセッションのどこでも、同じイベントで動きます。このページは早見表です。全イベントの表、exit code と JSON の表、最小の例、hook ごとに動かして確かめた記事への案内を載せています。どれも2026年10月24日に公式のリファレンスと照らし合わせ、Claude Code 2.1.310 で確かめました。

全イベントの一覧

公式ドキュメントに載っているイベントは33個です。「exit 2」の列は、そのイベントの hook が終了コード 2 で終わったときに起きること、「matcher」の列は matcher が何と比べられるかです。「なし」は matcher に対応せず、毎回動くイベントです。

イベント動くときexit 2matcher
SessionStartセッションの開始・再開人に stderr を見せるだけ始まり方(startup、resume、clear、compact、fork)
Setup--init-only、または -p 付きの --init / --maintenance のときだけ無視されるinit、maintenance
InstructionsLoadedCLAUDE.md や .claude/rules/*.md が読み込まれたとき無視される読み込みの理由
UserPromptSubmitプロンプトを送ったとき、Claude が処理する前プロンプトを止めるなし
UserPromptExpansion打ったコマンドがプロンプトに展開されるとき展開を止めるコマンド名
MessageDisplayアシスタントのメッセージが画面に流れるとき元の文が表示されるなし
PreToolUseツールの呼び出しを組み立てたあと、実行の前呼び出しを止めるツール名
PermissionRequest権限の確認を出す直前効かない。decision で拒否するツール名
PostToolUseツールが成功した直後Claude に stderr を見せる。ツールはもう動いているツール名
PostToolUseFailure実行を始めたツールが失敗したときClaude に stderr を見せるツール名
PostToolBatchまとめて呼んだツールがすべて終わったとき次のモデル呼び出しの前でループを止めるなし
PermissionDeniedauto mode が呼び出しを拒否したとき無視されるツール名
Notification通知を送るとき無視される通知の種類
SubagentStartサブエージェントを起動・再開したとき人に stderr を見せるだけエージェントの種類
SubagentStopサブエージェントが応答を終えたときサブエージェントを止めずに続けさせるエージェントの種類
TaskCreatedTaskCreate でタスクを作るとき作成を取り消すなし
TaskCompletedタスクを完了にするとき完了にさせないなし
Stopメインのエージェントが応答を終えたときClaude を止めずに続けさせるなし
StopFailureAPI のエラーでターンが終わったときterminalSequence 以外は無視されるエラーの種類
TeammateIdleエージェントチームのメンバーが待機に入る直前待機させずに続けさせるなし
ConfigChangeセッション中に設定ファイルが変わったとき変更を反映させない(policy_settings を除く)設定の出どころ
CwdChangedシェルのコマンドで作業ディレクトリが変わったとき人に stderr を見せるだけなし
DirectoryAdded/add-dir でディレクトリを足したときstderr はデバッグログへ足し方
FileChanged監視しているファイルが変わったとき人に stderr を見せるだけ監視するファイル名
WorktreeCreateworktree を作るとき0 以外の終了コードで作成が失敗するなし
WorktreeRemovehook が作った worktree を消すとき0 以外の終了コードで削除が失敗するなし
PreCompact要約(compact)の前要約を止めるmanual、auto
PostCompact要約の後人に stderr を見せるだけmanual、auto
PreModelSwitchモデルの切り替えを反映する前切り替えを止める切り替え先のモデル名
PostModelSwitchモデルが切り替わった後人に stderr を見せるだけ切り替え先のモデル名
SessionEndセッションが終わるとき人に stderr を見せるだけ終わった理由
ElicitationMCP サーバーが入力を求めたとき求めを断り、画面は出ないMCP サーバー名
ElicitationResultMCP の入力に人が答えた後答えを止めるMCP サーバー名

出典:https://code.claude.com/docs/en/hooks 、2026-10-24確認

exit 2 で止められるのは、PreToolUse、UserPromptSubmit、UserPromptExpansion、Stop、SubagentStop、TeammateIdle、TaskCreated、TaskCompleted、ConfigChange、PostToolBatch、PreCompact、PreModelSwitch、Elicitation、ElicitationResult、WorktreeCreate、WorktreeRemove の16個です。WorktreeCreate と WorktreeRemove は 0 以外の終了コードで失敗し、WorktreeRemove はその後もディレクトリが残っているときだけ失敗します。

exit code と JSON の早見表

hook の終わり方結果
exit 0成功。stdout の JSON があれば反映される。UserPromptSubmit、UserPromptExpansion、SessionStart、PostModelSwitch では、普通の文も Claude の文脈に足される
exit 2止められるイベントでは、止める種類のエラー。stderr が理由になる。JSON も読まれるが、"allow" でも止まる
それ以外(1 を含む)普通の文か何も出さない場合は止めないエラーで、処理は進み、hook error の通知が出る。検証を通る JSON を出した場合は、終了コードは無視され JSON の中身で決まる。方針を守らせる hook には exit 2 が勧められている
起動できない、タイムアウト、JSON が読めない既定では止めないエラー。ただし PreModelSwitch では、タイムアウトで取り消された hook はモデルの切り替えを止める
command か HTTP の hook に "onFailure": "block"失敗したとき(exit 1 も含む)も、そのイベントで exit 2 と同じことが起きる。exit 2 が効かない PermissionRequest では、権限の要求を拒否する。Claude Code v2.1.295 以降。Stop、SubagentStop、TaskCompleted、TeammateIdle と非同期の hook には効かない

よく使う JSON のフィールドです。

フィールド使うイベント効果
hookSpecificOutput.permissionDecisionPreToolUseallow・deny・ask・defer。複数の hook では deny > defer > ask > allow の順に強い。defer は -p の実行でだけ効く
hookSpecificOutput.permissionDecisionReasonPreToolUseask では確認の画面に、deny では Claude に見せる
hookSpecificOutput.updatedInputPreToolUseツールの入力をまるごと差し替える
一番外の decision: "block" と reasonPostToolUse、Stop、UserPromptSubmit などPostToolUse ではツールの結果の横に理由を足し、Stop では Claude を続けさせる
hookSpecificOutput.additionalContextいくつかのイベントClaude の文脈に文を足す
systemMessage多くのイベント(捨てるイベントもある)人にメッセージを見せる

出典:https://code.claude.com/docs/en/hooks 、2026-10-24確認

置き場所と最小の例

置き場所範囲
~/.claude/settings.json自分のすべてのプロジェクト
.claude/settings.json1つのプロジェクト。Git に入れて共有できる
.claude/settings.local.json1つのプロジェクト。自分だけ
managed policy settings組織全体
plugin の hooks/hooks.jsonplugin が有効な間
skill やサブエージェントの frontmatterskill を呼んだあと、またはサブエージェントが動いている間

hook の設定は、これらの階層で上書きされず足し合わされます(出典:https://code.claude.com/docs/en/hooks 、2026-10-24確認)。

一番小さい PreToolUse の hook は、1つのコマンドを止めるものです。ダミーのプロジェクトで npm publish を止める例です。

{
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash",
        "hooks": [ { "type": "command", "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/no-publish.sh" } ] }
    ]
  }
}
#!/usr/bin/env bash
# .claude/hooks/no-publish.sh  (PreToolUse, matcher: Bash)
cmd=$(jq -r '.tool_input.command // ""')
case "$cmd" in
  *"npm publish"*) echo "Blocked: publishing is done by a human." >&2; exit 2 ;;
esac
exit 0

2026年10月24日に、ダミーの JSON を流して確かめました。{"tool_name":"Bash","tool_input":{"command":"npm publish"}} では Blocked: publishing is done by a human. と出て exit 2、npm test では exit 0 でした。設定ファイルは jq と claude doctor を通りました。実際のセッションの中で発火するところは見ていません(未実行)。

hooks の記事を読む順番

考え方から入り、例を写し、動かないときの確かめ方を知り、最後に設計を考える順に並べました。

まとめ

よくある質問

Claude Code の PreToolUse とは?
Claude がツールの呼び出しを組み立てたあと、実行する前に動く hook です。呼び出しを許可・拒否・確認・保留にでき、exit 2 で止めることもできます。
フックでコマンドを止めるには?
matcher を Bash にした PreToolUse の hook を登録し、スクリプトで tool_input.command を調べて、理由を stderr に書いて exit 2 で終わります。Claude には stderr が理由として渡ります。
exit 2 は何を意味する?
止める種類のエラーです。PreToolUse、UserPromptSubmit、Stop のように止められるイベントでは、Claude Code が処理を止めます。PostToolUse のように止められないイベントでは、stderr を見せるだけです。
exit 1 でツールの呼び出しは止まる?
それだけでは止まりません。exit 1 で普通の文か何も出さない場合は止めないエラーで、ツールはそのまま動きます。検証を通る JSON を出した場合は JSON の中身で決まり、deny なら止まります。onFailure: block を付けると(v2.1.295 以降)exit 1 も失敗として止まります。公式は、方針を守らせる hook には exit 2 を勧めています。
フックが動かないときは?
設定ファイルの置き場所、JSON の書式、イベント名のつづり、matcher の大文字と小文字、スクリプトの実行権限をよく確かめます。確かめ方はチェックリストの記事にまとめています。