Hooks(フック)

Hooks は、Claude Code の動作の決まったタイミングで自動的に実行される処理です。ツール実行前にチェックを入れたり、実行後にログを取ったり、危険な操作を自動でブロックしたりできます。

Hooks とは

身近な例えで理解する

Hooks なし

社員は自由にサーバールームに入れる。危険な操作をしても誰も止めない。

Hooks あり

サーバールームのドアにセキュリティゲートがある。入る前にIDカードをかざし(PreToolUse)、退室後にログが記録される(PostToolUse)。権限のない人は入れない。

なぜ Hooks が必要なのか

1. 危険な操作を自動でブロックできる

CLAUDE.md に「rm -rf を実行しないで」と書いても、AI は指示を100%守るとは限りません。Hooks なら、rm -rf コマンドが実行される前にシェルスクリプトがチェックし、確実にブロックできます。ルールに頼るのではなく、仕組みで防ぐのが Hooks です。

2. 品質チェックを自動化できる

ファイルを編集した後に自動でフォーマッターを実行したり、コミット前にリントを走らせたりできます。「フォーマットし忘れた」「リント通してなかった」というミスがゼロになります。

3. 監査ログを残せる

誰が(どのセッションで)、いつ、何のツールを実行したかを自動記録できます。チーム開発でのトレーサビリティに役立ちます。

4. 環境の自動セットアップ

セッション開始時に環境変数を設定したり、必要なサービスを起動したりできます。毎回手動で環境を整える手間がなくなります。

CLAUDE.md のルールとの違い

CLAUDE.md のルール Hooks
守られる確度 AI が「従おうとする」(100%ではない) シェルスクリプトが強制する(100%)
実行タイミング AI がルールを読んで判断 指定したイベントで自動実行
できること AI の行動を指示 コマンド実行、HTTP 通信、AI 判定
使い分け ガイドライン、推奨事項 絶対に守らせたいルール、自動化

フックタイプ

Hooks には4つのタイプがあり、それぞれ異なる方法で処理を実行します。

タイプ 何をするか 使いどころ
command シェルスクリプトを実行 ファイルチェック、フォーマット、ログ記録
http HTTP エンドポイントに POST 外部サービス連携、リモートでの検証
prompt LLM に1回質問して判定 AI ベースの安全性チェック
agent サブエージェントで検証 ツールを使った複雑な検証

主要なフックイベント

よく使うイベント

イベント タイミング ブロック可能 使用例
SessionStart セッション開始時 - 環境変数の設定、サービス起動
PreToolUse ツール実行 Yes 危険コマンドのブロック、入力の検証
PostToolUse ツール実行 - 自動フォーマット、ログ記録
UserPromptSubmit プロンプト送信時 Yes 入力フィルタリング
Stop Claude の応答完了時 Yes テスト実行の強制
flowchart LR A(["セッション開始"]) B["PreToolUse
ツール実行前"] C["ツール実行"] D["PostToolUse
ツール実行後"] E["Stop
応答完了"] A --> B --> C --> D --> E N["Notification
通知発生時"] U["UserPromptSubmit
プロンプト送信時"] U -.->|"任意のタイミング"| B N -.->|"任意のタイミング"| D style A fill:#e0e7ff,stroke:#6366f1,color:#1e293b style B fill:#fef3c7,stroke:#f59e0b,color:#1e293b style C fill:#ecfdf5,stroke:#10b981,color:#1e293b style D fill:#fef3c7,stroke:#f59e0b,color:#1e293b style E fill:#e0e7ff,stroke:#6366f1,color:#1e293b style N fill:#f0f9ff,stroke:#3b82f6,color:#1e293b style U fill:#f0f9ff,stroke:#3b82f6,color:#1e293b
フックイベントのタイムライン — ツール実行の前後で発火

チーム開発向けイベント

イベント タイミング 用途
TeammateIdle チームメイトが休止する直前 作業を継続させる
TaskCompleted タスク完了マーク時 品質ゲート(テスト未通過なら完了を阻止)
SubagentStart / SubagentStop サブエージェントの開始/終了 サブエージェントの監視

設定方法

設定場所

Hooks は以下のいずれかの設定ファイルに定義します。

ファイル スコープ 用途
~/.claude/settings.json 全プロジェクト共通(個人) 個人の共通フック
.claude/settings.json プロジェクトレベル(チーム共有) プロジェクト共通のフック
.claude/settings.local.json ローカル(gitignore 対象) 個人のローカルフック

基本的な設定構造

.claude/settings.json
{
  "hooks": {
    "イベント名": [
      {
        "matcher": "ツール名の正規表現",
        "hooks": [
          {
            "type": "command",
            "command": "./.claude/hooks/スクリプト名.sh"
          }
        ]
      }
    ]
  }
}

マッチャー(matcher)

特定のツールにだけフックを適用したい場合に正規表現で指定します。省略すると全ツールに適用されます。

パターン マッチするツール
"Bash" Bash のみ
"Edit|Write" Edit または Write
"mcp__memory__.*" Memory MCP の全ツール
省略(matcher なし) 全てのツール
flowchart TD EVENT(["フックイベント発生
(例: PreToolUse)"]) HAS{"matcher が
設定されている?"} MATCH{"ツール名が
正規表現にマッチ?"} EXEC["フック実行"] SKIP["スキップ"] EXIT{"終了コード"} OK["0: 正常続行
stdout をコンテキストに注入"] BLOCK["2: ツール実行をブロック
stderr をエラー表示"] WARN["その他: 警告して続行"] EVENT --> HAS HAS -->|"なし"| EXEC HAS -->|"あり"| MATCH MATCH -->|"マッチ"| EXEC MATCH -->|"不一致"| SKIP EXEC --> EXIT EXIT -->|"0"| OK EXIT -->|"2"| BLOCK EXIT -->|"その他"| WARN style EVENT fill:#e0e7ff,stroke:#6366f1,color:#1e293b style HAS fill:#fef3c7,stroke:#f59e0b,color:#1e293b style MATCH fill:#fef3c7,stroke:#f59e0b,color:#1e293b style EXEC fill:#ecfdf5,stroke:#10b981,color:#1e293b style EXIT fill:#fef3c7,stroke:#f59e0b,color:#1e293b style OK fill:#ecfdf5,stroke:#10b981,color:#1e293b style BLOCK fill:#fee2e2,stroke:#ef4444,color:#1e293b style WARN fill:#fef3c7,stroke:#f59e0b,color:#1e293b
フックのマッチャー判定と終了コードによる処理分岐

終了コードの意味

フックスクリプトの終了コードで動作を制御します。

終了コード 意味 動作
0 成功 処理を続行。stdout の内容を Claude に伝達
2 ブロック 処理を中止。stderr の内容をエラーとして Claude に伝達
その他 エラー(非ブロック) 処理は続行

実践例

例1: 保護ファイルへの編集をブロック

.envpackage-lock.json など、AI が編集すべきでないファイルへのアクセスを自動でブロックします。

.claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "./.claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}
.claude/hooks/protect-files.sh
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

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

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == *"$pattern"* ]]; then
    echo "保護対象ファイルへの変更はブロックされました: $FILE_PATH" >&2
    exit 2
  fi
done

exit 0

例2: ファイル編集後の自動フォーマット

ファイルが編集された後に、自動的に Prettier などのフォーマッターを実行して整形します。

.claude/settings.json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "./.claude/hooks/auto-format.sh"
          }
        ]
      }
    ]
  }
}
.claude/hooks/auto-format.sh
#!/bin/bash
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')

if [[ -z "$FILE_PATH" ]]; then
  exit 0
fi

# ファイル拡張子に応じてフォーマッターを実行
case "$FILE_PATH" in
  *.ts|*.tsx|*.js|*.jsx|*.json|*.css|*.md)
    npx prettier --write "$FILE_PATH" 2>/dev/null
    ;;
  *.py)
    black "$FILE_PATH" 2>/dev/null
    ;;
esac

exit 0

例3: セッション開始時の環境セットアップ

セッション開始時に必要な環境変数を設定したり、前提条件をチェックしたりします。

.claude/settings.json
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "./.claude/hooks/setup-env.sh"
          }
        ]
      }
    ]
  }
}
.claude/hooks/setup-env.sh
#!/bin/bash
# 必要なツールの存在チェック
for cmd in jq node npm git; do
  if ! command -v "$cmd" &>/dev/null; then
    echo "警告: $cmd がインストールされていません" >&2
  fi
done

# Node.js の依存関係チェック
if [[ -f "package.json" ]] && [[ ! -d "node_modules" ]]; then
  echo "node_modules が見つかりません。npm install を実行してください。" >&2
fi

exit 0

例4: 危険なコマンドの実行をブロック

Bash ツールで rm -rfsudo など危険なコマンドが実行されそうなときにブロックします。

.claude/hooks/block-dangerous-commands.sh
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

DANGEROUS_PATTERNS=(
  "rm -rf /"
  "rm -rf ~"
  "sudo rm"
  "mkfs"
  "dd if="
  ":(){:|:&};:"
  "chmod -R 777 /"
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if [[ "$COMMAND" == *"$pattern"* ]]; then
    echo "危険なコマンドがブロックされました: $COMMAND" >&2
    exit 2
  fi
done

exit 0

ユースケース

セキュリティゲート

保護ファイルへの書き込みや危険なコマンドの実行を PreToolUse フックで自動ブロック。ルール違反を仕組みで防止。

コード品質の自動化

ファイル編集後に自動フォーマット、コミット前にリント実行。人間が忘れがちな品質チェックを自動化。

監査ログ

全ツール実行を PostToolUse でログファイルに記録。誰がいつ何を実行したかのトレーサビリティを確保。

環境セットアップ

SessionStart で環境変数の設定、依存関係チェック、サービス起動を自動化。開発環境の初期化を毎回手動で行う手間を削減。

外部サービス連携

http タイプのフックで Slack 通知やCI/CDトリガーなど外部サービスと連携。ツール実行結果をリアルタイムで共有。

品質ゲート

Stop イベントでテスト実行を強制。テストが通らない限り応答を完了させないことで、品質を担保。

フックスクリプト作成のコツ

ベストプラクティス:

  • jq を使って stdin の JSON を解析する - フックは stdin で実行コンテキストを JSON 形式で受け取ります
  • stderr にメッセージを出す>&2)- ブロック時のフィードバックに使われます
  • 冪等に作る - 何度実行しても同じ結果になるようにしましょう
  • タイムアウトを意識する - 重い処理はフックに向きません(デフォルト30秒)
  • 終了コードを正しく使う - 0 で成功、2 でブロック、その他はエラー(処理続行)
  • スクリプトに実行権限を付ける - chmod +x を忘れずに

確認方法

セッション内でフックを確認
# セッション内でフック一覧を確認
/hooks

# Verbose モード(Ctrl+O)でフック実行を確認