Claude Code hooks入門|自動フォーマットや実行制御の設定例
Claude CodeのCLAUDE.mdは「お願い」であり、Claudeが読み飛ばす可能性があります。一方hooksは、決められたタイミングで必ず実行されるシェルコマンドです。本記事ではhooksの主要イベント種別、settings.jsonでの書き方、自動フォーマットや危険なコマンドのブロックといった実用例を紹介します。設定全体は「Claude Code設定完全ガイド」もあわせてご覧ください。
前提・動作環境
hooksはClaude Code CLIのセッション内で動作し、設定は settings.json に記述します。書式は「settings.json解説」、権限の基本は「権限管理入門」を参照してください。例はWindows(PowerShell/Git Bash)前提ですが、macOS/Linuxでも考え方は共通です。
hooksとは何か
CLAUDE.mdに「編集後は必ずフォーマッタを実行してください」と書いても、Claudeが忘れたり別作業を優先したりすることがあります。LLMの判断に委ねている以上、この不確実性は避けられません。hooksはツール実行前後やセッション開始時など、ライフサイクル上の特定タイミングでコマンドを決定的に実行する仕組みで、Claudeの判断を介さずに「必ず起きること」を作れます。ルールの強制、繰り返し作業の自動化、既存ツールチェーンとの連携に向いています。
イベント種別一覧
代表的なイベントは次のとおりです。
SessionStart/SessionEnd: セッションの開始・再開時 / 終了時UserPromptSubmit: プロンプト送信後、処理前PreToolUse/PostToolUse: ツール実行の前(ブロック可能)/ 成功後Notification: 権限確認待ちなどの通知送信時Stop/SubagentStop: 応答・サブエージェントの終了時PreCompact/PostCompact: コンテキスト圧縮の前後
このほか PermissionRequest、CwdChanged など多数のイベントがあります。全一覧は /hooks コマンドや公式ドキュメントで確認できます。
settings.jsonでの基本的な書き方と実用レシピ1(自動フォーマット)
hooks キー配下にイベント名をキーとして設定します。次は PostToolUse フックで Edit/Write 直後にPrettierを走らせる例です。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }]
}
]
}
}
matcher: 反応するツール名。Bashの完全一致、Edit|Writeの複数指定、mcp__.*の正規表現も可能です。type: 通常はcommand(シェルコマンド実行)。ほかにhttp・mcp_tool・promptの型もあります。command: 標準入力のJSONからtool_input.file_pathをjqで取り出しPrettierをかけています。${CLAUDE_PROJECT_DIR}はプロジェクトルート環境変数です。
適用範囲は置き場所で変わり、全プロジェクトなら ~/.claude/settings.json、チーム共有なら .claude/settings.json(コミット可)、個人用なら .claude/settings.local.json です。
実用レシピ2: 危険な操作をブロックする
PreToolUse はツール実行前に走るため、条件を満たさない操作をそもそも実行させない用途に使えます。.env への編集を禁止する例です。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "[[ \"$(jq -r .tool_input.file_path)\" == *.env* ]] && echo Blocked >&2 && exit 2; exit 0" }]
}
]
}
}
対象パスが .env を含む場合は exit 2 でブロックします。stderrのメッセージはClaudeへのフィードバックとして渡され、Claudeはこれを読んで別のアプローチを試みます。
exit codeとJSON出力による制御
hooksはstdout・stderr・exit codeでClaude Codeと通信します。
- exit 0: 異議なし。通常フローが継続します。
UserPromptSubmit/SessionStartではstdoutがコンテキストに追加されます。 - exit 2: ブロッキングエラー。stderrがフィードバックになり、
PreToolUseならツール呼び出しをブロックします。ブロックできないイベントもあります。 - それ以外: 処理は継続し、トランスクリプトに「hook error」の通知が出ます。
さらに細かく制御するには、exit 0のままstdoutにJSONを出力します。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "grep ではなく rg を使ってください"
}
}
permissionDecision は allow(確認省略)・deny(拒否して理由を伝える)・ask(通常どおり確認)を指定できます。exit 2とJSON出力は併用できず、exit 2を返すとJSONは無視されます。
/hooksコマンドでの確認
設定内容はセッション内の /hooks で確認できます。イベントごとの登録数が一覧表示され、選択するとmatcherやtype、実行コマンド、設定ファイルの場所がわかります。読み取り専用なので、追加・変更・削除は settings.json を直接編集するか、Claudeに依頼します。
つまずきポイント/よくあるエラー
- hookが実行されない:
/hooksで対象イベント下に表示されているか確認します。matcherは大文字小文字を区別します。 command not foundになる: 相対パス指定だと見つからないことがあります。${CLAUDE_PROJECT_DIR}で絶対パスにしてください。- exit 2で拒否したのにJSONが反映されない: 併用不可です。ブロックはexit 2 + stderr、細かい制御はexit 0 + JSONと使い分けます。
- 意図せず危険なコマンドを自動実行してしまう: hooksは確認なしに任意のシェルコマンドを実行します。他人の設定を流用せず、内容を理解したうえで導入し、チーム共有前にレビューを挟んでください。
よくある質問
hooksとCLAUDE.mdはどう使い分ければよいですか?
「必ず実行してほしい処理」はhooks、「文脈に応じて考慮してほしい方針」はCLAUDE.mdが基本です。フォーマットや危険なコマンドの禁止などはhooksに任せましょう。
hooksの設定はチームで共有できますか?
できます。.claude/settings.json に記述してコミットすれば全員に適用されます。個人専用なら .claude/settings.local.json(Git管理対象外)を使います。
PreToolUseとPostToolUse、どちらを使えばいいですか?
操作を止めたい・入力を書き換えたいなら PreToolUse、実行後の後処理(フォーマット、ログ、通知)なら PostToolUse です。後者は実行後なので取り消しはできません。
まとめ
hooksはClaude Codeのライフサイクル上の特定タイミングで、Claudeの判断を介さずシェルコマンドを確実に実行できる機能です。PreToolUse・PostToolUse・SessionStart などのイベントをmatcherで絞り込み、settings.json に登録して使います。exit codeやJSON出力を使いこなせば、自動フォーマットから危険なコマンドのブロックまで幅広い制御が可能です。ただし任意のコマンドを自動実行する仕組みである以上、内容を理解したうえで導入しましょう。詳細は「settings.json解説」「権限管理入門」「設定完全ガイド」もあわせてご覧ください。