コンテンツにスキップ
LinkedInX

Hooks 実装 — ライフサイクルフックで自動化する

読了 10分 + 実践 35分

対象読者: Settings JSON の基本設定を理解しており、Claude の動作に自動化や制御を加えたい方。[Settings JSON 設計](./settings) を先に読むことを推奨します。
前提知識: `.claude/settings.json` の構造・JSON の基本的な書き方・シェルスクリプトの基礎

フック(Hooks)を設定すると、Claude Code がツールを実行したり応答を返したりするタイミングで、任意のシェルコマンドを自動的に実行できます。このページでは、4種類のフックイベント・環境変数・exit code の意味・.claude/settings.json への設定方法を順番に学びます。


フック(Hook)とは、Claude Code がツールを呼び出したり、レスポンスを生成したりする特定のタイミングでシェルコマンドを実行できる仕組みです。フックは .claude/settings.jsonhooks キーに設定します。

フックの主な用途は次のとおりです。

  • ログ記録: どのツールがいつ呼ばれたかをファイルに記録する
  • バリデーション: 危険なコマンドの実行をブロックする
  • 自動フォーマット: ファイル保存後に linter を自動実行する
  • 通知: Claude の作業完了をシステム通知で知らせる

Claude Code には4種類のフックイベントがあります。

イベントタイミング主な用途
PreToolUseツール実行前バリデーション、ブロック
PostToolUseツール実行後ログ記録、通知、後処理
UserPromptSubmitユーザー入力時プロンプト変換、前処理
Stopレスポンス終了時完了通知、後処理

PreToolUse はツール実行の前に呼ばれるため、特定のツール使用をブロックするゲートキーパーとして機能します。PostToolUse はツール実行後に呼ばれるため、副作用(ログ書き込み・通知など)を追加するのに適しています。


フックは .claude/settings.jsonhooks キーに設定します。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'Tool: $CLAUDE_TOOL_NAME'"
          }
        ]
      }
    ]
  }
}

設定の構造は次のとおりです。

  • hooks: フック設定のルートキー
  • PreToolUse / PostToolUse / UserPromptSubmit / Stop: イベント名
  • matcher: どのツール名に対してフックを適用するか。"Bash" と書くと Bash ツール使用時のみ実行される。省略するとすべてのツールに適用される
  • type: フックの種類。現時点では "command" のみサポート
  • command: 実行するシェルコマンド

フック実行時に、Claude Code は次の環境変数を提供します。

変数名内容利用可能なイベント
$CLAUDE_TOOL_NAME呼び出されたツール名(例: BashReadPreToolUse、PostToolUse
$CLAUDE_TOOL_INPUTツールへの入力(JSON 形式)PreToolUse、PostToolUse
$CLAUDE_TOOL_RESULTツールの実行結果(JSON 形式)PostToolUse のみ

$CLAUDE_TOOL_INPUT は JSON 文字列なので、jq コマンドを使って特定のフィールドを取り出せます。

# Bash ツールに渡されたコマンド文字列を取り出す例
echo "$CLAUDE_TOOL_INPUT" | jq -r '.command'

フックスクリプトの終了コード(exit code)によって、Claude Code の挙動が変わります。

exit code意味
0成功。ツール実行を続行する
1エラー。PreToolUse の場合はツール実行をブロックする
2非ブロッキングエラー。エラーメッセージを表示するが実行は続行する

PreToolUse フックで exit 1 を返すと、Claude はそのツールの実行を中止します。PostToolUse フックで exit 1 を返しても、すでに実行済みのツール操作は取り消せません。


フックが重い処理(ネットワーク通信・大量ファイル処理など)を行うと、Claude の応答が遅くなります。重い処理はバックグラウンドで実行します。

# バックグラウンドで実行する例(& をつけてバックグラウンド化)
some-heavy-command "$CLAUDE_TOOL_NAME" &

フックがブロックする場合は、必ずエラーメッセージを出力してから exit 1 します。メッセージがないとユーザーはなぜブロックされたか分かりません。

echo 'ERROR: npm run build はユーザーの明示承認が必要です。'
exit 1

ブロックするフックが多すぎると、Claude Code が使いにくくなります。ブロックの条件は具体的に絞り込み、必要な操作まで誤ってブロックしないように注意します。

PostToolUse フックでツール使用ログをファイルに記録すると、監査やデバッグに役立ちます。

echo "$(date): $CLAUDE_TOOL_NAME" >> /tmp/claude-tool-log.txt

フックスクリプトは単体テスト可能に書く

Section titled “フックスクリプトは単体テスト可能に書く”

フックコマンドを直接 command フィールドに長く書くより、別ファイルのシェルスクリプトとして切り出してから呼び出す方が、テストと保守が容易です。


Step 1: 現在のフック設定を確認する

Section titled “Step 1: 現在のフック設定を確認する”
cat .claude/settings.json

hooks キーの有無と現在の設定内容を確認します。

✅ 確認: ファイルの内容が表示されれば読み込み成功です。hooks キーがない場合は、次の手順で追加します。

Step 2: npm run build を誤って実行しないようにする PreToolUse フックを追加する

Section titled “Step 2: npm run build を誤って実行しないようにする PreToolUse フックを追加する”

.claude/settings.jsonhooks セクションに次の設定を追加します。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'npm run build'; then echo 'ERROR: npm run build はユーザーの明示承認が必要です。'; exit 1; fi"
          }
        ]
      }
    ]
  }
}

このフックは、Bash ツールへの入力に npm run build が含まれている場合にブロックし、エラーメッセージを表示します。

✅ 確認: .claude/settings.json を保存した後、cat .claude/settings.json で設定が正しく記録されていることを確認します。

Step 3: フックが正しくブロックするか確認する

Section titled “Step 3: フックが正しくブロックするか確認する”

Claude Code のセッションで次のように依頼します。

npm run build を実行して

Claude が Bash ツールで npm run build を実行しようとしたとき、フックが exit 1 を返してブロックされることを確認します。

✅ 確認: Claude の応答に「npm run build の実行がブロックされました」または「ユーザーの明示承認が必要です」という旨が含まれれば、フックが正しく機能しています。

Step 4: Stop フックで作業完了を macOS に通知する

Section titled “Step 4: Stop フックで作業完了を macOS に通知する”

Claude が応答を終了したタイミングで macOS 通知を送る Stop フックを追加します。

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'npm run build'; then echo 'ERROR: npm run build はユーザーの明示承認が必要です。'; exit 1; fi"
          }
        ]
      }
    ],
    "Stop": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude の作業が完了しました\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

✅ 確認: Claude が次のレスポンスを返し終えたとき、macOS の通知センターに「Claude の作業が完了しました」と表示されれば成功です。macOS 以外の環境では osascript を適切なコマンドに置き換えてください。


  • フックは Claude Code のライフサイクルの特定タイミングでシェルコマンドを実行する仕組み
  • 4種類のイベントは PreToolUse(ツール前)・PostToolUse(ツール後)・UserPromptSubmit(入力時)・Stop(終了時)
  • フック実行時は $CLAUDE_TOOL_NAME$CLAUDE_TOOL_INPUT$CLAUDE_TOOL_RESULT が利用できる
  • PreToolUseexit 1 を返すとツール実行をブロックできる
  • フックは .claude/settings.jsonhooks キーに設定し、軽量・明示的・テスト可能に設計する


Q: PreToolUse フックでブロックした場合、Claude はどう振る舞いますか?

A: フックが exit 1 を返すと、Claude はそのツールを実行せず、標準出力に書いたエラーメッセージをコンテキストとして受け取ります。その後、Claude はエラーの内容に応じて別のアプローチを試みるか、ユーザーに報告します。

Q: PostToolUse フックで exit 1 を返すと、ツールの実行結果は取り消せますか?

A: 取り消せません。PostToolUse はツール実行後に呼ばれるため、すでに完了した操作(ファイルの書き込みなど)は元に戻りません。実行前のバリデーションは PreToolUse で行ってください。

Q: matcher を省略するとどうなりますか?

A: すべてのツール呼び出しに対してフックが実行されます。Bash だけでなく Read・Write・Glob なども対象になるため、フックが重い処理を行う場合はレスポンスが大幅に遅くなる可能性があります。特定のツールのみを対象にする場合は matcher を明示的に指定してください。

Q: フックの設定を変更した後、Claude Code を再起動する必要がありますか?

A: .claude/settings.json の変更はセッションをまたいで読み込まれます。現在のセッションに変更を反映させるには、Claude Code を再起動するか新しいセッションを開始してください。

Q: Windows 環境で osascript の代わりに使えるコマンドはありますか?

A: Windows では powershell -Command "Add-Type -AssemblyName System.Windows.Forms; [System.Windows.Forms.MessageBox]::Show('Claude の作業が完了しました')" を使用できます。Linux では notify-send "Claude の作業が完了しました" が使えます(libnotify が必要)。

このページの外部仕様・背景情報は、参考文献を参照してください。[1][2]

  1. Anthropic, Claude Code documentation
  2. Anthropic, Claude API documentation
クイズ