Hooks システム

Claude Code の Hooks を完全習得 — 17 種類のライフサイクルイベント、3 種類のハンドラー、10 以上の実践レシピと企業向け設定

最終更新 2026-09-03

API キーが必要ですか? 登録する →エンドポイントと Base URL →

目次

Hooks を使うと、Claude Code のライフサイクルの要所に独自のロジックを差し込めます — コードの自動整形、危険なコマンドの遮断、通知の送信、監査ログの記録など。Hooks は Claude Code で最も強力な拡張機構のひとつです。


一、コアコンセプト

Hook は 3 つの要素で構成されます:

イベント(When)  →  マッチャー(Which)  →  ハンドラー(What)
PreToolUse           matcher: "Bash"         command: "check_safety.sh"
  • イベント:発火のタイミング(例:PreToolUse — ツール実行前)
  • マッチャー:任意のツール名フィルター(Bash だけ、Write だけ など)
  • ハンドラー:シェルコマンド、プロンプト注入、またはサブエージェント

二、イベント完全リスト

コアイベント

イベント 発火タイミング 遮断可否 代表的な用途
PreToolUse ツール実行前 可(exit 2) セキュリティ遮断、引数の検証
PostToolUse ツール実行後 不可 自動整形、ログ記録
Notification Claude が通知を送るとき 不可 Slack / Feishu / DingTalk への通知
Stop Claude が応答を終えたとき 不可 品質チェック、自動コミット
UserPromptSubmit ユーザーがプロンプトを送信したとき 可 コンテキスト注入、ポリシーチェック
SessionStart セッション開始時 不可 環境の初期化、ウェルカムメッセージ

拡張イベント(2026 年に追加)

イベント 発火タイミング 遮断可否 代表的な用途
SubagentStop サブエージェント完了時 不可 サブエージェントの結果を収集
SubagentToolUse サブエージェントがツールを使うとき 可 サブエージェントの権限を制限
FileChanged ファイルが変更されたとき 不可 自動 lint、ビルドのトリガー
CwdChanged 作業ディレクトリが変わったとき 不可 ディレクトリ固有の設定を読み込む
ModelChange モデルを切り替えたとき 不可 モデル利用状況の記録
CompactComplete /compact 完了時 不可 コンテキスト圧縮後の処理
ToolError ツールがエラーになったとき 不可 エラー収集、リトライ処理

三、ハンドラーの種類

種類 1:Command(シェルコマンド)

最もよく使う種類で、シェルコマンドを実行します:

{
  "type": "command",
  "command": "npx prettier --write $FILEPATH"
}

環境変数: | 変数 | 説明 | 利用できるイベント | |------|------|---------| | $FILEPATH | 対象ファイルのパス | PreToolUse/PostToolUse | | $TOOL_INPUT | ツール入力の JSON | PreToolUse | | $TOOL_NAME | ツール名 | PreToolUse/PostToolUse | | $SESSION_ID | セッション ID | すべて | | $NOTIFICATION_MESSAGE | 通知の本文 | Notification |

stdin 入力:Hook スクリプトには stdin からも JSON が渡され、session_id・tool_name・tool_input が含まれます。構造化データが必要なときは環境変数を解析するよりこちらのほうが確実です。

終了コード:

  • 0:続行を許可
  • 2:操作を遮断(PreToolUse/UserPromptSubmit のみ)
  • それ以外:エラー扱いだが遮断はしない

種類 2:Prompt(プロンプト注入)

テキストを Claude のコンテキストに注入します:

{
  "type": "prompt",
  "prompt": "重要:データベース操作は必ずトランザクションを使うこと"
}

向いている場面:SessionStart でプロジェクト固有のルールを追加で注入する。

種類 3:Subagent(サブエージェント)

イベントを処理するサブエージェントを生成します:

{
  "type": "subagent",
  "prompt": "たった今変更されたコードをレビューし、セキュリティ上の脆弱性がないか確認して"
}

向いている場面:PostToolUse の後に自動でコード品質をレビューする。


四、設定方法

.claude/settings.json(プロジェクト単位)または ~/.claude/settings.json(ユーザー単位)で設定します:

{
  "hooks": {
    "イベント名": [
      {
        "matcher": "ツール名(任意。| で複数指定可)",
        "hooks": [
          {
            "type": "command|prompt|subagent",
            "command": "..."
          }
        ]
      }
    ]
  }
}

五、実践レシピ

レシピ 1:ファイル保存後に自動整形する

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $FILEPATH 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

レシピ 2:危険なシェルコマンドを遮断する

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo $TOOL_INPUT | grep -qE 'rm -rf /|sudo rm|git push --force|DROP TABLE|DROP DATABASE' && echo '危険なコマンドを遮断しました' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

レシピ 3:機密ファイルを保護する

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Read|Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $TOOL_INPUT | grep -qE '\\.env|\\.env\\.|credentials|secrets?\\.ya?ml|private.key' && echo '機密ファイルへのアクセスを遮断しました' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

レシピ 4:タスク完了時にシステム通知を出す

macOS:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"$NOTIFICATION_MESSAGE\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Linux:

{
  "hooks": {
    "Notification": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' \"$NOTIFICATION_MESSAGE\""
          }
        ]
      }
    ]
  }
}

レシピ 5:Slack へ通知する

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "curl -s -X POST https://hooks.slack.com/services/xxx/yyy/zzz -H 'Content-Type: application/json' -d '{\"text\": \"Claude Code のタスクが完了しました\"}'"
          }
        ]
      }
    ]
  }
}

レシピ 6:ESLint の自動修正

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix $FILEPATH 2>/dev/null; npx prettier --write $FILEPATH 2>/dev/null; exit 0"
          }
        ]
      }
    ]
  }
}

レシピ 7:監査ログ

{
  "hooks": {
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date -u +%Y-%m-%dT%H:%M:%SZ) | session=$SESSION_ID | tool=$TOOL_NAME | file=$FILEPATH\" >> ~/.claude/audit.log"
          }
        ]
      }
    ]
  }
}

レシピ 8:テストを自動実行する

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $FILEPATH | grep -qE '\\.(ts|tsx|js|jsx)$' && echo $FILEPATH | grep -qvE '\\.test\\.|\\.spec\\.' && npx vitest related $FILEPATH --run 2>/dev/null || exit 0"
          }
        ]
      }
    ]
  }
}

レシピ 9:マイグレーションファイルを保護する

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo $FILEPATH | grep -qE 'migrations/|alembic/versions/' && echo '既存のマイグレーションは変更禁止です。新しいマイグレーションを作成してください' && exit 2 || exit 0"
          }
        ]
      }
    ]
  }
}

レシピ 10:セッション開始時にコンテキストを注入する

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "重要なお知らせ:本プロジェクトは v3.0 の大規模リファクタリング中です。新しいコードは必ず React Server Components を使い、pages/ ディレクトリはもう使いません。"
          }
        ]
      }
    ]
  }
}

六、エンタープライズ向け Hooks

managed-settings.d/ の設定

企業の管理者は managed-settings.d/ ディレクトリを使って、組織全体にセキュリティポリシーを強制できます:

# 企業管理ディレクトリにポリシーファイルを作成する
mkdir -p /etc/claude-code/managed-settings.d/
// /etc/claude-code/managed-settings.d/security.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/opt/claude-policy/check_command.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "/opt/claude-policy/audit_log.sh"
          }
        ]
      }
    ]
  }
}

企業ポリシーは ユーザー単位やプロジェクト単位の設定では上書きできません。


七、デバッグとトラブルシューティング

Verbose モード

Ctrl+O で verbose モードをオンにすると、次が見えます:

  • Hook が発火したタイミング
  • Hook スクリプトの stdout / stderr
  • Hook の終了コード

よくある問題

問題 原因 対処
Hook が発火しない matcher のつづり間違い ツール名の大文字小文字を確認:Bash、Write、Edit、Read
Hook が正常な操作まで遮断する 終了コードのロジック誤り 正常時は exit 0、遮断したいときだけ exit 2 にする
Hook が遅い スクリプトに時間がかかりすぎ Hook は 1〜2 秒で終わるように。長い処理はバックグラウンドで
環境変数が空 そのイベントでは提供されない 上の環境変数表で、そのイベントで使えるか確認する

Hook スクリプトをテストする

設定に入れる前に、ターミナルで手動テストします:

# PreToolUse の環境変数を模擬する
FILEPATH="src/main.ts" TOOL_INPUT="rm -rf /" bash -c 'echo $TOOL_INPUT | grep -qE "rm -rf" && echo "blocked" && exit 2 || exit 0'

八、Codex Hooks との比較

項目 Claude Code Hooks Codex Hooks
イベント数 17 種類 少なめ
設定方法 settings.json config.toml
ハンドラーの種類 command/prompt/subagent command
企業管理 managed-settings.d/ なし
遮断機能 終了コード 2 限定的

次のステップ

QCode を始める

API キーひとつで Claude Code・Codex などに対応。トークン単位の課金で、各モデルの単価は qcode.cc/models に掲載

企業版 →