はじめに
Claude Code には Hooks と呼ばれる仕組みがあります。これは、Claude Code のライフサイクル上の特定タイミングでシェルコマンドや HTTP リクエスト、LLM プロンプトを自動実行できる機能です。
Hooks を使うと、次のような自動化が実現できます。
- ファイル編集後に自動でコードフォーマッター(Prettier など)を実行する
-
.envやpackage-lock.jsonなど保護すべきファイルへの書き込みをブロックする - Claude が入力待ちになったときにデスクトップ通知や Slack 通知を送る
- コンテキスト圧縮(コンパクション)後にプロジェクト規則を自動注入する
- すべての Bash コマンドをログファイルに記録する
公式ドキュメント(Automate workflows with hooks)をもとに、実際の設定方法から実践的なユースケースまでを解説します。
この記事で学べること
- Claude Code Hooks の仕組みと 18 種類のイベント一覧
-
settings.jsonへの設定方法とスコープ(グローバル/プロジェクト) - 自動フォーマット・ファイル保護・通知など実践的なレシピ
- プロンプト型・エージェント型・HTTP 型の高度なフック
対象読者
- Claude Code を日常的に使っているエンジニア
- AI コーディングツールの自動化に興味がある方
- CI/CD と同様にローカル開発にもガードレールを設けたい方
前提環境
- Claude Code(最新バージョン推奨)
- macOS / Linux / Windows(PowerShell)
TL;DR
- Hooks はライフサイクルイベントにシェルコマンドを紐付ける仕組みで、18 種類のイベントをサポート
-
~/.claude/settings.json(グローバル)または.claude/settings.json(プロジェクト)に JSON で設定 - 主要イベント:
PreToolUse(ブロック可)、PostToolUse(後処理)、Notification(通知)、SessionStart(コンテキスト注入) - フックタイプは
command(シェル)、prompt(LLM)、agent(サブエージェント)、httpの 4 種類
Claude Code Hooks の仕組み
Hooks は Claude Code のエージェントループ上の特定ポイントで発火します。イベントが発火すると、Claude Code はイベント固有の JSON コンテキストをフックハンドラーに渡します。
フックの基本動作
Claude Code セッション
│
├─ SessionStart → フック発火(コンテキスト注入)
│
├─ UserPromptSubmit → フック発火(プロンプト前処理)
│
├─ PreToolUse → フック発火(ブロック可能)
│ │
│ ▼ ツール実行
│
├─ PostToolUse → フック発火(後処理)
│
├─ Stop → フック発火(完了検証)
│
└─ SessionEnd → フック発火(クリーンアップ)
フックハンドラー(シェルスクリプト等)は stdin で JSON を受け取り、stdout/stderr への出力と終了コードで Claude Code に応答します。
| 終了コード | 動作 |
|---|---|
0 |
処理を続行。SessionStart / UserPromptSubmit では stdout の内容が Claude のコンテキストに追加される |
2 |
アクションをブロック。stderr の内容が Claude へのフィードバックとして渡される |
| その他 | 処理を続行。stderr はログに記録される(Claude には渡されない) |
全 18 イベント一覧
| イベント | 発火タイミング |
|---|---|
SessionStart |
セッション開始または再開時 |
UserPromptSubmit |
プロンプト送信後、Claude が処理する前 |
PreToolUse |
ツール呼び出し前(ブロック可) |
PermissionRequest |
権限ダイアログ表示時 |
PostToolUse |
ツール呼び出し成功後 |
PostToolUseFailure |
ツール呼び出し失敗後 |
Notification |
Claude Code が通知を送信するとき |
SubagentStart |
サブエージェント起動時 |
SubagentStop |
サブエージェント終了時 |
Stop |
Claude が応答を完了したとき |
TeammateIdle |
Agent Team のチームメートがアイドル状態になるとき |
TaskCompleted |
タスクが完了としてマークされるとき |
InstructionsLoaded |
CLAUDE.md やルールファイルがロードされるとき |
ConfigChange |
セッション中に設定ファイルが変更されたとき |
WorktreeCreate |
ワークツリー作成時 |
WorktreeRemove |
ワークツリー削除時 |
PreCompact |
コンテキスト圧縮の直前 |
SessionEnd |
セッション終了時 |
設定ファイルの場所とスコープ
フックの設定場所でスコープが決まります。
| 設定ファイル | スコープ | 共有可否 |
|---|---|---|
~/.claude/settings.json |
全プロジェクト共通 | 不可(マシンローカル) |
.claude/settings.json |
プロジェクト単位 | 可(リポジトリにコミット可能) |
.claude/settings.local.json |
プロジェクト単位 | 不可(gitignore 推奨) |
プラグイン hooks/hooks.json
|
プラグイン有効時 | 可(プラグインに同梱) |
Claude Code が実行中のとき、設定ファイルを直接編集しても即時反映されません。
/hooksメニューで確認するか、セッションを再起動してください。/hooksメニューから追加したフックは即時反映されます。
設定の基本構造
{
"hooks": {
"イベント名": [
{
"matcher": "マッチャーパターン(正規表現)",
"hooks": [
{
"type": "command",
"command": "実行するシェルコマンド"
}
]
}
]
}
}
matcher はイベントによってフィルタリング対象が異なります。
| イベント | マッチャーの対象 | 例 |
|---|---|---|
PreToolUse, PostToolUse, PermissionRequest
|
ツール名 |
Bash, Edit|Write, mcp__.*
|
SessionStart |
セッション開始理由 |
startup, resume, compact
|
SessionEnd |
セッション終了理由 |
clear, logout
|
Notification |
通知タイプ |
permission_prompt, idle_prompt
|
PreCompact |
圧縮トリガー |
manual, auto
|
マッチャーを空文字列 "" にすると、すべての発火条件に対してフックが実行されます。
実践レシピ集
レシピ 1: デスクトップ通知(macOS)
Claude が入力待ちになったときにデスクトップ通知を受け取ります。別の作業をしながら Claude に長時間タスクを任せるときに便利です。
~/.claude/settings.json に追加:
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code が入力を待っています\" with title \"Claude Code\"'"
}
]
}
]
}
}
Linux では notify-send、Windows では PowerShell の MessageBox を使います。
レシピ 2: ファイル編集後に自動フォーマット
Claude がファイルを編集するたびに Prettier を自動実行します。コードスタイルの一貫性が保たれます。
.claude/settings.json に追加(プロジェクト単位):
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
jq で stdin の JSON から tool_input.file_path を抽出し、Prettier に渡しています。jq のインストールは brew install jq(macOS)または apt-get install jq(Debian/Ubuntu)。
レシピ 3: 保護ファイルへの書き込みをブロック
.env、package-lock.json、.git/ 配下への書き込みを防止します。誤った編集を事前に止められます。
まず .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/")
for pattern in "${PROTECTED_PATTERNS[@]}"; do
if [[ "$FILE_PATH" == *"$pattern"* ]]; then
echo "Blocked: $FILE_PATH is a protected file" >&2
exit 2
fi
done
exit 0
実行権限を付与:
chmod +x .claude/hooks/protect-files.sh
.claude/settings.json に登録:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
exit 2 で返すと、Claude は stderr のメッセージを受け取り、別のアプローチを検討します。
レシピ 4: Bash コマンドの全履歴をログに記録
Claude が実行したすべての Bash コマンドをファイルに記録します。監査やデバッグに活用できます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '[now | todate, .tool_input.command] | @tsv' >> ~/.claude/command-log.txt"
}
]
}
]
}
}
タイムスタンプ付きで ~/.claude/command-log.txt に追記されます。
レシピ 5: コンパクション後にプロジェクト規則を再注入
Claude のコンテキストウィンドウが満杯になると、コンパクション(要約)が行われます。この際、重要なプロジェクト規則が失われることがあります。SessionStart の compact マッチャーを使うと、圧縮後に自動でコンテキストを再注入できます。
.claude/settings.json に追加:
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'リマインダー: パッケージマネージャーは npm ではなく Bun を使うこと。コミット前に bun test を実行すること。現在のスプリント: 認証リファクタリング。'"
}
]
}
]
}
}
stdout への出力が Claude のコンテキストに追加されます。動的な情報(直近のコミット一覧など)を注入することも可能です。
{
"command": "git log --oneline -5"
}
レシピ 6: 設定変更の監査ログ
設定ファイルが変更されるたびに監査ログに記録します。コンプライアンス要件がある環境で活用できます。
{
"hooks": {
"ConfigChange": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "jq -c '{timestamp: now | todate, source: .source, file: .file_path}' >> ~/claude-config-audit.log"
}
]
}
]
}
}
高度なフックタイプ
プロンプト型フック(type: "prompt")
確定的なルールではなく判断が必要な場合に、LLM(デフォルト: Haiku)にフックの処理を委ねます。
モデルは "ok": true(続行)または "ok": false(ブロック)を JSON で返します。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "要求されたすべてのタスクが完了しているか確認してください。完了していない場合は {\"ok\": false, \"reason\": \"残作業の内容\"} を返してください。"
}
]
}
]
}
}
Stop イベントで使うと、タスクが本当に完了しているか LLM に判断させて、不完全な場合は作業を継続させることができます。
エージェント型フック(type: "agent")
ファイルの読み取りやコマンド実行が必要な検証には、サブエージェントを起動するエージェント型フックを使います。デフォルトタイムアウト 60 秒、最大 50 ターンのツール利用が可能です。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "すべてのユニットテストが通過することを確認してください。テストスイートを実行して結果を確認してください。",
"timeout": 120
}
]
}
]
}
}
「プロンプト型はフック入力データだけで判断できる場合、エージェント型はコードベースの実際の状態を確認する必要がある場合」という使い分けが推奨されています。
HTTP 型フック(type: "http")
チームで共有する監査サービスや外部 Webhook にイベントデータを送信します。
{
"hooks": {
"PostToolUse": [
{
"hooks": [
{
"type": "http",
"url": "http://localhost:8080/hooks/tool-use",
"headers": {
"Authorization": "Bearer $MY_TOKEN"
},
"allowedEnvVars": ["MY_TOKEN"]
}
]
}
]
}
}
ヘッダー値には $VAR_NAME 形式で環境変数を埋め込めます。allowedEnvVars に列挙された変数のみ解決されます。
HTTP フックは
/hooksインタラクティブメニューからは設定できません。設定ファイルを直接編集してください。
フックの設定手順
/hooks メニューを使う方法(推奨)
- Claude Code CLI で
/hooksと入力 - フックを設定したいイベントを選択(例:
Notification) - マッチャーを設定(すべてに適用する場合は
*) -
+ Add new hook…を選択してコマンドを入力 - 保存先を選択(
User settingsでグローバル、Project settingsでプロジェクト単位)
メニューから追加したフックは即時反映されます。
設定ファイルを直接編集する方法
-
~/.claude/settings.jsonまたは.claude/settings.jsonを開く -
hooksキーに上記の JSON 形式で設定を追加 - Claude Code を再起動するか、
/hooksメニューを開いて変更を反映させる
トラブルシューティング
フックが発火しない
-
/hooksメニューでフックが正しいイベントの下に登録されているか確認する - マッチャーはツール名と大文字小文字を区別する(
Editは正しいがeditは不正) -
PermissionRequestフックは非インタラクティブモード(-p)では発火しない。PreToolUseを代わりに使う
JSON パースエラーが発生する
~/.zshrc や ~/.bashrc に無条件の echo 文がある場合、その出力がフックの JSON 出力に混入して解析エラーになります。インタラクティブシェルのみで実行されるよう条件分岐を追加してください:
# ~/.zshrc
if [[ $- == *i* ]]; then
echo "Shell ready"
fi
Stop フックが無限ループになる
Stop フックが Claude に追加作業をさせ続けると無限ループになります。stop_hook_active フィールドを確認して早期リターンしてください:
#!/bin/bash
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0
fi
# ... 残りのフック処理
デバッグ方法
-
Ctrl+Oでバーボースモードを切り替え、フックの出力をトランスクリプトで確認できる -
claude --debugでフルデバッグログ(どのフックがマッチしたか、終了コードなど)を出力できる
まとめ
Claude Code Hooks は、Claude のエージェントループに決定論的なコントロールを追加する仕組みです。LLM の判断に頼らず、「常にこのアクションを実行する」という保証が得られます。
主要なポイントをまとめます。
-
18 種類のイベント:
PreToolUseでブロック、PostToolUseで後処理、Notificationで通知、SessionStartでコンテキスト注入など用途に応じて使い分ける -
4 種類のフックタイプ: シェルコマンド(
command)、LLM 判断(prompt)、サブエージェント(agent)、HTTP(http) -
スコープ管理: グローバル(
~/.claude/settings.json)とプロジェクト(.claude/settings.json)を使い分けてチーム共有も可能 -
終了コード:
0で続行、2でブロック(stderr がフィードバック)
まずは Notification イベントのデスクトップ通知から始めて、徐々に PostToolUse による自動フォーマット、PreToolUse によるファイル保護へと広げていくのが実践的なアプローチです。


