Claude Codeは「AIがコードを書く」ツールですが、Hooksを使うと「AIが何かをするたびに自動で別の処理が走る」環境を作れます。ファイルを編集するたびにlinterが走り、作業が完了するたびにSlackに通知が届き、セキュリティ問題のあるコードはLLMが自動ブロックする——これらをすべてJSONの設定だけで実現できます。
2026年3月のアップデートでHooksは大幅に強化され、従来のシェルコマンド実行(Command)に加えてHTTP・Prompt・Agentの3種類が追加されました。この記事では4種類すべてのHooksを、実際に動く設定例とともに体系的に解説します。
Claude Code全般の使い方はClaude Code完全ガイドを、2026年3月のその他の新機能(/loop・Channels・Agent Teams等)はClaude Code 2026年3月新機能完全ガイドを参照してください。
Hooksの基本概念
Hooksとは何か
HooksはClaude Codeの動作に自動処理を割り込ませる仕組みです。「どのタイミングで」「何が起きたら」「何を実行するか」の3つを.claude/settings.jsonまたは~/.claude/settings.json(グローバル設定)に記述します。
プロジェクト設定(
.claude/settings.json)はリポジトリ内でチームと共有。ユーザーグローバル設定(~/.claude/settings.json)はすべてのプロジェクトに適用。どちらに書いても動作します。プロジェクト固有の処理はプロジェクト設定、全プロジェクト共通の処理(Slack通知等)はグローバル設定が適しています。4つのイベントタイプ
| イベント | 発火タイミング | 主な用途 |
|---|---|---|
| PreToolUse | ツール実行の直前 | 事前チェック・実行ブロック・ログ記録 |
| PostToolUse | ツール実行の直後 | linter実行・フォーマット・事後チェック |
| Stop | Claude Codeが作業を完了した時 | 完了通知・レポート生成 |
| Notification | 状態変化・承認要求が発生した時 | スマホ通知・ダッシュボード更新 |
4つのHookタイプ
| Hookタイプ | 動作 | 特徴 |
|---|---|---|
| Command | シェルコマンドを実行 | 従来型。exit codeでブロック制御可 |
| HTTP | JSON を HTTP POST で送信 | Slack・Webhook・外部APIに通知 |
| Prompt | LLMにテキスト評価させる | blockOnResponseでブロック制御可 |
| Agent | ツール付きサブエージェントを起動 | Read/Grep/Globで高度な自動チェック |
基本的な構造
{
"hooks": {
"イベント名": [
{
"matcher": "対象ツール名のパターン(省略可)",
"hooks": [
{
"type": "command | http | prompt | agent",
"... hookタイプ固有の設定 ..."
}
]
}
]
}
}
matcherはツール名に対する正規表現です。"Edit|Write|MultiEdit"のようにパイプで複数指定できます。省略するとすべてのツールにマッチします。
Command Hook:シェルコマンドを実行する
Command HookはHooksの基本形です。シェルコマンドをexit code 0で終了させれば処理続行、1以上で終了させればブロックできます。stdout/stderrに出力したテキストはClaude Codeのコンテキストにフィードバックされます。
実践例1:ファイル編集後にESLintを自動実行
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "cd $CLAUDE_PROJECT_DIR && npx eslint --fix $(echo $CLAUDE_TOOL_OUTPUT | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('filePath',''))" 2>/dev/null) 2>&1 | tail -10 || true"
}
]
}
]
}
}
実践例2:危険なBashコマンドをブロックする
PreToolUseでBashツールをフックし、危険なパターンに一致するコマンドをexit 1でブロックします。stdout に出力したテキストがClaudeにフィードバックされ、理由として伝わります。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 - <<'EOF'
import sys, json, re, os
data = json.loads(sys.stdin.read())
cmd = data.get('command', '')
dangerous_patterns = [
r'rm\s+-rf\s+/',
r'DROP\s+TABLE',
r'DELETE\s+FROM\s+\w+\s*;',
r'format\s+[A-Z]:',
r'dd\s+if=.*of=/dev/'
]
for pat in dangerous_patterns:
if re.search(pat, cmd, re.IGNORECASE):
print(f'BLOCKED: 危険なコマンドパターンが検出されました: {cmd[:80]}')
sys.exit(1)
sys.exit(0)
EOF"
}
]
}
]
}
}
実践例3:全ファイル編集ログを記録する
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|Bash",
"hooks": [
{
"type": "command",
"command": "echo "$(date '+%Y-%m-%d %H:%M:%S') [$CLAUDE_TOOL_NAME] project=$CLAUDE_PROJECT_DIR" >> ~/.claude/audit.log"
}
]
}
]
}
}
exit 0 → 処理を続行。exit 1以上 → ツール実行をブロックしClaude Codeにstdoutの内容をフィードバック。linterのようにブロック不要な後処理は末尾に
|| true を付けておくと、linter自体が失敗してもClaude Codeの動作を止めません。HTTP Hook:外部サービスにリアルタイム通知する
HTTP HookはJSON PayloadをHTTP POSTで指定URLに送信します。Slackへの完了通知・監査ログAPIへの記録・外部Webhookの起動など、外部サービスとの連携に使います。
実践例1:作業完了をSlackに通知する
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "http",
"url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"text": "✅ Claude Codeの作業が完了しました",
"attachments": [
{
"color": "good",
"fields": [
{
"title": "プロジェクト",
"value": "$CLAUDE_PROJECT_DIR",
"short": true
},
{
"title": "完了時刻",
"value": "$CLAUDE_TIMESTAMP",
"short": true
}
]
}
]
}
}
]
}
]
}
}
実践例2:Bashコマンド実行を監査APIに記録する
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "http",
"url": "https://your-audit-api.example.com/v1/logs",
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer YOUR_API_TOKEN"
},
"body": {
"event": "bash_command",
"command": "$CLAUDE_TOOL_INPUT",
"project": "$CLAUDE_PROJECT_DIR",
"timestamp": "$CLAUDE_TIMESTAMP",
"source": "claude-code"
}
}
]
}
]
}
}
実践例3:承認要求をモバイルプッシュ通知に転送する
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "http",
"url": "https://api.pushover.net/1/messages.json",
"method": "POST",
"headers": {
"Content-Type": "application/json"
},
"body": {
"token": "YOUR_PUSHOVER_APP_TOKEN",
"user": "YOUR_PUSHOVER_USER_KEY",
"title": "Claude Code: 承認が必要です",
"message": "$CLAUDE_NOTIFICATION_MESSAGE",
"priority": 1
}
}
]
}
]
}
}
HTTP Hookは外部サービスからのレスポンスを受け取るまで処理をブロックします。遅延が大きいAPIを
PreToolUseに設定すると、ツール実行のたびに待ち時間が発生します。通知目的にはPostToolUseまたはStopを使うのが適切です。Prompt Hook:LLMが自動でコードを評価・ブロックする
Prompt Hookは最も強力なHookタイプです。ツール実行の前後に別のLLMを呼び出してコードを評価し、指定した文字列が含まれていれば実行をブロックできます。セキュリティチェック・コード品質ゲート・コンプライアンス確認などに使えます。
実践例1:セキュリティ脆弱性の自動検出とブロック
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "prompt",
"prompt": "以下のコード変更を確認してください。次の脆弱性が含まれていれば'BLOCK: 理由'と返してください。含まれていなければ'OK'とだけ返してください。
チェック項目:
- SQLインジェクション(文字列結合でクエリ生成)
- XSS(ユーザー入力の無害化なし)
- ハードコードされたAPIキー・パスワード・シークレット
- コマンドインジェクション(ユーザー入力のshell実行)
変更内容:
$CLAUDE_TOOL_INPUT",
"blockOnResponse": "BLOCK"
}
]
}
]
}
}
実践例2:コードレビューゲート(本番ブランチ保護)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "prompt",
"prompt": "以下のgitコマンドを確認してください。mainまたはproductionブランチへの直接pushやforce pushが含まれていれば'BLOCK: 本番ブランチへの直接操作は禁止されています'と返してください。問題なければ'OK'とだけ返してください。
コマンド: $CLAUDE_TOOL_INPUT",
"blockOnResponse": "BLOCK"
}
]
}
]
}
}
実践例3:コード品質スコアリング(ブロックなし)
blockOnResponseを設定しない場合、評価結果はClaude Codeにフィードバックされるだけでブロックは行われません。コメントや提案として活用できます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "prompt",
"prompt": "新しく作成されたコードの品質を評価してください。以下の観点で1〜5点のスコアと1行コメントを返してください。
1. 命名規則の一貫性
2. 関数の単一責任原則
3. エラーハンドリングの適切さ
形式: スコア: X/5 | コメント: ○○
コード:
$CLAUDE_TOOL_INPUT"
}
]
}
]
}
}
Prompt HookはAPIコールが追加で発生します。
PreToolUseのEdit|Writeに設定すると、ファイルを編集するたびにAPIが呼ばれます。コスト削減には①matcherを絞る(例: Writeのみ)②評価するコードの文字数を制限する——が有効です。Agent Hook:サブエージェントが自動チェックを実行する
Agent HookはRead・Grep・Globなどのツールを持つサブエージェントを起動して、複雑な自動チェックを行います。Prompt Hookが「単一のテキスト評価」なのに対し、Agent Hookは「ファイルシステムを調査しながら判断する」処理が可能です。
実践例1:新規ファイル作成時に重複チェック
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "agent",
"prompt": "新しく作成されたファイル $CLAUDE_TOOL_OUTPUT について、既存の類似ファイルがないか確認してください。
手順:
1. Glob でプロジェクト内の同種ファイル(同じ拡張子)を列挙する
2. Grep でファイル名・関数名・クラス名の重複を検索する
3. 重複が見つかった場合は警告を出す
4. 重複がない場合は「問題なし」と返す",
"tools": ["Read", "Glob", "Grep"]
}
]
}
]
}
}
実践例2:変更後のテスト自動実行と結果フィードバック
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|MultiEdit",
"hooks": [
{
"type": "agent",
"prompt": "編集されたファイルに関連するテストファイルを見つけて内容を確認し、テストカバレッジの抜けを報告してください。
手順:
1. Glob で *.test.ts, *.spec.ts などのテストファイルを検索
2. 編集ファイルと同名のテストファイルを優先的に確認
3. 新しく追加された関数・メソッドのテストケースが存在するか確認
4. テストが不足している場合は具体的に何をテストすべきか提案する",
"tools": ["Read", "Glob", "Grep"]
}
]
}
]
}
}
実践例3:依存パッケージの脆弱性確認
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "agent",
"prompt": "package.jsonが更新された場合、追加されたパッケージを確認し、以下をチェックしてください。
1. Read で package.json の変更内容を確認
2. 新しく追加されたパッケージ名を特定
3. Grep でリポジトリ内でそのパッケージが正しく使われているか確認
4. 不審な点(予期しないパッケージ追加・バージョン急変など)があれば警告
対象ファイル: $CLAUDE_TOOL_OUTPUT",
"tools": ["Read", "Glob", "Grep"]
}
]
}
]
}
}
Agent Hookに指定できるツールはRead・Glob・Grep・WebSearchなどの読み取り専用ツールに限られます。Write・Edit・Bashなどの変更系ツールは使えません。変更を伴う処理が必要な場合は、Agent Hookで問題を検出してフィードバックし、メインのClaudeが修正を行う設計にします。
イベント別活用パターン早見表
| イベント | Hookタイプ | 活用パターン | 設定例 |
|---|---|---|---|
| PreToolUse | Command | 危険コマンドブロック | exit 1でブロック |
| PreToolUse | Prompt | セキュリティレビュー | blockOnResponse: “BLOCK” |
| PreToolUse | HTTP | 監査ログAPIに記録 | POST to audit endpoint |
| PostToolUse | Command | ESLint/フォーマット自動実行 | npx eslint –fix |
| PostToolUse | Agent | 重複チェック・テスト確認 | tools: [Read, Glob, Grep] |
| PostToolUse | Prompt | コード品質スコアリング | blockOnResponse省略 |
| Stop | HTTP | Slack完了通知 | POST to slack webhook |
| Stop | Command | レポート自動生成 | script.sh でサマリ生成 |
| Notification | HTTP | スマホプッシュ通知 | POST to Pushover/FCM |
Hooks環境変数リファレンス
Hook内のコマンド・プロンプト・URLでは、Claude Codeが自動的に設定する環境変数を使えます。$CLAUDE_XXXの形式で参照します。
| 変数名 | 内容 | 利用可能なイベント |
|---|---|---|
$CLAUDE_PROJECT_DIR |
プロジェクトのルートパス | 全イベント |
$CLAUDE_TOOL_NAME |
ツール名(Edit, Bash等) | 全イベント |
$CLAUDE_TOOL_INPUT |
ツールへの入力(コマンド・コード等) | PreToolUse, PostToolUse |
$CLAUDE_TOOL_OUTPUT |
ツールの出力(ファイルパス・実行結果等) | PostToolUse |
$CLAUDE_TIMESTAMP |
実行日時(ISO 8601形式) | 全イベント |
$CLAUDE_SESSION_ID |
現在のセッションID | 全イベント |
$CLAUDE_NOTIFICATION_MESSAGE |
通知メッセージ本文 | Notificationのみ |
JSON形式での入力取得
Command Hook内では、$CLAUDE_TOOL_INPUTがJSON文字列として渡されます。Pythonなどで構造化データとして取得できます。
# Command Hook 内で JSON を解析する
python3 - << 'EOF'
import sys, json
data = json.loads(open('/dev/stdin').read() if not sys.stdin.isatty() else '{}')
# または環境変数から
import os
tool_input = os.environ.get('CLAUDE_TOOL_INPUT', '{}')
try:
parsed = json.loads(tool_input)
command = parsed.get('command', '')
file_path = parsed.get('file_path', '')
print(f"Command: {command}, File: {file_path}")
except json.JSONDecodeError:
print(f"Raw input: {tool_input}")
EOF
複数Hookを組み合わせた実践設定
実務では複数のHookを組み合わせて使うのが一般的です。以下は「セキュリティ重視のチーム開発」を想定した設定例です。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "prompt",
"prompt": "以下のコード変更にSQLインジェクション・XSS・ハードコードされたシークレットが含まれていれば'BLOCK: 理由'と返してください。問題なければ'OK'とだけ返してください。
変更: $CLAUDE_TOOL_INPUT",
"blockOnResponse": "BLOCK"
}
]
},
{
"matcher": "Bash",
"hooks": [
{
"type": "http",
"url": "https://your-audit-api.example.com/log",
"method": "POST",
"headers": { "Content-Type": "application/json" },
"body": {
"command": "$CLAUDE_TOOL_INPUT",
"project": "$CLAUDE_PROJECT_DIR",
"timestamp": "$CLAUDE_TIMESTAMP"
}
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "cd $CLAUDE_PROJECT_DIR && npx prettier --write . 2>&1 | tail -3 || true"
}
]
}
],
"Stop": [
{
"hooks": [
{
"type": "http",
"url": "https://hooks.slack.com/services/YOUR/WEBHOOK/URL",
"method": "POST",
"headers": { "Content-Type": "application/json" },
"body": {
"text": "✅ Claude Code作業完了: $CLAUDE_PROJECT_DIR"
}
}
]
}
]
}
}
まとめ
Claude Code HooksはJSON設定だけで、AIが何かをするたびに自動処理を走らせる強力な仕組みです。4種類のHookタイプを使い分けることで、linter自動実行から始まり、LLMによるセキュリティレビュー・Slack通知・サブエージェントによる品質チェックまで、幅広い自動化が実現できます。
まずはPostToolUseのCommand Hook(prettier/eslint自動修正)から始めるのがおすすめです。設定量が少なく、効果がすぐに実感できます。慣れてきたらHTTP HookでSlack通知を追加し、セキュリティ要件が高いプロジェクトではPrompt Hookのセキュリティチェックを導入しましょう。
Claude Codeの全体的な使い方はClaude Code完全ガイドを、Channelsとの組み合わせはClaude Code Channels完全ガイドを参考にしてください。
よくある質問
QHooksはClaude Code起動中だけ有効ですか?
Aはい。Hooksはsettings.jsonを読み込んだClaude Codeのセッション中だけ有効です。セッションを閉じると動作しなくなります。常時実行したい処理(定期ログなど)は/loopとの組み合わせを検討してください。
QCommand Hookでブロックしたとき、Claudeはどう動きますか?
Aexit 1以上で終了したHookのstdoutの内容がClaude Codeにフィードバックされます。Claudeはその内容を読んで、理由を把握した上で代替手段を検討します。ブロック理由を分かりやすく書くほど、Claudeが適切に対処できます。
QPrompt Hookの評価に使われるモデルはどれですか?
Aデフォルトではメインセッションと同じモデルが使われます。Prompt Hookは追加のAPIコストが発生するため、評価頻度の高い設定では使用量に注意してください。/costコマンドで現セッションのトークン消費量を確認できます。
Qmatcherに指定できるツール名の一覧はどこで確認できますか?
A主なツール名はEdit・Write・MultiEdit・Read・Glob・Grep・Bash・WebSearch・WebFetch・TodoWrite等です。正規表現が使えるので"Edit|Write|MultiEdit"のようにパイプで複数指定できます。省略するとすべてのツール実行でフックが発火します。
Qグローバル設定とプロジェクト設定でHooksが競合した場合はどうなりますか?
A両方のHooksが実行されます(どちらかが優先されるのではなく、両方動きます)。グローバル設定にはSlack通知など全プロジェクト共通のHooksを、プロジェクト設定にはリポジトリ固有のlinter・テストHooksを書くと整理しやすいです。
QHooksのデバッグはどうすればいいですか?
ACommand Hookはecho "debug: $CLAUDE_TOOL_NAME" >> /tmp/hook-debug.logのようにログファイルに書き出すと動作を確認しやすいです。Prompt HookとAgent Hookはレスポンス内容がClaude Codeのコンテキストに返るので、実際に動かして返答を確認するのが最も直感的なデバッグ方法です。

