create-hook について
create-hook は Claude Code 向けのスキルです。プロジェクトのツール構成を調べて適切なフックを提案し、作成とテストを支援します。
主な機能
- 01プロジェクトのツールと既存フックの検出
- 02構成に応じたフックの提案
- 03スクリプト作成と設定更新
- 04成功・失敗ケースのテスト
活用シーン
- 01編集後の型チェックやフォーマット
- 02コミット前のテストやビルド検証
- 03秘密情報を漏らす操作のブロック
- 04問題を Claude Code に実行可能なコンテキストとして伝達
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ neolabhq/ context-engineering-kit --skill create-hookインストール後、Claude Code で/create-hookを入力して読み込まれたか確認します。
詳細
フックコマンドの作成
プロジェクトを分析し、実用的なフックを提案して、適切にテストしたうえで作成します。
タスク(/create-hook)
- 環境を分析する - ツールと既存のフックを検出します
- フックを提案する - プロジェクトの設定に基づいて提案します
- フックを設定する - 対象を絞った質問をして、スクリプトを作成します
- テストと検証を行う - フックが正しく動作することを確認します
ワークフロー
1. 環境の分析と提案
プロジェクトで使用されているツールを自動的に検出し、関連するフックを提案します。
TypeScript が検出された場合(tsconfig.json):
- PostToolUse フック:「編集後にファイルの型をチェックする」
- PreToolUse フック:「型エラーがある場合は編集をブロックする」
Prettier が検出された場合(.prettierrc、prettier.config.js):
- PostToolUse フック:「編集後にファイルを自動フォーマットする」
- PreToolUse フック:「フォーマット済みのコードを必須にする」
ESLint が検出された場合(.eslintrc.*):
- PostToolUse フック:「編集後に lint を実行し、自動修正する」
- PreToolUse フック:「lint エラーがある場合はコミットをブロックする」
package.json にスクリプトがある場合:
testスクリプト →「コミット前にテストを実行する」buildスクリプト →「コミット前にビルドを検証する」
Git リポジトリが検出された場合:
- PreToolUse/Bash フック:「シークレットを含むコミットを防ぐ」
- PostToolUse フック:「ファイル変更時にセキュリティスキャンを実行する」
判断ツリー:
Project has TypeScript? → Suggest type checking hooks
Project has formatter? → Suggest formatting hooks
Project has tests? → Suggest test validation hooks
Security sensitive? → Suggest security hooks
+ Scan for additional patterns and suggest custom hooks based on:
- Custom scripts in package.json
- Unique file patterns or extensions
- Development workflow indicators
- Project-specific tooling configurations
2. フックの設定
まず、**「このフックに何をさせますか?」**と尋ね、分析結果に基づく関連する提案を提示します。
次に、ユーザーの説明からコンテキストを把握し、不明な点についてのみ質問します。
-
実行タイミング:いつ実行しますか?
PreToolUse:ファイル操作の前(ブロック可能)PostToolUse:ファイル操作の後(フィードバックや修正)UserPromptSubmit:リクエストの処理前- 必要に応じてその他のイベントタイプ
-
ツールマッチャー:どのツールを実行のトリガーにしますか?(
Write、Edit、Bash、*など) -
適用範囲:
global、project、project-local -
応答方法:
- 終了コードのみ:シンプル(終了コード 0 = 成功、PreToolUse で終了コード 2 = ブロック)
- JSON 応答:高度な制御(ブロック、コンテキスト、判断)
- 複雑さに応じて案内します:単純な成功/失敗 → 終了コード、詳細なフィードバック → JSON
-
ブロック動作(該当する場合):「問題が見つかった場合、操作を停止しますか?」
- PreToolUse:操作をブロックできます(セキュリティ、検証)
- PostToolUse:通常はフィードバックのみを提供します
-
Claude との連携(重要):「このフックが検出した問題を Claude Code が自動的に確認し、修正できるようにしますか?」
- はいの場合:エラーの伝達には
additionalContextを使用します - いいえの場合:通知せずに実行するには
suppressOutput: trueを使用します
- はいの場合:エラーの伝達には
-
コンテキストのノイズ:「ノイズを避けるため、成功した操作は通知しないようにしますか?」
- フォーマットや定期的なチェックでは「はい」を推奨します
- セキュリティ警告や重大なエラーでは「いいえ」を推奨します
-
ファイルのフィルタリング:このフックで処理するファイルの種類は何ですか?
3. フックの作成
以下を行います。
- フックディレクトリを作成する:スコープに応じて
~/.claude/hooks/または.claude/hooks/を作成します - スクリプトを生成する:次の要件を満たすフックスクリプトを作成します。
- 適切なシェバンと実行権限を設定する
- プロジェクト固有のコマンドを使用する(検出した設定パスを使います)
- フックの目的を説明するコメントを記述する
- 設定を更新する:適切な
settings.jsonにフック設定を追加します - 絶対パスを使用する:スクリプトや実行ファイルに相対パスを使わないでください。プロジェクトルートを参照するには
$CLAUDE_PROJECT_DIRを使います - 検証を提案する:フックをテストするかユーザーに確認します
主な実装基準:
- 標準入力から JSON を読み取る(argv は使いません)
- Claude との通信にはトップレベルの
additionalContext/systemMessageを使用する - 正常に処理された場合は
suppressOutput: trueを含める - 具体的なエラー件数と、実行可能な対応策を提示する
- コードベース全体ではなく、変更されたファイルに注目する
- 一般的な開発ワークフローに対応する
⚠️ 重要:入出力形式
フックの実装で最も失敗が多いのがこの部分です。次の点に特に注意してください。
- 入力:標準入力から JSON を正しく読み取る(argv からではありません)
- 出力:Claude との通信に適したトップレベルの JSON 構造を使用する
- ドキュメント:スキーマが不明な場合は、正確な仕様を公式ドキュメントで確認する
4. テストと検証
重要:成功するケースと失敗するケースの両方をテストしてください。
成功するケースのテスト:
- 想定される成功ケースをテストする — フックがパスする条件を用意します
- 例:TypeScript(有効なコード)、Lint(フォーマット済みのコード)、セキュリティ(安全なコマンド)
失敗するケースのテスト: 2. 想定される失敗ケースをテストする — フックが失敗または警告する条件を用意します
- 例:TypeScript(型エラー)、Lint(フォーマットされていないコード)、セキュリティ(危険な操作)
検証手順: 3. 想定される動作を確認する:意図どおりにブロック、警告、またはコンテキストの提供が行われるか確認します
テストプロセスの例:
- ファイル削除を防ぐフックの場合:テストファイルを作成し、保護対象の操作を試して、フックがそれを防ぐことを確認します
問題が発生した場合:
- 設定でフックが登録されているか確認する
- スクリプトの権限を確認する(
chmod +x) - まず簡易版でテストする
- フックの実行状況を詳しく分析してデバッグする
フックテンプレート
型チェック(PostToolUse)
#!/usr/bin/env node
// Read stdin JSON, check .ts/.tsx files only
// Run: npx tsc --noEmit --pretty
// Output: JSON with additionalContext for errors
自動フォーマット(PostToolUse)
#!/usr/bin/env node
// Read stdin JSON, check supported file types
// Run: npx prettier --write [file]
// Output: JSON with suppressOutput: true
セキュリティスキャン(PreToolUse)
#!/bin/bash
# Read stdin JSON, check for secrets/keys
# Block if dangerous patterns found
# Exit 2 to block, 0 to continue
テンプレートの完全版はこちら:https://docs.claude.com/en/docs/claude-code/hooks#examples
クイックリファレンス
📖 公式ドキュメント:https://docs.claude.com/en/docs/claude-code/hooks.md
一般的なパターン:
- 標準入力からの入力:
JSON.parse(process.stdin.read()) - ファイルのフィルタリング:処理前に拡張子を確認する
- 成功時の応答:
{continue: true, suppressOutput: true} - エラー時の応答:
{continue: true, additionalContext: "error details"} - 操作のブロック:PreToolUse フックで
exit(2)を使用する
用途別のフックタイプ:
- コード品質:フィードバックと修正には PostToolUse を使用する
- セキュリティ:危険な操作のブロックには PreToolUse を使用する
- CI/CD:コミット前の検証には PreToolUse を使用する
- 開発:自動的な改善には PostToolUse を使用する
フック実行のベストプラクティス:
- 公式ドキュメントによると、フックは並列実行されます
- 実行順序が保証されないため、独立して動作するよう設計します
- 複数のフックが同じファイルに影響する場合は、フック間の連携を慎重に計画します
成功基準
✅ 次の場合、フックの作成は成功です。
- スクリプトに実行権限が設定されている
- 正しい
settings.jsonに登録されている - テストケースに正しく応答する
- 自動修正のために Claude と適切に連携する
- プロジェクトの規約と検出されたツールに準拠している
結果:ユーザーは、インテリジェントな自動化と品質チェックによって開発ワークフローを強化する、動作するフックを利用できます。
ドキュメントインデックス
ドキュメントインデックスの完全版を取得するには、こちらにアクセスしてください:https://code.claude.com/docs/llms.txt このファイルを使って、さらに調べる前に利用可能なすべてのページを確認してください。
フックでワークフローを自動化する
Claude Code がファイルを編集したとき、タスクを完了したとき、または入力を必要としたときに、シェルコマンドを自動的に実行します。コードのフォーマット、通知の送信、コマンドの検証、プロジェクトルールの適用ができます。
フックは、Claude Code のライフサイクルにおける特定のタイミングで実行される、ユーザー定義のシェルコマンドです。Claude Code が実行するかどうかを LLM の判断に委ねるのではなく、特定のアクションを常に実行することで、Claude Code の動作を確実に制御できます。フックを使ってプロジェクトルールを適用し、繰り返しの作業を自動化し、Claude Code を既存のツールと連携させましょう。
決定的なルールではなく判断が必要な場合は、Claude モデルを使って条件を評価するプロンプトベースのフックやエージェントベースのフックも使用できます。
Claude Code を拡張するその他の方法については、Claude に追加の指示や実行可能なコマンドを与えるスキル、分離されたコンテキストでタスクを実行するサブエージェント、拡張機能をパッケージ化してプロジェクト間で共有するプラグインをご覧ください。
このガイドでは、一般的なユースケースと利用開始方法を説明します。イベントスキーマ、JSON の入出力形式、非同期フックや MCP ツールフックなどの高度な機能については、[フックのリファレンス](/en/hooks)をご覧ください。 ## 最初のフックを設定するフックを作成する最も手早い方法は、Claude Code の /hooks インタラクティブメニューを使うことです。この手順ではデスクトップ通知フックを作成します。これにより、ターミナルを見続けなくても、Claude が入力を待っているときに通知を受け取れます。
<Tabs>
<Tab title="macOS">
[`osascript`](https://ss64.com/mac/osascript.html) を使い、AppleScript 経由で macOS ネイティブの通知を表示します。
```
osascript -e 'display notification "Claude Code needs your attention" with title "Claude Code"'
```
</Tab>
<Tab title="Linux">
ほとんどの Linux デスクトップでは通知デーモンとともにプリインストールされている `notify-send` を使います。
```
notify-send 'Claude Code' 'Claude Code needs your attention'
```
</Tab>
<Tab title="Windows (PowerShell)">
PowerShell を使い、.NET の Windows Forms 経由でネイティブのメッセージボックスを表示します。
```
powershell.exe -Command "[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')"
```
</Tab>
</Tabs>
メニューでフック設定の保存先を尋ねられます。`User settings` を選択すると、`~/.claude/settings.json` に保存され、すべてのプロジェクトにフックが適用されます。`Project settings` を選択して、現在のプロジェクトだけに適用することもできます。利用可能なすべての適用範囲については、[フックの保存場所を設定する](#configure-hook-location)を参照してください。
`Esc` を押して CLI に戻ります。権限が必要な操作を Claude に依頼してから、ターミナルから切り替えてください。デスクトップ通知が届くはずです。
自動化できること
フックを使うと、Claude Code のライフサイクル上の重要なタイミングでコードを実行できます。編集後のファイルのフォーマット、実行前のコマンドのブロック、Claude が入力を必要とするときの通知、セッション開始時のコンテキストの挿入などが可能です。フックイベントの一覧については、フックのリファレンスを参照してください。
各例には、設定ファイルに追加できる、そのまま使える設定ブロックが含まれています。よく使われるパターンは次のとおりです。
Claude が入力を必要としたときに通知を受け取る
Claude の作業が完了し、入力を必要としているときにデスクトップ通知を受け取れるため、ターミナルを確認せずにほかのタスクに切り替えられます。
このフックでは、Claude が入力または許可を待っているときに発火する Notification イベントを使用します。以下の各タブでは、プラットフォーム標準の通知コマンドを使用しています。これを ~/.claude/settings.json に追加するか、上記のインタラクティブな設定手順を使って /hooks で設定します。
編集後にコードを自動フォーマットする
Claude が編集するすべてのファイルに Prettier を自動的に実行し、手作業なしでフォーマットを統一します。
このフックでは、Edit|Write マッチャーを指定した PostToolUse イベントを使用するため、ファイル編集ツールの実行後にのみ動作します。このコマンドは jq で編集したファイルのパスを抽出し、Prettier に渡します。プロジェクトルートの .claude/settings.json に追加します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
このページの Bash の例では、JSON の解析に `jq` を使用します。`brew install jq`(macOS)、`apt-get install jq`(Debian/Ubuntu)でインストールするか、[`jq` のダウンロード](https://jqlang.github.io/jq/download/)を参照してください。
### 保護対象ファイルへの編集をブロックする
.env、package-lock.json、.git/ 内のファイルなど、機密ファイルを Claude が変更できないようにします。Claude には編集がブロックされた理由を説明するフィードバックが届くため、アプローチを調整できます。
この例では、フックから呼び出す独立したスクリプトファイルを使用します。スクリプトは対象ファイルのパスを保護対象パターンのリストと照合し、編集をブロックするために終了コード 2 で終了します。
次の内容を `.claude/hooks/protect-files.sh` に保存します。```bash theme={null}
#!/bin/bash
# protect-files.sh
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 matches protected pattern '$pattern'" >&2
exit 2
fi
done
exit 0
```
Claude Code がフックスクリプトを実行するには、スクリプトに実行権限が必要です。
```bash theme={null}
chmod +x .claude/hooks/protect-files.sh
```
`.claude/settings.json` に `PreToolUse` フックを追加し、`Edit` または `Write` ツールの呼び出し前にスクリプトを実行します。
```json theme={null}
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh"
}
]
}
]
}
}
```
コンパクション後にコンテキストを再注入する
Claude のコンテキストウィンドウがいっぱいになると、空き容量を確保するために会話が要約されます。その際、重要な詳細が失われることがあります。compact マッチャーを指定した SessionStart フックを使用して、コンパクションのたびに重要なコンテキストを再注入します。
コマンドが標準出力に書き込んだテキストは、Claude のコンテキストに追加されます。この例では、プロジェクトの規約と最近の作業を Claude に再確認させます。プロジェクトのルートにある .claude/settings.json に次の内容を追加します。
{
"hooks": {
"SessionStart": [
{
"matcher": "compact",
"hooks": [
{
"type": "command",
"command": "echo 'Reminder: use Bun, not npm. Run bun test before committing. Current sprint: auth refactor.'"
}
]
}
]
}
}
echo を、最近のコミットを表示する git log --oneline -5 など、動的な出力を生成する任意のコマンドに置き換えることができます。すべてのセッション開始時にコンテキストを注入するには、代わりに CLAUDE.md の使用を検討してください。環境変数については、リファレンスの CLAUDE_ENV_FILE を参照してください。
フックの仕組み
フックイベントは、Claude Code のライフサイクルにおける特定のタイミングで発生します。イベントが発生すると、一致するすべてのフックが並行して実行され、同一のフックコマンドは自動的に重複排除されます。以下の表に、各イベントとその発生タイミングを示します。
| イベント | 発生タイミング |
|---|---|
SessionStart | セッションが開始または再開されたとき |
UserPromptSubmit | プロンプトを送信したとき。Claude が処理する前 |
PreToolUse | ツール呼び出しが実行される前。実行をブロックできます |
PermissionRequest | 権限ダイアログが表示されたとき |
PostToolUse | ツール呼び出しが成功した後 |
PostToolUseFailure | ツール呼び出しが失敗した後 |
Notification | Claude Code が通知を送信したとき |
SubagentStart | サブエージェントが起動されたとき |
SubagentStop | サブエージェントが終了したとき |
Stop | Claude が応答を終了したとき |
PreCompact | コンテキストが圧縮される前 |
SessionEnd | セッションが終了したとき |
各フックには、実行方法を決める type があります。ほとんどのフックでは、シェルコマンドを実行する "type": "command" を使用します。ほかに、Claude モデルを使って判断するオプションが2つあります。1ターンの評価には "type": "prompt"、ツールを利用した複数ターンの検証には "type": "agent" を使用します。詳しくは、プロンプトベースのフックとエージェントベースのフックをご覧ください。
入力の読み取りと出力の返却
フックは、stdin、stdout、stderr、終了コードを通じて Claude Code と通信します。イベントが発生すると、Claude Code はイベント固有のデータを JSON としてスクリプトの stdin に渡します。スクリプトはそのデータを読み取り、処理を行い、終了コードを使って Claude Code に次の動作を伝えます。
フックの入力
すべてのイベントには session_id や cwd などの共通フィールドが含まれますが、イベントの種類ごとに異なるデータが追加されます。たとえば、Claude が Bash コマンドを実行すると、PreToolUse フックは stdin から次のようなデータを受け取ります。
{
"session_id": "abc123", // unique ID for this session
"cwd": "/Users/sarah/myproject", // working directory when the event fired
"hook_event_name": "PreToolUse", // which event triggered this hook
"tool_name": "Bash", // the tool Claude is about to use
"tool_input": { // the arguments Claude passed to the tool
"command": "npm test" // for Bash, this is the shell command
}
}
スクリプトでは、この JSON を解析し、任意のフィールドに応じて処理を行えます。UserPromptSubmit フックは代わりに prompt テキストを受け取り、SessionStart フックは source(startup、resume、compact)を受け取ります。共通フィールドについてはリファレンスの共通入力フィールドを、イベント固有のスキーマについては各イベントのセクションをご覧ください。
フックの出力
スクリプトは stdout または stderr に書き込み、特定の終了コードで終了することで、Claude Code に次の動作を伝えます。たとえば、コマンドをブロックしたい PreToolUse フックは次のようになります。
#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q "drop table"; then
echo "Blocked: dropping tables is not allowed" >&2 # stderr becomes Claude's feedback
exit 2 # exit 2 = block the action
fi
exit 0 # exit 0 = let it proceed
終了コードによって、その後の動作が決まります。
- 終了コード 0:処理は続行されます。
UserPromptSubmitとSessionStartのフックでは、stdout に書き込んだ内容が Claude のコンテキストに追加されます。 - 終了コード 2:処理はブロックされます。stderr に理由を書き込むと、Claude はフィードバックとして受け取り、それに応じて調整できます。
- その他の終了コード:処理は続行されます。stderr はログに記録されますが、Claude には表示されません。トランスクリプトでこれらのメッセージを確認するには、
Ctrl+Oで詳細モードを切り替えます。
構造化 JSON 出力
終了コードには、許可またはブロックという 2 つの選択肢があります。より細かく制御するには、終了コード 0 で stdout に JSON オブジェクトを出力します。
ブロックする場合は終了コード 2 と stderr へのメッセージを、構造化された制御を行う場合は終了コード 0 と JSON を使用してください。これらを混在させないでください。終了コード 2 の場合、Claude Code は JSON を無視します。たとえば、PreToolUse フックはツール呼び出しを拒否して Claude にその理由を伝えたり、ユーザーに承認を求めるためにエスカレーションしたりできます。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Use rg instead of grep for better performance"
}
}
Claude Code は permissionDecision を読み取ってツール呼び出しをキャンセルし、permissionDecisionReason をフィードバックとして Claude に返します。次の 3 つのオプションは PreToolUse に固有です。
"allow": 権限プロンプトを表示せずに続行します"deny": ツール呼び出しをキャンセルし、理由を Claude に送信します"ask": 通常どおりユーザーに権限プロンプトを表示します
その他のイベントでは、異なる決定パターンを使用します。たとえば、PostToolUse と Stop フックはトップレベルの decision: "block" フィールドを使用し、PermissionRequest は hookSpecificOutput.decision.behavior を使用します。イベント別の詳細な内訳については、リファレンスの概要表を参照してください。
UserPromptSubmit フックの場合は、代わりに additionalContext を使用して Claude のコンテキストにテキストを注入します。プロンプトベースのフック(type: "prompt")は出力を異なる方法で処理します。プロンプトベースのフックを参照してください。
マッチャーでフックを絞り込む
マッチャーがない場合、フックはそのイベントが発生するたびに実行されます。マッチャーを使用すると、それを絞り込めます。たとえば、ファイル編集の後だけ(すべてのツール呼び出しの後ではなく)フォーマッターを実行したい場合は、PostToolUse フックにマッチャーを追加します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{ "type": "command", "command": "prettier --write ..." }
]
}
]
}
}
"Edit|Write" マッチャーは、ツール名に一致する正規表現パターンです。このフックは Claude が Edit または Write ツールを使用したときだけ実行され、Bash、Read、その他のツールを使用したときには実行されません。
各イベントタイプは特定のフィールドでマッチングします。マッチャーは完全一致文字列と正規表現パターンをサポートしています。
| イベント | マッチャーがフィルタリングする対象 | マッチャー値の例 |
|---|---|---|
PreToolUse, PostToolUse, PostToolUseFailure, PermissionRequest | ツール名 | Bash, Edit|Write, mcp__.* |
SessionStart | セッションの開始方法 | startup, resume, clear, compact |
SessionEnd | セッションの終了理由 | clear, logout, prompt_input_exit, other |
Notification | 通知タイプ | permission_prompt, idle_prompt, auth_success, elicitation_dialog |
SubagentStart | エージェントタイプ | Bash、Explore、Plan、またはカスタムエージェント名 |
PreCompact | 圧縮のトリガー | manual, auto |
UserPromptSubmit, Stop | マッチャー非対応 | 発生するたびに常に実行されます |
SubagentStop | エージェントタイプ | SubagentStart と同じ値 |
さまざまなイベントタイプでのマッチャーの例をさらにいくつか示します。
Bash ツール呼び出しのみにマッチし、各コマンドをファイルにログとして記録します。PostToolUse イベントはコマンドの完了後に発火するため、tool_input.command には実行された内容が含まれます。フックはイベントデータを JSON として stdin で受け取り、jq -r '.tool_input.command' がコマンド文字列だけを抽出し、>> がそれをログファイルに追記します:
```json theme={null}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' >> ~/.claude/command-log.txt"
}
]
}
]
}
}
```
MCP ツールは組み込みツールとは異なる命名規則を使用します:`mcp____`。ここで `` は MCP サーバー名、`` はそれが提供するツールです。たとえば、`mcp__github__search_repositories` や `mcp__filesystem__read_file` です。正規表現マッチャーを使用して特定のサーバーからのすべてのツールを対象にするか、`mcp__.*__write.*` のようなパターンでサーバーをまたいでマッチさせます。例の完全なリストについては、リファレンスの [MCP ツールにマッチする](/en/hooks#match-mcp-tools) を参照してください。
以下のコマンドは、フックの JSON 入力から `jq` でツール名を抽出し、それを stderr に書き込みます。これは詳細モード(`Ctrl+O`)で表示されます:
```json theme={null}
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__github__.*",
"hooks": [
{
"type": "command",
"command": "echo \"GitHub tool called: $(jq -r '.tool_name')\" >&2"
}
]
}
]
}
}
```
`SessionEnd` イベントは、セッションが終了した理由に対するマッチャーをサポートします。このフックは `clear` の場合(`/clear` を実行したとき)にのみ発火し、通常の終了時には発火しません:
```json theme={null}
{
"hooks": {
"SessionEnd": [
{
"matcher": "clear",
"hooks": [
{
"type": "command",
"command": "rm -f /tmp/claude-scratch-*.txt"
}
]
}
]
}
}
```
マッチャーの構文の詳細については、フックのリファレンス を参照してください。
フックの配置場所を設定する
フックをどこに追加するかによって、そのスコープが決まります。
| 配置場所 | スコープ | 共有可否 |
|---|---|---|
~/.claude/settings.json | すべてのプロジェクト | いいえ、お使いのマシン上のみ |
.claude/settings.json | 単一のプロジェクト | はい、リポジトリにコミットできます |
.claude/settings.local.json | 単一のプロジェクト | いいえ、gitignore されます |
| 管理ポリシー設定 | 組織全体 | はい、管理者が制御します |
プラグイン hooks/hooks.json | プラグインが有効なとき | はい、プラグインに同梱されます |
| スキルまたはエージェントの frontmatter | スキルまたはエージェントがアクティブな間 | はい、コンポーネントファイル内で定義されます |
Claude Code の/hooks メニューを使って、フックを対話的に追加、削除、表示することもできます。すべてのフックを一度に無効にするには、/hooks メニューの下部にあるトグルを使用するか、設定ファイルで "disableAllHooks": true を設定します。
/hooks メニューから追加されたフックは即座に有効になります。Claude Code の実行中に設定ファイルを直接編集した場合、/hooks メニューでそれらを確認するか、セッションを再起動するまで変更は有効になりません。
プロンプトベースのフック
決定論的なルールではなく判断を必要とする決定には、type: "prompt" フックを使用します。シェルコマンドを実行する代わりに、Claude Code はプロンプトとフックの入力データを Claude モデル(デフォルトでは Haiku)に送信して判断を下します。より高い能力が必要な場合は、model フィールドで別のモデルを指定できます。
モデルの唯一の役割は、yes/no の判断を JSON として返すことです。
"ok": true: アクションは続行されます"ok": false: アクションはブロックされます。モデルの"reason"は Claude にフィードバックされ、調整できるようになります。
この例では、Stop フックを使用して、要求されたすべてのタスクが完了しているかどうかをモデルに問い合わせます。モデルが "ok": false を返した場合、Claude は作業を続け、reason を次の指示として使用します。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Check if all tasks are complete. If not, respond with {\"ok\": false, \"reason\": \"what remains to be done\"}."
}
]
}
]
}
}
設定オプションの詳細については、リファレンスのプロンプトベースのフックを参照してください。
エージェントベースのフック
検証にファイルの検査やコマンドの実行が必要な場合は、type: "agent" フックを使用します。単一の LLM 呼び出しを行うプロンプトフックとは異なり、エージェントフックはサブエージェントを起動し、そのサブエージェントがファイルを読み取り、コードを検索し、その他のツールを使用して条件を検証してから判断を返します。
エージェントフックはプロンプトフックと同じ "ok" / "reason" レスポンス形式を使用しますが、デフォルトのタイムアウトが 60 秒と長く、最大 50 回のツール使用ターンがあります。
この例では、Claude が停止する前にテストが成功することを検証します。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "Verify that all unit tests pass. Run the test suite and check the results. $ARGUMENTS",
"timeout": 120
}
]
}
]
}
}
フックの入力データだけで判断できる場合はプロンプトフックを使用します。コードベースの実際の状態に対して何かを検証する必要がある場合はエージェントフックを使用します。
設定オプションの詳細については、リファレンスのエージェントベースのフックを参照してください。
制限事項とトラブルシューティング
制限事項
- フックは stdout、stderr、終了コードを通じてのみ通信します。スラッシュコマンドやツール呼び出しを直接トリガーすることはできません。
- フックのタイムアウトはデフォルトで 10 分で、
timeoutフィールド(秒単位)でフックごとに設定できます。 PostToolUseフックは、ツールがすでに実行されているため、アクションを元に戻すことはできません。PermissionRequestフックは非対話モード(-p)では発火しません。自動化された権限判断にはPreToolUseフックを使用してください。Stopフックは、タスク完了時だけでなく、Claude が応答を終了するたびに発火します。ユーザーの中断時には発火しません。
フックが実行されない
フックは設定されていますが、実行されません。
/hooksを実行し、フックが正しいイベントの下に表示されることを確認してください- マッチャーパターンがツール名と完全に一致していることを確認してください(マッチャーでは大文字と小文字が区別されます)
- 正しいイベントタイプをトリガーしていることを確認してください(例:
PreToolUseはツール実行前に、PostToolUseは実行後に実行されます) - 非対話モード(
-p)でPermissionRequestフックを使用している場合は、代わりにPreToolUseに切り替えてください
フックエラーが出力に表示される
トランスクリプトに「PreToolUse hook error: ...」のようなメッセージが表示されます。
-
スクリプトが予期せずゼロ以外のコードで終了しました。サンプル JSON をパイプで渡して、手動でテストしてください:
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh echo $? # Check the exit code
- 「command not found」と表示される場合は、絶対パスまたは
$CLAUDE_PROJECT_DIRを使ってスクリプトを参照してください
- 「jq: command not found」と表示される場合は、
jqをインストールするか、JSON の解析に Python/Node.js を使用してください - スクリプトがまったく実行されない場合は、実行可能にしてください:
chmod +x ./my-hook.sh
/hooks に設定済みのフックが表示されない
設定ファイルを編集しましたが、メニューにフックが表示されません。
- セッションを再起動するか、
/hooksを開いて再読み込みしてください。/hooksメニューから追加したフックはすぐに反映されますが、ファイルを手動で編集した場合は再読み込みが必要です。 - JSON が有効であることを確認してください(末尾のカンマとコメントは使用できません)
- 設定ファイルが正しい場所にあることを確認してください:プロジェクトのフックは
.claude/settings.json、グローバルフックは~/.claude/settings.json
Stop フックがいつまでも実行される
Claude が停止せず、無限ループで作業を続けます。
Stop フックスクリプトでは、継続処理がすでにトリガーされているかどうかを確認する必要があります。JSON 入力から stop_hook_active フィールドを解析し、true の場合は早期に終了してください:
#!/bin/bash
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0 # Allow Claude to stop
fi
# ... rest of your hook logic
JSON の検証に失敗する
フックスクリプトが有効な JSON を出力しているのに、Claude Code で JSON 解析エラーが表示されます。
Claude Code がフックを実行すると、ユーザープロファイル(~/.zshrc または ~/.bashrc)を読み込むシェルを起動します。プロファイルに無条件で実行される echo 文が含まれていると、その出力がフックの JSON の先頭に追加されます:
Shell ready on arm64
{"decision": "block", "reason": "Not allowed"}
Claude Code はこれを JSON として解析しようとするため、失敗します。修正するには、シェルプロファイル内の echo 文を、対話型シェルでのみ実行されるように囲んでください:
# In ~/.zshrc or ~/.bashrc
if [[ $- == *i* ]]; then
echo "Shell ready"
fi
$- 変数にはシェルのフラグが含まれており、i は対話型を意味します。フックは非対話型シェルで実行されるため、echo はスキップされます。
デバッグ方法
Ctrl+O で詳細モードを切り替えると、トランスクリプトにフックの出力が表示されます。または claude --debug を実行すると、どのフックが一致したかや終了コードを含む、実行の詳細をすべて確認できます。
詳細はこちら
- フックのリファレンス:イベントスキーマ、JSON 出力形式、非同期フック、MCP ツールフックの詳細
- セキュリティに関する考慮事項:共有環境または本番環境にフックをデプロイする前に確認してください
- Bash コマンドバリデーターの例:完全なリファレンス実装
ドキュメントインデックス
ドキュメントの完全なインデックスはこちらから取得できます:https://code.claude.com/docs/llms.txt このファイルを使って、さらに調べる前に利用可能なすべてのページを確認してください。
フックのリファレンス
例を含むクイックスタートガイドについては、[フックでワークフローを自動化する](/en/hooks-guide)を参照してください。Claude Code のフックイベント、設定スキーマ、JSON 入出力形式、終了コード、非同期フック、プロンプトフック、MCP ツールフックのリファレンスです。
フックは、Claude Code のライフサイクルにおける特定のタイミングで自動実行される、ユーザー定義のシェルコマンドまたは LLM プロンプトです。このリファレンスでは、イベントスキーマ、設定オプション、JSON 入出力形式、非同期フックや MCP ツールフックなどの高度な機能を確認できます。初めてフックを設定する場合は、まずガイドを参照してください。
フックのライフサイクル
フックは、Claude Code のセッション中の特定のタイミングで実行されます。イベントが発生し、マッチャーが一致すると、Claude Code はそのイベントに関する JSON コンテキストをフックハンドラーに渡します。コマンドフックの場合、この情報は標準入力で渡されます。ハンドラーは入力を調べて処理を実行し、必要に応じて判断を返すことができます。イベントによってはセッションごとに 1 回だけ発生し、エージェントループ内で繰り返し発生するものもあります。
以下の表は、各イベントが発生するタイミングをまとめたものです。フックイベントのセクションでは、それぞれのイベントの入力スキーマと判断制御オプションについて詳しく説明しています。
| イベント | 発生するタイミング |
|---|---|
SessionStart | セッションが開始または再開されたとき |
UserPromptSubmit | プロンプトを送信したとき。Claude が処理する前 |
PreToolUse | ツール呼び出しが実行される前。ブロックできます |
PermissionRequest | 権限ダイアログが表示されたとき |
PostToolUse | ツール呼び出しが成功した後 |
PostToolUseFailure | ツール呼び出しが失敗した後 |
Notification | Claude Code が通知を送信したとき |
SubagentStart | サブエージェントが起動されたとき |
SubagentStop | サブエージェントが終了したとき |
Stop | Claude が応答を完了したとき |
PreCompact | コンテキストが圧縮される前 |
SessionEnd | セッションが終了したとき |
フックの解決方法
これらの要素がどのように連携するかを確認するため、破壊的なシェルコマンドをブロックするこの PreToolUse フックを見てみましょう。このフックは、Bash ツールを呼び出すたびに block-rm.sh を実行します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/block-rm.sh"
}
]
}
]
}
}
スクリプトは stdin から JSON 入力を読み取り、コマンドを抽出します。コマンドに rm -rf が含まれている場合は、permissionDecision として "deny" を返します。
#!/bin/bash
# .claude/hooks/block-rm.sh
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -q 'rm -rf'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "Destructive command blocked by hook"
}
}'
else
exit 0 # allow the command
fi
ここで、Claude Code が Bash "rm -rf /tmp/build" を実行すると決定したとします。次のように処理されます。
```json theme={null}
{ "tool_name": "Bash", "tool_input": { "command": "rm -rf /tmp/build" }, ... }
```
マッチャー `"Bash"` がツール名に一致するため、`block-rm.sh` が実行されます。マッチャーを省略するか `"*"` を使用すると、イベントが発生するたびにフックが実行されます。マッチャーが定義されていて、一致しない場合にのみフックはスキップされます。
スクリプトは入力から `"rm -rf /tmp/build"` を抽出し、`rm -rf` を検出すると、標準出力に判定を出力します。
```json theme={null}
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Destructive command blocked by hook"
}
}
```
コマンドが安全なもの(`npm test` など)であれば、代わりに `exit 0` が実行されます。これにより、Claude Code は追加の操作を行わずにツール呼び出しを許可します。
Claude Code は JSON の判定を読み取り、ツール呼び出しをブロックして、その理由を Claude に表示します。
以下の設定セクションではスキーマ全体を説明し、各フックイベントセクションでは、コマンドが受け取る入力と返せる出力について説明します。
設定
フックは JSON 設定ファイルで定義します。設定は次の 3 つの階層で構成されます。
PreToolUseやStopなど、応答するフックイベントを選択します- 「Bash ツールの場合のみ」のように、実行条件を絞り込むマッチャーグループを追加します
- 条件に一致したときに実行する 1 つ以上のフックハンドラーを定義します
注釈付きの例を使った詳しい手順については、上記のフックの解決方法をご覧ください。
このページでは、各階層に固有の用語を使用します。ライフサイクル上のポイントには**フックイベント**、フィルターには**マッチャーグループ**、実行されるシェルコマンド、プロンプト、またはエージェントには**フックハンドラー**を使用します。「フック」は、それ自体では一般的な機能を指します。フックの配置場所
フックを定義する場所によって、適用範囲が決まります。
| 場所 | 適用範囲 | 共有可能性 |
|---|---|---|
~/.claude/settings.json | すべてのプロジェクト | いいえ。自分のマシンに限られます |
.claude/settings.json | 単一のプロジェクト | はい。リポジトリにコミットできます |
.claude/settings.local.json | 単一のプロジェクト | いいえ。gitignore の対象です |
| 管理ポリシー設定 | 組織全体 | はい。管理者が制御します |
プラグインのhooks/hooks.json | プラグインが有効な間 | はい。プラグインに同梱されます |
| スキルまたはエージェントのフロントマター | コンポーネントが有効な間 | はい。コンポーネントファイルで定義します |
設定ファイルの解決について詳しくは、設定をご覧ください。エンタープライズ管理者は、allowManagedHooksOnlyを使用してユーザー、プロジェクト、プラグインのフックをブロックできます。フックの設定をご覧ください。
マッチャーパターン
matcher フィールドは、フックが実行されるタイミングをフィルタリングする正規表現文字列です。すべての発生に一致させるには、"*"、"" を使用するか、matcher を完全に省略します。イベントの種類ごとに、照合対象となるフィールドが異なります。
| イベント | マッチャーのフィルタリング対象 | マッチャーの値の例 |
|---|---|---|
PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest | ツール名 | Bash、Edit|Write、mcp__.* |
SessionStart | セッションの開始方法 | startup、resume、clear、compact |
SessionEnd | セッションの終了理由 | clear、logout、prompt_input_exit、bypass_permissions_disabled、other |
Notification | 通知の種類 | permission_prompt、idle_prompt、auth_success、elicitation_dialog |
SubagentStart | エージェントの種類 | Bash、Explore、Plan、またはカスタムエージェント名 |
PreCompact | コンパクションのトリガー | manual、auto |
SubagentStop | エージェントの種類 | SubagentStart と同じ値 |
UserPromptSubmit、Stop | マッチャーは非対応 | 発生するたびに常に実行される |
マッチャーは正規表現です。そのため、Edit|Write はどちらかのツールに一致し、Notebook.* は Notebook で始まる任意のツールに一致します。マッチャーは、Claude Code が標準入力でフックに送信するJSON 入力のフィールドに対して実行されます。ツールイベントの場合、このフィールドは tool_name です。各フックイベントのセクションには、マッチャーで使用できる値の一覧と、そのイベントの入力スキーマが記載されています。
次の例では、Claude がファイルを書き込むか編集した場合にのみ、リンティングスクリプトを実行します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "/path/to/lint-check.sh"
}
]
}
]
}
}
UserPromptSubmit と Stop はマッチャーに対応しておらず、発生するたびに常に実行されます。これらのイベントに matcher フィールドを追加しても、無視されます。
MCP ツールに一致させる
MCP サーバーのツールは、ツールイベント(PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest)では通常のツールとして表示されるため、ほかのツール名と同じ方法で一致させることができます。
MCP ツールは mcp__<server>__<tool> という命名パターンに従います。たとえば、次のとおりです。
mcp__memory__create_entities:Memory サーバーのエンティティ作成ツールmcp__filesystem__read_file:Filesystem サーバーのファイル読み取りツールmcp__github__search_repositories:GitHub サーバーの検索ツール
正規表現パターンを使って、特定の MCP ツールやツールのグループを対象にできます。
mcp__memory__.*はmemoryサーバーのすべてのツールに一致しますmcp__.*__write.*は、どのサーバーでも名前に「write」を含むツールに一致します
次の例では、memory サーバーのすべての操作をログに記録し、任意の MCP サーバーの書き込み操作を検証します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "mcp__memory__.*",
"hooks": [
{
"type": "command",
"command": "echo 'Memory operation initiated' >> ~/mcp-operations.log"
}
]
},
{
"matcher": "mcp__.*__write.*",
"hooks": [
{
"type": "command",
"command": "/home/user/scripts/validate-mcp-write.py"
}
]
}
]
}
}
フックハンドラーのフィールド
内側の hooks 配列の各オブジェクトはフックハンドラーです。マッチャーが一致したときに実行されるシェルコマンド、LLM プロンプト、またはエージェントを指定します。種類は 3 つあります。
- コマンドフック(
type: "command"):シェルコマンドを実行します。スクリプトはイベントのJSON 入力を標準入力で受け取り、終了コードと標準出力を通じて結果を返します。 - プロンプトフック(
type: "prompt"):Claude モデルにプロンプトを送信して、単一ターンで評価します。モデルは JSON 形式で yes/no の判定を返します。プロンプトベースのフックを参照してください。 - エージェントフック(
type: "agent"):Read、Grep、Glob などのツールを使用して条件を検証し、判定を返すサブエージェントを起動します。エージェントベースのフックを参照してください。
共通フィールド
これらのフィールドはすべてのフックタイプに適用されます。
| フィールド | 必須 | 説明 |
|---|---|---|
type | はい | "command"、"prompt"、または "agent" |
timeout | いいえ | キャンセルするまでの秒数です。デフォルトは、command が 600、prompt が 30、agent が 60 です |
statusMessage | いいえ | フックの実行中に表示されるカスタムのスピンナー メッセージ |
once | いいえ | true の場合、セッションごとに 1 回だけ実行され、その後削除されます。スキルのみが対象で、エージェントは対象外です。スキルとエージェントのフックを参照してください |
コマンドフックのフィールド
共通フィールドに加えて、コマンドフックでは次のフィールドを指定できます。
| フィールド | 必須 | 説明 |
|---|---|---|
command | はい | 実行するシェルコマンド |
async | いいえ | true の場合、ブロックせずにバックグラウンドで実行されます。フックをバックグラウンドで実行するを参照してください |
プロンプトフックとエージェントフックのフィールド
共通フィールドに加えて、プロンプトフックとエージェントフックでは次のフィールドを指定できます。
| フィールド | 必須 | 説明 |
|---|---|---|
prompt | はい | モデルに送信するプロンプトテキストです。フック入力 JSON のプレースホルダーとして $ARGUMENTS を使用します |
model | いいえ | 評価に使用するモデルです。デフォルトは高速モデルです |
一致するすべてのフックは並列で実行され、同一のハンドラーは自動的に重複排除されます。ハンドラーは、Claude Code の環境で現在のディレクトリ内にて実行されます。リモートのウェブ環境では環境変数 $CLAUDE_CODE_REMOTE が "true" に設定され、ローカルの CLI では設定されません。
パスで参照するスクリプト
フックの実行時に作業ディレクトリがどこであっても、環境変数を使ってプロジェクトまたはプラグインのルートからの相対パスでフックスクリプトを参照できます。
$CLAUDE_PROJECT_DIR:プロジェクトのルートです。パスにスペースが含まれる場合に備えて、引用符で囲んでください。${CLAUDE_PLUGIN_ROOT}:プラグインにバンドルされたスクリプト用の、プラグインのルートディレクトリです。
```json theme={null}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-style.sh"
}
]
}
]
}
}
```
プラグインのフックは、任意のトップレベル`description`フィールドを含めて、`hooks/hooks.json`で定義します。プラグインを有効にすると、そのフックはユーザーおよびプロジェクトのフックと統合されます。
この例では、プラグインにバンドルされたフォーマットスクリプトを実行します。
```json theme={null}
{
"description": "Automatic code formatting",
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh",
"timeout": 30
}
]
}
]
}
}
```
プラグインのフックの作成方法については、[プラグインコンポーネントのリファレンス](/en/plugins-reference#hooks)を参照してください。
スキルとエージェントのフック
設定ファイルやプラグインに加えて、フックはフロントマターを使ってスキルやサブエージェント内に直接定義できます。これらのフックはコンポーネントのライフサイクルにスコープされ、そのコンポーネントがアクティブなときにのみ実行されます。
すべてのフックイベントがサポートされています。サブエージェントでは、サブエージェントの完了時に発生するイベントに合わせて、Stopフックは自動的にSubagentStopに変換されます。
フックでは設定ベースのフックと同じ構成形式を使用しますが、コンポーネントの存続期間にスコープされ、コンポーネントの終了時にクリーンアップされます。
このスキルでは、各Bashコマンドの前にセキュリティ検証スクリプトを実行するPreToolUseフックを定義しています。
---
name: secure-operations
description: Perform operations with security checks
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/security-check.sh"
---
エージェントでも、YAMLフロントマターで同じ形式を使用します。
/hooksメニュー
Claude Codeで/hooksと入力すると、インタラクティブなフックマネージャーが開きます。設定ファイルを直接編集せずに、フックの表示、追加、削除ができます。手順を追った説明については、ガイドの最初のフックを設定するを参照してください。
メニュー内の各フックには、ソースを示す角括弧付きの接頭辞が付いています。
[User]:~/.claude/settings.jsonから[Project]:.claude/settings.jsonから[Local]:.claude/settings.local.jsonから[Plugin]:プラグインのhooks/hooks.jsonから。読み取り専用です
フックを無効化または削除する
フックを削除するには、設定JSONファイルからそのエントリを削除するか、/hooksメニューを使ってフックを選択し、削除します。
フックを削除せずに一時的にすべて無効化するには、設定ファイルで"disableAllHooks": trueを設定するか、/hooksメニューの切り替えを使用します。個々のフックを設定に残したまま無効化する方法はありません。
設定ファイルでフックを直接編集しても、すぐには反映されません。Claude Codeは起動時にフックのスナップショットを取得し、セッション中はそれを使用します。これにより、悪意のある変更や誤った変更が、レビューなしにセッションの途中で反映されるのを防ぎます。フックが外部で変更された場合、Claude Codeは警告を表示し、変更を適用する前に/hooksメニューでのレビューを求めます。
フックの入力と出力
フックは標準入力から JSON データを受け取り、終了コード、標準出力、標準エラー出力を通じて結果を通知します。このセクションでは、すべてのイベントに共通するフィールドと動作について説明します。各イベント固有の入力スキーマと判断制御オプションについては、フックイベント内の各イベントのセクションを参照してください。
共通の入力フィールド
すべてのフックイベントは、各フックイベントのセクションに記載されているイベント固有のフィールドに加えて、以下のフィールドを JSON として標準入力から受け取ります。
| フィールド | 説明 |
|---|---|
session_id | 現在のセッション識別子 |
transcript_path | 会話 JSON へのパス |
cwd | フックが呼び出された時点の現在の作業ディレクトリ |
permission_mode | 現在の権限モード:「default」、「plan」、「acceptEdits」、「dontAsk」、または「bypassPermissions」 |
hook_event_name | 発生したイベントの名前 |
たとえば、Bash コマンド用の PreToolUse フックは、次の内容を標準入力で受け取ります。
{
"session_id": "abc123",
"transcript_path": "/home/user/.claude/projects/.../transcript.jsonl",
"cwd": "/home/user/my-project",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
}
}
tool_name フィールドと tool_input フィールドはイベント固有です。各フックイベントのセクションで、そのイベントに固有の追加フィールドについて説明します。
終了コードの出力
フックコマンドの終了コードによって、アクションを続行するか、ブロックするか、無視するかが Claude Code に伝えられます。
終了コード 0 は成功を意味します。Claude Code は標準出力からJSON 出力フィールドを解析します。JSON 出力が処理されるのは、終了コードが 0 の場合のみです。ほとんどのイベントでは、標準出力は詳細モード(Ctrl+O)でのみ表示されます。例外は UserPromptSubmit と SessionStart で、標準出力は Claude が参照して対応できるコンテキストとして追加されます。
終了コード 2 はブロックを伴うエラーを意味します。Claude Code は標準出力と、その中の JSON を無視します。代わりに、標準エラー出力のテキストがエラーメッセージとして Claude に渡されます。その影響はイベントによって異なります。たとえば、PreToolUse はツール呼び出しをブロックし、UserPromptSubmit はプロンプトを拒否します。詳しくはイベントごとの終了コード 2 の動作を参照してください。
それ以外の終了コードは、ブロックを伴わないエラーを意味します。標準エラー出力は詳細モード(Ctrl+O)で表示され、実行は続行されます。
たとえば、危険な Bash コマンドをブロックするフックコマンドのスクリプトは、次のようになります。
#!/bin/bash
# Reads JSON input from stdin, checks the command
command=$(jq -r '.tool_input.command' < /dev/stdin)
if [[ "$command" == rm* ]]; then
echo "Blocked: rm commands are not allowed" >&2
exit 2 # Blocking error: tool call is prevented
fi
exit 0 # Success: tool call proceeds
イベントごとの終了コード 2 の動作
終了コード 2 は、フックが「停止して、これを実行しないでください」と通知する方法です。イベントによって効果は異なります。イベントの中には、まだ実行されていないツール呼び出しのようにブロックできるアクションを表すものもあれば、すでに実行済み、または阻止できないものを表すものもあるためです。
| フックイベント | ブロック可能? | 終了コード 2 の動作 |
|---|---|---|
PreToolUse | はい | ツール呼び出しをブロックします |
PermissionRequest | はい | 権限を拒否します |
UserPromptSubmit | はい | プロンプトの処理をブロックし、プロンプトを消去します |
Stop | はい | Claude の停止を防ぎ、会話を続けます |
SubagentStop | はい | サブエージェントの停止を防ぎます |
PostToolUse | いいえ | stderr を Claude に表示します(ツールはすでに実行済みです) |
PostToolUseFailure | いいえ | stderr を Claude に表示します(ツールはすでに失敗しています) |
Notification | いいえ | stderr をユーザーのみに表示します |
SubagentStart | いいえ | stderr をユーザーのみに表示します |
SessionStart | いいえ | stderr をユーザーのみに表示します |
SessionEnd | いいえ | stderr をユーザーのみに表示します |
PreCompact | いいえ | stderr をユーザーのみに表示します |
JSON 出力
終了コードを使うと許可またはブロックできますが、JSON 出力を使えば、より細かく制御できます。ブロックするために終了コード 2 を返す代わりに、終了コード 0 で終了し、JSON オブジェクトを標準出力に出力します。Claude Code は、その JSON の特定のフィールドを読み取り、ブロック、許可、ユーザーへのエスカレーションを行う判定制御など、動作を制御します。
フックごとにどちらか一方の方法を選ぶ必要があり、併用はできません。通知には終了コードのみを使うか、終了コード 0 で終了して構造化制御のための JSON を出力してください。Claude Code が JSON を処理するのは、終了コード 0 の場合のみです。終了コード 2 で終了した場合、JSON は無視されます。フックの標準出力には、JSON オブジェクトのみを含める必要があります。シェルプロファイルが起動時にテキストを出力すると、JSON の解析に支障をきたすことがあります。トラブルシューティングガイドのJSON の検証に失敗しましたを参照してください。
JSON オブジェクトでは、次の 3 種類のフィールドがサポートされています。
continueのような共通フィールドは、すべてのイベントで機能します。以下の表に記載されています。- トップレベルの
decisionとreasonは、一部のイベントでブロックやフィードバックの提供に使用されます。 hookSpecificOutputは、より高度な制御が必要なイベント向けのネストされたオブジェクトです。イベント名を設定したhookEventNameフィールドが必要です。
| フィールド | デフォルト | 説明 |
|---|---|---|
continue | true | false の場合、フックの実行後に Claude は処理を完全に停止します。イベント固有の判定フィールドよりも優先されます |
stopReason | なし | continue が false の場合にユーザーに表示されるメッセージです。Claude には表示されません |
suppressOutput | false | true の場合、詳細モードの出力から標準出力を非表示にします |
systemMessage | なし | ユーザーに表示される警告メッセージ |
イベントの種類にかかわらず Claude を完全に停止するには、次のようにします。
{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }
判断の制御
すべてのイベントが、JSON を介した動作のブロックや制御に対応しているわけではありません。対応しているイベントでは、それぞれ異なるフィールドのセットを使って判断を表現します。フックを作成する前に、次の表をクイックリファレンスとしてご利用ください。
| イベント | 判断パターン | 主なフィールド |
|---|---|---|
| UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStop | トップレベルの decision | decision: "block", reason |
| PreToolUse | hookSpecificOutput | permissionDecision (allow/deny/ask), permissionDecisionReason |
| PermissionRequest | hookSpecificOutput | decision.behavior (allow/deny) |
各パターンの動作例を以下に示します。
`UserPromptSubmit`、`PostToolUse`、`PostToolUseFailure`、`Stop`、`SubagentStop` で使用します。値は `"block"` のみです。アクションの続行を許可するには、JSON から `decision` を省略するか、JSON をまったく出力せずに 0 で終了してください。```json theme={null}
{
"decision": "block",
"reason": "Test suite must pass before proceeding"
}
```
より細かな制御のために `hookSpecificOutput` を使用します。許可、拒否、またはユーザーへの確認を求めることができます。実行前にツールの入力を変更したり、Claude に追加のコンテキストを注入したりすることもできます。すべてのオプションについては、[PreToolUse の判断制御](#pretooluse-decision-control)を参照してください。
```json theme={null}
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Database writes are not allowed"
}
}
```
ユーザーに代わって権限リクエストを許可または拒否するには、`hookSpecificOutput` を使用します。許可する場合は、ツールの入力を変更したり、権限ルールを適用してユーザーに再度確認が表示されないようにしたりすることもできます。すべてのオプションについては、[PermissionRequest の判断制御](#permissionrequest-decision-control)を参照してください。
```json theme={null}
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow",
"updatedInput": {
"command": "npm run lint"
}
}
}
}
```
Bash コマンドの検証、プロンプトのフィルタリング、自動承認スクリプトなど、さらに詳しい例については、ガイドの自動化できることと、Bash コマンド検証ツールのリファレンス実装を参照してください。
フックイベント
各イベントは、フックを実行できる Claude Code のライフサイクル上の時点に対応しています。以下のセクションは、セッションのセットアップからエージェントループ、セッションの終了まで、ライフサイクルの順に並んでいます。各セクションでは、イベントが発生するタイミング、対応するマッチャー、受け取る JSON 入力、出力による動作の制御方法について説明します。
SessionStart
Claude Code が新しいセッションを開始するか、既存のセッションを再開するときに実行されます。既存の課題やコードベースへの最近の変更など、開発コンテキストの読み込みや、環境変数の設定に便利です。スクリプトを必要としない静的なコンテキストには、代わりに CLAUDE.md を使用してください。
SessionStart はすべてのセッションで実行されるため、これらのフックは高速に保ってください。
マッチャーの値は、セッションの開始方法に対応します。
| マッチャー | 実行されるタイミング |
|---|---|
startup | 新しいセッション |
resume | --resume、--continue、または /resume |
clear | /clear |
compact | 自動または手動の圧縮 |
SessionStart の入力
共通の入力フィールドに加えて、SessionStart フックは source、model、および任意で agent_type を受け取ります。source フィールドはセッションの開始方法を示します。新しいセッションでは "startup"、再開したセッションでは "resume"、/clear の実行後は "clear"、圧縮後は "compact" です。model フィールドにはモデル識別子が含まれます。claude --agent <name> を指定して Claude Code を起動すると、agent_type フィールドにエージェント名が含まれます。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SessionStart",
"source": "startup",
"model": "claude-sonnet-4-5-20250929"
}
SessionStart の判定制御
フックスクリプトが標準出力に出力したテキストは、Claude のコンテキストに追加されます。すべてのフックで使用できるJSON 出力フィールドに加えて、次のイベント固有のフィールドを返すことができます。
| フィールド | 説明 |
|---|---|
additionalContext | Claude のコンテキストに追加される文字列。複数のフックの値は連結されます |
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"additionalContext": "My additional context here"
}
}
環境変数を永続化する
SessionStart フックは CLAUDE_ENV_FILE 環境変数にアクセスできます。この環境変数には、後続の Bash コマンドで環境変数を永続化するためのファイルパスが設定されています。
個別の環境変数を設定するには、export 文を CLAUDE_ENV_FILE に書き込みます。他のフックが設定した変数を保持するため、追記(>>)を使用してください。
#!/bin/bash
if [ -n "$CLAUDE_ENV_FILE" ]; then
echo 'export NODE_ENV=production' >> "$CLAUDE_ENV_FILE"
echo 'export DEBUG_LOG=true' >> "$CLAUDE_ENV_FILE"
echo 'export PATH="$PATH:./node_modules/.bin"' >> "$CLAUDE_ENV_FILE"
fi
exit 0
セットアップコマンドによるすべての環境の変更を取得するには、エクスポートされた変数を実行前後で比較します。
#!/bin/bash
ENV_BEFORE=$(export -p | sort)
# Run your setup commands that modify the environment
source ~/.nvm/nvm.sh
nvm use 20
if [ -n "$CLAUDE_ENV_FILE" ]; then
ENV_AFTER=$(export -p | sort)
comm -13 <(echo "$ENV_BEFORE") <(echo "$ENV_AFTER") >> "$CLAUDE_ENV_FILE"
fi
exit 0
このファイルに書き込まれた変数は、セッション中に Claude Code が実行するすべての後続の Bash コマンドで使用できます。
`CLAUDE_ENV_FILE` は SessionStart フックで使用できます。他の種類のフックはこの変数にアクセスできません。UserPromptSubmit
ユーザーがプロンプトを送信したとき、Claude がそれを処理する前に実行されます。これにより、プロンプトや会話に基づいて追加のコンテキストを加えたり、プロンプトを検証したり、特定の種類のプロンプトをブロックしたりできます。
UserPromptSubmit の入力
共通の入力フィールドに加えて、UserPromptSubmit フックはユーザーが送信したテキストを含む prompt フィールドを受け取ります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "UserPromptSubmit",
"prompt": "Write a function to calculate the factorial of a number"
}
UserPromptSubmit の判定制御
UserPromptSubmit フックは、ユーザープロンプトを処理するかどうかを制御し、コンテキストを追加できます。すべてのJSON 出力フィールドを利用できます。
終了コード 0 の場合、会話にコンテキストを追加する方法は 2 つあります。
- プレーンテキストの標準出力:標準出力に書き込まれた JSON 以外のテキストは、コンテキストとして追加されます
additionalContextを含む JSON:以下の JSON 形式を使用すると、より細かく制御できます。additionalContextフィールドがコンテキストとして追加されます
プレーンテキストの標準出力は、トランスクリプトにフックの出力として表示されます。additionalContext フィールドは、より目立たない形で追加されます。
プロンプトをブロックするには、decision に "block" を設定した JSON オブジェクトを返します。
| フィールド | 説明 |
|---|---|
decision | "block" を指定すると、プロンプトの処理が阻止され、コンテキストから削除されます。プロンプトの続行を許可する場合は省略します |
reason | decision が "block" の場合にユーザーに表示されます。コンテキストには追加されません |
additionalContext | Claude のコンテキストに追加される文字列 |
{
"decision": "block",
"reason": "Explanation for decision",
"hookSpecificOutput": {
"hookEventName": "UserPromptSubmit",
"additionalContext": "My additional context here"
}
}
シンプルな用途では、JSON 形式は必須ではありません。コンテキストを追加するには、終了コード 0 でプレーンテキストを標準出力に出力できます。
プロンプトをブロックする場合や、より構造化された制御が必要な場合は JSON を使用してください。
PreToolUse
Claude がツールのパラメーターを作成した後、ツール呼び出しを処理する前に実行されます。ツール名 Bash、Edit、Write、Read、Glob、Grep、Task、WebFetch、WebSearch、および任意の MCP ツール名に一致します。
PreToolUse の判定制御を使用して、ツールの使用を許可、拒否、または許可を求めることができます。
PreToolUse の入力
共通入力フィールドに加えて、PreToolUse フックは tool_name、tool_input、tool_use_id を受け取ります。tool_input のフィールドはツールによって異なります。
Bash
シェルコマンドを実行します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
command | string | "npm test" | 実行するシェルコマンド |
description | string | "Run test suite" | コマンドの処理内容に関する任意の説明 |
timeout | number | 120000 | ミリ秒単位の任意のタイムアウト |
run_in_background | boolean | false | コマンドをバックグラウンドで実行するかどうか |
Write
ファイルを作成または上書きします。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
file_path | string | "/path/to/file.txt" | 書き込むファイルの絶対パス |
content | string | "file content" | ファイルに書き込む内容 |
Edit
既存のファイル内の文字列を置換します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
file_path | string | "/path/to/file.txt" | 編集するファイルの絶対パス |
old_string | string | "original text" | 検索して置換するテキスト |
new_string | string | "replacement text" | 置換後のテキスト |
replace_all | boolean | false | すべての一致箇所を置換するかどうか |
Read
ファイルの内容を読み取ります。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
file_path | string | "/path/to/file.txt" | 読み取るファイルの絶対パス |
offset | number | 10 | 読み取りを開始する行番号(任意) |
limit | number | 50 | 読み取る行数(任意) |
Glob
glob パターンに一致するファイルを検索します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
pattern | string | "**/*.ts" | ファイルのマッチングに使用する glob パターン |
path | string | "/path/to/dir" | 検索するディレクトリ(任意)。デフォルトは現在の作業ディレクトリ |
Grep
正規表現を使用してファイルの内容を検索します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
pattern | string | "TODO.*fix" | 検索する正規表現パターン |
path | string | "/path/to/dir" | 検索するファイルまたはディレクトリ(任意) |
glob | string | "*.ts" | ファイルを絞り込む glob パターン(任意) |
output_mode | string | "content" | "content"、"files_with_matches"、または "count"。デフォルトは "files_with_matches" |
-i | boolean | true | 大文字と小文字を区別しない検索 |
multiline | boolean | false | 複数行マッチングを有効にする |
WebFetch
Web コンテンツを取得して処理します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
url | string | "https://example.com/api" | コンテンツを取得する URL |
prompt | string | "Extract the API endpoints" | 取得したコンテンツに対して実行するプロンプト |
WebSearch
Web を検索します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
query | string | "react hooks best practices" | 検索クエリ |
allowed_domains | array | ["docs.example.com"] | 任意: これらのドメインの結果のみを含める |
blocked_domains | array | ["spam.example.com"] | 任意: これらのドメインの結果を除外する |
Task
サブエージェントを起動します。
| フィールド | 型 | 例 | 説明 |
|---|---|---|---|
prompt | string | "Find all API endpoints" | エージェントが実行するタスク |
description | string | "Find API endpoints" | タスクの短い説明 |
subagent_type | string | "Explore" | 使用する専門エージェントの種類 |
model | string | "sonnet" | デフォルトを上書きするモデルエイリアス(任意) |
PreToolUse による判断制御
PreToolUse フックは、ツール呼び出しを続行するかどうかを制御できます。トップレベルの decision フィールドを使用する他のフックとは異なり、PreToolUse は hookSpecificOutput オブジェクト内で判断を返します。これにより、3 つの結果(許可、拒否、確認)に加え、実行前にツールの入力を変更できる、より細かな制御が可能になります。
| フィールド | 説明 |
|---|---|
permissionDecision | "allow" は権限システムを迂回し、"deny" はツール呼び出しを阻止し、"ask" はユーザーに確認を求めます |
permissionDecisionReason | "allow" と "ask" の場合、ユーザーに表示されますが、Claude には表示されません。"deny" の場合、Claude に表示されます |
updatedInput | 実行前にツールの入力パラメーターを変更します。"allow" と組み合わせると自動承認でき、"ask" と組み合わせると変更後の入力をユーザーに表示できます |
additionalContext | ツールの実行前に Claude のコンテキストに追加される文字列 |
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"permissionDecisionReason": "My reason here",
"updatedInput": {
"field_to_modify": "new value"
},
"additionalContext": "Current environment: production. Proceed with caution."
}
}
PreToolUse では以前、トップレベルの `decision` フィールドと `reason` フィールドを使用していましたが、このイベントでは非推奨になりました。代わりに `hookSpecificOutput.permissionDecision` と `hookSpecificOutput.permissionDecisionReason` を使用してください。非推奨の値 `"approve"` と `"block"` は、それぞれ `"allow"` と `"deny"` に対応します。PostToolUse や Stop などの他のイベントでは、引き続きトップレベルの `decision` と `reason` が現在の形式として使用されます。
PermissionRequest
ユーザーに権限ダイアログが表示されるときに実行されます。 PermissionRequest による判断制御を使用すると、ユーザーに代わって許可または拒否できます。
ツール名で照合します。値は PreToolUse と同じです。
PermissionRequest の入力
PermissionRequest フックは、PreToolUse フックと同様に tool_name フィールドと tool_input フィールドを受け取りますが、tool_use_id は受け取りません。省略可能な permission_suggestions 配列には、権限ダイアログで通常ユーザーに表示される「常に許可」オプションが含まれます。違いはフックが実行されるタイミングです。PermissionRequest フックはユーザーに権限ダイアログが表示される直前に実行される一方、PreToolUse フックは権限の状態にかかわらず、ツールの実行前に実行されます。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PermissionRequest",
"tool_name": "Bash",
"tool_input": {
"command": "rm -rf node_modules",
"description": "Remove node_modules directory"
},
"permission_suggestions": [
{ "type": "toolAlwaysAllow", "tool": "Bash" }
]
}
PermissionRequest による判断制御
PermissionRequest フックは、権限リクエストを許可または拒否できます。すべてのフックで使用できるJSON 出力フィールドに加えて、フックスクリプトは、このイベント固有のフィールドを含む decision オブジェクトを返すことができます。
| フィールド | 説明 |
|---|---|
behavior | "allow" は権限を許可し、"deny" は拒否します |
updatedInput | "allow" の場合のみ:実行前にツールの入力パラメーターを変更します |
updatedPermissions | "allow" の場合のみ:権限ルールの更新を適用します。これはユーザーが「常に許可」オプションを選択するのと同等です |
message | "deny" の場合のみ:権限が拒否された理由を Claude に伝えます |
interrupt | "deny" の場合のみ:true のとき、Claude を停止します |
{
"hookSpecificOutput": {
"hookEventName": "PermissionRequest",
"decision": {
"behavior": "allow",
"updatedInput": {
"command": "npm run lint"
}
}
}
}
PostToolUse
ツールの正常な完了直後に実行されます。
ツール名で照合します。値は PreToolUse と同じです。
PostToolUse の入力
PostToolUse フックは、ツールが正常に実行された後に呼び出されます。入力には、ツールに送信された引数である tool_input と、ツールが返した結果である tool_response の両方が含まれます。それぞれの正確なスキーマは、ツールによって異なります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PostToolUse",
"tool_name": "Write",
"tool_input": {
"file_path": "/path/to/file.txt",
"content": "file content"
},
"tool_response": {
"filePath": "/path/to/file.txt",
"success": true
},
"tool_use_id": "toolu_01ABC123..."
}
PostToolUse の判断制御
PostToolUse フックは、ツールの実行後に Claude へフィードバックを返せます。すべてのフックで利用できるJSON 出力フィールドに加えて、フックスクリプトはイベント固有の次のフィールドを返せます。
| フィールド | 説明 |
|---|---|
decision | "block" を指定すると、reason を Claude に提示します。アクションを続行する場合は省略します |
reason | decision が "block" の場合に Claude に表示される説明 |
additionalContext | Claude が考慮する追加のコンテキスト |
updatedMCPToolOutput | MCP ツールのみ:指定した値でツールの出力を置き換えます |
{
"decision": "block",
"reason": "Explanation for decision",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "Additional information for Claude"
}
}
PostToolUseFailure
ツールの実行が失敗したときに呼び出されます。このイベントは、ツール呼び出しでエラーが発生した場合、または失敗の結果が返された場合に発生します。失敗の記録、アラートの送信、Claude への修正に役立つフィードバックの提供に使用します。
ツール名でマッチします。値は PreToolUse と同じです。
PostToolUseFailure の入力
PostToolUseFailure フックは、PostToolUse と同じ tool_name と tool_input フィールドに加えて、トップレベルフィールドとしてエラー情報を受け取ります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PostToolUseFailure",
"tool_name": "Bash",
"tool_input": {
"command": "npm test",
"description": "Run test suite"
},
"tool_use_id": "toolu_01ABC123...",
"error": "Command exited with non-zero status code 1",
"is_interrupt": false
}
| フィールド | 説明 |
|---|---|
error | 発生した問題を説明する文字列 |
is_interrupt | 失敗がユーザーによる中断で発生したかどうかを示す省略可能なブール値 |
PostToolUseFailure の判断制御
PostToolUseFailure フックは、ツールの失敗後に Claude へコンテキストを提供できます。すべてのフックで利用できるJSON 出力フィールドに加えて、フックスクリプトはイベント固有の次のフィールドを返せます。
| フィールド | 説明 |
|---|---|
additionalContext | エラーとあわせて Claude が考慮する追加のコンテキスト |
{
"hookSpecificOutput": {
"hookEventName": "PostToolUseFailure",
"additionalContext": "Additional information about the failure for Claude"
}
}
Notification
Claude Code が通知を送信したときに呼び出されます。通知タイプ(permission_prompt、idle_prompt、auth_success、elicitation_dialog)でマッチします。すべての通知タイプに対してフックを実行するには、マッチャーを省略します。
通知タイプに応じて異なるハンドラーを実行するには、個別のマッチャーを使用します。この設定では、Claude が権限の承認を必要とするときに権限専用のアラートスクリプトを実行し、Claude がアイドル状態のときには別の通知を実行します。
{
"hooks": {
"Notification": [
{
"matcher": "permission_prompt",
"hooks": [
{
"type": "command",
"command": "/path/to/permission-alert.sh"
}
]
},
{
"matcher": "idle_prompt",
"hooks": [
{
"type": "command",
"command": "/path/to/idle-notification.sh"
}
]
}
]
}
}
Notification の入力
共通の入力フィールドに加えて、Notification フックは通知テキストを含む message、省略可能な title、および発生した通知のタイプを示す notification_type を受け取ります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "Notification",
"message": "Claude needs your permission to use Bash",
"title": "Permission needed",
"notification_type": "permission_prompt"
}
Notification フックは通知をブロックしたり変更したりできません。すべてのフックで利用できるJSON 出力フィールドに加えて、会話にコンテキストを追加するために additionalContext を返せます。
| フィールド | 説明 |
|---|---|
additionalContext | Claude のコンテキストに追加される文字列 |
SubagentStart
Task ツールを使用して Claude Code のサブエージェントが起動されたときに呼び出されます。エージェントのタイプ名(Bash、Explore、Plan などの組み込みエージェントや、.claude/agents/ にあるカスタムエージェント名)で絞り込むマッチャーをサポートしています。
SubagentStart の入力
共通入力フィールドに加えて、SubagentStart フックはサブエージェントの一意の識別子である agent_id と、エージェント名("Bash"、"Explore"、"Plan" などの組み込みエージェント名、またはカスタムエージェント名)を示す agent_type を受け取ります。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SubagentStart",
"agent_id": "agent-abc123",
"agent_type": "Explore"
}
SubagentStart フックはサブエージェントの作成をブロックできませんが、サブエージェントにコンテキストを追加できます。すべてのフックで使用できるJSON 出力フィールドに加えて、次のフィールドを返すことができます。
| フィールド | 説明 |
|---|---|
additionalContext | サブエージェントのコンテキストに追加される文字列 |
{
"hookSpecificOutput": {
"hookEventName": "SubagentStart",
"additionalContext": "Follow security guidelines for this task"
}
}
SubagentStop
Claude Code のサブエージェントが応答を完了したときに実行されます。SubagentStart と同じ値で、エージェントタイプに基づいてマッチングします。
SubagentStop の入力
共通入力フィールドに加えて、SubagentStop フックは stop_hook_active、agent_id、agent_type、agent_transcript_path を受け取ります。agent_type フィールドは、マッチャーによるフィルタリングに使用される値です。transcript_path はメインセッションのトランスクリプトを示し、agent_transcript_path はネストされた subagents/ フォルダーに保存されているサブエージェント自身のトランスクリプトを示します。
{
"session_id": "abc123",
"transcript_path": "~/.claude/projects/.../abc123.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SubagentStop",
"stop_hook_active": false,
"agent_id": "def456",
"agent_type": "Explore",
"agent_transcript_path": "~/.claude/projects/.../abc123/subagents/agent-def456.jsonl"
}
SubagentStop フックは、Stop フックと同じ判定制御形式を使用します。
Stop
メインの Claude Code エージェントが応答を完了したときに実行されます。ユーザーによる中断で停止した場合は実行されません。
Stop の入力
共通入力フィールドに加えて、Stop フックは stop_hook_active を受け取ります。このフィールドは、停止フックの結果として Claude Code がすでに処理を続行している場合に true になります。Claude Code が無限に実行され続けないよう、この値を確認するか、トランスクリプトを処理してください。
{
"session_id": "abc123",
"transcript_path": "~/.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "Stop",
"stop_hook_active": true
}
Stop の判定制御
Stop フックと SubagentStop フックは、Claude が続行するかどうかを制御できます。すべてのフックで使用できるJSON 出力フィールドに加えて、フックスクリプトから次のイベント固有のフィールドを返すことができます。
| フィールド | 説明 |
|---|---|
decision | "block" にすると Claude の停止を防ぎます。Claude の停止を許可する場合は省略します |
reason | decision が "block" の場合に必須です。続行すべき理由を Claude に伝えます |
{
"decision": "block",
"reason": "Must be provided when Claude is blocked from stopping"
}
PreCompact
Claude Code がコンパクト化操作を実行する直前に実行されます。
マッチャーの値は、コンパクト化が手動で開始されたか、自動で開始されたかを示します。
| マッチャー | 実行されるタイミング |
|---|---|
manual | /compact |
auto | コンテキストウィンドウがいっぱいになったときの自動コンパクト化 |
PreCompact の入力
共通入力フィールドに加えて、PreCompact フックは trigger と custom_instructions を受け取ります。manual の場合、custom_instructions にはユーザーが /compact に渡した内容が含まれます。auto の場合、custom_instructions は空です。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "PreCompact",
"trigger": "manual",
"custom_instructions": ""
}
SessionEnd
Claude Code のセッションが終了したときに実行されます。クリーンアップ作業、セッション統計の記録、セッション状態の保存に便利です。終了理由でフィルタリングするマッチャーをサポートしています。
フック入力の reason フィールドは、セッションが終了した理由を示します。
| 理由 | 説明 |
|---|---|
clear | /clear コマンドでセッションがクリアされた |
logout | ユーザーがログアウトした |
prompt_input_exit | プロンプト入力が表示されている間にユーザーが終了した |
bypass_permissions_disabled | バイパス権限モードが無効になった |
other | その他の終了理由 |
SessionEnd の入力
共通の入力フィールドに加えて、SessionEnd フックはセッションが終了した理由を示す reason フィールドを受け取ります。すべての値については、上記の理由の表を参照してください。
{
"session_id": "abc123",
"transcript_path": "/Users/.../.claude/projects/.../00893aaf-19fa-41d2-8238-13269b9b3ca0.jsonl",
"cwd": "/Users/...",
"permission_mode": "default",
"hook_event_name": "SessionEnd",
"reason": "other"
}
SessionEnd フックには決定を制御する機能はありません。セッションの終了を阻止することはできませんが、クリーンアップタスクを実行できます。
プロンプトベースのフック
Bash コマンドフック(type: "command")に加えて、Claude Code は LLM を使用してアクションを許可するかブロックするかを評価する、プロンプトベースのフック(type: "prompt")をサポートしています。プロンプトベースのフックは、次のイベントで使用できます:PreToolUse、PostToolUse、PostToolUseFailure、PermissionRequest、UserPromptSubmit、Stop、SubagentStop。
プロンプトベースのフックの仕組み
Bash コマンドを実行する代わりに、プロンプトベースのフックは次の処理を行います。
- フックの入力とプロンプトを Claude モデル(デフォルトでは Haiku)に送信します
- LLM が決定を含む構造化 JSON を返します
- Claude Code がその決定を自動的に処理します
プロンプトフックの設定
type に "prompt" を設定し、command の代わりに prompt 文字列を指定します。$ARGUMENTS プレースホルダーを使用して、フックの JSON 入力データをプロンプトのテキストに挿入します。Claude Code はプロンプトと入力を組み合わせて高速な Claude モデルに送信し、モデルは JSON 形式の決定を返します。
この Stop フックは、Claude が終了する前にすべてのタスクが完了しているかを LLM に評価させます。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evaluate if Claude should stop: $ARGUMENTS. Check if all tasks are complete."
}
]
}
]
}
}
| フィールド | 必須 | 説明 |
|---|---|---|
type | はい | "prompt" である必要があります |
prompt | はい | LLM に送信するプロンプトテキストです。フックの入力 JSON のプレースホルダーとして $ARGUMENTS を使用します。$ARGUMENTS が含まれていない場合、入力 JSON がプロンプトに追加されます |
model | いいえ | 評価に使用するモデルです。デフォルトは高速モデルです |
timeout | いいえ | タイムアウト時間(秒)です。デフォルト:30 |
レスポンススキーマ
LLM は次の内容を含む JSON を返す必要があります。
{
"ok": true | false,
"reason": "Explanation for the decision"
}
| フィールド | 説明 |
|---|---|
ok | true はアクションを許可し、false はアクションを阻止します |
reason | ok が false の場合に必須です。Claude に表示される説明です |
例:複数条件を確認する Stop フック
この Stop フックは詳細なプロンプトを使用し、Claude の終了を許可する前に3つの条件を確認します。"ok" が false の場合、Claude は提示された理由を次の指示として作業を続けます。SubagentStop フックも同じ形式を使用して、サブエージェントを停止すべきか評価します。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "You are evaluating whether Claude should stop working. Context: $ARGUMENTS\n\nAnalyze the conversation and determine if:\n1. All user-requested tasks are complete\n2. Any errors need to be addressed\n3. Follow-up work is needed\n\nRespond with JSON: {\"ok\": true} to allow stopping, or {\"ok\": false, \"reason\": \"your explanation\"} to continue working.",
"timeout": 30
}
]
}
]
}
}
エージェントベースのフック
エージェントベースのフック(type: "agent")は、複数ターンにわたってツールにアクセスできるプロンプトベースのフックです。単一の LLM 呼び出しではなく、エージェントフックはサブエージェントを起動し、ファイルの読み取り、コードの検索、コードベースの調査を行って条件を確認できます。エージェントフックは、プロンプトベースのフックと同じイベントをサポートしています。
エージェントフックの仕組み
エージェントフックが実行されると、次の処理が行われます。
- Claude Code は、プロンプトとフックの JSON 入力を渡してサブエージェントを起動します
- サブエージェントは、Read、Grep、Glob などのツールを使って調査できます
- 最大 50 ターンの後、サブエージェントは
{ "ok": true/false }形式の構造化された判定を返します - Claude Code は、プロンプトフックの場合と同じ方法で判定を処理します
エージェントフックは、フック入力データだけを評価するのではなく、実際のファイルやテスト出力の確認が必要な検証に便利です。
エージェントフックの設定
type を "agent" に設定し、prompt 文字列を指定します。設定フィールドはプロンプトフックの設定と同じですが、デフォルトのタイムアウトはより長くなっています。
| フィールド | 必須 | 説明 |
|---|---|---|
type | はい | "agent" に設定する必要があります |
prompt | はい | 検証内容を記述するプロンプトです。フック入力の JSON を表すプレースホルダーとして $ARGUMENTS を使用します |
model | いいえ | 使用するモデルです。デフォルトでは高速なモデルが使用されます |
timeout | いいえ | タイムアウトの秒数です。デフォルト:60 |
応答スキーマはプロンプトフックと同じです。許可する場合は { "ok": true }、ブロックする場合は { "ok": false, "reason": "..." } を返します。
この Stop フックは、Claude が処理を終了する前にすべての単体テストがパスすることを検証します。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "agent",
"prompt": "Verify that all unit tests pass. Run the test suite and check the results. $ARGUMENTS",
"timeout": 120
}
]
}
]
}
}
フックをバックグラウンドで実行する
デフォルトでは、フックが完了するまで Claude の実行はブロックされます。デプロイ、テストスイート、外部 API の呼び出しなど時間のかかるタスクでは、"async": true を設定すると、Claude が作業を続けている間にフックをバックグラウンドで実行できます。非同期フックは Claude の動作をブロックしたり制御したりできません。decision、permissionDecision、continue などの応答フィールドは、制御対象のアクションがすでに完了しているため、効果がありません。
非同期フックを設定する
コマンドフックの設定に "async": true を追加すると、Claude をブロックせずにバックグラウンドで実行できます。このフィールドは type: "command" のフックでのみ使用できます。
このフックは、Write ツールが呼び出されるたびにテストスクリプトを実行します。run-tests.sh の実行中も Claude はただちに作業を続け、スクリプトは最大 120 秒間実行されます。スクリプトが完了すると、次の会話ターンで出力が渡されます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "/path/to/run-tests.sh",
"async": true,
"timeout": 120
}
]
}
]
}
}
timeout フィールドは、バックグラウンドプロセスの最大実行時間を秒数で指定します。指定しない場合、非同期フックには同期フックと同じデフォルトの 10 分が適用されます。
非同期フックの実行方法
非同期フックが実行されると、Claude Code はフックプロセスを起動し、完了を待たずにただちに処理を続けます。フックには、同期フックと同じ JSON 入力が標準入力経由で渡されます。
バックグラウンドプロセスの終了後、フックが systemMessage または additionalContext フィールドを含む JSON 応答を返した場合、その内容は次の会話ターンでコンテキストとして Claude に渡されます。
例:ファイル変更後にテストを実行する
このフックは、Claude がファイルを書き込むたびにテストスイートをバックグラウンドで起動し、テスト完了後に結果を Claude に返します。このスクリプトをプロジェクトの .claude/hooks/run-tests-async.sh に保存し、chmod +x で実行可能にしてください。
#!/bin/bash
# run-tests-async.sh
# Read hook input from stdin
INPUT=$(cat)
FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
# Only run tests for source files
if [[ "$FILE_PATH" != *.ts && "$FILE_PATH" != *.js ]]; then
exit 0
fi
# Run tests and report results via systemMessage
RESULT=$(npm test 2>&1)
EXIT_CODE=$?
if [ $EXIT_CODE -eq 0 ]; then
echo "{\"systemMessage\": \"Tests passed after editing $FILE_PATH\"}"
else
echo "{\"systemMessage\": \"Tests failed after editing $FILE_PATH: $RESULT\"}"
fi
次に、この設定をプロジェクトルートの .claude/settings.json に追加します。async: true フラグにより、テストの実行中も Claude は作業を続けられます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/run-tests-async.sh",
"async": true,
"timeout": 300
}
]
}
]
}
}
制限事項
非同期フックには、同期フックと比べていくつかの制約があります。
type: "command"のフックのみがasyncをサポートします。プロンプトベースのフックは非同期で実行できません。- 非同期フックはツール呼び出しをブロックしたり、判断を返したりできません。フックが完了する時点で、トリガーとなったアクションはすでに実行されています。
- フックの出力は次の会話ターンで配信されます。セッションがアイドル状態の場合、次にユーザーが操作するまで応答は保留されます。
- 実行ごとに個別のバックグラウンドプロセスが作成されます。同じ非同期フックが複数回発火しても、重複排除は行われません。
セキュリティに関する考慮事項
免責事項
フックは、システムユーザーのすべての権限で実行されます。
フックは、ユーザーのすべての権限でシェルコマンドを実行します。ユーザーアカウントからアクセスできるあらゆるファイルを変更、削除、または参照できます。設定に追加する前に、すべてのフックコマンドを確認し、テストしてください。セキュリティのベストプラクティス
フックを作成する際は、次の点に留意してください。
- 入力を検証してサニタイズする:入力データを決して無条件に信頼しないでください
- シェル変数は必ず引用符で囲む:
$VARではなく"$VAR"を使用してください - パストラバーサルを防ぐ:ファイルパスに
..が含まれていないか確認してください - 絶対パスを使用する:スクリプトには完全なパスを指定し、プロジェクトのルートには
"$CLAUDE_PROJECT_DIR"を使用してください - 機密ファイルを除外する:
.env、.git/、キーなどは避けてください
フックのデバッグ
claude --debug を実行すると、一致したフック、終了コード、出力など、フックの実行に関する詳細を確認できます。Ctrl+O で詳細モードを切り替えると、トランスクリプトにフックの進行状況が表示されます。
[DEBUG] Executing hooks for PostToolUse:Write
[DEBUG] Getting matching hook commands for PostToolUse with query: Write
[DEBUG] Found 1 hook matchers in settings
[DEBUG] Matched 1 hooks for query "Write"
[DEBUG] Found 1 hook commands to execute
[DEBUG] Executing hook command: <Your command> with timeout 600000ms
[DEBUG] Hook command completed with status 0: <Your stdout>
フックが発火しない、Stop フックのループが無限に続く、設定エラーが発生するといった一般的な問題のトラブルシューティングについては、ガイドの制限事項とトラブルシューティングを参照してください。