
Claude Code Hooks:エージェントを自動化するパワーユーザー向けガイド
Claude Codeのhooksは、ライフサイクルイベント発生時にコマンドを自動実行します——ループに介在せずとも検証・lint・ブロック・ログ記録が可能です。イベント一覧、設定方法、5つの実践レシピ、終了コードの落とし穴、そしてセットアップ不要でClaude Codeを実行する方法を解説します。
Claude Code フックとは、Claude Code のライフサイクルにおける特定のタイミング——ツール呼び出しの前、編集の後、セッション開始時、Claude がターンを終えたとき——に自動的に実行されるユーザー定義コマンドです。これにより、毎回自分がループに入らなくても、アクションの検証、フォーマット、ログ記録、ブロックが可能になります。これは、提案するだけの AI コーディングエージェントと、あなたのルールに決定論的に従うエージェントとの違いです。このガイドでは、フックとは何か、発火可能なすべてのイベント、設定方法、コピーして使える5つの実践的なレシピ、誰もが引っかかる終了コードの落とし穴、そしてローカル環境の構築なしで Claude Code のフルパワーを使う方法について解説します。
Claude Code フックとは何か
フックとは、特定のイベントが発生したときに Claude Code が自動的に実行するハンドラー——シェルコマンド、HTTP エンドポイント、MCP ツール呼び出し、あるいはモデルへのプロンプトすら——です。ハンドラーは構造化された入力を受け取り(コマンドフックの場合は標準入力、HTTP フックの場合は POST ボディとして)、何が起きているかを検査し、アクションを実行し、任意でその後の Claude の動作を変える決定を返すことができます。
この最後の部分こそが、フックを単なる便利機能ではなく強力な仕組みにしている理由です。フックは通知だけでなく、ツール呼び出しをブロックしたり、ツールの入力や出力を書き換えたり、追加のコンテキストを注入したり、Claude を完全に停止させたりすることができます。つまりフックは、Claude Code をスマートなアシスタントから、モデルがたまたま覚えているときだけでなく決定論的にチームのガードレールを強制するプログラム可能なものへと変えるのです。
フックが発火するタイミング:ライフサイクル
フックはイベントに紐づいており、Claude Code は非常に多くのイベントを公開しています。これらは頻度によってグループ分けされます:セッションごとに一度発火するもの、ターンごとに一度発火するもの、そしてすべてのツール呼び出しで発火するものです。
Claude Code セッション全体でフックが発火する場所——SessionStart から SessionEnd まで。
最もよく使われるイベント:
SessionStart/SessionEnd— セッションの開始時または終了時に一度発火。コンテキストの読み込み(未解決の issue、ブランチ情報、環境変数)やクリーンアップに最適です。UserPromptSubmit— プロンプトを送信したとき、Claude がそれを処理する前に発火します。プロンプトのフィルタリングや拡張が可能です。PreToolUse— 任意のツール呼び出しの前。危険なアクションをブロックするのはここです。PostToolUse(およびPostToolUseFailure)— ツール呼び出しが成功(または失敗)した後。リンティング、フォーマット、検証を行う場所です。Stop/StopFailure— Claude が応答を終えたとき、またはターンがエラーで終了したとき。Notification— Claude Code が通知を発するとき(デスクトップアラートに便利です)。
これら以外にも、Claude Code はサブエージェント(SubagentStart/SubagentStop)、タスク(TaskCreated/TaskCompleted)、コンテキスト圧縮(PreCompact/PostCompact)、作業ディレクトリの変更(CwdChanged)、ディスク上のファイル変更(FileChanged)、インストラクションの読み込み(InstructionsLoaded)など、さらに多くのイベントでフックを発火します。この幅広さこそが重要なポイントで、エージェントのループのほぼどの瞬間にもポリシーを紐づけることができます。
フックハンドラーの5つのタイプ
1つのフックイベントは5種類の異なるハンドラーをトリガーでき、これがシステムを柔軟にしている理由です:
command— シェルコマンドを実行します。標準入力から入力を読み取り、終了コードと標準出力で決定を伝えます。http— イベントの JSON を URL に POST し、JSON レスポンスを読み取ります。mcp_tool— 接続された MCP サーバー上のツールを呼び出します。prompt— yes/no の JSON 決定を返す単一ターンのモデル評価(あいまいなチェックに便利)。agent— サブエージェントを起動します(実験的機能)。
ほとんどのチームでは、command フックが作業の90%をカバーします——リント、ブロック、ログ記録にはシェルスクリプトで十分です。
フックの設定方法
フックは設定ファイルに記述します(公式の Claude Code フックドキュメントが正式なリファレンスです)。どこに配置するかがスコープを決定します:
| 場所 | スコープ |
|---|---|
~/.claude/settings.json | すべてのプロジェクト |
.claude/settings.json | 1つのプロジェクト(コミット可能——チームと共有可能) |
.claude/settings.local.json | 1つのプロジェクト、ローカルのみ(gitignore 対象) |
| 管理ポリシー設定 | 組織全体(管理者) |
構造は3階層にネストされます:イベントを選び、マッチャーグループを追加し、ハンドラーを定義します。マッチャーはフックがどのツール呼び出しに適用されるかを決定します——"*"(または省略)はすべてにマッチし、Edit|Write のような単純な指定はその正確なツールにマッチし、それより複雑なものは正規表現として扱われます。(MCP ツールは mcp__<server>__<tool> というパターンにマッチします。)
以下は、編集のたびにリントチェックを実行する PostToolUse フックの例です:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [{ "type": "command", "command": "/path/to/lint-check.sh" }]
}
]
}
}フックの実践レシピ5選
これらはチームが最初に採用するパターンです:
- 編集のたびにリントまたはフォーマットする。
Edit|WriteにマッチしたPostToolUseフックがフォーマッターやリンターを実行し、エージェントのコードが常にスタイルルールに準拠するようにします。 - 破壊的なコマンドをブロックする。
BashにマッチしたPreToolUseフックがコマンドを検査し、rm -rfなどが実行される前にブロックします。 - デスクトップ通知。 Claude が注意を必要としているとき、または長いタスクを完了したときに通知する
Notificationフック。 - 監査ログ。 コンプライアンスのためにすべてのツール呼び出し(何が実行され、いつ、どんな引数で)をログに記録する
PostToolUse(または MCP をターゲットにした)フック。 - 起動時にプロジェクトのコンテキストを読み込む。 未解決の issue、現在のブランチ、環境変数を取り込む
SessionStartフックにより、エージェントが各セッションを最初から適切に方向づけられた状態で開始できます。
5つの一般的なフックレシピと、それらが紐づくイベント。
終了コードの落とし穴
これは誰もが引っかかる細部なので、しっかり頭に入れておいてください:command フックでは、終了コード 2 のみがブロックします。終了 0 は成功を意味します(標準出力は任意の JSON 決定として解析されます)。終了 2 はブロッキングエラーであり、その標準エラー出力は Claude にフィードバックされます。それ以外のコード(終了 1 を含む)はすべて非ブロッキングエラーであり、Claude はそのまま続行します。
つまり、「これをブロックする」フックを書いて exit 1 とすると、それはブロックされません——アクションはそのまま進行します。コマンドフックからポリシーを実際に強制するには、exit 2 を使う必要があります。(コマンドフックは標準出力に JSON としてより詳細な制御を返すこともできます——PreToolUse 用の permissionDecision: "deny"、引数を書き換える updatedInput、情報を注入する additionalContext、Claude を完全に停止させる continue: false など。)
実例:rm -rf のブロック
破壊的コマンドのガードを最初から最後まで構築してみましょう。すべての要素が揃っているのがわかります。まず設定です——Bash にマッチした PreToolUse フック:
{ "hooks": { "PreToolUse": [{ "matcher": "Bash",
"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard.sh" }] }] } }続いてスクリプト、guard.sh です。Claude Code はイベントをツールの入力を含む JSON として標準入力に送信します。スクリプトはそれを読み取り、コマンドをチェックし、判断を下します:
#!/usr/bin/env bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -Eq 'rm +-rf|mkfs'; then
echo "Blocked: destructive command refused by policy." >&2
exit 2 # exit 2 blocks — exit 1 would NOT
fi
exit 0決定的な行は exit 2 です。0 を返せばコマンドは実行され、1 を返すと——直感に反して——それでも非ブロッキングエラーとして実行されてしまいます。ブロックするのは exit 2 のみで、あなたの標準エラーメッセージを Claude にフィードバックし、なぜブロックされたのかを理解させます。スクリプトを実行可能にし、.claude/hooks/ の下にコミットすれば、すべての Bash 呼び出しがあなたのガードを通過するようになります——プロジェクトの settings.json は共有可能なので、チーム全体に適用されます。ベストエフォートのネットではなくハードな保証が必要な場合は、これを Claude Code の権限ルールと組み合わせてください。決定論的でバージョン管理されたセーフティネットとして、このフックはすでに役割を果たしています。
フックが答えにならない場面
フックは決定論的で反復可能なポリシーのためのものです——「編集の後は常にリントする」「rm -rf は絶対に実行しない」といったものです。判断が必要なもの(あいまいな判定にはモデルや prompt フックを使ってください)や、ハードなセキュリティ保証が必要なもの(コマンドフックの if フィルターはフェイルオープンするため、権限システムを使ってください)には不向きです。フックを使いすぎないようにもしてください。すべてのコマンドフックはタイムアウト付きのプロセスを実行し、遅いフックが乱立するとすべてのツール呼び出しにレイテンシが加わります。フックは高速に、少数に、本当に重要なルールに絞って使いましょう。
知っておくべき安全性に関する注意点
ドキュメントが明確に述べているいくつかの現実:
ifフィルターはフェイルオープンします。ifフィールドを使ってフックを権限ルールにスコープさせ、コマンドが解析できない場合、フックはそれでも実行されてしまいます。ハードな許可/拒否の強制には、フックではなく Claude Code の権限システムを使ってください。- フックは制御端末なしで実行されます——
/dev/ttyでプロンプトを出すことはできません。ユーザー向けメッセージにはsystemMessageか、制限付きのterminalSequence出力を使ってください。 - 標準出力はクリーンでなければなりません。 JSON の決定オブジェクトだけが標準出力に出力されるべきで、シェルのプロファイルからの余分な出力があると解析が壊れる可能性があります。
- 注入するコンテキストは慎重に扱ってください。
additionalContextは命令形ではなく事実の記述として書くべきで、それによってプロンプトインジェクション対策とうまく共存できます。
フックは縮図としてのハーネスエンジニアリング
一歩引いてみると、フックはより大きなアイデアの具体例です:モデルはエージェントのすべてではなく、その周りのシステムこそが重要だという考え方です。フックは、ループ、ツール、メモリ、サンドボックスと並んで、コーディングエージェントを信頼できるものにするハーネスの一部です。(この思考モデルについてはハーネスエンジニアリングで詳しく解説しています。)PreToolUse のブロックや PostToolUse のリンターを書くとき、あなたはモデルがうまく振る舞ってくれることを期待するのではなく、エージェントの振る舞いを決定論的に形作るというハーネスエンジニアリングを行っているのです。
このフレーミングは、フックが労力に見合う価値があるタイミングも教えてくれます:毎回エージェントに思い出させなければならないルールは、フック化の候補です。
ローカル環境の構築なしで Claude Code のフルパワーを使う
フックは Claude Code の CLI 上で動作するため、それを使うにはインストールと設定が必要です——ターミナルに慣れていない人にとっては壁であり、開発者ではないチームメイトにとっては不可能です。ローカルインストールを管理せずに Claude Code のエージェント機能を使いたい場合は、Happycapy でブラウザ上で Claude Code を実行できます。管理されたクラウドサンドボックスで Claude Code が実行され、フックが組み込まれるハーネス——ループ、ツール、メモリ、隔離——はすでにあなたのために配線済みです。タスクを説明すれば、視覚的なデスクトップ上でエージェントが作業する様子を見ることができます。ターミナルは不要です。
こう考えてみてください:フックは上級ユーザーが Claude Code のハーネスを手作業でチューニングできるようにするものであり、Happycapy はすべての人に最初から管理されたハーネスを提供します。Claude Code を活用したいと思っていたけれど CLI のセットアップに阻まれていたなら、happycapy.ai で無料で始めて、今日ブラウザで実際のタスクを実行してみてください。
よくある質問
Q: Claude Code フックとは何ですか?
これらはユーザー定義のハンドラー——シェルコマンド、HTTP エンドポイント、MCP ツール呼び出し、モデルへのプロンプト——であり、ツール呼び出しの前(PreToolUse)、編集の後(PostToolUse)、セッション開始時など、ライフサイクルイベントで Claude Code が自動的に実行します。アクションの検証、フォーマット、ログ記録、ブロック、書き換えが可能です。
Q: Claude Code はどのようなフックイベントをサポートしていますか?
SessionStart/SessionEnd、UserPromptSubmit、PreToolUse、PostToolUse(および PostToolUseFailure)、Stop/StopFailure、Notification、サブエージェントおよびタスクイベント、圧縮イベントなど、多数あります。これらはセッションごとに一度、ターンごとに一度、またはツール呼び出しのたびに発火します。
Q: フックがツール呼び出しをブロックするようにするにはどうすればいいですか?
コマンドフックの場合、終了コード 2 で終了させてください——終了 2 のみがブロックします(終了 1 はブロックしません)。PreToolUse の場合、permissionDecision: "deny" を含む JSON を返すこともできます。ハードな強制には、フックの if フィルターがフェイルオープンするため、Claude Code の権限システムを優先してください。
Q: Claude Code フックはどこで設定しますか?
設定ファイルの中です:~/.claude/settings.json(すべてのプロジェクト)、.claude/settings.json(1つのプロジェクト、共有可能)、または .claude/settings.local.json(ローカルのみ)。イベントを選び、マッチャーを追加し、ハンドラーを定義します。
Q: CLI をインストールせずに Claude Code フックを使えますか?
フック自体は Claude Code の CLI を必要とします。ローカル環境の構築なしで Claude Code を使いたい場合は、Happycapy のような管理されたブラウザサンドボックスで実行してください。エージェントとそのハーネスがすぐに使える状態で提供されており、CLI を自分でインストール・設定したくない場合に最適です。
Q: 最初に追加すべき良いフックは何ですか?
Edit|Write にマッチした PostToolUse リンターです——コードの変更のたびにフォーマッターを実行し、エージェントの出力が常にスタイルルールに準拠するようにします。低リスクですぐに役立ちます。

