blog

claude code hooks|2026年版ガイド

Claude Code Hooksとは何か:概要と位置づけ

Claude Code Hooksは、Claude Codeのエージェント実行サイクルの特定タイミングに対して、任意のシェルコマンドやスクリプトを自動実行させる仕組みです。2025年に正式リリースされたこの機能により、「AIがコードを書いた直後に自動でlintを走らせる」「ツール呼び出しのたびにログを記録する」「承認なしでは実行できないコマンドをブロックする」といった、開発ワークフローの自動化・ガードレール設定が可能になりました。

弊社(クリスタルメソッド)ではClaude Codeを実務の中心ツールとして日常利用しており、Hooksの登場によってコードレビュー補助・品質チェック・セキュリティ制約の運用が根本的に変わりました。本記事では、Hooksの仕組みから設定方法、実践的な活用例まで、網羅的に解説します。

Hooksが解決する問題:なぜ必要か

Claude Codeはエージェントとして自律的にコードを編集・実行します。その自律性は強力ですが、次のような課題を生みます。

  • 品質チェックの抜け漏れ:AIが生成したコードにlintやフォーマッタを毎回手動で実行するのは非現実的
  • セキュリティ・ガバナンス:特定のコマンド(本番DBへの直接操作など)を誤って実行させないための歯止めが必要
  • 可観測性の欠如:AIが何をいつ実行したか、監査ログを残す仕組みがデフォルトでは薄い
  • チームルールの強制:個人の設定に依存せず、プロジェクト全体で一貫したルールを適用したい

Hooksはこれらをすべてシェルスクリプトの記述という馴染みある手段で解決します。Claude Code側のコードを変更せず、外部コマンドを挟み込むだけでワークフローを制御できる点が革新的です。

Hooksの実行タイミング:4つのライフサイクルイベント

Hooksは以下のライフサイクルイベントに対応しています。それぞれの役割を理解することが設計の出発点になります。

イベント名 発火タイミング 主なユースケース
PreToolUse ツール実行の直前(ユーザー確認の前) コマンドのブロック・検証・事前ログ
PostToolUse ツール実行の直後(結果が返った後) lint/テスト自動実行・変更後ログ
Notification Claude Codeが通知を送るとき Slack通知・デスクトップ通知連携
Stop エージェントがタスクを完了したとき 完了通知・後処理・サマリー生成

実務で最も使用頻度が高いのはPostToolUsePreToolUseです。PostToolUseでファイル保存後の自動フォーマットを実行し、PreToolUseで危険なコマンドを遮断するパターンが、開発チームの標準構成として定着しています。

Hooksの設定場所:settings.jsonの構造

HooksはClaude Codeの設定ファイル(settings.json)に記述します。設定ファイルには適用スコープによって3つの場所があります。

スコープ ファイルパス 適用範囲
ユーザーグローバル ~/.claude/settings.json そのユーザーの全プロジェクト
プロジェクトローカル {project}/.claude/settings.json そのプロジェクトのみ(git管理推奨)
プロジェクトローカル(個人) {project}/.claude/settings.local.json そのプロジェクト内の個人設定(gitignore推奨)

チーム開発では.claude/settings.jsonをgitリポジトリにコミットすることで、全メンバーに同一のHooksルールを自動適用できます。個人の追加設定はsettings.local.jsonに分離する運用が、弊社では標準パターンになっています。

settings.jsonの基本スキーマ

Hooksの設定は"hooks"キー配下に記述します。基本的な構造は以下のとおりです。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_TOOL_INPUT_FILE_PATH"
          }
        ]
      }
    ],
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "/home/user/.claude/hooks/block_dangerous.sh"
          }
        ]
      }
    ]
  }
}

設定の主要要素を整理すると次のようになります。

  • matcher:どのツール名(またはツール名パターン)に反応するかを正規表現で指定
  • hooks配列:マッチしたときに実行するコマンド群(複数指定可)
  • type:現時点では"command"固定
  • command:実行するシェルコマンド文字列

環境変数:Hooksスクリプトで使えるコンテキスト情報

Hooksコマンド実行時には、Claude Codeが文脈情報を環境変数として渡します。スクリプト内でこれらを参照することで、「どのファイルが編集されたか」「どのコマンドが実行されようとしているか」を動的に処理できます。

環境変数名 内容 利用可能なイベント
CLAUDE_TOOL_NAME 実行されたツール名(例:WriteBash PreToolUse / PostToolUse
CLAUDE_TOOL_INPUT_FILE_PATH Write/Editツールで操作されたファイルパス PostToolUse(Write/Edit系)
CLAUDE_TOOL_INPUT_COMMAND Bashツールで実行されようとしているコマンド文字列 PreToolUse(Bash)
CLAUDE_PROJECT_DIR 現在のプロジェクトディレクトリのパス 全イベント
CLAUDE_SESSION_ID セッションの一意ID(ログ用途に有用) 全イベント

なお、標準入力(stdin)にはツールの入出力がJSON形式で渡されます。より詳細な情報(Bashツールの完全な実行結果など)が必要な場合はjqなどでstdinをパースする方法が使えます。

Hooksの終了コードとClaude Codeの制御フロー

Hooksスクリプトの終了コード(exit code)は、Claude Codeの動作に直接影響します。この仕組みを理解することが、ガードレール実装の核心です。

終了コード 0

正常終了。処理を続行する。

終了コード 1

エラー。Claude Codeにエラーメッセージを通知するが、処理は続行する(警告扱い)。

終了コード 2

ブロック。ツールの実行をキャンセルし、理由をClaudeにフィードバックする(PreToolUse専用)。

終了コード2がPreToolUse専用のブロック機能です。スクリプトが2を返すと、Claude Codeはツールの実行を中止し、スクリプトの標準出力をエラー理由としてモデルに伝えます。モデルはそのフィードバックを受けて別の方法を検討します。

実践的な設定例5選

1. ファイル保存後の自動フォーマット(Prettier)

最もシンプルで効果の高い設定です。JavaScriptやTypeScriptファイルをWriteまたはEditするたびにPrettierを自動実行します。

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'echo \"$CLAUDE_TOOL_INPUT_FILE_PATH\" | grep -qE \"\\.(js|ts|jsx|tsx|json|css)$\" && npx prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\" || true'"
          }
        ]
      }
    ]
  }
}

弊社ではこれをユーザーグローバル設定(~/.claude/settings.json)に記述し、全プロジェクトで有効にしています。AIが生成するコードのフォーマットを毎回手動修正する手間がゼロになりました。

2. 危険なBashコマンドのブロック

本番環境に関連するコマンドや破壊的な操作を自動でブロックするスクリプトです。

#!/bin/bash
# ~/.claude/hooks/block_dangerous.sh

COMMAND=$(echo "$CLAUDE_TOOL_INPUT_COMMAND" | tr '[:upper:]' '[:lower:]')

# 禁止パターン定義
BLOCKED_PATTERNS=(
  "rm -rf /"
  "drop table"
  "drop database"
  "production"
  "prod_db"
  "curl.*\| bash"
)

for pattern in "${BLOCKED_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qi "$pattern"; then
    echo "BLOCKED: Pattern '$pattern' is not allowed in automated execution."
    echo "Please review and execute manually if intended."
    exit 2
  fi
done

exit 0

設定ファイルへの組み込みは以下のとおりです。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/block_dangerous.sh"
          }
        ]
      }
    ]
  }
}

3. Python ファイルの自動 lint(flake8 + black)

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash -c 'if echo \"$CLAUDE_TOOL_INPUT_FILE_PATH\" | grep -q \"\\.py$\"; then black \"$CLAUDE_TOOL_INPUT_FILE_PATH\" && flake8 \"$CLAUDE_TOOL_INPUT_FILE_PATH\"; fi'"
          }
        ]
      }
    ]
  }
}

flake8がエラーを検出した場合(終了コード1)、Claude Codeはそのエラー内容をコンテキストとして受け取り、次のステップで自動修正を試みる動作が期待できます。

4. 実行ログの記録

コンプライアンス要件やデバッグのために、Claude Codeが実行したすべてのツール呼び出しをログファイルに記録します。

#!/bin/bash
# ~/.claude/hooks/audit_log.sh

LOG_FILE="${HOME}/.claude/audit.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

echo "${TIMESTAMP} | SESSION:${CLAUDE_SESSION_ID} | TOOL:${CLAUDE_TOOL_NAME} | FILE:${CLAUDE_TOOL_INPUT_FILE_PATH:-N/A} | CMD:${CLAUDE_TOOL_INPUT_COMMAND:-N/A}" >> "$LOG_FILE"

exit 0
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": ".*",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/audit_log.sh"
          }
        ]
      }
    ]
  }
}

matcher".*"を指定することで全ツールをキャッチします。弊社のセキュリティ要件対応プロジェクトでは、この監査ログを毎日自動アーカイブするcronジョブと組み合わせて運用しています。

5. タスク完了時のSlack通知(Stopイベント)

長時間かかるエージェントタスクが完了したとき、SlackのWebhookに通知します。席を離れている間に実行させておき、完了したら知らせる運用に有用です。

#!/bin/bash
# ~/.claude/hooks/notify_slack.sh

WEBHOOK_URL="${SLACK_CLAUDE_WEBHOOK_URL}"  # 環境変数で管理
PROJECT=$(basename "$CLAUDE_PROJECT_DIR")
TIMESTAMP=$(date '+%H:%M:%S')

curl -s -X POST "$WEBHOOK_URL" \
  -H 'Content-type: application/json' \
  --data "{\"text\":\"✅ Claude Code タスク完了 [${PROJECT}] at ${TIMESTAMP} (Session: ${CLAUDE_SESSION_ID})\"}" \
  > /dev/null

exit 0
{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/notify_slack.sh"
          }
        ]
      }
    ]
  }
}

Stopイベントではmatcherは空文字列で問題ありません。WebhookURLはコード中に直書きせず、必ず環境変数経由で渡すようにしてください。

複数イベント・複数コマンドの組み合わせ設定

実際の運用設定ファイルでは、複数のイベントと複数のhooksを組み合わせることになります。以下は弊社が実際に使用しているプロジェクト設定のベースパターンです。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/audit_log.sh"
          },
          {
            "type": "command",
            "command": "~/.claude/hooks/block_dangerous.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/audit_log.sh"
          },
          {
            "type": "command",
            "command": "~/.claude/hooks/format_on_save.sh"
          }
        ]
      }
    ],
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/notify_slack.sh"
          }
        ]
      }
    ]
  }
}

同一イベント・同一matcherに複数のhooksを定義した場合、配列の順番通りに逐次実行されます。前のコマンドが終了コード2を返した時点で後続のhooksは実行されません(PreToolUseのブロック時)。

Claude Code Hooksのライフサイクルフローイメージ
Claude Code Hooksのライフサイクルフローイメージ

設定時の注意点とよくある落とし穴

コマンドのパスは絶対パスで指定する

Hooksコマンドはシェルのインタラクティブセッションとは異なる環境で実行されます。PATHの解決が期待どおりにならないケースがあるため、npxnodeなども含め、絶対パスまたはbash -c '...'経由での実行が安定します。特にnvmやpyenvで管理しているランタイムは注意が必要です。

無限ループに注意する

PostToolUseのHooksでファイルを書き換えるコマンドを実行すると、そのWriteが再びPostToolUseを発火させる可能性があります。Prettierなどの冪等なツールはファイルが変更されなければ終了コード0で終わるため問題になりにくいですが、スクリプト内でファイルを新たに生成・書き込む処理には注意してください。

タイムアウトを意識した設計

Hooksコマンドの実行はClaudeの処理をブロックします。実行時間が長いスクリプト(テストスイート全体の実行など)をPostToolUseに入れると、全体のレスポンス性が著しく低下します。重い処理はバックグラウンド実行(&)にするか、Stopイベントへの移動を検討してください。

matcherの正規表現の確認

matcherはツール名に対する正規表現マッチングです。例えば"Write"Writeという文字列を含む全ツール名にマッチします。意図しないツールに適用されないよう、^Write$のように厳密な境界指定を使う場面もあります。

スクリプトに実行権限を付与する

外部スクリプトファイルを参照する場合、chmod +x ~/.claude/hooks/your_script.shで実行権限を付与しておく必要があります。権限がないと終了コード1相当の失敗になります。

Hooksのデバッグ方法

Hooksが意図どおりに動かない場合のデバッグ手順を紹介します。

  1. スクリプト単体の動作確認:対象の環境変数を手動でexportしてスクリプトを直接実行し、終了コードと出力を確認する
  2. ログ出力の追加:スクリプト冒頭にset -xexec 2>>/tmp/hooks_debug.logを追加して実行トレースをファイルに記録する
  3. Claude Code の –verbose オプションclaude --verboseで起動するとHooksの実行情報が詳細に出力される
  4. matcher のテスト:設定を"matcher": ".*"に変えて全ツールにマッチさせ、発火しているかを確認した後、絞り込む

Hooksとpermissions設定の使い分け

Claude Codeにはpermissions設定(allowedTools / deniedTools)もあります。Hooksとの違いを理解して適切に使い分けることが重要です。

機能 Hooks(PreToolUse exit 2) permissions(deniedTools)
ブロックの粒度 コマンド内容・引数レベルで動的判定可能 ツール単位での静的な許可/拒否のみ
フィードバック ブロック理由をモデルに伝えられる ツール自体が使えない旨の通知のみ
柔軟性 高(スクリプトで任意ロジック実装) 低(ツール名の一覧のみ)
用途 条件付きブロック・パターンマッチング 特定ツールの完全無効化

「Bashツールは使えるが、本番に関わるコマンドだけブロックしたい」という要件にはHooksが適しており、「WebSearchツール自体を一切使わせない」という要件にはpermissionsが適しています。両者を組み合わせた多層防御が実践的なアプローチです。

まとめ

Claude Code Hooksは、エージェント実行サイクルの各タイミング(PreToolUse・PostToolUse・Notification・Stop)にシェルコマンドを差し込む仕組みです。終了コードによってツールのブロックも可能であり、自動フォーマット・危険コマンドの遮断・監査ログ・完了通知といった実務的な要件をシェルスクリプトという普遍的な技術で実現できます。

弊社での実運用を通じて得た最大の知見は、「Hooksはコストゼロでチームの開発標準を強制できる装置である」という点です。プロジェクトの.claude/settings.jsonにHooksを定義してgitにコミットするだけで、チーム全員の環境に即座に適用されます。まずは自動フォーマットと監査ログの2つから導入し、チームの実情に合わせてガードレールを追加していく段階的なアプローチが、スムーズな定着につながります。

関連記事

AIブログ購読

 
クリスタルメソッドがお届けする
AIブログの更新通知を受け取る

Study about AI

AIについて学ぶ

  • claude code 権限設定|2026年版ガイド

    claude code 権限設定|2026年版ガイド

    Claude Code 権限設定の完全ガイド|実務で使える設定例と運用ノウハウ Claude Codeを業務で活用する際、最初の壁になるのが権限設定です。ファイ...

  • claude code 拡張機能|2026年版ガイド

    claude code 拡張機能|2026年版ガイド

    Claude Code 拡張機能とは——できることと全体像 Claude Codeは、AnthropicのAIアシスタント「Claude」をターミナル上で動かす...

  • claude code 学習させない設定|2026年版ガイド

    claude code 学習させない設定|2026年版ガイド

    Claude Codeに学習させない設定とは何か Claude Codeを業務で使っていると「自分が入力したコードや会話内容がAnthropicのAI学習に使わ...

View more