4

Hooks Cheatsheet

全オプション網羅
GOALEVENTHANDLERBlock dangerous opsValidate outputAuto-format / lintAudit & loggingExternal notifySession lifecycleAgent monitoringContext controlPreToolUseall 4 typesPostToolUseall 4 typesPostToolUseFailureall 4 typesPermissionRequestall 4 typesStopall 4 typesUserPromptSubmitall 4 typesNotificationcommand onlySessionStartcommand onlySessionEndcommand onlySubagentStart/StopmixedPreCompactcommand onlycommandShell scripthttpWebhookpromptLLM judgeagentSub-agent

イベント選択ガイド

上のダイアグラムでノードにホバーすると、目的→イベント→ハンドラーの関連が可視化される。 「何をしたいか」から最適なイベントを逆引きしよう。


全18イベントリファレンス

ツール制御イベント

最も使用頻度が高いカテゴリ。ツール実行のライフサイクルに介入する。

イベントハンドラーMatcher対象いつ使う?頻度
PreToolUse全4種ツール名危険操作の事前ブロック、入力検証
PostToolUse全4種ツール名出力検証、自動フォーマット、監査ログ
PostToolUseFailure全4種ツール名失敗時のフォールバック、エラー通知
PermissionRequest全4種ツール名権限ダイアログの自動応答、ポリシー適用

PreToolUse stdin入力:

{
  "session_id": "abc123",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_use_id": "tool_123",
  "tool_input": { "command": "npm test" },
  "cwd": "/project",
  "transcript_path": "...",
  "permission_mode": "default",
  "ts": 1693478400
}

PreToolUse 出力制御 (hookSpecificOutput):

{
  "hookSpecificOutput": {
    "permissionDecision": "allow",
    "permissionDecisionReason": "Security check passed"
  }
}

permissionDecision"allow" | "deny" | "ask" の3値。

PostToolUse stdin入力 (追加フィールド):

{
  "tool_name": "Bash",
  "tool_input": { "command": "npm test" },
  "tool_use_output": {
    "stdout": "All tests passed",
    "stderr": "",
    "exit_code": 0
  }
}

PermissionRequest 出力制御:

{
  "hookSpecificOutput": {
    "decision": { "behavior": "allow" }
  }
}

ライフサイクルイベント

セッションやエージェントの開始・終了に反応する。

イベントハンドラーMatcher対象いつ使う?頻度
SessionStartcommand開始理由環境セットアップ、状態初期化
SessionEndcommand終了理由クリーンアップ、統計記録
Stop全4種なし最終チェック、サマリー生成
SubagentStartcommandエージェント型サブエージェント監視、リソース制限
SubagentStop全4種エージェント型サブエージェント結果検証

SessionStart matcher値:

意味
startup新規セッション開始
resume既存セッション再開

SessionEnd matcher値:

意味
clearセッションクリア
compactコンテキスト圧縮
logoutログアウト
prompt_input_exit入力終了

Stop stdin入力:

{
  "session_id": "abc123",
  "hook_event_name": "Stop",
  "stop_reason": "complete",
  "cwd": "/project",
  "ts": 1693478400
}

SubagentStart/Stop matcher値: Bash, Explore, Plan, カスタムエージェント名

コンテキストイベント

ユーザー入力やインストラクション読み込みに反応する。

イベントハンドラーMatcher対象いつ使う?頻度
UserPromptSubmit全4種なしプロンプト前処理、入力バリデーション
TaskCompleted全4種なしタスク完了通知、後処理トリガー
InstructionsLoadedcommandなしインストラクション検証、動的設定注入

UserPromptSubmit stdin入力:

{
  "session_id": "abc123",
  "hook_event_name": "UserPromptSubmit",
  "user_prompt": "Fix the bug in main.js",
  "user_prompt_type": "user_message",
  "cwd": "/project",
  "ts": 1693478400
}

InstructionsLoaded stdin入力:

{
  "file_path": "/project/CLAUDE.md",
  "memory_type": "Project",
  "load_reason": "session_start"
}

環境・通知イベント

通知配信、設定変更、ワークツリー管理に反応する。

イベントハンドラーMatcher対象いつ使う?頻度
Notificationcommand通知タイプカスタム通知ルーティング
TeammateIdlecommandなしチームメイトアイドル時の処理
ConfigChangecommandなし設定変更の検知・監査
PreCompactcommandトリガー種別圧縮前のコンテキスト保存
WorktreeCreatecommandなしワークツリー作成時の初期化
WorktreeRemovecommandなしワークツリー削除時のクリーンアップ

Notification matcher値: permission_prompt, idle_prompt, auth_success, elicitation_dialog

PreCompact matcher値: manual (手動) / auto (自動)


4ハンドラータイプ比較

特性commandhttppromptagent
実行環境ローカルシェルHTTPエンドポイントLLM内判定サブエージェント
入力stdin (JSON)POST body (JSON)コンテキスト自動注入コンテキスト自動注入
出力stdout (JSON)Response bodyyes/no判定検証結果
非同期async: true不可不可不可
timeout設定可設定可設定可設定可
対応イベント全18種8種8種8種
最適ユースケーススクリプト実行外部API連携セマンティック検証複雑な判断ロジック

command ハンドラー

{
  "type": "command",
  "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/validate.sh",
  "timeout": 30,
  "async": false
}
  • async: true で非同期実行(結果は次ターンで配信)
  • $CLAUDE_PROJECT_DIR でプロジェクトルート参照
  • exit code: 0 = 成功, 2 = ブロック (stderr がエラーメッセージ)

http ハンドラー

{
  "type": "http",
  "url": "https://webhook.example.com/hooks",
  "timeout": 30
}
  • イベントJSONをHTTP POSTで送信
  • レスポンスボディでcommandと同じJSON形式を返す

prompt ハンドラー

{
  "type": "prompt",
  "prompt": "Is this operation safe? Evaluate for security risks.",
  "timeout": 20
}
  • Claudeモデルがyes/no判定を実行
  • セマンティックな検証(パターンマッチでは判断できないケース)に最適

agent ハンドラー

{
  "type": "agent",
  "agent": "security-verifier",
  "timeout": 60
}
  • ツールアクセス付きの検証エージェントを起動
  • ファイル読み込みやコード解析を含む複雑な判断に使用

Matcher パターン詳解

Matcherは正規表現をサポートする。イベントタイプごとにマッチ対象が異なる。

ツール名マッチング

"Bash"                    → Bashツールのみ
"Edit|Write"              → EditまたはWrite
"mcp__slack__.*"          → Slack MCPの全ツール
"mcp__.*__delete.*"       → 任意MCPサーバーのdelete系
""                        → 全ツール (空文字 = ワイルドカード)

MCPツールの命名規則

MCPツールは mcp__<server>__<tool> パターンで参照される。

mcp__github__search_repositories   → GitHub検索
mcp__filesystem__read_file         → ファイル読み取り
mcp__memory__.*                    → memoryサーバーの全ツール

レシピカード

1. Git品質ゲート — コミット前のlintチェック

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); CMD=$(echo $INPUT | jq -r .tool_input.command); if echo \"$CMD\" | grep -q \"git commit\"; then cd $(echo $INPUT | jq -r .cwd) && npx lint-staged --quiet || exit 2; fi'"
      }]
    }]
  }
}

2. Webhook通知 — 権限リクエスト時にSlackへ通知

{
  "hooks": {
    "Notification": [{
      "matcher": "permission_prompt",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); curl -s -X POST $SLACK_WEBHOOK_URL -H \"Content-Type: application/json\" -d \"{\\\"text\\\": \\\"Claude Code permission request: $(echo $INPUT | jq -r .notification_message)\\\"}\"'"
      }]
    }]
  }
}

3. セキュリティ監査ログ — 全ツール実行を記録

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); echo \"[$(date -Iseconds)] $(echo $INPUT | jq -c {tool:.tool_name,input:.tool_input})\" >> $CLAUDE_PROJECT_DIR/.claude/audit.log'"
      }]
    }]
  }
}

4. 自動フォーマット — ファイル変更後にPrettier実行

{
  "hooks": {
    "PostToolUse": [{
      "matcher": "Edit|Write",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); FILE=$(echo $INPUT | jq -r .tool_input.file_path); npx prettier --write \"$FILE\" 2>/dev/null; exit 0'"
      }]
    }]
  }
}

5. LLM安全判定 — 危険操作のセマンティック検証

{
  "hooks": {
    "PreToolUse": [{
      "matcher": "Bash",
      "hooks": [{
        "type": "prompt",
        "prompt": "Evaluate if this bash command could be destructive (deleting files, dropping databases, modifying system config). If dangerous, deny it."
      }]
    }]
  }
}

6. サブエージェント監視 — 起動ログ記録

{
  "hooks": {
    "SubagentStart": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); echo \"[$(date -Iseconds)] Subagent started: $(echo $INPUT | jq -r .agent_type)\" >> /tmp/claude-agents.log'"
      }]
    }]
  }
}

7. セッション統計 — 開始・終了時刻の記録

{
  "hooks": {
    "SessionStart": [{
      "matcher": "startup",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'echo \"{\\\"start\\\": \\\"$(date -Iseconds)\\\", \\\"session_id\\\": \\\"$(cat | jq -r .session_id)\\\"}\" >> ~/.claude/session-stats.jsonl'"
      }]
    }],
    "SessionEnd": [{
      "matcher": "",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'echo \"{\\\"end\\\": \\\"$(date -Iseconds)\\\", \\\"session_id\\\": \\\"$(cat | jq -r .session_id)\\\"}\" >> ~/.claude/session-stats.jsonl'"
      }]
    }]
  }
}

8. コンテキスト圧縮前バックアップ — トランスクリプト保存

{
  "hooks": {
    "PreCompact": [{
      "matcher": "auto",
      "hooks": [{
        "type": "command",
        "command": "bash -c 'INPUT=$(cat); cp \"$(echo $INPUT | jq -r .transcript_path)\" \"$(echo $INPUT | jq -r .transcript_path).bak.$(date +%s)\"'"
      }]
    }]
  }
}

セキュリティ脅威モデルマッピング

脅威攻撃例防御フックハンドラー
コマンドインジェクションrm -rf /, DROP TABLEPreToolUse (Bash)command / prompt
機密ファイルアクセス.env, credentials.json 読み書きPreToolUse (Read/Write/Edit)command
データ漏洩機密情報を含む出力の外部送信PostToolUsecommand / prompt
過剰権限取得不要な権限の自動承認PermissionRequestcommand / prompt
プロンプトインジェクションユーザー入力に埋め込まれた悪意ある指示UserPromptSubmitprompt / agent
リソース枯渇無限ループ、大量サブエージェント生成SubagentStart + timeoutcommand
設定改ざんセキュリティ設定の無断変更ConfigChangecommand

出力制御リファレンス

exit code (command ハンドラー)

コード動作
0成功 / 許可 (JSON出力で詳細制御可)
2ブロック / 拒否 (stderr がエラーメッセージ)
その他フックのエラーとして処理

decision フィールド (JSON出力)

{ "decision": "block", "reason": "Policy violation" }

ブロック可能なイベント: UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStop, ConfigChange

continue フィールド (TaskCompleted / TeammateIdle)

{ "continue": false, "stopReason": "Test failed" }

設定ファイルの配置

レベルパススコープ
ユーザー~/.claude/settings.json全プロジェクト共通
プロジェクト.claude/settings.json当該プロジェクトのみ
スキル/プラグインhooks/hooks.jsonスキル内のみ

マネージド設定 (~/.claude/settings.jsonmanagedHooks) はチームで強制適用できる。


デバッグのコツ

  1. ドライラン — フックスクリプトに直接JSONを流して動作確認:

    echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | bash .claude/hooks/my-hook.sh
  2. ログ出力 — stderr はClaude Codeのログに出力される(stdout は制御用なので分離)

  3. タイムアウト — デフォルトタイムアウトは短い。重い処理には timeout を明示的に設定

  4. 実行順序 — 同一イベントの複数フックは配列順に直列実行。最初のブロック判定で停止

  5. /hooks コマンド — Claude Code内で /hooks と入力するとインタラクティブな設定UIが起動