- 危険な操作をブロックする:破壊的なシェルコマンドや不正なファイルアクセスなど、実行前に危険な操作をブロックします
- ログと監査:コンプライアンス、デバッグ、分析のためにすべてのツール呼び出しをログして監査します
- 入力と出力を変換する:データをサニタイズしたり、認証情報を注入したり、ファイルパスをリダイレクトしたりします
- 人間の承認を要求する:データベース書き込みや API 呼び出しなどの機密アクションに対して
- セッションライフサイクルを追跡する:状態を管理したり、リソースをクリーンアップしたり、通知を送信したりします
フックの仕組み
イベントが発火する
エージェント実行中に何かが起こり、SDK がイベントを発火します。ツールが呼び出されようとしている(
PreToolUse)、ツールが結果を返した(PostToolUse)、サブエージェントが開始または停止した、エージェントがアイドル状態である、または実行が完了したなどです。イベントの完全なリストを参照してください。SDK が登録されたフックを収集する
SDK は、そのイベントタイプに登録されたフックをチェックします。これには、
options.hooks に渡すコールバックフックと、対応する settingSources または setting_sources エントリが有効になっているときの設定ファイルからのシェルコマンドフックが含まれます。これはデフォルトの query() オプションで有効になっています。マッチャーがどのフックを実行するかをフィルタリングする
フックに
matcher パターン("Write|Edit" など)がある場合、SDK はそれをイベントのターゲット(たとえば、ツール名)に対してテストします。マッチャーのないフックは、そのタイプのすべてのイベントに対して実行されます。コールバック関数が実行される
各マッチングフックのコールバック関数は、何が起こっているかについての入力を受け取ります。ツール名、その引数、セッション ID、およびその他のイベント固有の詳細です。
コールバックが決定を返す
任意の操作(ログ、API 呼び出し、検証)を実行した後、コールバックは出力オブジェクトを返します。これはエージェントに何をするかを指示します。操作を許可する、ブロックする、入力を変更する、または会話にコンテキストを注入するなどです。
PreToolUse フック(ステップ 1)を "Write|Edit" マッチャー(ステップ 3)で登録して、コールバックがファイル書き込みツールに対してのみ発火するようにします。トリガーされると、コールバックはツールの入力(ステップ 4)を受け取り、ファイルパスが .env ファイルをターゲットにしているかどうかをチェックし、permissionDecision: "deny" を返して操作をブロックします(ステップ 5)。
利用可能なフック
SDK はエージェント実行のさまざまなステージのフックを提供します。一部のフックは両方の SDK で利用可能ですが、その他は TypeScript のみです。| フックイベント | Python SDK | TypeScript SDK | トリガーされる条件 | 使用例 |
|---|---|---|---|---|
PreToolUse | はい | はい | ツール呼び出しリクエスト(ブロックまたは変更可能) | 危険なシェルコマンドをブロックする |
PostToolUse | はい | はい | ツール実行結果 | すべてのファイル変更を監査証跡にログする |
PostToolUseFailure | はい | はい | ツール実行失敗 | ツールエラーを処理またはログする |
PostToolBatch | いいえ | はい | ツール呼び出しの完全なバッチが解決される。次のモデル呼び出しの前に 1 回 | バッチ全体に対して規約を 1 回注入する |
UserPromptSubmit | はい | はい | ユーザープロンプト送信 | プロンプトに追加のコンテキストを注入する |
MessageDisplay | いいえ | はい | テキスト付きのアシスタントメッセージが完了する。メッセージごとに 1 回、完全なメッセージテキスト付き | 表示されたテキストを編集または再フォーマットする(トランスクリプトは変更しない) |
Stop | はい | はい | エージェント実行停止 | 終了前にセッション状態を保存する |
SubagentStart | はい | はい | サブエージェント初期化 | 並列タスク生成を追跡する |
SubagentStop | はい | はい | サブエージェント完了 | 並列タスクから結果を集約する |
PreCompact | はい | はい | 会話圧縮リクエスト | 要約する前に完全なトランスクリプトをアーカイブする |
PermissionRequest | はい | はい | パーミッションダイアログが表示される | カスタムパーミッション処理 |
SessionStart | いいえ | はい | セッション初期化 | ログとテレメトリを初期化する |
SessionEnd | いいえ | はい | セッション終了 | 一時的なリソースをクリーンアップする |
Notification | はい | はい | エージェントステータスメッセージ | エージェントステータス更新を Slack または PagerDuty に送信する |
Setup | いいえ | はい | セッション設定/メンテナンス | 初期化タスクを実行する |
TeammateIdle | いいえ | はい | チームメイトがアイドル状態になる | 作業を再割り当てするか通知する |
TaskCompleted | いいえ | はい | バックグラウンドタスク完了 | 並列タスクから結果を集約する |
ConfigChange | いいえ | はい | 設定ファイル変更 | 設定を動的に再ロードする |
WorktreeCreate | いいえ | はい | Git ワークツリー作成 | 分離されたワークスペースを追跡する |
WorktreeRemove | いいえ | はい | Git ワークツリー削除 | ワークスペースリソースをクリーンアップする |
フックを設定する
フックを設定するには、エージェントオプション(Python ではClaudeAgentOptions、TypeScript では options オブジェクト)の hooks フィールドに渡します。
hooks オプションは辞書(Python)またはオブジェクト(TypeScript)です。ここで:
- キーはフックイベント名です(例:
'PreToolUse'、'PostToolUse'、'Stop') - 値はマッチャーの配列です。各マッチャーには、オプションのフィルタパターンとコールバック関数が含まれます
マッチャー
マッチャーを使用して、コールバックがいつ発火するかをフィルタリングします。matcher フィールドは、フックイベントタイプに応じて異なる値に対してマッチングされます。たとえば、ツールベースのフックはツール名に対してマッチングされ、Notification フックは通知タイプに対してマッチングされます。各イベントタイプのマッチャー値の完全なリストについては、Claude Code フックリファレンスを参照してください。
SDK マッチャーは設定ファイルのマッチャーと同じルールに従います。文字、数字、_、および | のみを含むマッチャーは正確な文字列として比較され、| は代替案を区切るため、Write|Edit はこれら 2 つのツールと正確にマッチします。* のマッチャー、空の文字列、またはマッチャーを完全に省略すると、イベントのすべての発生にマッチします。他の文字を含むマッチャーは正規表現として評価されるため、^mcp__ はすべての MCP ツールにマッチします。mcp__memory のようなマッチャーは文字とアンダースコアのみを含むため、正確な文字列として比較され、ツールにマッチしません。そのサーバーからすべてのツールにマッチするには、mcp__memory__.* を使用します。
| オプション | 型 | デフォルト | 説明 |
|---|---|---|---|
matcher | string | undefined | イベントのフィルタフィールドに対してマッチングされるパターン。上記の比較ルールに従います。ツールフックの場合、これはツール名です。組み込みツールには Bash、Read、Write、Edit、Glob、Grep、WebFetch、Agent などが含まれます(完全なリストについてはツール入力型を参照)。MCP ツールはパターン mcp__<server>__<action> を使用します。 |
hooks | HookCallback[] | - | 必須。パターンがマッチしたときに実行するコールバック関数の配列 |
timeout | number | 60 | タイムアウト(秒単位) |
matcher パターンを使用して特定のツールをターゲットにします。'Bash' のマッチャーは Bash コマンドに対してのみ実行されますが、パターンを省略するとコールバックはそのイベントのすべての発生に対して実行されます。ツールベースのフックの場合、マッチャーはツール名でのみフィルタリングされ、ファイルパスやその他の引数ではフィルタリングされません。ファイルパスでフィルタリングするには、コールバック内で tool_input.file_path をチェックします。
コールバック関数
入力
すべてのフックコールバックは 3 つの引数を受け取ります。- 入力データ: イベント詳細を含む型付きオブジェクト。各フック型には独自の入力形状があります(たとえば、
PreToolUseHookInputにはtool_nameとtool_inputが含まれ、NotificationHookInputにはmessageが含まれます)。TypeScript および Python SDK リファレンスで完全な型定義を参照してください。- すべてのフック入力は
session_id、cwd、およびhook_event_nameを共有します。 agent_idとagent_typeは、フックがサブエージェント内で発火するときに入力されます。TypeScript では、これらはベースフック入力にあり、すべてのフック型で利用可能です。Python では、PreToolUse、PostToolUse、およびPostToolUseFailureのみにあります。
- すべてのフック入力は
- ツール使用 ID(
str | None/string | undefined):同じツール呼び出しのPreToolUseとPostToolUseイベントを相関させます。 - コンテキスト: TypeScript では、キャンセル用の
signalプロパティ(AbortSignal)を含みます。Python では、この引数は将来の使用のために予約されています。
出力
コールバックは 2 つのカテゴリのフィールドを持つオブジェクトを返します。- トップレベルフィールドはすべてのイベントで同じように機能します。
systemMessageはユーザーにメッセージを表示し、continue(Python ではcontinue_)はこのフック後にエージェントが実行を続けるかどうかを決定します。 hookSpecificOutputは現在の操作を制御します。内部のフィールドはフックイベントタイプに依存します。PreToolUseフックの場合、ここでpermissionDecision("allow"、"deny"、"ask"、または"defer")、permissionDecisionReason、およびupdatedInputを設定します。"defer"を返すとクエリが終了し、後で再開できます。PostToolUseフックの場合、additionalContextを設定してツール結果に情報を追加できます。Claude がそれを見る前にツールの出力を置き換えるには、updatedToolOutputを設定します。これは両方の SDK のすべてのツールで機能します。古いupdatedMCPToolOutputフィールドは MCP ツール出力のみを置き換え、非推奨です。
{} を返します。SDK コールバックフックは、Claude Code シェルコマンドフックと同じ JSON 出力形式を使用します。これはすべてのフィールドとイベント固有のオプションを文書化しています。SDK 型定義については、TypeScript および Python SDK リファレンスを参照してください。
複数のフックまたはパーミッションルールが適用される場合、deny は defer より優先され、defer は ask より優先され、ask は allow より優先されます。いずれかのフックが
deny を返す場合、他のフックに関係なく操作はブロックされます。非同期出力
デフォルトでは、エージェントはコールバックが返されるのを待ってから続行します。フックが副作用(ログ、ウェブフック送信)を実行し、エージェントの動作に影響を与える必要がない場合、代わりに非同期出力を返すことができます。これはエージェントに、フックが完了するのを待たずに即座に続行するよう指示します。| フィールド | 型 | 説明 |
|---|---|---|
async | true | 非同期モードを通知します。エージェントは待たずに続行します。Python では、予約キーワードを避けるために async_ を使用します。 |
asyncTimeout | number | バックグラウンド操作のオプションのタイムアウト(ミリ秒単位) |
非同期出力はエージェントが既に先に進んでいるため、ブロック、変更、またはコンテキストを注入することはできません。ログ、メトリクス、または通知などの副作用にのみ使用します。
例
ツール入力を変更する
この例は Write ツール呼び出しをインターセプトし、file_path 引数を書き直して /sandbox を先頭に追加し、すべてのファイル書き込みをサンドボックスディレクトリにリダイレクトします。コールバックは変更されたパスで updatedInput を返し、permissionDecision: 'allow' を返して書き直された操作を自動承認します。
updatedInput を使用する場合、permissionDecision: 'allow' を含めて変更された入力を自動承認するか、permissionDecision: 'ask' を含めてユーザーに表示する必要があります。'defer' の場合、updatedInput は無視されます。常に元の tool_input を変更するのではなく、新しいオブジェクトを返します。コンテキストを追加してツールをブロックする
この例は/etc ディレクトリへの書き込みをブロックし、モデルとユーザーの両方に理由を説明します。
permissionDecision: 'deny'はツール呼び出しを停止します。permissionDecisionReasonはモデルに理由を伝えるため、再試行を避けます。systemMessageはユーザーに何が起こったかを表示します。
特定のツールを自動承認する
デフォルトでは、エージェントは特定のツールを使用する前にパーミッションを求めるプロンプトを表示する場合があります。この例は、permissionDecision: 'allow' を返すことで読み取り専用ファイルシステムツール(Read、Glob、Grep)を自動承認し、ユーザー確認なしで実行できるようにしながら、他のすべてのツールは通常のパーミッションチェックの対象のままにします。
複数のフックを登録する
イベントが発火すると、すべてのマッチするフックが並列で実行されます。パーミッション決定の場合、最も制限的な結果が優先されます。単一のdeny は、他のフックが何を返すかに関係なく、ツール呼び出しをブロックします。完了順序は非決定的であるため、別のフックが最初に実行されたことに依存するのではなく、各フックが独立して動作するように記述します。
以下の例は、すべてのツール呼び出しに対して 3 つの独立したチェックを登録します。
マルチツールマッチャーでフィルタリングする
マルチツールマッチャーを使用して、関連するツール間で 1 つのコールバックを共有します。この例は、異なるスコープを持つ 3 つのマッチャーを登録します。- パイプで区切られた正確なリスト(
Write|Edit|Delete)は、ファイル変更ツールに対してのみfile_security_hookをトリガーします。 - 正規表現(
^mcp__)は、名前がmcp__で始まる任意の MCP ツールに対してmcp_audit_hookをトリガーします。 - 省略されたマッチャーは、名前に関係なくすべてのツール呼び出しに対して
global_loggerをトリガーします。
サブエージェントアクティビティを追跡する
SubagentStop フックを使用して、サブエージェントが作業を完了するときを監視します。TypeScript および Python SDK リファレンスで完全な入力型を参照してください。この例は、サブエージェントが完了するたびに概要をログします。
フックから HTTP リクエストを行う
フックは HTTP リクエストなどの非同期操作を実行できます。フック内でエラーをキャッチして、処理されない例外がエージェントを中断しないようにします。 この例は、各ツールが完了した後にウェブフックを送信し、どのツールが実行されたかと実行時刻をログします。フックはエラーをキャッチして、失敗したウェブフックがエージェントを中断しないようにします。通知を Slack に転送する
Notification フックを使用して、エージェントからのシステム通知を受け取り、外部サービスに転送します。通知は以下のようなイベントタイプに対して発火します。
permission_prompt(Claude がパーミッションを必要とする)idle_prompt(Claude が入力を待機している)auth_success(認証が完了した)elicitation_dialog、elicitation_complete、およびelicitation_response(ユーザープロンプト引き出しフロー用)
message フィールドと、オプションで title が含まれます。
この例は、すべての通知を Slack チャネルに転送します。Slack 受信ウェブフック URL が必要です。これは、Slack ワークスペースにアプリを追加し、受信ウェブフックを有効にすることで作成します。
一般的な問題を修正する
フックが発火しない
- フックイベント名が正しく、大文字と小文字が区別されていることを確認します(
preToolUseではなくPreToolUse) - マッチャーパターンがツール名と正確にマッチしていることを確認します
- フックが
options.hooksの正しいイベントタイプの下にあることを確認します StopやSubagentStopなどの非ツールフックの場合、マッチャーは異なるフィールドに対してマッチングされます(マッチャーパターンを参照)- エージェントが
max_turns制限に達するとセッションが終了する前にフックが実行される可能性があるため、フックが発火しない場合があります
マッチャーが期待どおりにフィルタリングしない
マッチャーはツール名のみをマッチングし、ファイルパスやその他の引数はマッチングしません。ファイルパスでフィルタリングするには、フック内でtool_input.file_path をチェックします:
フックタイムアウト
HookMatcher設定でtimeout値を増やします- TypeScript で 3 番目のコールバック引数から
AbortSignalを使用して、キャンセルを適切に処理します
ツールが予期せずブロックされた
- すべての
PreToolUseフックでpermissionDecision: 'deny'を返していないかチェックします - フックにログを追加して、返している
permissionDecisionReasonを確認します - マッチャーパターンが広すぎないことを確認します(空のマッチャーはすべてのツールにマッチングします)
変更された入力が適用されない
-
updatedInputがhookSpecificOutputの内部にあり、トップレベルにないことを確認します: -
変更された入力を自動承認するには
permissionDecision: 'allow'を返すか、ユーザーに承認を求めるには'ask'を返します -
hookSpecificOutputにhookEventNameを含めて、出力がどのフック型用かを識別します
Python でセッションフックが利用できない
SessionStart と SessionEnd は TypeScript で SDK コールバックフックとして登録できますが、Python SDK では利用できません(HookEvent は除外されています)。Python では、設定ファイルで定義されたシェルコマンドフックとしてのみ利用可能です(たとえば、.claude/settings.json)。SDK アプリケーションからシェルコマンドフックをロードするには、setting_sources または settingSources で適切な設定ソースを含めます:
client.receive_response() からの最初のメッセージをトリガーとして使用します。
サブエージェントパーミッションプロンプトが増加する
複数のサブエージェントを生成する場合、各サブエージェントは個別にパーミッションをリクエストする可能性があります。サブエージェントは親エージェントのパーミッションを自動的に継承しません。繰り返されるプロンプトを避けるには、PreToolUse フックを使用して特定のツールを自動承認するか、サブエージェントセッションに適用されるパーミッションルールを設定します。
サブエージェントを使用した再帰的フックループ
サブエージェントを生成するUserPromptSubmit フックは、それらのサブエージェントが同じフックをトリガーする場合、無限ループを作成できます。これを防ぐには:
- サブエージェント指標をチェックしてからサブエージェントを生成する前にフック入力をチェックします
- 共有変数またはセッション状態を使用して、既にサブエージェント内にいるかどうかを追跡します
- フックをトップレベルエージェントセッションのみに実行するようにスコープします
systemMessage が出力に表示されない
systemMessage フィールドはユーザーにメッセージを表示します。デフォルトでは SDK はメッセージストリームにフック出力を表示しないため、includeHookEvents(Python では include_hook_events)を設定しない限り、メッセージが表示されない場合があります。代わりにモデルにコンテキストを渡すには、additionalContextを返します。
フック決定をアプリケーションに確実に表示する必要がある場合は、別途ログするか、専用の出力チャネルを使用します。
関連リソース
- Claude Code フックリファレンス:完全な JSON 入力/出力スキーマ、イベント文書、およびマッチャーパターン
- Claude Code フックガイド:シェルコマンドフックの例とウォークスルー
- TypeScript SDK リファレンス:フック型、入力/出力定義、および設定オプション
- Python SDK リファレンス:フック型、入力/出力定義、および設定オプション
- パーミッション:エージェントが何をできるかを制御します
- カスタムツール:エージェント機能を拡張するツールを構築します