Hooks 実装 — ライフサイクルフックで自動化する
読了 10分 + 実践 35分
フック(Hooks)を設定すると、Claude Code がツールを実行したり応答を返したりするタイミングで、任意のシェルコマンドを自動的に実行できます。このページでは、4種類のフックイベント・環境変数・exit code の意味・.claude/settings.json への設定方法を順番に学びます。
フックとは何か
Section titled “フックとは何か”フック(Hook)とは、Claude Code がツールを呼び出したり、レスポンスを生成したりする特定のタイミングでシェルコマンドを実行できる仕組みです。フックは .claude/settings.json の hooks キーに設定します。
フックの主な用途は次のとおりです。
- ログ記録: どのツールがいつ呼ばれたかをファイルに記録する
- バリデーション: 危険なコマンドの実行をブロックする
- 自動フォーマット: ファイル保存後に linter を自動実行する
- 通知: Claude の作業完了をシステム通知で知らせる
4種類のフックイベント
Section titled “4種類のフックイベント”Claude Code には4種類のフックイベントがあります。
| イベント | タイミング | 主な用途 |
|---|---|---|
PreToolUse | ツール実行前 | バリデーション、ブロック |
PostToolUse | ツール実行後 | ログ記録、通知、後処理 |
UserPromptSubmit | ユーザー入力時 | プロンプト変換、前処理 |
Stop | レスポンス終了時 | 完了通知、後処理 |
PreToolUse はツール実行の前に呼ばれるため、特定のツール使用をブロックするゲートキーパーとして機能します。PostToolUse はツール実行後に呼ばれるため、副作用(ログ書き込み・通知など)を追加するのに適しています。
設定ファイルの構造
Section titled “設定ファイルの構造”フックは .claude/settings.json の hooks キーに設定します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "echo 'Tool: $CLAUDE_TOOL_NAME'"
}
]
}
]
}
}設定の構造は次のとおりです。
hooks: フック設定のルートキーPreToolUse/PostToolUse/UserPromptSubmit/Stop: イベント名matcher: どのツール名に対してフックを適用するか。"Bash"と書くと Bash ツール使用時のみ実行される。省略するとすべてのツールに適用されるtype: フックの種類。現時点では"command"のみサポートcommand: 実行するシェルコマンド
フック実行時に、Claude Code は次の環境変数を提供します。
| 変数名 | 内容 | 利用可能なイベント |
|---|---|---|
$CLAUDE_TOOL_NAME | 呼び出されたツール名(例: Bash、Read) | PreToolUse、PostToolUse |
$CLAUDE_TOOL_INPUT | ツールへの入力(JSON 形式) | PreToolUse、PostToolUse |
$CLAUDE_TOOL_RESULT | ツールの実行結果(JSON 形式) | PostToolUse のみ |
$CLAUDE_TOOL_INPUT は JSON 文字列なので、jq コマンドを使って特定のフィールドを取り出せます。
# Bash ツールに渡されたコマンド文字列を取り出す例
echo "$CLAUDE_TOOL_INPUT" | jq -r '.command'exit code の意味
Section titled “exit code の意味”フックスクリプトの終了コード(exit code)によって、Claude Code の挙動が変わります。
| exit code | 意味 |
|---|---|
0 | 成功。ツール実行を続行する |
1 | エラー。PreToolUse の場合はツール実行をブロックする |
2 | 非ブロッキングエラー。エラーメッセージを表示するが実行は続行する |
PreToolUse フックで exit 1 を返すと、Claude はそのツールの実行を中止します。PostToolUse フックで exit 1 を返しても、すでに実行済みのツール操作は取り消せません。
ベストプラクティス
Section titled “ベストプラクティス”フックは高速に保つ
Section titled “フックは高速に保つ”フックが重い処理(ネットワーク通信・大量ファイル処理など)を行うと、Claude の応答が遅くなります。重い処理はバックグラウンドで実行します。
# バックグラウンドで実行する例(& をつけてバックグラウンド化)
some-heavy-command "$CLAUDE_TOOL_NAME" &エラーは明示的に
Section titled “エラーは明示的に”フックがブロックする場合は、必ずエラーメッセージを出力してから exit 1 します。メッセージがないとユーザーはなぜブロックされたか分かりません。
echo 'ERROR: npm run build はユーザーの明示承認が必要です。'
exit 1PreToolUse は慎重に設計する
Section titled “PreToolUse は慎重に設計する”ブロックするフックが多すぎると、Claude Code が使いにくくなります。ブロックの条件は具体的に絞り込み、必要な操作まで誤ってブロックしないように注意します。
PostToolUse フックでツール使用ログをファイルに記録すると、監査やデバッグに役立ちます。
echo "$(date): $CLAUDE_TOOL_NAME" >> /tmp/claude-tool-log.txtフックスクリプトは単体テスト可能に書く
Section titled “フックスクリプトは単体テスト可能に書く”フックコマンドを直接 command フィールドに長く書くより、別ファイルのシェルスクリプトとして切り出してから呼び出す方が、テストと保守が容易です。
Step 1: 現在のフック設定を確認する
Section titled “Step 1: 現在のフック設定を確認する”cat .claude/settings.jsonhooks キーの有無と現在の設定内容を確認します。
✅ 確認: ファイルの内容が表示されれば読み込み成功です。
hooksキーがない場合は、次の手順で追加します。
Step 2: npm run build を誤って実行しないようにする PreToolUse フックを追加する
Section titled “Step 2: npm run build を誤って実行しないようにする PreToolUse フックを追加する”.claude/settings.json の hooks セクションに次の設定を追加します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'npm run build'; then echo 'ERROR: npm run build はユーザーの明示承認が必要です。'; exit 1; fi"
}
]
}
]
}
}このフックは、Bash ツールへの入力に npm run build が含まれている場合にブロックし、エラーメッセージを表示します。
✅ 確認:
.claude/settings.jsonを保存した後、cat .claude/settings.jsonで設定が正しく記録されていることを確認します。
Step 3: フックが正しくブロックするか確認する
Section titled “Step 3: フックが正しくブロックするか確認する”Claude Code のセッションで次のように依頼します。
npm run build を実行してClaude が Bash ツールで npm run build を実行しようとしたとき、フックが exit 1 を返してブロックされることを確認します。
✅ 確認: Claude の応答に「npm run build の実行がブロックされました」または「ユーザーの明示承認が必要です」という旨が含まれれば、フックが正しく機能しています。
Step 4: Stop フックで作業完了を macOS に通知する
Section titled “Step 4: Stop フックで作業完了を macOS に通知する”Claude が応答を終了したタイミングで macOS 通知を送る Stop フックを追加します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'npm run build'; then echo 'ERROR: npm run build はユーザーの明示承認が必要です。'; exit 1; fi"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude の作業が完了しました\" with title \"Claude Code\"'"
}
]
}
]
}
}✅ 確認: Claude が次のレスポンスを返し終えたとき、macOS の通知センターに「Claude の作業が完了しました」と表示されれば成功です。macOS 以外の環境では
osascriptを適切なコマンドに置き換えてください。
- フックは Claude Code のライフサイクルの特定タイミングでシェルコマンドを実行する仕組み
- 4種類のイベントは
PreToolUse(ツール前)・PostToolUse(ツール後)・UserPromptSubmit(入力時)・Stop(終了時) - フック実行時は
$CLAUDE_TOOL_NAME・$CLAUDE_TOOL_INPUT・$CLAUDE_TOOL_RESULTが利用できる PreToolUseでexit 1を返すとツール実行をブロックできる- フックは
.claude/settings.jsonのhooksキーに設定し、軽量・明示的・テスト可能に設計する
次のステップ
Section titled “次のステップ”- MCP Plugins 統合 — 外部ツールと Claude Code を統合する MCP プラグインの設定を学ぶ
- ハーネスのテストと検証 — フックが意図通りに機能するかを体系的に検証する方法へ進む
よくある質問
Section titled “よくある質問”Q: PreToolUse フックでブロックした場合、Claude はどう振る舞いますか?
A: フックが exit 1 を返すと、Claude はそのツールを実行せず、標準出力に書いたエラーメッセージをコンテキストとして受け取ります。その後、Claude はエラーの内容に応じて別のアプローチを試みるか、ユーザーに報告します。
Q: PostToolUse フックで exit 1 を返すと、ツールの実行結果は取り消せますか?
A: 取り消せません。PostToolUse はツール実行後に呼ばれるため、すでに完了した操作(ファイルの書き込みなど)は元に戻りません。実行前のバリデーションは PreToolUse で行ってください。
Q: matcher を省略するとどうなりますか?
A: すべてのツール呼び出しに対してフックが実行されます。Bash だけでなく Read・Write・Glob なども対象になるため、フックが重い処理を行う場合はレスポンスが大幅に遅くなる可能性があります。特定のツールのみを対象にする場合は matcher を明示的に指定してください。
Q: フックの設定を変更した後、Claude Code を再起動する必要がありますか?
A: .claude/settings.json の変更はセッションをまたいで読み込まれます。現在のセッションに変更を反映させるには、Claude Code を再起動するか新しいセッションを開始してください。
Q: Windows 環境で osascript の代わりに使えるコマンドはありますか?
A: Windows では powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('Claude の作業が完了しました')" を使用できます。Linux では notify-send "Claude の作業が完了しました" が使えます(libnotify が必要)。
このページの外部仕様・背景情報は、参考文献を参照してください。[1][2]
- Anthropic, Claude Code documentation
- Anthropic, Claude API documentation