Claude Code Hooks完全ガイド|ツールイベント自動化で開発フローを加速する実装テクニック【2026年版】
こんにちは、株式会社TIMEWELLの濱本です。
Claude Codeを半年以上使い続けているエンジニアにとって、2026年に入ってから存在感を一気に強めた機能が「Hooks」です。AIエージェントが勝手に rm -rf を叩いたらどうしよう、Edit後のフォーマットを忘れて汚いコードがコミットされたらどうしよう。そういう地味な怖さに、決定的な解を与えてくれます。
面白いのは、Hooksが目立たない割に現場の運用を根本から変える点です。CLAUDE.mdに「必ずprettierをかけてね」と書いても、AIは忘れる日もあります。お願いベースだと守られないから、Hooksというレールを敷いて強制する。これがAnthropic自身が強調している「決定的コントロール(deterministic control)」の思想です[^1]。
この記事では、2026年4月時点の公式仕様と現場での使われ方をふまえ、Claude Code Hooksの全貌と実装テクニックをまとめます。PreToolUseやPostToolUseといった主要イベントの挙動、settings.jsonの書き方、セキュリティ設計、CI/CD連携まで、一本で把握できる内容を目指しました。
Hooksの正体と3つのケイデンス
Claude Code Hooksは、Claude Codeセッションのライフサイクル上で起きるイベントに、あなたが書いたシェルコマンドやHTTPリクエストをフックさせる機能です。設定先は settings.json の hooks キー。マッチャーとコマンドを宣言するだけで、AIの挙動に割り込めます[^1]。
公式ドキュメントはイベントを3つのケイデンスで整理しています[^1]。
- セッション単位(SessionStart、SessionEnd)
- ターン単位(UserPromptSubmit、Stop、StopFailure)
- ツール呼び出し単位(PreToolUse、PostToolUse、PostToolUseFailure、PostToolBatch)
さらに通知系のNotification、権限ダイアログ時のPermissionRequest、サブエージェント終了時のSubagentStopが加わります。たとえばSessionStartは起動や再開、/clear、/compact のたびに発火して、そのときの source フィールドで理由を区別できる仕組みになっています。UserPromptSubmitはあなたがEnterを押した瞬間、Claudeがプロンプトを処理する前に走るので、プロンプト内容を検閲したり、外部コンテキストを差し込んだりする用途にはまります。
ここで効くのが、イベントごとに渡るJSONの形が決まっている点です。PreToolUseなら tool_name、tool_input、tool_use_id が入り、PostToolUseなら tool_response も加わる。フックスクリプトは標準入力でこのJSONを受け取り、jq などでパースして意思決定します。値を返すときは標準出力に hookSpecificOutput を出すか、exit code 2で強制ブロック。この二層構造がClaude Code Hooksの実装規約です[^2]。
初めて触るときに戸惑うのは、Hooksが「AIへのお願い」ではなく「ホストOSで動くプログラム」であることです。Anthropicのサーバーで動くわけではありません。あなたのMacBookやLinuxシェル上で、あなたの権限で走ります。だからこそ決定的に制御できる一方、書き方を誤れば自分の足を撃ち抜きます。この緊張感を最初に理解しておくと、後続の設計判断がぶれなくなります。
settings.jsonの基本構造と配置ルール
設定ファイルは用途別に3つの階層があります。まずユーザー全体に効く ~/.claude/settings.json、チームで共有するプロジェクト共有の .claude/settings.json、そしてコミットしない個人実験用の .claude/settings.local.json。プラグインに同梱する場合は hooks/hooks.json、スキルやエージェントのフロントマターに書く方法もあります[^1]。
実務でいちばん使うのはプロジェクト共有の .claude/settings.json です。Gitに乗せて配れば、チーム全員が同じルールで動く。CLAUDE.mdだと読み飛ばされる約束ごとも、Hooksにすれば嫌でも守られます。
基本形はこうなります。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard-bash.sh",
"timeout": 30
}
]
}
]
}
}
matcher はツール名にマッチさせる文字列で、"Bash" のような完全一致、"Edit|Write" のような縦棒連結、正規表現が使えます。MCPサーバー経由のツールをまとめて捕まえたいときは "mcp__memory__.*" のようなパターンで、メモリーサーバー配下の全ツールにフックをかけられます。"*" または省略で全ツールに当たる挙動です[^1]。
type は command のほかに、外部エンドポイントへPOSTする http、LLM判定する prompt、サブエージェントで検証する agent、MCPツールを呼ぶ mcp_tool の5種類が用意されています[^1]。初心者はまず command で試すのが素直で、チーム全体にロールアウトする段階になって初めて http を検討する、くらいの順番でよいでしょう。
環境変数もいくつか便利なものが提供されています。$CLAUDE_PROJECT_DIR はプロジェクトルートの絶対パス、プラグインからは ${CLAUDE_PLUGIN_ROOT} と ${CLAUDE_PLUGIN_DATA} にアクセスできます。/hooks と打てば現在のセッションで有効になっているフック一覧を確認できるので、デバッグ時はまずここを見るのが早道です。全フックを緊急停止したいときは "disableAllHooks": true を足せば一発で止まります。
PreToolUseとPostToolUseで最初に組むべき実装
実務で最初に組むべきは、危険コマンドを止めるPreToolUseと、編集後の自動整形を担うPostToolUseです。どちらも5分で効果が出るので、Hooksに慣れる教材として理想的です。
まずPreToolUseで rm -rf 系を遮断する例を見てみましょう。.claude/hooks/guard-bash.sh にこう書きます。
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
if echo "$cmd" | grep -qE '(rm\s+-rf|sudo\s+rm|mkfs|dd\s+if=)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "破壊的コマンドのため遮断しました"
}
}'
exit 0
fi
exit 0
ポイントはexit codeを0のまま保ち、JSONで permissionDecision: "deny" を返すところです。exit code 2でも遮断できますが、理由を構造化して返す方がClaude側のリカバリーが賢くなります。decision は allow deny ask defer の4種類があり、ask だとユーザーに都度問い合わせる挙動、defer は次段のPermissionRequestに委ねる挙動になります[^1][^3]。
次にPostToolUseです。Editした直後にprettierとeslintを走らせ、失敗したらClaudeに差し戻すパターンを紹介します。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write|MultiEdit",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/format-after-edit.sh",
"timeout": 60
}
]
}
]
}
}
スクリプト側では tool_input.file_path を受け取り、拡張子に応じて npx prettier --write と npx eslint --fix を順に叩きます。eslintがエラーを吐いたらstderrに理由を出してexit code 2で返す。するとClaudeはフィードバックを読み、該当箇所を直したうえで再度Editしてきます。手で「lintが落ちてるよ」と指摘する必要がなくなり、ループが自動化されるわけです。これは公式ブログやDataCampのチュートリアルでも繰り返し紹介されている鉄板パターンです[^4]。
個人的には、最初はPostToolUseを緩めに(exit code 2で落とさず、ログだけ出す)始めて、ルールが安定してから厳格化するのがおすすめです。いきなり厳しくするとClaudeが延々とリトライしてターンを浪費するので、プロジェクトの性格に合わせて温度を調整してください。
SessionStart・UserPromptSubmit・Stopで文脈を操る
PreToolUseとPostToolUseが「ツール単位の安全装置」だとすれば、SessionStart、UserPromptSubmit、Stopは「ターンと会話そのものを操る」ためのフックです。ここに手を入れるとClaudeの賢さが一段変わります。
SessionStartは起動直後に1回だけ走るので、プロジェクトの現状をClaudeのコンテキストへ注入するのに向いています。たとえば git status と git log -10 --oneline の結果を追加コンテキストとして渡せば、再開直後からClaudeが最新の作業状況を前提に提案してくれます。JSON側では additionalContext フィールドに文字列を入れて返します[^1]。
UserPromptSubmitはプロンプトが処理される前のタイミングで、検閲と情報追加の両方に使えます。たとえば「プロンプトに TICKET-123 のようなIDが入っていたら、Linearから該当チケットの本文を引いてきて追加コンテキストに差し込む」といった実装はコミュニティ事例でよく見ます[^5]。逆に、社外秘のファイル名が含まれていたら decision: "block" を返してプロンプトごと拒否する、という検閲用途にも向きます。
Stopは1ターンが完結したときに走ります。個人的に気に入っているのは、Stop時に音声通知を鳴らす設定です。長いタスクを走らせてターミナルから目を離しているとき、「ピンポン」と音が鳴るだけで生産性がまるで違います。Anthropicの公式ブログでも、Stopで say "Claude is done"(macOSのテキスト読み上げ)を叩く例が紹介されています[^2]。
SubagentStopはサブエージェントが終わったときの専用イベントで、Stopフックをサブエージェントに適用しようとすると自動的にSubagentStopへ変換される挙動になっています[^3]。親エージェントのStopとは別のルートで通知したい、ログを分けたい、といった場面で使い分けます。
次のスニペットはSessionStart・UserPromptSubmit・Stopをまとめて設定する構成例です。
{
"hooks": {
"SessionStart": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/inject-git-status.sh"
}
]
}
],
"UserPromptSubmit": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/expand-ticket-id.sh"
}
]
}
],
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "say 'Claude is done'"
}
]
}
]
}
}
3つを組み合わせるとセッション全体に「文脈を厚くして、プロンプトを補強して、終了を知らせる」という流れが自然に通ります。CLAUDE.mdで書くよりも、設定ファイルでガチッと縛った方が抜け漏れが減ります。
セキュリティとCI/CD連携で運用に乗せる
Hooksで忘れてはいけないのが、フックはホストOSの権限で走るという事実です。~/.claude/settings.json に入った第三者のフックは、あなたの ~/.aws/credentials も ~/.ssh/id_rsa も読めます。公式ドキュメントも「Hook code can exfiltrate data or damage your system」と明記しており、配布されたフックは必ずレビューしてから入れるべきだと繰り返しています[^1]。
現実的な運用ルールとして、私は次の3点を徹底しています。最初は最小権限で始めて、必要になったら緩める。外部から持ってきたフックはGit差分を全部読んで、わからない行があれば実行しない。シークレット系のファイルにアクセスするコマンドは、PreToolUseで明示的に deny する。とくに3番目は見落としがちなので、.env 系や ~/.aws/ 配下を読もうとするBashコマンドをブロックするサンプルを紹介します。
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command // ""')
file=$(echo "$input" | jq -r '.tool_input.file_path // ""')
if echo "$cmd $file" | grep -qE '(\.env|\.aws/|id_rsa|credentials\.json)'; then
jq -n '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: "シークレットファイルへのアクセスを遮断しました"
}
}'
exit 0
fi
exit 0
ここまでやっておくと、Claude Codeに強めの自律性を与える「auto-accept」モードでも腹を括って任せられます。GitHubのkornysietsma/claude-code-permissions-hookや、karanb192/claude-code-hooksは、こうした粒度細かい権限制御のテンプレート集として参考になります[^6]。
CI/CD連携に踏み込む場合は、type: "http" が切り札になります。PostToolUseやStopをトリガーにして、GitHub ActionsのRepository Dispatchエンドポイントへイベントを投げる構成が王道です。Claude Labの解説記事では、PR作成時の自動レビュー、コミット単位のセキュリティスキャン、ステージング反映後の回帰テスト起動までを一本のパイプラインに束ねる実装パターンが詳しく紹介されています[^7]。
{
"hooks": {
"Stop": [
{
"matcher": "*",
"hooks": [
{
"type": "http",
"url": "https://api.github.com/repos/acme/app/dispatches",
"headers": {
"Authorization": "Bearer $GITHUB_TOKEN",
"Accept": "application/vnd.github+json"
},
"body": {
"event_type": "claude-turn-complete",
"client_payload": { "session": "$SESSION_ID" }
}
}
]
}
]
}
}
Stopで毎回GitHub Actionsのワークフローを起こし、そこでlint、test、セキュリティスキャン、SlackへのレポートまでをCI側で回す。Claude Codeをただのコーディング補助に留めず、自律的なエンジニアリングワークフローの中に組み込む筋が一気に開けます。
企業の開発組織にこの仕組みを持ち込む場合、AnthropicのAPI単体で完結させるより、ガバナンスやナレッジ整備とセットで考えた方が定着します。TIMEWELLではエンタープライズ向けに、日本語主体のナレッジをAWS東京リージョンに閉じて扱う ZEROCK というエンタープライズAIプラットフォームを提供しており、社内文書をClaude Codeとどう噛み合わせるかという実装相談が増えています。組織としてClaude Codeをどこまで解放するか、どのフックを標準化するかといったAI戦略設計は、AIコンサルティングの WARP が伴走する領域です。自社で一から作るより、一緒に設計した方が回り道は少ないと感じています。
まとめと次の一歩
Claude Code Hooksを触り始めると、最初は「便利な自動整形ツール」くらいの印象だと思います。ただ、PreToolUseで危険を止めて、PostToolUseで品質を担保して、UserPromptSubmitで文脈を厚くして、Stopで外部へイベントを飛ばす。ここまでくると、AIコーディングが「お願いベースの補助輪」から「ルール駆動のエンジニアリング基盤」に変わります。
今日から試すなら、順番はこの通りがおすすめです。
.claude/settings.jsonを作り、PostToolUseでprettier実行だけ書く- 1日使ってみて、落とし穴を把握する
- PreToolUseで
rm -rfとシークレット系の遮断を足す - SessionStartで
git statusをコンテキストに流し込む - 慣れたらStopをGitHub ActionsやSlackに繋いでCI化する
ちなみに、Claude Codeのスキルやプラグインも絡めると威力が一段上がります。スキル側の詳細は Claude Codeおすすめスキル45選 に、プラグインによる拡張の全体像は Superpowersプラグインの徹底解説 に、マルチエージェント構成の設計論は Claude Codeエージェントチーム構築ガイド にそれぞれまとめています。Hooksとこれらを組み合わせて読むと、Claude Codeの全体像がきれいに立ち上がるはずです。
Hooksは派手さこそないものの、AIを自分の開発環境へ迎え入れるうえでの「設計の背骨」になります。settings.json 10行分の工夫が、半年後の開発体験を大きく変える。触ってみないと実感できない類のものなので、まずは1つ、PostToolUseのフォーマッターから始めてみてください。
参考文献
[^1]: Anthropic公式ドキュメント「Hooks reference」 https://code.claude.com/docs/en/hooks [^2]: Anthropic Blog「Claude Code power user customization: How to configure hooks」 https://claude.com/blog/how-to-configure-hooks [^3]: Anthropic公式「Automate workflows with hooks」 https://code.claude.com/docs/en/hooks-guide [^4]: DataCamp Tutorial「Claude Code Hooks: A Practical Guide to Workflow Automation」 https://www.datacamp.com/tutorial/claude-code-hooks [^5]: GitHub disler/claude-code-hooks-mastery https://github.com/disler/claude-code-hooks-mastery [^6]: GitHub kornysietsma/claude-code-permissions-hook https://github.com/kornysietsma/claude-code-permissions-hook [^7]: Claude Lab「Claude Code HTTP Hooks × GitHub Actions Integration Guide」 https://claudelab.net/en/articles/claude-code/claude-code-http-hooks-cicd-github-actions-guide
