「hooksを設定したのに、なぜか通知が鳴らない」「lintを毎回手動で走らせるのが面倒」。
Claude Codeを使い込むほど、そうした細かい引っかかりに気づくはずだ。
Claude Code hooksは、ファイル編集やコミットといった特定のイベントが起きた瞬間に、あらかじめ登録したシェルコマンドを問答無用で実行する仕組みだ。
CLAUDE.mdに「編集後はlintを回して」と書いても、Claudeが忘れることはある。hooksは違う。決定論的に、毎回必ず動く。
PreToolUse・PostToolUseなど実務で使う主要イベントの発火タイミング、.claude/settings.jsonにそのまま貼れる設定例(自動lint・タスク完了通知・危険コマンドのブロック)、「hookが動かない」ときに確認すべきポイントまでをコード付きで押さえられる。
ただし2026年に入ってイベントの種類は9個どころではなくなった。
実務でよく使うのはごく一部だが、その全体像を知らないまま組むと、あとで「このイベント名、もう無いのか」と手戻りする。
Claude Codeのhooksとは?

Claude Codeのhooksは、特定のイベントが発生したタイミングで、あらかじめ設定しておいたスクリプトやコマンドを自動的に実行する仕組みです。
例えば、「ファイルを編集したら」や「Claudeが応答を終えたら」といったイベントをきっかけ(トリガー)に、さまざまな処理を自動で動かせます。
hooksの役割と仕組み
hooksの最大の役割は、開発ワークフローの自動化です。
釣りで魚を「フック」にかけるように、ツールの実行やセッションの開始・終了などの特定のイベントに処理を引っかけて自動実行させます。
開発者が手動で行っていた作業をClaude Codeが肩代わりしてくれるんです。
仕組みは、開発者が設定ファイルに「いつ」「何をするか」を定義し、実行スクリプトを配置するだけ。
残りはClaude Codeが引き受け、イベントを監視して条件に合致したタイミングでスクリプトを実行してくれます。
ここで押さえておきたいのが、CLAUDE.mdへの指示との違いだ。
CLAUDE.mdに「編集後はlintを回して」と書いても、それはあくまでモデルへのお願いであり、モデルが確率的に従うものにすぎない。
従わないこともある。一方hooksは、Claude Codeのハーネス自身が必ず実行する。だから判断基準はシンプルだ。
毎回絶対に実行してほしい処理(lint・フォーマット・危険コマンドのブロック)はhooksに任せ、多少のブレを許容できる方針はCLAUDE.mdに書けば十分、ということになる。
なぜhooksが必要なのか
hooksが必要な理由は、主に3つあります。
Claude Codeにおけるhooksの位置づけ
Claude Codeにおいて、hooksはローカルの開発セッション内でイベント駆動の自動化を実現する機能です。
GitHub ActionsのようなCI/CDパイプラインそのものを構成する仕組みではない。
コミット前のlintやフォーマットなど、CI/CDに送り出す前の品質担保を手元で肩代わりする役割に近いといえます。
GUIで設定する複雑なパイプラインとは異なり、コードベースで手軽に自動化を導入できるのが大きな特徴。
小規模なチェックから本格的なデプロイフローまで、幅広い用途に対応できる柔軟性を持っています。
まさに、開発者のかゆいところに手が届く機能といえるでしょう。
hooksはどう使う?【基本編】

ここからは、実際にClaude Codeでhooksを使うための基本的な手順を解説します。
hooksの設定は、settings.jsonを直接編集して行う。/hooksコマンドは、設定済みのhooksを確認するための閲覧用メニューだ。
/hooksコマンドで設定済みのhooksを確認する
Claude Codeのチャット欄で/hooksと入力すると、設定済みのhooksを一覧できる読み取り専用のブラウザが開く(hooksの追加・編集はここからはできない)。
各hookについて、定義されている設定ファイル(ユーザー設定・プロジェクト設定・プラグインなど)と、実行されるコマンドの全文を確かめられる。設定を書いたあとに「意図したhookが読み込まれているか」を確認するのに便利だ。
hooksを追加するときは、settings.jsonを編集するか、Claudeに設定を依頼する。書き込み先の使い分けの目安は次のとおり。
- 通知音やログなど個人的な設定 →
~/.claude/settings.json - 危険コマンドのブロックなどチームで統一したいルール →
.claude/settings.json(Gitで管理し、チーム全員に共有)
hooksを設定する手順
ここからは、settings.jsonを直接編集する方法を見ていく。
- 以下の設定ファイルを作成する
- 設定ファイルに“hooks”セクションを追加する。たとえば、ファイル編集後にlintを走らせたいなら、以下のように書く。
3. スクリプト本体(もし自作するなら)を用意・実行可能に
例えば ./.claude/hooks/pre-commit-check.shのようなスクリプトを作って、それを設定ファイルの command で呼び出します。
作成後に、
を実行して実行権限を付与します。
event
フック(hook)イベント の一覧と、それぞれの意味・使いどころです。
本記事の内容はClaude Code公式ドキュメント(code.claude.com/docs/en/hooks)の記載に基づきますが、Claude Code自体のアップデートで挙動が変わる可能性があるため、重要な自動化を組む前には公式ドキュメントで最新仕様を確認するとよいでしょう。
2026年に入りイベントの種類は大幅に増え、2026年10月時点の公式hooksリファレンスには33種類が載っている(イベントは随時追加されるため、最新の一覧は公式ドキュメントで確認したい)。
上記のイベントは実務で最もよく使う顔ぶれであり、まずはここから使い始めれば十分だ。
matcher
matcher は、フック設定内で「どのツール実行(またはどの条件)に対してこのフックを走らせるか」を指定するフィルターです。
つまり「ツール名」「ツールの入力/出力」「ファイルパス」といった条件にマッチしていたら、該当フックが発動する、という仕組みです。
具体的には、以下のようなルールがあります
- matcher は主に PreToolUse/PostToolUse イベントのときに使われます。
- matcher に指定できる値としては ツール名の文字列(厳密一致)や、正規表現パターン(例:Edit|Write)が使えます。
- すべてのツールに対してフックを走らせたいときは matcher: "*" や空文字 "" で “無条件” に設定可能です。
いくつか matcher を使うときに押さえておくべき仕様ポイントがあります。
イベントによってmatcherが受け付ける値も変わる。
例えばSessionStartはstartup|resume|clear|compact|fork、SessionEndはclear|resume|logout|prompt_input_exit|otherのように、ツール名ではなく「何がきっかけで発生したか」という区分を指定する形になる。
ツール名でmatcherするのはPreToolUse・PostToolUseなど一部のイベントに限られる点を押さえておこう。
利用可能なツール名(matcher で指定する値)は、主に以下のようなものがあります。
matcherを正規表現で書くときは、思っている通りにマッチしているかを事前に確認したほうがいい。
実際にPythonのreモジュールで検証してみると、"Edit|Write"はEditとWriteだけに一致し、"mcp__memory__.*"はmcp__memory__storeのようなMCPツール名に一致する。
一方で、公式ドキュメントによると、英数字・_・-・|・,・空白だけの文字列は完全一致の名前(のリスト)として扱われ、それ以外の文字を含むとアンカーなしのJavaScript正規表現として扱われる。"^Notebook"はNotebookEditのようにNotebookで始まるすべてのツールに一致する。逆に"Edit.*"のように先頭を固定しない書き方は、EditとNotebookEditの両方に一致してしまう。ツール名ちょうどに絞りたいときは"^Edit$"のように前後を固定する。
「先頭を固定したつもりのmatcherが、意図しないツールにも一致していた」という事故を避けるために、本番投入前に一致するツールを確認しておく習慣をつけたい。
type
typeで指定できる値は現在5種類ある。
シェルコマンドを実行するcommand、外部URLへPOSTするhttp、接続済みMCPサーバーのツールを呼び出すmcp_tool、LLMに単発で判定させるprompt、ツールを使えるサブエージェントを起動して検証させるagentだ。
promptとagentはすべてのイベントで使えるわけではなく、対応イベントは限られる。
commandタイプには、実行を細かく制御するオプションも用意されている。
argsでコマンドへの引数を配列として分離指定でき、コマンド文字列を組み立てる際のクォート崩れを避けられる。
async: trueを指定すると、hookの完了を待たずに次の処理へ進む(重い処理をブロッキングにしたくないとき向き)。
スクリプトのパスは./.claude/hooks/xxx.shのような相対パスではなく、${CLAUDE_PROJECT_DIR}/.claude/hooks/xxx.shのようにプレースホルダーで指定するのが安全だ。
相対パスはClaude Codeの実行時カレントディレクトリに依存するため、プロジェクトルート以外から起動されると解決に失敗することがある。
条件付き実行(ifフィールド)と環境変数の活用
hooksの設定には、type以外にも実務でよく使う制御用フィールドがある。代表的なのがifフィールドとallowedEnvVarsだ。
- if(条件付き実行): 例えば
"if": "Bash(rm *)"のように書くと、実行しようとしているBashコマンドがrmで始まるときだけhookを発動できる。すべてのBash実行にhookをかけたくない場合に便利。 - allowedEnvVars(環境変数の許可リスト):
httpタイプでSlack通知やWebhookに外部送信する際、allowedEnvVarsで明示的に許可した環境変数だけが送信対象になる。意図しない値の漏洩を防ぐ仕組みだ。 - timeout・once:
timeoutでhookの実行時間上限を秒単位で指定でき、onceをtrueにすると最初に成功した実行のあとでhookが取り除かれるが、これはスキルのフロントマターに書いたhookでのみ有効で、settings.jsonに書いても無視される。
hooksを使う上でのセキュリティ上の注意点
hooksは便利な反面、ユーザーの権限で任意のシェルコマンドを無条件に実行する仕組みでもある。ここを軽視すると、自動化のつもりが事故の入り口になる。
- matcherを広げすぎない: matcherを
"*"にして全ツールに同じhookをかけると、意図しない操作にまでコマンドが発火する。まずは特定のツール・イベントに絞って検証し、動作を確認してから対象を広げるほうが安全だ。 - 外部入力をコマンドにそのまま埋め込まない: ツールの入力値やプロンプト内容を検証せずにシェルコマンドへ展開すると、コマンドインジェクションのリスクがある。固定コマンド+引数を渡す形に留め、動的な文字列展開は最小限にする。
- チーム共有設定はレビューを通す:
.claude/settings.jsonはGitで管理されチーム全員に配布される。追加・変更するコマンドは、通常のコード変更と同様にプルリクエストでレビューしてからマージする運用が推奨される。
PreCompactイベントの使いどころ
長時間セッションでは、会話履歴が一定量を超えるとClaude Codeが自動でコンテキストを圧縮(compact)する。
PreCompactは、その圧縮が実行される直前に発火するイベントだ。
圧縮されると、それ以前の会話の細かい経緯は失われやすい。
PreCompactで圧縮直前の会話ログをファイルに書き出しておけば、あとから「あのときどういう判断をしたか」を追いかけられる。
基本イベント以外の拡張イベント(PermissionRequest・TaskCompletedなど)
ここまで紹介した9イベント(PreToolUse・PostToolUse・Notification・UserPromptSubmit・Stop・SubagentStop・PreCompact・SessionStart・SessionEnd)は基本セットにすぎない。
実際にはさらに多くのイベントが存在する。
代表例がPermissionRequest(権限確認ダイアログが表示されるタイミングで発火し、自動許可・自動拒否の判定に使える)、PostToolUseFailure(ツール実行が失敗した直後に発火し、エラー内容に応じた後処理に使える)、PermissionDenied(自動モードでツール実行が拒否されたときに発火)、SubagentStart(サブエージェントの起動時に発火。
終了時のSubagentStopとペアで使う)、TaskCompleted(タスク管理ツールでタスクが完了マークされたときに発火し、品質ゲートとして使える)だ。
古い情報や勘違いによる誤った名称にも注意したい。PostResponseという名称のイベントは存在せず、応答完了時に使うべきはStop。
PreResponseではなくUserPromptSubmitが該当する。
すべてのイベントを網羅的に覚える必要はなく、まずは基本の9イベントから使い始めれば十分だ。
hookが「ブロックできる」かどうかは、実はexit codeで機械的に決まる。
終了コードでブロックできるのはexit code 2のときだけで(ブロックできるイベントに限る。JSONでdecisionを返す方法もある)、それ以外の非ゼロ値(exit 1を含む)は「非ブロッキングのエラー」として扱われ、処理はそのまま続行される。
「exit 1で止まるはず」という思い込みは、hooksを組むときに誰もが一度は踏む典型的なハマりどころだ。
例で理解するhooksの流れ
上記で設定したhooksのもう少し具体的なhooksの流れを見てみましょう。
- ユーザーの操作 ユーザーが Claude Code を使用してファイルを編集する。例えば、コードエディタで TypeScript ファイルを開いて内容を変更
- ツールの呼び出し Claude Code は内部で Edit ツールを使用して、編集されたファイルを処理
- フックのトリガー PostToolUse イベントが発生し、matcher が "Edit" に一致するため、設定されたフックが実行
- コマンドの実行 フック内で指定されたコマンド(この場合は npm run lint)が実行
- 結果の確認 npm run lint の実行結果がターミナルに表示され、コードの静的解析結果を確認
hooksを活用した実践例

基本を理解したところで、次はより実践的なClaude Codeのhooks活用例を3つ紹介する。これらの実践例を参考に自動化を導入してみよう。
実践例に共通するのは、いずれも数行のJSON設定だけで導入できる点だ。
自動通知(サウンド再生)
MacのClaude Codeの作業が完了した際に自動で通知音を送るhooksです。
通知音をオリジナルの効果音に変える方法は、後述の「通知音をカスタムする実例」で詳しく解説します。
通知をSlack・Telegramにも広げる
macOSのサウンド通知だけでなく、Notificationイベントを使えばSlack・Telegramなどチャットツールへの通知にも広げられる。
離席中や長時間タスクの実行中でも気づきやすくなるのが利点だ。
例えば、Slack Incoming Webhookへcurlでメッセージを送る場合の設定は以下のようになる。
通知先を複数登録したい場合は、hooks配列に実行したいコマンドを並べて追加するだけでよい。
pre-commitでのlintとフォーマット実行
これは最も一般的で効果的なhooksの一つです。
ファイル編集のたびにESLintやPrettierといったツールを自動実行し、コーディング規約に沿わないコードが残るのを防ぎます。
.claude/hooks/pre-commit-check.sh スクリプト例:
通知音をカスタムする実例|ドラクエの効果音に差し替える方法
Claude Codeを1日動かしていると、許可を求められるたび、処理が終わるたびに通知が鳴ります。私の環境ではhooksから通知を出していて、標準のシステムサウンドを鳴らしていました。何十回も聞くうちに単調に感じてきたため、ドラクエの効果音に差し替えました。
許可待ちは「カーソル音」、完了は「バシルーラのSE」にしています。ここでは、その手順と、つまずいた点を順に紹介します。
仕組み|terminal-notifierとhooksの組み合わせ
Claude Code本体に通知音を選ぶ設定項目は見当たらなかったため(2026年8月時点)、hooksから自前の通知を鳴らす形にしています。
~/.claude/settings.jsonのhooksで、PermissionRequestとStopの2イベントから、notify.shというシェルスクリプトを呼び出しています。
notify.shは、Claude CodeからJSONで渡されるイベント情報を受け取ります。種別に応じてメッセージとサウンドを切り替え、terminal-notifierでmacOSの通知として表示する仕組みです。
変更が必要なのは、MESSAGEとSOUNDの2つの変数だけです。まだterminal-notifierを入れていなければ、Homebrewで入れます(2026年8月時点で確認済みの手順)。
最初につまずいたのは、-soundオプションの仕様です。音声ファイルのパスを直接渡すのではなく、macOSのシステムサウンド名(拡張子を除いたファイル名)を指定する仕様になっています。ダウンロードフォルダに置いたwavファイルのままでは鳴らず、macOSがサウンドとして認識する場所に置く必要があります。
手順|~/Library/Soundsに置いてSOUND変数を書き換える
~/Library/Sounds/は、macOSが個人用のカスタムサウンドとして認識するディレクトリです。ここにwavファイルを置くと、拡張子なしのファイル名で参照できます。
次に、notify.shのSOUND変数を、拡張子を除いたファイル名に書き換えます。日本語や括弧を含むファイル名でも、そのまま指定して動きました。
notify.shを編集する前に、terminal-notifierを単体で叩いて鳴るか確認しておくと安全です。
完了と許可待ちで音とメッセージを鳴らし分ける
notify.shは、$EVENTが「permission」かどうかで分岐しています。許可待ちと完了で違う音を割り当てると、画面を見なくても耳だけで状況が分かります。
メッセージ文言も同時に変えると、体験が統一されます。私は「許可を求めています」を「ボス許可をくれ」に、「処理が完了しました」を「ボス完了した」に変えました。
音量調整|ffmpegのvolumeフィルタで音源を加工する
効果音は、選んだ瞬間は満足しても、何度も鳴らすうちに「思ったより音が大きい」と感じます。terminal-notifierの-soundには音量のパラメータがないため、音源ファイル自体を加工します。
volume=0.5は、現在の音量の50%にするという意味です。同じファイル名で上書きすれば、notify.sh側の設定をそのまま使い回せます。
私は、倍率を0.7、0.5、0.5、0.2と4回に分けて掛け、最終的に元の音量の3.5%程度まで下げました。一気に下げると、下げすぎて無音同然になったときに大きい音源から作り直す羽目になります。少しずつ試して聞き直すのが、結果的に近道でした。
音が鳴らないときによくある原因
鳴らない場合は、次の3つのどれかに絞られます。
- ファイル名のスペルミス(
SOUND変数の値と~/Library/Sounds/内のファイル名が一致しているか) ~/Library/Sounds/への移動漏れ(ls ~/Library/Sounds/で存在を確認)- macOSの通知設定で、terminal-notifierの通知がオフになっている
私は3つ目に気づかず、しばらく設定ファイルばかり疑っていました。通知そのものが出ているかを先に確認すると、原因の切り分けが早くなります。
ここでは2イベントだけを変えましたが、他のイベントにもそれぞれ別の音を割り当てられます。「今どのフェーズか」を耳だけで判別できる環境も作れます。
hooksを使うときによくあるエラーと対処法

hooksは便利ですが、設定でつまずくこともあります。ここでは、よくあるエラーとその対処法を紹介します。
エラーの大半は「実行権限」「設定ファイルの記述ミス」「shebang」の3点に集約されます。
hookが動かないときに確認すべきポイント
「設定したはずなのにhookが動かない…」というときは、まず以下の3点を確認しましょう。
ログで原因を特定する方法
問題が解決しない場合は、ログを確認するのが一番の近道です。
Claude CodeにはCtrl+Oで開くトランスクリプト表示があり、hookの失敗やブロックを確認できます(成功時は原則何も表示されず、失敗時は「〜 hook error」の通知とエラー内容の先頭行が表示される)。
フル情報が必要ならclaude --debug(または--debug-file <path>)で起動し、書き出されたデバッグログを読むと、どのhookが一致したか・終了コード・stdout/stderrの全文まで確認できます。
また、スクリプト内でset -xコマンドを実行すると、どのコマンドが実行されているかを詳細にログ出力できるため、デバッグに役立ちます。
hooks活用のベストプラクティス

要点は、フックを高速に保つこと・冪等性を意識すること・エラー処理を丁寧に行うことの3つだ。
安全にhooksを使うための設計指針
- フックは高速に保つ:
PreToolUseのようにClaudeの操作をブロックするhookは、処理が数秒で終わるように設計しましょう。重い処理(例: E2Eテスト)は、async: trueを指定して完了を待たずに実行するのがおすすめです。 - 冪等性(べきとうせい)を意識する: フックスクリプトは、何度実行しても同じ結果になるように作りましょう。これにより、予期せず再実行された場合でも問題が起きにくくなります。
- エラー処理を丁寧に行う: スクリプトが失敗した場合は、分かりやすいエラーメッセージを出力して処理を中断するようにします。これにより、問題の早期発見につながります。
開発効率を上げるhooksの組み方
- チームでhooksを共有する:
.claude/settings.jsonと.claude/hooksディレクトリをGitの管理対象に含めることで、チーム全員が同じフックを利用できます。これにより、開発環境の差異による問題を減らし、チーム全体の生産性を向上させられます。 - 小さな自動化から始める: 最初から複雑なワークフローを組もうとせず、まずは「コードフォーマットの自動化」のような、簡単で効果の大きいものから導入してみましょう。成功体験を積み重ねることが大切です。
よくある質問
Q1. Claude Code hooksとは何ですか?
A1. 特定のイベント(ファイル編集やコミットなど)が起きた瞬間に、あらかじめ登録したシェルコマンドを自動実行する仕組みです。CLAUDE.mdへの指示と違い、決定論的に毎回必ず動作します。
Q2. hooksはどこで設定しますか?
A2. .claude/settings.json(プロジェクト共有用)または~/.claude/settings.json(個人設定用)に、イベント・matcher・実行コマンドをJSON形式で記述します。Claude Codeのチャット欄で/hooksと入力すると、設定済みのhooksを確認できます(閲覧専用で、追加・編集はsettings.jsonで行います)。
Q3. hooksのtypeにはどんな種類がありますか?
A3. シェルコマンドを実行するcommand、外部URLへPOSTするhttp、MCPサーバーのツールを呼ぶmcp_tool、LLMに判定させるprompt、サブエージェントを起動するagentの5種類があります。
Q4. hookが動かないときはどう対処しますか?
A4. まずchmod +xでスクリプトに実行権限が付与されているか、.claude/settings.jsonのイベント名・matcherの綴りにタイポがないか、スクリプトのshebang(#!/bin/sh等)が正しいかの3点を確認します。
Q5. hooksで通知をカスタマイズできますか?
A5. はい。Notificationイベントを使えば、macOSのサウンド再生だけでなく、Slack Incoming WebhookへのcurlコマンドでSlack通知に広げることもできます。
Q6. CLAUDE.mdとhooksはどう使い分けますか?
A6. CLAUDE.mdへの指示はモデルが確率的に従うもので、毎回実行されるとは限りません。hooksはハーネスが決定論的に必ず実行するため、lint・フォーマット・危険コマンドのブロックなど「絶対に毎回実行してほしい処理」に向いています。
Q7. Claude Code hooksのイベントは全部で何種類ありますか?
A7. 基本の9イベント(PreToolUse・PostToolUse・Notification・UserPromptSubmit・Stop・SubagentStop・PreCompact・SessionStart・SessionEnd)に加え、2026年10月時点の公式リファレンスでは33種類まで拡大しています。実務でよく使うのは基本9イベントとPostToolUseFailure・PermissionDenied・SubagentStart・TaskCompletedなど一部です。
Q8. hookでコマンドの実行を確実にブロックするにはどうすればいいですか?
A8. スクリプトからexit code 2を返してください。終了コードでブロックできるのはexit code 2のときだけで(ブロックできるイベントの場合)、それ以外の非ゼロ値(exit 1を含む)は非ブロッキングのエラーとして扱われ、処理はそのまま続行されます。
Q9. Claude Codeの通知音は変更できますか?
A9. できます。hooksから呼び出すシェルスクリプト内で、terminal-notifierのSOUND変数をmacOSのシステムサウンド名に差し替えれば、好きな効果音を通知音にできます。
Q10. terminal-notifierの-soundに音声ファイルのパスを直接指定できますか?
A10. できません。-soundオプションはmacOSのシステムサウンド名(拡張子を除いたファイル名)だけを受け付けます。音源ファイルは~/Library/Sounds/に置く必要があります。
Q11. 通知音の音量を下げるにはどうすればいいですか?
A11. terminal-notifierの-soundには音量のパラメータがないため、ffmpegのvolumeフィルタで音源ファイル自体を加工します。一気に下げず、少しずつ試して聞き直す方法が安全です。
まとめ|Claude Codeのhooksで自動化の幅を広げよう
hooksの要点を整理すると、次のようになる。
- hooksとは: 特定のイベントをきっかけに、処理を自動実行する仕組み。
- 目的: ヒューマンエラーの防止、開発効率の向上、チーム開発の標準化。
- 使い方:
.claude/settings.jsonにイベント・matcher・実行コマンドをJSONで記述し、必要に応じて呼び出すスクリプトに実行権限を付与するだけ。 - 活用例: Slack通知、lint実行、自動テスト、デプロイの自動化など。
hooksを使いこなせば、これまで手作業に奪われていた時間を取り戻し、より創造的な開発作業に集中できます。
| REV. | DATE | 内容 |
|---|---|---|
| 4 | 2026-10-06 | 記載内容の事実確認と修正 |
| 3 | 2026-08-29 | 2026年8月時点の情報で全体を見直し |
| 2 | 2026-08-02 | 2026年8月時点の情報で全体を見直し(古い記述を6件更新) |
| 1 | 2025-10-19 | 初版 |



