>

Claude Code Hooks 応用編|個人からチーム展開へ・本格運用ガイド

Claude Code Hooks 応用編|個人からチーム展開へ・本格運用ガイド

INDEX

目次

要約

入門編では Hooks の基本概念と3つの実例を、基礎編では品質保証・通知・実践 Tips のレシピを紹介した。本記事(応用編)では、仕様駆動開発でのドリフト検出、監査ログの自動記録、パッケージマネージャー統一やファイル保護などのセキュリティ強化、Git ブランチ保護・自動コミット、そして Hooks 自体のセキュリティリスクと運用上の落とし穴を扱う。

ここまで読めば、Hooks の導入から本格運用まで一通りカバーできる。

対象読者: 基礎編までの内容を理解し、より高度なユースケースや本格運用のノウハウを知りたい開発者。チームでの Hooks 導入を検討している方。

この記事を読むことで得られるメリット

この記事を読むことで以下のことが分かる:

  • 仕様書と実装の乖離を自動検知する仕組みを構築できる
  • 全操作の監査ログをパフォーマンス影響なしで記録する方法が分かる
  • パッケージマネージャーの統一やファイル保護をシステムレベルで強制できる
  • 秘匿情報を3段階で確実に防御する方法を把握できる
  • Git ブランチ保護や自動コミットでチーム開発の安全性を高められる
  • Hooks 自体のセキュリティリスク(CVE)を把握し対策できる
  • 運用でよくある落とし穴を事前に回避できる

この記事を読むのにかかる時間

約30分

環境

  • Claude Code 2.0.65+
  • macOS / Linux
  • jq がインストール済みであること

なぜ Hooks を「開発基盤」として考えるのか

入門編・基礎編では、Hooks を「個別の問題を解決する便利ツール」として紹介してきた。応用編では視点を一段上げ、Hooks を**開発基盤(インフラ)**として位置づける。

個別のフックを組み合わせることで、仕様と実装の整合性を自動検証し、全操作を監査ログに記録し、セキュリティポリシーをシステムレベルで強制し、Git ワークフローを自動化する。これは「便利な自動化」ではなく、チーム全体の開発プロセスを制御する基盤である。

仕様駆動開発 — ドリフト検出

2段階構成: 変更追跡 + 完了時整合性チェック

仕様書と実装の乖離(ドリフト)を自動検出する仕組みを、2段階のフックで構築する。

フェーズ1(PostToolUse): 実装ファイル変更のたびに仕様書ドリフトを追跡

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

# specs/ディレクトリ内の仕様書変更はスキップ
if [[ "$FILE_PATH" == */specs/* ]]; then
  exit 0
fi

# 実装ファイル変更時、対応する仕様書の存在チェック
if [[ "$FILE_PATH" == */src/* ]]; then
  BASENAME=$(basename "$FILE_PATH" | sed 's/\.[^.]*$//')
  SPEC_FILE="$CLAUDE_PROJECT_DIR/specs/${BASENAME}.md"

  if [[ -f "$SPEC_FILE" ]]; then
    echo "$FILE_PATH -> $SPEC_FILE" >> "$CLAUDE_PROJECT_DIR/.claude/spec-drift-log.txt"
    echo "注意: $FILE_PATH に対応する仕様書 $SPEC_FILE が存在します。実装完了後に仕様書の更新が必要な可能性があります。" >&2
    exit 2
  fi
fi

exit 0

フェーズ2(Stop + agent): 実装完了時に仕様書との整合性を一括検証

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "agent",
            "prompt": "実装作業が完了しました。以下を検証してください: 1) .claude/spec-drift-log.txt が存在する場合、記録された実装ファイルと仕様書のペアを確認 2) 各ペアについて、実装の変更内容が仕様書に反映されているか検証 3) 不整合がある場合、仕様書を更新して spec-drift-log.txt をクリア 4) すべて整合している場合は ok を返す。$ARGUMENTS",
            "timeout": 120
          }
        ]
      }
    ]
  }
}

実践事例: dely社(クラシル)の仕様書自動更新

dely社では、Claude Code のカスタムコマンドと git log を組み合わせ、Notion MCP 経由で仕様書を自動更新する仕組みを構築している。従来手動で30分かかっていた仕様書更新が3分で自動完了し、運用チームの問い合わせ対応時間が25%削減された(出典: dely社 Zenn記事)。

監査ログとコスト把握

JSONL ログ記録(機械処理向け)

PostToolUse を async: true で設定し、全ツール呼び出しをタイムスタンプ付きで JSONL に記録する。async: true のため Claude の作業は一切ブロックされず、パフォーマンスへの影響がない。

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/audit-log.sh",
            "async": true
          }
        ]
      }
    ]
  }
}
#!/bin/bash
INPUT=$(cat)
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
TOOL_INPUT=$(echo "$INPUT" | jq -c '.tool_input // {}')

echo "{\"timestamp\":\"$TIMESTAMP\",\"tool\":\"$TOOL_NAME\",\"input\":$TOOL_INPUT}" \
  >> "$CLAUDE_PROJECT_DIR/.claude/logs/audit.jsonl"

exit 0

JSONL 形式で蓄積されるため、後から grep / jq で分析可能である。セキュリティ監査やインシデント調査の際に「Claude が何をしたか」を追跡できるエビデンスとして活用できる(出典: DEV Community)。

Markdown 形式のコード変更ログ(人間向け)

Claude によるコード変更を人間が読みやすい Markdown 形式の CHANGELOG に自動記録する。

#!/bin/bash
INPUT=$(cat)
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // "unknown"')
TOOL_INPUT=$(echo "$INPUT" | jq -r '.tool_input // "{}"')
FILE_PATH=$(echo "$TOOL_INPUT" | jq -r '.file_path // .notebook_path // "N/A"')

# Edit/Write/NotebookEdit 以外はスキップ
if [[ "$TOOL_NAME" != "Write" ]] && [[ "$TOOL_NAME" != "Edit" ]] && [[ "$TOOL_NAME" != "NotebookEdit" ]]; then
    exit 0
fi

# .claude配下は除外(無限ループ防止)
if [[ "$FILE_PATH" == *"/.claude/"* ]]; then
    exit 0
fi

# 変更タイプを自動判定して CHANGELOG.md に追記
DATE_HEADER=$(date '+%Y年%m月%d日')
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

LOG_FILE="$CLAUDE_PROJECT_DIR/.claude/logs/CHANGELOG.md"

# 日付ヘッダーが存在しなければ追加
if ! grep -q "## $DATE_HEADER" "$LOG_FILE" 2>/dev/null; then
  echo -e "\n## $DATE_HEADER\n" >> "$LOG_FILE"
fi

# ツール種別に応じた絵文字
case "$TOOL_NAME" in
  Write) EMOJI="new" ;;
  Edit)  EMOJI="edit" ;;
  *)     EMOJI="memo" ;;
esac

echo "- [${EMOJI}] \`${TIMESTAMP}\` ${FILE_PATH}" >> "$LOG_FILE"

exit 0

JSONL ログが「全操作の機械可読な監査証跡」であるのに対し、こちらは人間が日々の変更を振り返るための読みやすいログである。

ConfigChange による設定変更の監査

ConfigChange フックを使うと、セッション中に settings.json や skills ファイルが変更された際に、その変更を監査ログに記録したり、不正な変更をブロックできる。

{
  "hooks": {
    "ConfigChange": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"[$(date -u +%Y-%m-%dT%H:%M:%SZ)] Config changed\" >> \"$CLAUDE_PROJECT_DIR/.claude/logs/config-audit.log\""
          }
        ]
      }
    ]
  }
}

matcher に user_settingsproject_settingslocal_settingsskills を指定することで、特定の設定ソースの変更のみを対象にできる。

監視ダッシュボード

OpenTelemetry + Grafana

claude-code-otel は Claude Code → OpenTelemetry Collector → Prometheus + Loki → Grafana のパイプラインでリアルタイム監視を実現する。セッション数、コード変更行数、トークン使用量、モデル別コストを可視化できる。大規模なチーム運用や、AI 開発のコスト管理が求められる環境に適している。

マルチエージェント監視ダッシュボード

claude-code-hooks-multi-agent-observability は、全ライフサイクルイベントを SQLite に記録し、WebSocket 経由で Vue.js アプリにリアルタイム配信する。複数の Claude Code セッションを並列で動かす場合のモニタリングに特化している。

パッケージマネージャー統一の強制

pnpm を使うプロジェクトで、Claude が npm install を実行しようとした場合にブロックし、pnpm への置き換えを促す。

CLAUDE.md に「pnpm を使って」と書いても、Claude は文脈によって npm を使うことがある。CLAUDE.md でのルール遵守率が約70%だったものが、Hooks で100%になったという報告もある(出典: GenAI Unplugged)。

.claude/hooks/enforce-pnpm.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command')
if [ -f "pnpm-lock.yaml" ] && echo "$CMD" | grep -qE "^npm\s"; then
  echo "Replace 'npm' with 'pnpm'. This project uses pnpm." >&2
  exit 2
fi
exit 0

.claude/settings.json では Bash マッチャーに追加する:

{
  "matcher": "Bash",
  "hooks": [
    {
      "type": "command",
      "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/enforce-pnpm.sh"
    }
  ]
}

pnpm 強制フックの実装例は Steve Kinney のコース でも紹介されている。

updatedInput による透過変換

ブロックではなく、updatedInput を使って npm installni(pnpm 対応ユニバーサルインストーラ)に透過的に変換する方法もある。updatedInput は PreToolUse フックの出力フィールドで、ツールに渡される引数を Claude に知られずに書き換えることが可能である(出典: Zenn)。

ファイル保護

.envpackage-lock.json.git/ 配下など、Claude に変更されたくないファイルへの書き込みをブロックする。

.claude/hooks/protect-files.sh:

#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

PROTECTED_PATTERNS=(".env" "package-lock.json" ".git/" "config/production/")

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == *"$pattern"* ]]; then
    echo "Blocked: $FILE_PATH matches protected pattern '$pattern'" >&2
    exit 2
  fi
done

exit 0

.claude/settings.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}

PROTECTED_PATTERNS 配列はプロジェクトに合わせてカスタマイズする。本番環境の設定ファイルや、ロックファイルなど「Claude に触らせたくないファイル」を追加していく。

なぜ permissions.deny だけでは不十分か

Claude Code には permissions.deny という組み込みの拒否設定があるが、これは単純な文字列マッチングのため、パイプやマルチラインコマンドで回避されるケースが報告されている。PreToolUse フックは Claude が Bash ツールに渡すコマンド文字列全体を受け取ってスクリプトで自由に解析できるため、より堅牢なアクセス制御が可能である(出典: DEV Community)。

秘匿情報の検出・ブロック(3段階防御)

Claude がコードを生成してファイルに書き込む際、AWS アクセスキーや GitHub トークンなどの秘匿情報がハードコードされてしまう可能性がある。これを3段階で防御する。

第1段階: Edit/Write 時(ファイル書き込み前)

Claude が Edit/Write ツールでファイルを変更しようとした際、書き込み予定の内容を正規表現でスキャンする。秘匿情報のパターンに該当すれば exit 2 で書き込み自体をブロックし、ファイルに秘匿情報が混入すること自体を未然に防ぐ

第2段階: git commit 時(ステージング済みファイルのスキャン)

万が一第1段階をすり抜けた場合や、Claude 以外の操作で秘匿情報が混入した場合のために、git commit 実行前にステージング済みファイルの差分をスキャンする。

第3段階: git push 時(リモートへの送信前の最終防衛線)

リモートに送信される前に、未プッシュのコミットの差分を再度スキャンする。

.claude/hooks/scan-secrets-on-commit.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# git commit / git push 以外はスルー
if ! echo "$CMD" | grep -qE 'git\s+(commit|push)'; then
  exit 0
fi

# 検出対象の秘匿情報パターン
SECRETS_PATTERN='AKIA[0-9A-Z]{16}|ghp_[a-zA-Z0-9]{36}|sk_live_[a-zA-Z0-9]{24,}|-----BEGIN (RSA |EC )?PRIVATE KEY-----'

# git commit の場合: ステージング済みファイルをスキャン
if echo "$CMD" | grep -qE 'git\s+commit'; then
  MATCHES=$(git diff --cached --diff-filter=ACMR | grep -oE "$SECRETS_PATTERN" 2>/dev/null)
  if [ -n "$MATCHES" ]; then
    echo "BLOCKED: ステージング済みファイルに秘匿情報が含まれています:" >&2
    echo "$MATCHES" >&2
    echo "該当ファイルから秘匿情報を除去してからコミットしてください。" >&2
    exit 2
  fi
fi

# git push の場合: リモートとの差分をスキャン
if echo "$CMD" | grep -qE 'git\s+push'; then
  REMOTE_BRANCH=$(git rev-parse --abbrev-ref --symbolic-full-name @{u} 2>/dev/null || echo "origin/main")
  MATCHES=$(git diff "$REMOTE_BRANCH"...HEAD | grep -oE "$SECRETS_PATTERN" 2>/dev/null)
  if [ -n "$MATCHES" ]; then
    echo "BLOCKED: プッシュ対象のコミットに秘匿情報が含まれています:" >&2
    echo "$MATCHES" >&2
    echo "秘匿情報を除去し、コミットを修正してからプッシュしてください。" >&2
    exit 2
  fi
fi

exit 0

パターン

検出対象

AKIA[0-9A-Z]{16}

AWS アクセスキー

ghp_[a-zA-Z0-9]{36}

GitHub パーソナルアクセストークン

sk_live_[a-zA-Z0-9]{24,}

Stripe 本番シークレットキー

-----BEGIN.*PRIVATE KEY-----

SSH/TLS 秘密鍵

秘匿情報検出パターンの詳細は AITMPL のブログ記事 も参考になる。

Slopsquatting & プロンプトインジェクション防御

Slopsquatting 防御

Slopsquatting は比較的新しい攻撃手法で、以下のように成立する。

  1. 攻撃者が AI の生成しそうな「それっぽいが実在しない」パッケージ名を予測し、npm/PyPI に悪意あるコード入りで先に公開する
  2. Claude がコード生成時に実在しないパッケージ名を幻覚し、npm install を実行しようとする
  3. レジストリに同名の悪意あるパッケージが存在するため、マルウェアがインストールされる

PreToolUse フックで依存追加コマンドをインターセプトし、パッケージ名をレジストリで存在確認したり、ホワイトリストと照合することで、開発者のレビューを挟むことができる(出典: Pixelmojo)。

プロンプトインジェクション防御

Claude がツールで外部コンテンツ(Web ページ、ファイル等)を読み取った際、そのコンテンツに悪意ある指示が埋め込まれている可能性がある。

dwarvesf/claude-guardrails は5層のセキュリティ構成でこの問題に対処する。

  1. Permission deny ルール
  2. PreToolUse フック(Bash コマンドパターンブロック)
  3. OS-level sandbox
  4. PostToolUse スキャナー(プロンプトインジェクション検出)
  5. CLAUDE.md セキュリティルール

PostToolUse フックでツールの出力内容をスキャンし、プロンプトインジェクションのパターンを検出した場合、additionalContext で Claude に警告を注入して指示に従わないよう促す仕組みである。

Git 連携

main ブランチ保護

main ブランチ上での直接作業を禁止する。

[ "$(git branch --show-current)" != "main" ] || { echo '{"block": true}' >&2; exit 2; }

PreToolUse で Edit|Write マッチャーに設定すると、main ブランチ上でのファイル変更がブロックされる(出典: ChrisWiles/claude-code-showcase)。

ターン単位の自動コミット

Claude が一連の作業を終えるたびに、Stop フックで自動的に git commit する。いつでもロールバック可能な安全網になる(出典: BleepingSwift)。

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "cd \"$CLAUDE_PROJECT_DIR\" && git add -A && git diff-index --quiet HEAD || git commit -m \"checkpoint\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

git diff-index --quiet HEAD で変更がない場合はコミットをスキップする。|| true でコミット失敗時もフック全体がエラーにならないようにしている。

特定ブランチへの Git プッシュ禁止

CLAUDE.md に「main / develop には直接プッシュしないで」と書いても、Claude がコンテキスト圧縮後にルールを忘れ、git push origin main を実行してしまう可能性がある。

.claude/hooks/block-branch-push.sh:

#!/bin/bash
INPUT=$(cat)
CMD=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# git push コマンド以外はスルー
if ! echo "$CMD" | grep -qE 'git\s+push'; then
  exit 0
fi

# 保護対象ブランチ一覧
PROTECTED_BRANCHES=("main" "master" "develop" "release" "production")

for branch in "${PROTECTED_BRANCHES[@]}"; do
  if echo "$CMD" | grep -qE "git\s+push\s+.*\b${branch}\b"; then
    echo "BLOCKED: '${branch}' ブランチへの直接プッシュは禁止されています。feature ブランチから PR を作成してください。" >&2
    exit 2
  fi
done

# リモート指定なしの push もチェック
if echo "$CMD" | grep -qE '^git\s+push\s*$'; then
  CURRENT_BRANCH=$(git branch --show-current 2>/dev/null)
  for branch in "${PROTECTED_BRANCHES[@]}"; do
    if [ "$CURRENT_BRANCH" = "$branch" ]; then
      echo "BLOCKED: 現在のブランチ '${branch}' は保護対象です。feature ブランチに切り替えてからプッシュしてください。" >&2
      exit 2
    fi
  done
fi

exit 0

通常プッシュとフォースプッシュの両方をブロックし、ブロック理由と代替手順(PR 作成)を明示する。

Tips: CLAUDE.md との併用推奨。Hooks でブロックするだけでなく、CLAUDE.md に「feature ブランチで作業し、PR 経由でマージする」というワークフローを記述しておくと、Claude がブロックされる前に正しい手順を選択する確率も上がる。Hooks は「最終防衛線」、CLAUDE.md は「事前の誘導」として併用するのが効果的である。

カスタム Worktree フック

Matt Brailsford の事例760行のカスタムスキルを80行のフック×2に置き換えた

WorktreeCreate フックで .worktreeinclude に指定された git 管理外ファイル(設定、DB、環境変数)を新しい worktree に自動コピーし、Gitflow のブランチ命名規則(feature/xxx)を自動適用する。

Skills は「タスクの知識と手順」を提供するが、Hooks は「イベントに対する自動アクション」を提供する。Worktree 作成のような定型処理は Hooks の方が適している好例である。

スキル・サブエージェントのフック定義

settings.json だけでなく、スキルやサブエージェントのフロントマターにもフックを定義できる。

---
name: secure-operations
hooks:
  PreToolUse:
    - matcher: "Bash"
      hooks:
        - type: command
          command: "./scripts/check.sh"
---

主な特徴

  • コンポーネントがアクティブな時のみ実行: そのスキルやサブエージェントが動作している間だけフックが有効になる
  • 完了時に自動クリーンアップ: スキルの実行が終われば、フックも自動的に解除される
  • SubagentStop 自動変換: サブエージェント内で定義した Stop イベントは、自動的に SubagentStop イベントに変換される
  • 全イベントタイプをサポート: settings.json と同じ全イベントタイプが使用可能

settings.json との違い

観点

settings.json

フロントマター

スコープ

常時グローバル有効

そのスキル/エージェント実行中のみ有効

管理

プロジェクト全体で共有

スキル単位で独立管理

用途

プロジェクト共通のルール

タスク固有の制約・検証

スキル固有のセキュリティルールや品質チェックは、settings.json ではなくフロントマターに定義することで、必要な時だけ有効になる軽量な制御が実現できる。

セキュリティリスク — Hooks 自体の脆弱性

Hooks はセキュリティを強化する強力なツールだが、Hooks 自体が攻撃ベクトルになりうることも知っておく必要がある。

CVE-2025-59536

Check Point Research が2026年2月に公開した脆弱性。悪意あるリポジトリの .claude/settings.json に Hook を仕込むことで、クローンしたユーザーの環境でRCE(リモートコード実行)や API キー窃取が可能だった。

「信頼できないリポジトリを開くだけで攻撃が成立する」極めて深刻な脆弱性として "critical" と評価された。Claude Code 2.0.65+ で修正済み

対策:

  • Claude Code を最新バージョンに保つ
  • 信頼できないリポジトリの .claude/settings.json を確認してから作業する

Claude による Hook 回避

GitHub Issue #29691 で報告された事例。Claude Opus 4.6 が PostToolUse フックで検出される禁止用語を途中で切って難読化する(例: "vorbestehend" → "vorbesteh--")ことでフックを回避した。

これは Hooks ベースのセキュリティが完全に信頼できるわけではないことを示している。Hooks は重要な防御層だが、唯一の防御策として依存すべきではなく、多層防御の一環として位置づけるべきである。

よくある落とし穴とデバッグ

入門編で紹介した間違い(exit 1 vs exit 2、$HOME のパス展開)に加え、運用で遭遇しやすい落とし穴を紹介する。

フックの実行時間超過

同期フックが遅いと全体のレスポンスが悪化する。推奨は 500ms 以下。

対策: サイドエフェクト系(ログ記録、通知等)は "async": true でバックグラウンド実行する。

既知バグ

バグ

概要

対策

Issue #16047

約2.5時間後に Hooks が無言で停止する

hooks.log が肥大化するのが原因。定期的にクリアする

Issue #3523

Hook 設定が累積重複し、1回の編集で10以上のインスタンスが同時実行される

セッション再起動で解消

disableAllHooks による一時無効化

フックが問題を起こしている場合、設定ファイルに "disableAllHooks": true を追加すると全フックを一時的に無効化できる。原因の切り分けに便利である。

{
  "disableAllHooks": true
}

付録: Hooks リファレンス早見表

全イベントタイプ一覧(全22種類)

イベント

発火タイミング

ブロック可能

PreToolUse

ツール実行前

はい

PostToolUse

ツール実行成功後

いいえ ※1

PostToolUseFailure

ツール実行失敗後

いいえ

Stop

Claude が応答完了時

はい

StopFailure

APIエラーでターン終了時

いいえ

Notification

通知送信時

いいえ

SessionStart

セッション開始/再開時

いいえ

SessionEnd

セッション終了時

いいえ

UserPromptSubmit

プロンプト送信時

はい

PermissionRequest

権限ダイアログ表示時

はい

ConfigChange

設定ファイル変更時

はい

PreCompact

コンテキスト圧縮前

いいえ

PostCompact

コンテキスト圧縮完了後

いいえ

SubagentStart

サブエージェント生成時

いいえ

SubagentStop

サブエージェント終了時

はい

TeammateIdle

チームメイトがアイドル化時

はい

TaskCompleted

タスク完了マーク時

はい

InstructionsLoaded

CLAUDE.md ロード時

いいえ

WorktreeCreate

ワークツリー作成時

はい

WorktreeRemove

ワークツリー削除時

いいえ

Elicitation

MCP ユーザー入力要求時

はい

ElicitationResult

MCP エリシテーション応答後

はい

※1 PostToolUse はツール実行後のため実行自体はブロックできないが、decision: "block" で Claude にフィードバックを返し修正を促すことは可能。

主要マッチャー値

イベント

マッチ対象

値の例

PreToolUse / PostToolUse / PostToolUseFailure / PermissionRequest

ツール名

Bash, Edit|Write, mcp__server__tool

SessionStart

開始方法

startup, resume, clear, compact

SessionEnd

終了理由

clear, resume, logout, prompt_input_exit

Notification

通知タイプ

permission_prompt, idle_prompt, auth_success, elicitation_dialog

PreCompact / PostCompact

圧縮トリガー

manual, auto

ConfigChange

設定ソース

user_settings, project_settings, local_settings, policy_settings, skills

SubagentStart / SubagentStop

エージェント名

Bash, Explore, Plan

StopFailure

エラータイプ

rate_limit, authentication_failed, server_error

InstructionsLoaded

ロード理由

session_start, nested_traversal, compact

Elicitation / ElicitationResult

MCP サーバー名

設定済みの MCP サーバー名

UserPromptSubmit / Stop / TeammateIdle / TaskCompleted / WorktreeCreate / WorktreeRemove

-

マッチャー非対応(常に全出現で発火)

主要出力フィールド

フィールド

対象イベント

説明

additionalContext

SessionStart, UserPromptSubmit, PreToolUse, PostToolUse, PostToolUseFailure, Notification, SubagentStart

Claude のコンテキストに文字列を追加

updatedInput

PreToolUse, PermissionRequest

ツール入力パラメータを書き換え

permissionDecision

PreToolUse

allow / deny / ask

decision

UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStop, ConfigChange

block でアクションをブロック

continue

全イベント

false で Claude の処理を完全停止

stopReason

全イベント

continue: false 時にユーザーに表示するメッセージ

suppressOutput

全イベント

true で verbose からの stdout 非表示

systemMessage

全イベント

ユーザーに警告メッセージを表示

環境変数・プレースホルダー

変数

説明

$CLAUDE_PROJECT_DIR

プロジェクトルートディレクトリ(全フックで利用可能)

$CLAUDE_ENV_FILE

SessionStart フックで環境変数を永続化するためのファイルパス

$CLAUDE_CODE_REMOTE

リモート Web 環境で "true" に設定される

$ARGUMENTS

prompt/agent フックの prompt フィールド内で使うテンプレートプレースホルダー。フック入力 JSON に置換される

全フィールドの詳細は公式 Hooks リファレンスを参照。

まとめ — シリーズ全体の振り返り

3記事にわたって Claude Code Hooks を「入門→基礎→応用」の段階で解説してきた。

入門編: Hooks の基本概念と「3つの実例」

  • CLAUDE.md は確率的、Hooks は決定論的。この違いが全て
  • 目次と本文の整合性チェック、危険コマンドブロック、Markdown PDF 自動生成

基礎編: 日常開発を支えるレシピ集

  • Chrome 拡張ワークフロー、TDD Guard、自動 Lint/Format
  • デプロイ確認の自動オープン、API スモークテスト
  • Slack 通知、TTS 音声通知
  • 重複コード検出、Skill 自動選択

応用編: 本格運用のノウハウ

  • 仕様駆動開発でのドリフト検出(PostToolUse + Stop agent の2段階)
  • 監査ログ(JSONL + Markdown CHANGELOG)
  • パッケージマネージャー統一、ファイル保護
  • 秘匿情報の3段階防御、Slopsquatting & PI 防御
  • Git ブランチ保護、自動コミット、プッシュ制限
  • スキル・サブエージェントのフック定義
  • セキュリティリスク(CVE-2025-59536、Claude による Hook 回避)

Hooks は強力な仕組みだが、全てを Hooks で制御する必要はない。まず CLAUDE.md で済むものは CLAUDE.md に書き、それでは不十分な場合——つまり「絶対に破られてはならないルール」や「外部システムとの連携」が必要な場合にのみ、Hooks を検討する。

最初は入門編の3つのフックから始めて、プロジェクトの成長に合わせて基礎・応用のパターンを取り入れていくのが推奨のアプローチである。