Claude Code Hooks実践:AIエージェント自動化編【2025年最新版】¶
この記事のポイント
- Claude Code Hooksは初期の4種から11種のイベントタイプに拡張され、セッション全体のライフサイクルをカバーする仕組みへ進化した
- Hook実行タイプもcommand(シェル)/ prompt(LLM評価)/ agent(サブエージェント)の3種に拡充され、単純なスクリプト実行からコンテキスト認識型の判断まで対応する
- PreToolUseのツール入力修正機能、Plugin hooks、MCP連携、Skills/Subagentsフロントマターでのhook定義など、エコシステム全体との統合が大幅に強化された
- 2025年7月に報告されたCVE-2025-59536を含むセキュリティ脆弱性が修正されており、設定ファイルの取り扱いには引き続き注意が必要
はじめに¶
Claude Code Hooks完全ガイドで基本概念を学んだ方向けに、本記事では最新仕様に基づく実践的なHooks実装パターンと、AIエージェント自動化の最新テクニックを解説する。
本記事は2025年1月の初版公開以降に追加された新機能・仕様変更を反映した改訂版である。Claude Codeのバージョンアップに伴い、Hooksの仕様は大幅に拡張されている。
Claude Code Hooksとは¶
Claude Code Hooksは、AIエージェント実行の特定のライフサイクルポイントで自動的にアクションを実行する仕組みである。プロンプトベースの「お願い」とは異なり、条件が満たされれば確実に実行される決定論的な制御レイヤーとして機能する。
CLAUDE.mdやプロンプトでの指示は「モデルが従う可能性が高い」提案であるのに対し、Hooksは「必ず実行される」ガードレールという点が本質的な違いとなる。
11のHookイベントタイプ¶
初期の4種から大幅に拡張され、現在は以下の11種のイベントタイプが利用可能である。
| イベント | 発火タイミング | 主な用途 |
|---|---|---|
| PreToolUse | ツール実行前 | コマンドのバリデーション、危険操作ブロック、入力の自動修正 |
| PermissionRequest | 権限ダイアログ表示時(v2.0.45+) | 権限の自動承認・拒否 |
| PostToolUse | ツール実行後 | コードフォーマット、品質チェック、ログ記録 |
| Notification | 通知イベント発生時 | デスクトップ通知、Slack連携 |
| UserPromptSubmit | ユーザーがプロンプト送信時 | プロンプトバリデーション、コンテキスト注入 |
| Stop | メインエージェント応答完了時 | タスク完了判定、自動コミット |
| SubagentStop | サブエージェント完了時 | サブエージェントの完了検証 |
| SubagentStart | サブエージェント起動時 | サブエージェントの監視、コンテキスト注入 |
| PreCompact | コンパクト操作実行前 | トランスクリプトのバックアップ |
| SessionStart | セッション開始時 | 環境変数の設定、開発コンテキストの読み込み |
| SessionEnd | セッション終了時 | クリーンアップ、ログ集計 |
→ 全15種のイベント一覧はコマンドリファレンスを参照
3つのHook実行タイプ¶
従来のシェルコマンド実行に加え、LLMベースの評価とサブエージェントによる検証が追加された。
1. Command Hook(シェルコマンド)¶
従来型のシェルコマンド実行。stdinでイベントのJSON入力を受け取り、exit codeとstdoutで結果を返す。
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-style.sh"
}
2. Prompt Hook(LLM評価)¶
軽量なClaudeモデル(Haiku)にプロンプトを送信し、approve/blockの判断をJSON形式で返す。Stop/SubagentStopでの「タスクが本当に完了したか」の判定に効果的である。
{
"type": "prompt",
"prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete and no errors remain.",
"timeout": 30
}
3. Agent Hook(サブエージェント)¶
Read、Grep、Globなどのツールを使用できるサブエージェントを起動し、条件を検証してから判断を返す。より複雑な検証ロジックが必要な場合に有用である。
実装ガイド:基本設定¶
設定ファイル¶
Claude Code Hooksは以下の設定ファイルで構成する。
~/.claude/settings.json— ユーザー設定.claude/settings.json— プロジェクト設定(Git管理対象).claude/settings.local.json— ローカルプロジェクト設定(Git管理対象外)- Enterprise managed policy settings — 管理者設定
設定構造¶
{
"hooks": {
"EventName": [
{
"matcher": "ToolPattern",
"hooks": [
{
"type": "command",
"command": "your-command-here",
"timeout": 60
}
]
}
]
}
}
matcherはツール名に対する正規表現パターン(大文字・小文字区別あり)である。Edit|Writeのようにパイプで複数指定、Notebook.*のようにワイルドカードも使える。*や空文字列で全ツールにマッチする。
matcherはPreToolUse、PermissionRequest、PostToolUseで使用される。UserPromptSubmit、Stop、SubagentStop等ではmatcherフィールドを省略する。
/hooks インタラクティブマネージャー¶
Claude Code内で /hooks と入力すると、対話型のhookマネージャーが起動する。設定ファイルを直接編集することなく、hookの確認・追加・削除が可能である。
hookの一時無効化¶
設定ファイルに "disableAllHooks": true を追加するか、/hooksメニュー内のトグルで全hookを一時的に無効化できる。なお、管理者ポリシーで設定されたhookはこの設定では無効化できない。
実践的な使用例¶
例1: 自動コード品質チェック(PostToolUse)¶
ファイル書き込み後に自動でlint/フォーマットを実行する。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/lint-check.sh"
}
]
}
]
}
}
.claude/hooks/lint-check.shの実装例:
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
if [[ "$file_path" == *.py ]]; then
ruff check "$file_path" && ruff format "$file_path"
elif [[ "$file_path" == *.js ]] || [[ "$file_path" == *.ts ]]; then
npx eslint "$file_path" --fix && npx prettier --write "$file_path"
fi
パフォーマンスに関する注意
PostToolUseでフォーマッタを実行するとファイル変更のたびにコンテキストウィンドウを消費する。高頻度の編集が想定される場合は、Stop hookでまとめてフォーマットする方が効率的である。
例2: 危険コマンドのブロック(PreToolUse)¶
PreToolUse hookでは、exit code 2を返すことでツール実行をブロックできる。さらにJSON出力でpermissionDecisionによる精密な制御も可能である。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous.sh"
}
]
}
]
}
}
.claude/hooks/block-dangerous.shの実装例:
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')
# 危険なコマンドパターンをチェック
if echo "$command" | grep -qE '(rm -rf /|sudo rm|chmod 777|DROP TABLE)'; then
# JSON出力による精密な制御
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Dangerous command pattern detected: $command"
}
}
EOF
exit 0
fi
exit 0
例3: ツール入力の自動修正(PreToolUse updatedInput)¶
v2.0.10以降、PreToolUse hookがツール実行前に入力パラメータを修正できるようになった。Claudeに透過的にサンドボックス化や自動セキュリティ強制を適用できる。
#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')
command=$(echo "$input" | jq -r '.tool_input.command // empty')
# git pushをdry-runに自動変換
if [[ "$tool_name" == "Bash" ]] && echo "$command" | grep -q "git push"; then
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Auto-converted to dry-run",
"updatedInput": {
"command": "${command} --dry-run"
}
}
}
EOF
exit 0
fi
exit 0
例4: セッション開始時のコンテキスト注入(SessionStart)¶
SessionStart hookで開発コンテキストを自動読み込みし、環境変数を永続化できる。
{
"hooks": {
"SessionStart": [
{
"matcher": "startup",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/session-init.sh"
}
]
}
]
}
}
.claude/hooks/session-init.shの実装例:
#!/bin/bash
# 環境変数の永続化(SessionStart限定のCLAUDE_ENV_FILE)
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo 'export NODE_ENV=development' >> "$CLAUDE_ENV_FILE"
fi
# コンテキスト情報をJSON出力で注入
recent_changes=$(git log --oneline -5 2>/dev/null || echo "No git history")
open_issues=$(git log --oneline --all --grep="TODO" -3 2>/dev/null || echo "No issues found")
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "Recent changes:\n${recent_changes}\n\nOpen items:\n${open_issues}"
}
}
EOF
exit 0
例5: インテリジェントなStop Hook(Prompt型)¶
LLMベースのPrompt hookで、タスクの完了状態をコンテキストを踏まえて判断する。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "You are evaluating whether Claude should stop working. Context: $ARGUMENTS\n\nAnalyze and determine if:\n1. All user-requested tasks are complete\n2. Any errors need to be addressed\n3. Tests have been run and pass\n\nRespond with JSON: {\"decision\": \"approve\" or \"block\", \"reason\": \"your explanation\"}",
"timeout": 30
}
]
}
]
}
}
高度な活用パターン¶
1. MCP Toolsとの連携¶
MCP(Model Context Protocol)経由で提供されるツールに対してもhookを設定できる。MCPツールは mcp__<server>__<tool> の命名パターンに従う。
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__memory__.*",
"hooks": [
{
"type": "command",
"command": "echo '[MCP] Memory operation' >> ~/mcp-audit.log"
}
]
},
{
"matcher": "mcp__.*__write.*",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/validate-mcp-write.py"
}
]
}
]
}
}
2. Plugin Hooks¶
Pluginがhookを提供し、ユーザーやプロジェクトのhookとシームレスに統合できる。プラグインのhookはプラグイン有効化時に自動マージされ、既存のhookと並列で実行される。
{
"description": "Automatic code formatting plugin",
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",
"timeout": 30
}
]
}
]
}
}
プラグインでは ${CLAUDE_PLUGIN_ROOT} 環境変数でプラグインディレクトリへの絶対パスを参照できる。
3. Skills/Subagentsフロントマターでのhook定義¶
設定ファイルとは別に、SkillsやSubagentsのYAMLフロントマターに直接hookを定義できる。これらのhookはコンポーネントのライフサイクルにスコープされ、そのコンポーネントがアクティブな間のみ実行される。
---
name: secure-operations
description: Perform operations with security checks
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/security-check.sh"
---
サブエージェントのStopフックは自動的にSubagentStopに変換される。
4. 監査ログとPermissionRequest自動制御¶
PermissionRequest hook(v2.0.45+)で権限ダイアログへの応答を自動化できる。
{
"hooks": {
"PermissionRequest": [
{
"matcher": "Read",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/auto-approve-reads.sh"
}
]
}
]
}
}
#!/bin/bash
# .claude/hooks/auto-approve-reads.sh
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path // empty')
# ドキュメントファイルの読み取りを自動承認
if [[ "$file_path" == *.md ]] || [[ "$file_path" == *.txt ]] || [[ "$file_path" == *.json ]]; then
cat <<EOF
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow"
}
}
}
EOF
exit 0
fi
# それ以外はデフォルトの権限フローに委ねる
exit 0
→ 権限設定の詳細は自動承認設定ガイドを参照
5. マルチエージェントオーケストレーション¶
SubagentStop hookとStop hookを組み合わせることで、サブエージェント間のタスクハンドオフを自動化できる。
{
"hooks": {
"SubagentStop": [
{
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/subagent-handoff.sh"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-pipeline.sh"
}
]
}
]
}
}
stop_hook_activeフラグをチェックして無限ループを防止することが重要である。
→ Agent Teamsの詳細はAgent Teams導入ガイドを参照
Hook入出力の詳細¶
入力(stdin JSON)¶
すべてのhookは以下の共通フィールドを含むJSONをstdinで受け取る。
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/path/to/project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
},
"tool_use_id": "toolu_01ABC123..."
}
出力制御¶
2つの方式がある(排他的に選択)。
方式1: Exit Code
exit 0— 成功(stdoutはverboseモードで表示。UserPromptSubmit/SessionStartではコンテキストとして追加)exit 2— ブロック(stderrがエラーメッセージとしてClaudeに通知。JSON出力は無視)- その他 — 非ブロックエラー(stderrがverboseモードで表示)
方式2: JSON出力(exit 0と組み合わせ)
{
"continue": true,
"stopReason": "Custom stop message",
"suppressOutput": false,
"systemMessage": "Warning shown to user",
"decision": "block",
"reason": "Explanation",
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "Auto-approved",
"updatedInput": {},
"additionalContext": "Extra context for Claude"
}
}
セキュリティ考慮事項¶
CVE-2025-59536:設定ファイル経由のRCE脆弱性¶
2025年7月、Check Point Researchにより .claude/settings.json を通じた任意コード実行の脆弱性が報告された。悪意あるリポジトリのクローン時にhookが自動実行されるリスクがあり、2025年8月にAnthropicが修正を実施している。
セキュリティベストプラクティス¶
- hookスクリプト内で入力を必ずバリデーション・サニタイズする
- シェル変数は常にクォートする(
"$VAR"を使用、$VARではなく) - ファイルパスのパストラバーサル(
..)をチェックする - スクリプトパスには絶対パスまたは
$CLAUDE_PROJECT_DIRを使用する .env、.git/、鍵ファイルなどの機密ファイルへのアクセスを回避する- hookの設定変更はセッション起動時にスナップショットとして取得され、実行中の変更は即座に反映されない(
/hooksメニューでのレビューが必要)
Enterprise管理¶
allowManagedHooksOnly設定により、組織が承認したhookのみに制限できる。管理者ポリシーで設定されたhookは、ユーザー側のdisableAllHooks設定では無効化できない。
トラブルシューティング¶
デバッグ手順¶
/hooksで登録状態を確認するclaude --debugで実行詳細を確認する- hookコマンドを手動で実行してテストする
- スクリプトの実行権限(
chmod +x)を確認する - JSON設定の構文を検証する
よくある問題¶
hookが発火しない場合
- matcherのツール名が正確か確認する(大文字・小文字区別あり、
Bashであってbashではない) - イベント名がPascalCaseか確認する(
PreToolUseであってpreToolUseではない)
JSON出力がパースされない場合
- シェルプロファイル(
.bashrc等)の出力がstdoutに混入していないか確認する - exit code 0でのみJSON出力が処理される(exit 2ではstderrのみ使用)
タイムアウトの場合
- デフォルトは60秒。hookごとに
timeoutフィールドで個別設定が可能
{
"type": "command",
"command": "your-slow-command",
"timeout": 120
}
環境変数リファレンス¶
| 変数名 | 説明 | 利用可能なhook |
|---|---|---|
$CLAUDE_PROJECT_DIR | プロジェクトルートの絶対パス | 全hook |
$CLAUDE_ENV_FILE | 環境変数永続化用のファイルパス | SessionStartのみ |
$CLAUDE_CODE_REMOTE | リモート(Web)環境で"true"、ローカルCLIでは未設定 | 全hook |
${CLAUDE_PLUGIN_ROOT} | プラグインディレクトリの絶対パス | Plugin hooks |
まとめ¶
Claude Code Hooksは、初期の4イベント・コマンド実行のみの仕組みから、11イベント・3実行タイプを備えたエコシステム統合型の自動化基盤へと進化した。Plugin hooks、MCP連携、Skills/Subagentsフロントマターでの定義など、Claude Codeの各機能との統合が深まっており、開発ワークフロー全体にわたる決定論的な制御が可能になっている。
適切に実装することで「モデルへの期待」から「確実な実行保証」への移行を実現できる。一方で、hookはユーザー権限で任意のコマンドを実行するため、セキュリティへの配慮は不可欠である。
関連記事¶
14種のイベント・3種のハンドラタイプの基礎知識
エラーハンドリングとチーム開発での活用
全コマンド・設定・ショートカットを活用度別に整理
安全な自動許可モードの運用
関連リソース¶
- Claude Code Hooks公式リファレンス
- Claude Code Hooksガイド(入門)
- Claude Code Plugins公式ドキュメント
- awesome-claude-code(コミュニティhook集)
- claude-code-hooks-mastery(実装サンプル集)
この記事は2025年1月18日に初版公開、2026年2月27日に最新仕様に基づき全面改訂しました。最新情報は公式ドキュメントをご確認ください。