
Claude Code Hooks とは|全イベント一覧と設定・自動化活用法
Claude Code の Hooks は、セッションのライフサイクル上の特定タイミングで自動実行されるユーザー定義コマンドです。ファイル編集後に自動フォーマット、危険なコマンドの即時ブロック、作業完了時のデスクトップ通知——これらをモデルの「判断」に頼らず、決定論的に 実現できる仕組みです。本記事では Anthropic 公式ドキュメント(Hooks リファレンス・フックで自動化するガイド)をもとに、全イベント一覧から設定方法、実践ユースケースまでを解説します。
Hooks には PreToolUse・PostToolUse・SessionStart・Stop など 30 種類近くのイベントが用意されており、ハンドラーも command・http・prompt・agent など 5 タイプから選択できます。マッチャーを使えば特定のツールや引数パターンにだけ絞り込んで発火させることも可能です。
設定は ~/.claude/settings.json(全プロジェクト共通)か .claude/settings.json(プロジェクト固有)に JSON で記述します。本記事では Anthropic 公式ドキュメントをもとに、全イベント一覧から設定方法、実践ユースケースまでを解説します。
目次 (13)
Hooks が解決する問題
Claude Code は指示どおりにコードを書いたりコマンドを実行したりしますが、「編集のたびに必ず Prettier を走らせる」「.env への書き込みは例外なく拒否する」といった ルールの強制 はモデルの裁量に依存します。モデルが「今回は不要」と判断すれば実行されません。
Hooks はこの問題を解消します。特定のイベントが発火するたびにシェルコマンドや HTTP エンドポイントを呼び出し、LLM の判断を介さず決定論的にアクションを実行します。Anthropic 公式も「Hooks は特定のアクションが常に発生することを保証する」と明言しています。
全イベント一覧
Hooks は発火タイミングによってカテゴリーに分かれます。代表的なものを以下に示します。
| イベント | 発火タイミング | 主な用途 |
|---|---|---|
SessionStart |
セッション開始・再開時 | 環境セットアップ、コンテキスト注入 |
UserPromptSubmit |
プロンプト送信時 | プロンプト検証、追加コンテキスト付与 |
PreToolUse |
ツール実行前 | ツール呼び出しのブロック・承認 |
PostToolUse |
ツール実行後 | Lint/フォーマット、ログ記録 |
PermissionRequest |
許可ダイアログ表示時 | 自動承認・自動拒否 |
Stop |
Claude の応答完了時 | タスク完了チェック、通知 |
Notification |
Claude が入力待ち状態になったとき | デスクトップ通知 |
SessionEnd |
セッション終了時 | クリーンアップ処理 |
ConfigChange |
設定ファイルが変更されたとき | 監査ログ |
CwdChanged |
作業ディレクトリが変わったとき | direnv 統合 |
FileChanged |
監視ファイルが変更されたとき | 環境リロード |
PreCompact / PostCompact |
コンテキスト圧縮の前後 | コンテキスト再注入 |
公式の完全一覧には SubagentStart、TaskCreated、WorktreeCreate など 30 種類近くのイベントが定義されています。
ハンドラーの 5 タイプ
Hook の実行方式は 5 種類から選べます。
- command(最も一般的): シェルコマンドを実行。stdin に JSON が渡される
- http: 指定 URL に POST。クラウド関数や社内サービスに委譲できる
- mcp_tool: 接続済みの MCP サーバーのツールを呼び出す
- prompt: LLM(デフォルトは Haiku)に判断させる。ルールに収まらない条件判断に向く
- agent: ファイル読み取りや検索ツールつきのサブ実行環境を起動。複雑な検証に使う
command と http は決定論的、prompt と agent は LLM を介した判断ベースです。
設定ファイルと適用スコープ
Hooks は JSON で記述し、スコープに応じたファイルに配置します。
| ファイルパス | スコープ | リポジトリへのコミット |
|---|---|---|
~/.claude/settings.json |
全プロジェクト共通 | 不可(マシンローカル) |
.claude/settings.json |
単一プロジェクト | 可能 |
.claude/settings.local.json |
単一プロジェクト | 不可(gitignored) |
基本構造は以下の 3 層です。
{
"hooks": {
"PostToolUse": [ // ① イベント名
{
"matcher": "Edit|Write", // ② マッチャー
"hooks": [ // ③ ハンドラー
{
"type": "command",
"command": "..."
}
]
}
]
}
}
設定後は CLI で /hooks と入力すると登録済み Hook の一覧を確認できます。
マッチャーで発火対象を絞り込む
matcher フィールドを使うと、全呼び出しではなく特定のツールやイベントだけに Hook を絞れます。
""→ 空文字列を指定すると全てのイベントにマッチします(フィルタなし)"Bash"→ Bash ツール呼び出しのみ"Edit|Write"→ Edit または Write のみ(パイプで OR 結合)"mcp__github__.*"→ GitHub MCP サーバーの全ツール(正規表現)"compact"→ SessionStart の中でコンパクト再開時のみ
また if フィールドを使うと、ツール名に加えて引数の中身でもフィルタリングできます(Claude Code v2.1.85 以降)。
{
"if": "Bash(git *)",
"command": "..."
}
これにより git コマンドのときだけ Hook プロセスが起動し、無関係な Bash 呼び出しで無駄にプロセスが生成されるのを防げます。
実践ユースケース
作業完了時にデスクトップ通知を受け取る
Claude が入力待ちになったとき、ターミナルを監視しなくても通知を受け取れます。
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
}
]
}
]
}
}
matcher に空文字列を指定すると全てのイベントにマッチします。フィルタリングが不要な場合は "" を使います。
macOS は osascript -e 'display notification "..."'、Windows(PowerShell)は MessageBox API を使います。
編集後に Prettier を自動実行する
PostToolUse に Edit|Write マッチャーを設定し、編集されたファイルパスを jq で取り出して Prettier に渡します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
Claude が何ファイル編集しても、手動で Prettier を走らせる手間がゼロになります。
機密ファイルへの書き込みをブロックする
.env や package-lock.json など保護対象のファイルへの編集を、exit 2 で即時拒否します。
#!/bin/bash
# .claude/hooks/protect-files.sh
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
PROTECTED=(".env" "package-lock.json" ".git/")
for pattern in "${PROTECTED[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
exit 2
fi
done
exit 0
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
exit 2 で返すと Claude はブロック理由を受け取り、別のアプローチを試みます。
圧縮後にコンテキストを再注入する
コンテキスト圧縮後に重要な規約を Claude に再度伝えられます。
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: Bun を使う、コミット前に bun test を実行する'"
}
]
}
]
}
}
stdout に書いたテキストが Claude のコンテキストに追加されます。
direnv で環境変数を自動リロードする
ディレクトリ移動時に direnv で環境変数をリロードし、Bash ツールに即時反映させます。
{
"hooks": {
"CwdChanged": [
{
"hooks": [
{
"type": "command",
"command": "direnv export bash > \"$CLAUDE_ENV_FILE\""
}
]
}
]
}
}
CLAUDE_ENV_FILE に書いた内容は、以降の Bash コマンド実行時のプリアンブルとして自動適用されます。
終了コードと JSON 出力
Hook の動作はシェルの終了コードで制御します。
| 終了コード | 動作 |
|---|---|
0 |
異議なし。通常の許可フローが継続 |
2 |
アクションをブロック。stderr の内容が Claude へのフィードバックになる |
| その他 | 非ブロッキングエラー。実行は継続するがトランスクリプトに警告が表示される |
exit 2 とエラーメッセージ出力の代わりに、JSON を stdout に書いて exit 0 で返す構造化出力も使えます。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "grep より rg(ripgrep)を使ってください"
}
}
permissionDecision は "allow" / "deny" / "ask" から選択します。"allow" はインタラクティブな許可プロンプトをスキップしますが、設定ファイルの deny ルールはオーバーライドできません。
デバッグと注意点
Hook が動かないときの確認ポイントをまとめます。
/hooksコマンドで Hook がイベントの下に表示されているか確認する- スクリプトに実行権限があるか確認する(
chmod +x) claude --debug-file /tmp/claude.logでデバッグログを出力し、マッチ状況・終了コード・stderr を確認する- シェルプロファイル(
~/.bashrc等)に無条件のechoが含まれていると stdout が汚染され JSON 解析エラーが発生する。インタラクティブシェル時のみ実行するようif [[ $- == *i* ]]; thenでガードする StopHook が 8 回連続でブロックするとオーバーライドされる。無限ループを防ぐには Hook 入力のstop_hook_activeを確認して早期exit 0する
Hook は強力な自動化ツールですが、PreToolUse で "allow" を返しても管理ポリシーの deny ルールはバイパスできない点に注意が必要です。反対に "deny" は bypassPermissions モードでもブロックを実現でき、ポリシー強制に使えます。
詳細な入力/出力スキーマや非同期 Hook については、Anthropic 公式の Hooks リファレンス と Hooks ガイド を参照してください。