Claude Code のパワーユーザー向けカスタマイズ:フックの設定方法
Claude Code のフックを設定し、反復作業の自動化、プロジェクトルールの適用、そしてコーディングセッションへの動的なコンテキスト注入を実現する方法を解説します。
Claude Code を使用したスムーズなワークフローであっても、使い込むほどに小さな手間や不便さhaClaude Code を使用したスムーズなワークフローであっても、使い込むほどに小さな手間や不便さは積み重なっていくものです。Claude がファイルを書き出すたびに手動でPrettier Prettier を実行したり、npm test を実行するたびに同じ許可プロンプトに応答したり、セッションの開始時に毎回同じプロジェクトの定型文を最初のメッセージに貼り付けたり——こうした手間は積み重なると無視できません。
解決策は、フックの活用です。フックとは、特定のアクションの前後に実行するように構成できるトリガーです。これを利用すれば、カスタムロジック、スクリプト、コマンドを Claude の操作に直接組み込むことが可能です。
この記事では、Claude Code の基礎を習得済みの開発者を対象に、高度な設定方法を解説します。読み終える頃には、8 種類のフックの概要、それぞれの使いどころ、設定手順、そして予期せぬトラブルが発生した際のデバッグ方法を習得できているはずです。
それでは、詳しく見ていきましょう。
フックとは?
フックとは、Claude Code セッション内で特定のイベント(Claude がファイルを書き込もうとする際や、プロンプトを送信する際など)が発生したときに、自動的に実行されるカスタムシェルコマンドのことです。アクションの実行前に介入する、エージェントにコンテキストを注入する、承認作業を自動化する、あるいは特定の操作をブロックするなど、幅広い用途で活用できます。
フックは設定ファイルにて、イベント名、マッチャー(どのツールがフックを起動するかを絞り込むフィルタ)、実行するコマンドを JSON 形式で指定します。ローカル環境でユーザー権限のもと実行され、標準入力(stdin)を通じてイベント情報を受け取り、終了コードと標準出力(stdout)を介して通信します。これにより、ツール本体を改変することなく、Claude Code の挙動を細かく制御できます。
Claude Code でフックを使用する利点
フックは大きく分けて 3 つの課題を解決します。
まず、反復的な手動ステップの排除です。ファイル変更のたびにフォーマッターを手動実行する代わりに PostToolUse フックで自動化し、何度も繰り返される npm test の承認を PermissionRequest フックで自動承認させることができます。
第二に、プロジェクト固有のルールを自動的に適用することです。危険なコマンドの実行阻止、書き込み前のファイルパス検証、命名規則の順守などを強制できます。これらは人間が確認を忘れた場合でも、フックが毎回自動でチェックしてくれます。
第三に、手動作業なしで動的なコンテキストを注入することです。SessionStart フックで最新の git ステータスや TODO リストを Claude に読み込ませ、UserPromptSubmit フックでスプリントの優先事項をすべてのリクエストに付与することで、何度も同じ説明を繰り返すことなく、Claude が常に最新情報を把握した状態で作業を進められます。
Claude Code ののフックの種類と活用シーン
Claude Code は、起動からツールの実行、完了に至るまで、セッションの全ライフサイクルを網羅する 8 つのフックイベントを提供しています。それぞれのフックは特定のタイミングで作動し、自動化の実行タイミングを極めて精密に制御することが可能です。どのフックを選択すべきかは、何を実現したいかによって決まります。
各フックの概要
| フック | 作動タイミング | 主な用途 |
|---|---|---|
| PreToolUse | ツールの実行前 | 危険なコマンドのブロック、ファイルパスの検証、安全な操作の自動承認 |
| PermissionRequest | 許可ダイアログの表示前 | テストコマンドの自動承認、機密ファイルへのアクセス制限 |
| PostToolUse | ツールの実行後 | フォーマッターの実行、リンターの起動、ファイル変更のログ記録 |
| PreCompact | コンテキスト圧縮の前 | トランスクリプトのバックアップ、重要な決定事項の保存 |
| SessionStart | セッション開始または再開時 | git ステータスの注入、TODO リストの読み込み、環境コンテキストの設定 |
| Stop | Claude の回答終了時 | タスク完了の確認、テスト実行、要約の生成 |
| SubagentStop | サブエージェントの完了時 | サブエージェント出力の検証、フォローアップアクションの起動 |
| UserPromptSubmit | プロンプト送信時 | スプリントコンテキストの注入、リクエスト検証、動的コンテキストの追加 |
PreToolUse
最も頻繁に使用されるフックです。Claude がツールを選択した後、実際に実行される直前に作動します。スクリプト側で、計画されたアクションの内容を精査し、その承認、ブロック、ユーザー確認の要求、あるいはパラメータの変更などを行うことが可能です。また、マッチャーを使用して、どのツールでこのフックを作動させるかをフィルタリングできます。
以下の例では、ファイル書き込み前に内容を検証します。Claude が計画しているアクションを特定の基準と照らし合わせ、そのロジックに応じて承認、ブロック、あるいは懸念のフラグ立てを行います。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "/path/to/validate-file-path.sh"
}
]
}
]
}
}PreToolUse を使用するタイミング:
- rm -rf や強制プッシュ(force push)などの危険な Bash コマンドのブロック
- 安全かつ反復的な操作の自動承認によるプロンプト疲れの解消
- 書き込み前のファイルパス検証による誤書き込みの防止
- プロジェクト固有のデフォルト値を注入するためのツール入力値の変更
PermissionRequest
Claude が通常表示する許可ダイアログの直前に作動します。このフックはユーザーへの確認プロンプトが表示される直前の瞬間を捉え、そのスクリプトによって、実行を許可するか、拒否するか、あるいはそのままユーザーに確認を求めるかを決定できます。
{
"hooks": {
"PermissionRequest": [
{
"matcher": "Bash(npm test*)",
"hooks": [
{
"type": "command",
"command": "/path/to/validate-test-command.sh"
}
]
}
]
}
}この例では、npm test で始まるすべての Bash コマンドを自動承認します。マッチャーパターンに引数を含めることで、より詳細な制御が可能です。
PermissionRequest を使用するタイミング:
- セッション内で数十回実行するようなテストコマンドの自動承認
- 本番環境の設定ファイルに対する書き込みアクセスのブロック
- 特定ディレクトリ内の読み込み操作をプロンプトなしで許可
- 危険なパターンに一致するあらゆるコマンドの拒否
PostToolUse
ツールが正常に完了した直後に作動します。ツール出力を含む実行結果を受け取ることができ、マッチャーで対象ツールをフィルタリング可能です。
この PostToolUse の例では、Claude が書き込みまたは編集を行ったファイルに対して Prettier を実行します。マッチャー内のパイプ構文は、Write ツールと Edit ツールの両方でフックが作動することを意味します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "prettier --write \"$CLAUDE_TOOL_INPUT_FILE_PATH\""
}
]
}
]
}
}PostToolUse を使用するタイミング:
- ファイル書き込み後の Prettier、Black、gofmt 実行によるフォーマット強制
- 全ファイル変更内容の監査ログへの記録
- コード変更後のリンター起動と警告表示
- 特定の操作完了時の通知送信
PreCompact
Claude が会話コンテキストを圧縮してスペースを空ける直前に作動します。圧縮により古い詳細情報が失われる可能性があるため、このフックを使用すれば事前に情報を保護できます。
この PreCompact の例では、自動圧縮が行われる前にトランスクリプトをバックアップします。マッチャーには「auto」または「manual」を指定可能で、自動圧縮とユーザー主導の圧縮イベントを区別できます。
{
"hooks": {
"PreCompact": [
{
"matcher": "auto",
"hooks": [
{
"type": "command",
"command": "/path/to/backup-transcript.sh"
}
]
}
]
}
}PreCompact を使用するタイミング:
- 要約プロセス前のトランスクリプト全体のファイルバックアップ
- 重要な決定事項やコードスニペットの抽出と保存
- 後で確認するためのセッションマイルストーンの記録
SessionStart
Claude Code が新規セッションを開始する、または既存セッションを再開する際に作動します。スクリプトの出力は会話コンテキストに追加されるため、Claude は開始時点でその情報を把握できます。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "git status --short && echo '---' && cat TODO.md"
}
]
}
]
}
}すべてのセッションが、現在の git ステータスと TODO リストを把握した状態で開始されます。標準出力は自動的にコンテキストの一部となります。
SessionStart を使用するタイミング:
- 現在の git ブランチと直近のコミット履歴の読み込み
- TODO リストやスプリントバックログの内容の読み込み
- 環境固有の設定情報の注入
Stop
Claude が回答を終え、次の入力を待機する直前に作動します。スクリプトは Claude の出力を精査し、タスクが完全に完了したかを判断できます。
スクリプトで {"continue": true} を含む JSON を返すと、Claude に作業を続行させることができます。これはマルチステップのワークフローに有効です。
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Review whether the task is complete. If all requirements are met, respond with 'complete'. If work remains, respond with 'continue' and specify what still needs to be done."
}
]
}
]
}
}Stop を使用するタイミング:
- チェックリストの全項目が完了するまで作業を強制的に継続させる
- タスク完了と見なす前にテストの通過を確認する
- セッション終了時に要約生成をトリガーする
- 生成されたコードがコンパイル可能かを確認してから停止する
SubagentStop
このフックは、Task ツール経由で作成されたサブエージェントが終了するたびに作動します。動作は Stop フックと同様ですが、メインエージェントではなくサブエージェントがそのアクションを完了した際に特化して作動します。SubagentStop の設定構造は Stop フックと同一です。
{
"hooks": {
"SubagentStop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Evaluate the subagent's output. Verify the task was completed correctly and the results meet quality standards. If the output is satisfactory, respond with 'accept'. If issues exist, respond with 'reject' and explain what needs to be fixed."
}
]
}
]
}
}SubagentStop を使用するタイミング:
- サブエージェントの出力が品質基準を満たしているかの検証
- サブエージェントの結果に基づくフォローアップアクションの起動
- デバッグや監査のためのサブエージェント活動の記録
UserPromptSubmit
ユーザーがプロンプトを送信した後、Claude が処理を開始する前に作動します。スクリプトが標準出力(stdout)経由で出力したすべての内容は、プロンプトと共に Claude のコンテキストへ追加されます。この特性により、UserPromptSubmit は Claude が考慮すべき情報を動的に注入する際に有用です。
この例では、プロンプトを送信するたびに、Claude がスプリントコンテキストファイルのコンテンツを受け取ります。これらにより、現在の優先事項を毎回説明し直さなくても、Claude が常に最新情報を把握できます。
{
"hooks": {
"UserPromptSubmit": [
{
"hooks": [
{
"type": "command",
"command": "cat ./current-sprint-context.md"
}
]
}
]
}
}UserPromptSubmit を使用するタイミング:
- プロンプト送信ごとのスプリントコンテキストやプロジェクト優先事項の注入
- Claude に到達する前のプロンプトの検証
- コンテンツに基づいた特定タイプのリクエストのブロック
- 最新のエラーログやテスト結果などの動的コンテキストの追加
設定とファイル配置
フックは 3 つの階層で JSON 設定ファイルとして管理されます。プロジェクトレベルのフックはリポジトリ内の .claude/settings.json に記述され、チーム間での共有が可能です。ユーザーレベルのフックは ~/.claude/settings.json に記述され、すべてのプロジェクトに適用されます。ローカルプロジェクト用のフックは .claude/settings.local.json に記述され、コミットしたくない個人設定に使用します。
プロジェクトレベルの設定は、ユーザーレベルの設定よりも優先されます。また、組織管理のためにエンタープライズ単位のポリシー設定も利用可能です。詳細については、Claude Code の設定情報を参照してください。
プロのヒント:このファイルは、Claude のアクションに対してプロジェクト、ユーザー、またはローカルレベルで詳細な権限を設定できる場所でもあります。たとえば、特定のディレクトリ内の全ファイルの読み取りを明示的に許可して承認の手間を省いたり、機密ファイルの改変をブロックしたりすることが可能です。
マッチャー(Matcher)の構文
マッチャーは、どのツールがフックを起動するかをフィルタリングする仕組みで、PreToolUse、PostToolUse、PermissionRequest で使用します。
単純な文字列一致は期待通りの挙動となり、「Write」と指定すれば Write ツールのみが対象となります。
例:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Write",
"hooks": [
{
"type": "command",
"command": "your-command-here"
}
]
}
]
}
}パイプ構文を使えば複数のツールを指定可能です。「Write|Edit」と指定すればどちらのツールでもフックが作動し、ワイルドカードを指定すればすべてが対象となります。
注意:マッチャーは大文字と小文字を区別するため、「bash」と指定しても Bash ツールにはマッチしません。
より詳細な制御を行うには、「Bash(npm test*)」のように引数パターンを使用することで、特定のコマンド引数にマッチさせることができます。Model Context Protocol(MCP)ツールについては、「mcp__memory__.*」といった形式でパターンを指定します。
入力、出力、および構造化されたレスポンス
フックの入力データ
すべてのフックは、標準入力(stdin)を通じて、セッション情報やイベント固有のデータを含む JSON を受け取ります。これには session_id、transcript_path、cwd、permission_mode、hook_event_name といった一般的なフィールドが含まれます。
また、ツール関連のフックでは tool_name や tool_input も提供されるため、スクリプト側で状況に応じた的確な判断が可能になります。
フックの応答形式
終了コード(Exit code)によって基本的な結果が決まります。
コード 0 は成功を意味し、標準出力の内容は JSON として処理されるか、あるいはコンテキストに追加されます。コード 2 はブロックを伴うエラーを意味し、標準エラー(stderr)に出力された内容がエラーメッセージとして表示され、アクションが阻止されます。
それ以外のコードは非ブロックエラーとして扱われ、冗長モード時のみ標準エラーの内容が表示されます。
終了コードに加え、フックはより詳細な制御を行うために構造化された JSON を返すことができます。
含まれるフィールドは、decision(approve、block、allow、または deny)、reason(Claude に表示される説明文)、continue(Stop フックで処理の続行を強制する場合)、updatedInput(実行前にツールパラメータを修正する場合)です。
環境と実行
フックは、以下の環境変数にアクセス可能です。プロジェクトルートパスを示す CLAUDE_PROJECT_DIR、ウェブ環境であれば true となる CLAUDE_CODE_REMOTE、そして SessionStart フックで変数を永続化するための CLAUDE_ENV_FILE などが用意されています。また、シェルから引き継がれる標準的な環境変数も利用可能です。
なお、各フックにはデフォルトで 60 秒のタイムアウトが設定されています(フックごとに変更可能)。同一のイベントに複数のフックが合致した場合、それらは並行して作動します。同一のコマンドは自動的に重複排除されます。
セキュリティに関する考慮事項
フックは、ユーザーの権限で任意のシェルコマンドを実行します。Claude Code には保護機能が備わっており、フック設定ファイルを直接編集した場合は、変更が有効になる前に /hooks メニューでの確認が必要です。これにより、悪意のあるコードが警告なしにフックとして追加されるのを防ぎます。
ただし、自身でフックを設定し承認した場合は、そのフックは自身の権限レベルで実行されることに留意してください。
プロのヒント:環境内でコマンドを実行する際は、リスクを十分に検討してください。フックでコマンドを実行する場合は、標準入力からの入力値のバリデーションとサニタイズ、シェル変数へのクォートによるインジェクション対策、スクリプトへの絶対パス指定、および .env や認証情報などの機密ファイルへのアクセス回避といった適切なプラクティスを推奨します。
デバッグおよびテスト
Claude Code はすべての操作をトランスクリプトファイルにログとして出力するため、特別な設定なしでツール呼び出しと応答を確認できます。各フックにはセッション履歴全体を記録した JSONL ファイルを指す transcript_path フィールドが渡されます。これを利用し、SessionStart フックで各トランスクリプトの保存先をログ出力することが可能です。
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '\"Session: \" + .transcript_path' >> ~/.claude/sessions.log"
}
]
}
]
}
}その後、tail でそのトランスクリプトを監視すると、Claude の動作をリアルタイムで確認できます:tail -f /path/to/transcript.jsonl | jq .
フック固有のデバッグ
フック固有のデバッグを行うには、フックスクリプト内にロギングを追加してください。トランスクリプトファイルには Claude の実行内容は記録されますが、フックがなぜ特定の操作(承認やブロック)を行ったのかという理由は記録されません。
ラッパースクリプトを一つ作成し、ツールをラップして情報を追加で記録するようにすれば、少しの手間で詳細なログを取得できるようになります。例として、log-wrapper.sh を作成します:
#!/bin/bash
LOG=~/.claude/hooks.log
INPUT=$(cat)
TOOL=$(echo "$INPUT" |
jq -r '.tool_name // "n/a"')
EVENT=$(echo "$INPUT" | jq -r '.hook_event_name // "n/a"')
echo "=== $(date) | $EVENT | $TOOL ===" >> "$LOG"
echo "$INPUT" | "$1"
CODE=$?
echo "Exit: $CODE" >> "$LOG"
exit $CODEこの小さなラッパースクリプトは、標準入力を変数に格納し、タイムスタンプとツール名をログに記録してから、その入力を本来のツールへとパイプで渡します。
この log-wrapper.sh を作成したら、フック内のツール実行コマンドの先頭にこのスクリプトを追加します:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "log-wrapper.sh your-tool-command.py"
}
]
}
]
}
}プロのヒント:その他のデバッグに関するヒントについては、Claude Code のデバッグドキュメントを参照してください。
独自のフックの作成
まずは、日々のワークフローにおける「小さな不便」を解消する単純なフックを一つ作ってみましょう。フォーマッターを実行する PostToolUse フックは、即座にフィードバックが得られるため最初の題材として最適です。成功体験を積み重ねながら、徐々に用途を広げていくことをお勧めします。
利用可能なすべてのフィールドや高度なパターンを含む完全なリファレンスについては、公式のフックドキュメントを参照してください。
フックを活用すれば、自身のワークフローをツールに合わせて変えるのではなく、Claude Code を自身のワークフローに最適化できます。フックの設定に費やした時間は、セッションを重ねるごとに大きな恩恵となって返ってきます。
今すぐフックを使用して Claude Code のワークフローをカスタマイズしましょう。