mcpField
C
create-hook

create-hook

github.com/neolabhqエージェントワークフロー1.8k1.2k 回インストール9 週間前に更新
リポジトリ

create-hook について

create-hook は Claude Code 向けのスキルです。プロジェクトのツール構成を調べて適切なフックを提案し、作成とテストを支援します。

主な機能

  1. 01プロジェクトのツールと既存フックの検出
  2. 02構成に応じたフックの提案
  3. 03スクリプト作成と設定更新
  4. 04成功・失敗ケースのテスト

活用シーン

  1. 01編集後の型チェックやフォーマット
  2. 02コミット前のテストやビルド検証
  3. 03秘密情報を漏らす操作のブロック
  4. 04問題を Claude Code に実行可能なコンテキストとして伝達

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/neolabhq/context-engineering-kit --skill create-hook

インストール後、Claude Code で/create-hookを入力して読み込まれたか確認します。

詳細

フックコマンドの作成

プロジェクトを分析し、実用的なフックを提案して、適切にテストしたうえで作成します。

タスク(/create-hook)

  1. 環境を分析する - ツールと既存のフックを検出します
  2. フックを提案する - プロジェクトの設定に基づいて提案します
  3. フックを設定する - 対象を絞った質問をして、スクリプトを作成します
  4. テストと検証を行う - フックが正しく動作することを確認します

ワークフロー

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. フックの設定

まず、**「このフックに何をさせますか?」**と尋ね、分析結果に基づく関連する提案を提示します。

次に、ユーザーの説明からコンテキストを把握し、不明な点についてのみ質問します。

  1. 実行タイミング:いつ実行しますか?

    • PreToolUse:ファイル操作の前(ブロック可能)
    • PostToolUse:ファイル操作の後(フィードバックや修正)
    • UserPromptSubmit:リクエストの処理前
    • 必要に応じてその他のイベントタイプ
  2. ツールマッチャー:どのツールを実行のトリガーにしますか?(Write、Edit、Bash、* など)

  3. 適用範囲:global、project、project-local

  4. 応答方法:

    • 終了コードのみ:シンプル(終了コード 0 = 成功、PreToolUse で終了コード 2 = ブロック)
    • JSON 応答:高度な制御(ブロック、コンテキスト、判断)
    • 複雑さに応じて案内します:単純な成功/失敗 → 終了コード、詳細なフィードバック → JSON
  5. ブロック動作(該当する場合):「問題が見つかった場合、操作を停止しますか?」

    • PreToolUse:操作をブロックできます(セキュリティ、検証)
    • PostToolUse:通常はフィードバックのみを提供します
  6. Claude との連携(重要):「このフックが検出した問題を Claude Code が自動的に確認し、修正できるようにしますか?」

    • はいの場合:エラーの伝達には additionalContext を使用します
    • いいえの場合:通知せずに実行するには suppressOutput: true を使用します
  7. コンテキストのノイズ:「ノイズを避けるため、成功した操作は通知しないようにしますか?」

    • フォーマットや定期的なチェックでは「はい」を推奨します
    • セキュリティ警告や重大なエラーでは「いいえ」を推奨します
  8. ファイルのフィルタリング:このフックで処理するファイルの種類は何ですか?

3. フックの作成

以下を行います。

  • フックディレクトリを作成する:スコープに応じて ~/.claude/hooks/ または .claude/hooks/ を作成します
  • スクリプトを生成する:次の要件を満たすフックスクリプトを作成します。
    • 適切なシェバンと実行権限を設定する
    • プロジェクト固有のコマンドを使用する(検出した設定パスを使います)
    • フックの目的を説明するコメントを記述する
  • 設定を更新する:適切な settings.json にフック設定を追加します
  • 絶対パスを使用する:スクリプトや実行ファイルに相対パスを使わないでください。プロジェクトルートを参照するには $CLAUDE_PROJECT_DIR を使います
  • 検証を提案する:フックをテストするかユーザーに確認します

主な実装基準:

  • 標準入力から JSON を読み取る(argv は使いません)
  • Claude との通信にはトップレベルの additionalContext/systemMessage を使用する
  • 正常に処理された場合は suppressOutput: true を含める
  • 具体的なエラー件数と、実行可能な対応策を提示する
  • コードベース全体ではなく、変更されたファイルに注目する
  • 一般的な開発ワークフローに対応する

⚠️ 重要:入出力形式

フックの実装で最も失敗が多いのがこの部分です。次の点に特に注意してください。

  • 入力:標準入力から JSON を正しく読み取る(argv からではありません)
  • 出力:Claude との通信に適したトップレベルの JSON 構造を使用する
  • ドキュメント:スキーマが不明な場合は、正確な仕様を公式ドキュメントで確認する
4. テストと検証

重要:成功するケースと失敗するケースの両方をテストしてください。

成功するケースのテスト:

  1. 想定される成功ケースをテストする — フックがパスする条件を用意します
    • 例: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 が入力を待っているときに通知を受け取れます。

Claude Code CLI で `/hooks` と入力します。利用可能なすべてのフックイベントの一覧と、すべてのフックを無効にするオプションが表示されます。各イベントは、カスタムコードを実行できる Claude のライフサイクル上のタイミングに対応しています。Claude が注意を必要とするときに実行されるフックを作成するには、`Notification` を選択します。 メニューに、フックが実行されるタイミングを絞り込むマッチャーの一覧が表示されます。すべての通知タイプで実行するには、マッチャーを `*` に設定します。あとからマッチャーを `permission_prompt` や `idle_prompt` などの特定の値に変更して、対象を絞ることもできます。 `+ Add new hook…` を選択します。メニューで、イベント発生時に実行するシェルコマンドの入力を求められます。フックでは指定した任意のシェルコマンドを実行できるため、お使いのプラットフォームに組み込まれている通知ツールを利用できます。OS に応じたコマンドをコピーしてください。
<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 で設定します。

```json theme={null} { "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'" } ] } ] } } ``` ```json theme={null} { "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "notify-send 'Claude Code' 'Claude Code needs your attention'" } ] } ] } } ``` ```json theme={null} { "hooks": { "Notification": [ { "matcher": "", "hooks": [ { "type": "command", "command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\"" } ] } ] } } ```
編集後にコードを自動フォーマットする

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ツール呼び出しが失敗した後
NotificationClaude Code が通知を送信したとき
SubagentStartサブエージェントが起動されたとき
SubagentStopサブエージェントが終了したとき
StopClaude が応答を終了したとき
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 を実行すると、どのフックが一致したかや終了コードを含む、実行の詳細をすべて確認できます。

詳細はこちら


ドキュメントインデックス

ドキュメントの完全なインデックスはこちらから取得できます:https://code.claude.com/docs/llms.txt このファイルを使って、さらに調べる前に利用可能なすべてのページを確認してください。

フックのリファレンス

Claude Code のフックイベント、設定スキーマ、JSON 入出力形式、終了コード、非同期フック、プロンプトフック、MCP ツールフックのリファレンスです。

例を含むクイックスタートガイドについては、[フックでワークフローを自動化する](/en/hooks-guide)を参照してください。

フックは、Claude Code のライフサイクルにおける特定のタイミングで自動実行される、ユーザー定義のシェルコマンドまたは LLM プロンプトです。このリファレンスでは、イベントスキーマ、設定オプション、JSON 入出力形式、非同期フックや MCP ツールフックなどの高度な機能を確認できます。初めてフックを設定する場合は、まずガイドを参照してください。

フックのライフサイクル

フックは、Claude Code のセッション中の特定のタイミングで実行されます。イベントが発生し、マッチャーが一致すると、Claude Code はそのイベントに関する JSON コンテキストをフックハンドラーに渡します。コマンドフックの場合、この情報は標準入力で渡されます。ハンドラーは入力を調べて処理を実行し、必要に応じて判断を返すことができます。イベントによってはセッションごとに 1 回だけ発生し、エージェントループ内で繰り返し発生するものもあります。

SessionStart からエージェントループを経て SessionEnd までのフックの順序を示す、フックのライフサイクル図

以下の表は、各イベントが発生するタイミングをまとめたものです。フックイベントのセクションでは、それぞれのイベントの入力スキーマと判断制御オプションについて詳しく説明しています。

イベント発生するタイミング
SessionStartセッションが開始または再開されたとき
UserPromptSubmitプロンプトを送信したとき。Claude が処理する前
PreToolUseツール呼び出しが実行される前。ブロックできます
PermissionRequest権限ダイアログが表示されたとき
PostToolUseツール呼び出しが成功した後
PostToolUseFailureツール呼び出しが失敗した後
NotificationClaude Code が通知を送信したとき
SubagentStartサブエージェントが起動されたとき
SubagentStopサブエージェントが終了したとき
StopClaude が応答を完了したとき
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" を実行すると決定したとします。次のように処理されます。

フックの解決フロー:PreToolUse イベントが発生し、マッチャーが Bash に一致するか確認し、フックハンドラーが実行され、結果が Claude Code に返されます `PreToolUse` イベントが発生します。Claude Code はツール入力を JSON として stdin でフックに送信します。
```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 つの階層で構成されます。

  1. PreToolUse や Stop など、応答するフックイベントを選択します
  2. 「Bash ツールの場合のみ」のように、実行条件を絞り込むマッチャーグループを追加します
  3. 条件に一致したときに実行する 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"、"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}:プラグインにバンドルされたスクリプト用の、プラグインのルートディレクトリです。
この例では、`$CLAUDE_PROJECT_DIR`を使って、`Write`または`Edit`ツールの呼び出し後にプロジェクトの`.claude/hooks/`ディレクトリにあるスタイルチェッカーを実行します。
```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 フィールドが必要です。
フィールドデフォルト説明
continuetruefalse の場合、フックの実行後に Claude は処理を完全に停止します。イベント固有の判定フィールドよりも優先されます
stopReasonなしcontinue が false の場合にユーザーに表示されるメッセージです。Claude には表示されません
suppressOutputfalsetrue の場合、詳細モードの出力から標準出力を非表示にします
systemMessageなしユーザーに表示される警告メッセージ

イベントの種類にかかわらず Claude を完全に停止するには、次のようにします。

{ "continue": false, "stopReason": "Build failed, fix errors before continuing" }
判断の制御

すべてのイベントが、JSON を介した動作のブロックや制御に対応しているわけではありません。対応しているイベントでは、それぞれ異なるフィールドのセットを使って判断を表現します。フックを作成する前に、次の表をクイックリファレンスとしてご利用ください。

イベント判断パターン主なフィールド
UserPromptSubmit, PostToolUse, PostToolUseFailure, Stop, SubagentStopトップレベルの decisiondecision: "block", reason
PreToolUsehookSpecificOutputpermissionDecision (allow/deny/ask), permissionDecisionReason
PermissionRequesthookSpecificOutputdecision.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 出力フィールドに加えて、次のイベント固有のフィールドを返すことができます。

フィールド説明
additionalContextClaude のコンテキストに追加される文字列。複数のフックの値は連結されます
{
  "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" を指定すると、プロンプトの処理が阻止され、コンテキストから削除されます。プロンプトの続行を許可する場合は省略します
reasondecision が "block" の場合にユーザーに表示されます。コンテキストには追加されません
additionalContextClaude のコンテキストに追加される文字列
{
  "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

シェルコマンドを実行します。

フィールド型例説明
commandstring"npm test"実行するシェルコマンド
descriptionstring"Run test suite"コマンドの処理内容に関する任意の説明
timeoutnumber120000ミリ秒単位の任意のタイムアウト
run_in_backgroundbooleanfalseコマンドをバックグラウンドで実行するかどうか
Write

ファイルを作成または上書きします。

フィールド型例説明
file_pathstring"/path/to/file.txt"書き込むファイルの絶対パス
contentstring"file content"ファイルに書き込む内容
Edit

既存のファイル内の文字列を置換します。

フィールド型例説明
file_pathstring"/path/to/file.txt"編集するファイルの絶対パス
old_stringstring"original text"検索して置換するテキスト
new_stringstring"replacement text"置換後のテキスト
replace_allbooleanfalseすべての一致箇所を置換するかどうか
Read

ファイルの内容を読み取ります。

フィールド型例説明
file_pathstring"/path/to/file.txt"読み取るファイルの絶対パス
offsetnumber10読み取りを開始する行番号(任意)
limitnumber50読み取る行数(任意)
Glob

glob パターンに一致するファイルを検索します。

フィールド型例説明
patternstring"**/*.ts"ファイルのマッチングに使用する glob パターン
pathstring"/path/to/dir"検索するディレクトリ(任意)。デフォルトは現在の作業ディレクトリ
Grep

正規表現を使用してファイルの内容を検索します。

フィールド型例説明
patternstring"TODO.*fix"検索する正規表現パターン
pathstring"/path/to/dir"検索するファイルまたはディレクトリ(任意)
globstring"*.ts"ファイルを絞り込む glob パターン(任意)
output_modestring"content""content"、"files_with_matches"、または "count"。デフォルトは "files_with_matches"
-ibooleantrue大文字と小文字を区別しない検索
multilinebooleanfalse複数行マッチングを有効にする
WebFetch

Web コンテンツを取得して処理します。

フィールド型例説明
urlstring"https://example.com/api"コンテンツを取得する URL
promptstring"Extract the API endpoints"取得したコンテンツに対して実行するプロンプト
WebSearch

Web を検索します。

フィールド型例説明
querystring"react hooks best practices"検索クエリ
allowed_domainsarray["docs.example.com"]任意: これらのドメインの結果のみを含める
blocked_domainsarray["spam.example.com"]任意: これらのドメインの結果を除外する
Task

サブエージェントを起動します。

フィールド型例説明
promptstring"Find all API endpoints"エージェントが実行するタスク
descriptionstring"Find API endpoints"タスクの短い説明
subagent_typestring"Explore"使用する専門エージェントの種類
modelstring"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 に提示します。アクションを続行する場合は省略します
reasondecision が "block" の場合に Claude に表示される説明
additionalContextClaude が考慮する追加のコンテキスト
updatedMCPToolOutputMCP ツールのみ:指定した値でツールの出力を置き換えます
{
  "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 を返せます。

フィールド説明
additionalContextClaude のコンテキストに追加される文字列
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 の停止を許可する場合は省略します
reasondecision が "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 コマンドを実行する代わりに、プロンプトベースのフックは次の処理を行います。

  1. フックの入力とプロンプトを Claude モデル(デフォルトでは Haiku)に送信します
  2. LLM が決定を含む構造化 JSON を返します
  3. 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"
}
フィールド説明
oktrue はアクションを許可し、false はアクションを阻止します
reasonok が 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 呼び出しではなく、エージェントフックはサブエージェントを起動し、ファイルの読み取り、コードの検索、コードベースの調査を行って条件を確認できます。エージェントフックは、プロンプトベースのフックと同じイベントをサポートしています。

エージェントフックの仕組み

エージェントフックが実行されると、次の処理が行われます。

  1. Claude Code は、プロンプトとフックの JSON 入力を渡してサブエージェントを起動します
  2. サブエージェントは、Read、Grep、Glob などのツールを使って調査できます
  3. 最大 50 ターンの後、サブエージェントは { "ok": true/false } 形式の構造化された判定を返します
  4. 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 フックのループが無限に続く、設定エラーが発生するといった一般的な問題のトラブルシューティングについては、ガイドの制限事項とトラブルシューティングを参照してください。

コメント