Claude Codeのフック(hooks)の使い方|僕が入れている6本は、ほとんどが「知らせるだけ」
フックは、決まった時点で自分のコマンドを必ず走らせる Claude Code の仕組み。
設定の場所・イベント・終了コードを公式ドキュメントで整理した。
僕の6本と、作って決めた3つのことも並べた。
Claude Code のフック(hooks)は、決まったタイミングで自分のコマンドを必ず走らせる仕組みだ。
僕はいま6本入れているが、作業を止めるものは1本もない。
ほとんどが「Claude に一言知らせるだけ」のフックになっている。
この記事では、公式ドキュメントに書いてある仕様を先に整理して、僕の設定ファイルに入っている6本を順に並べる。
作ってみて分かった注意点も最後に書いておく。
「僕は〜と思う」と書いたところだけが、僕の意見になる。
フックは「AIに任せずに、必ず起きる」処理
公式のガイドには、フックはユーザーが定義したシェルコマンドで、Claude Code が決まった時点で実行する、とある。
続けて、LLM が実行するかどうかを選ぶのに頼らず、ある処理が必ず起きるようにできる、と書かれている。
僕がフックを使い始めた理由は、まさにこの一文だった。
規約ファイルに「作業の前に引き継ぎメモを読むこと」と書いても、読まれない日がある。
AIは書いてあることを毎回同じように守るとは限らないからだ。
フックはプログラムなので、決めた時点で毎回動く。
「読むかどうか」はAIに任せたまま、「メモがあること」だけは毎回確実に伝えられる。
設定を書く場所と、主なイベント
設定は settings.json の hooks という欄に書く。
置き場所は3つあり、~/.claude/settings.json は自分のPCの全プロジェクトに、.claude/settings.json はそのプロジェクトだけに効く。.claude/settings.local.json はそのプロジェクト用で、共有しない設定を置く場所だ。
複数の場所に書いたフックは、上書きではなく足し合わされる。
どの時点で動かすかは「イベント」で選ぶ。
公式のイベント表から、よく使いそうなものを抜き出すとこうなる。
- SessionStart:セッションが始まったとき・再開したとき
- UserPromptSubmit:こちらが指示を送った直後、Claude が処理する前
- PreToolUse:ツールを使う直前(止めることもできる)
- PostToolUse:ツールの実行が成功した直後
- PreCompact/PostCompact:会話の圧縮の前と後
- Stop:Claude が返答を終えたとき
フックのコマンドには、セッションIDや作業フォルダ(cwd)などが JSON で標準入力に渡される。
UserPromptSubmit なら送った指示の本文が prompt に入り、PreToolUse ならツール名と引数が入る。
この JSON を読んで、何をするかを自分のスクリプトで決める。
終了コードで「通す・止める」が決まる
フックの返事は終了コードで伝える。
0 なら通常どおり進み、2 なら止められるイベントでは処理が止まる。
それ以外の番号は「止めないエラー」として扱われ、作業は続く。
止まるものはイベントごとに違う。
PreToolUse で 2 を返すとツールの実行が止まり、UserPromptSubmit で 2 を返すと指示そのものが Claude に届かない。
PostToolUse は、もうツールが動いたあとなので止められない。
SessionStart と PostCompact も止められず、エラーの文はユーザーに見えるだけになる。
もう1つ大事なのが、Claude に何かを伝える方法だ。
SessionStart と UserPromptSubmit などでは、フックが標準出力に書いた文が、Claude の見える文脈として足される。
JSON で返すなら hookSpecificOutput.additionalContext に入れる。
公式のガイドには、これを JSON の一番上の階層に置くと黙って無視される、とも書いてある。
僕が入れている6本
僕の ~/.claude/settings.json に入っているフックを、イベントごとに並べる。
どれも Python の小さなスクリプトか、1行の echo だ。
- SessionStart(1本目):作業フォルダの中から引き継ぎメモを探し、場所と最終更新日だけを知らせる
- SessionStart(2本目):作業の重さとモデルの選び方の目安を、毎回同じ文で渡す
- PostCompact:会話が圧縮されたときの要約を
.claude/handoff.mdに保存する - UserPromptSubmit(1本目):僕の指示に「やり直し」のサインがあれば、片づいたあとで学びを台帳に残すよう一言添える
- UserPromptSubmit(2本目):指示の重さを見て、モデルの切り替えを提案するよう一言添える
- PostModelSwitch:モデルを切り替えた記録を残す
PreToolUse で何かを止めるフックは入れていない。
止めたい操作は、フックではなく権限の設定(どのコマンドを許可するか)のほうで決めている。
公式のリファレンスにも、確実に許可・拒否したいならフックの条件ではなく権限の仕組みを使うように、という注意がある。
いちばん効いたのは、引き継ぎメモの「場所だけ」知らせるフック
前に、引き継ぎメモは「次のセッションの自分」に向けて書く、という話を書いた。
ただ、書いても新しいセッションが読まなければ意味がない。
そこで SessionStart のフックで、メモの在りかを毎回知らせるようにした。
中身は流さず、ファイルの場所と最終更新日だけを渡している。
スクリプトの冒頭にも「本文は注入しない(毎セッションのトークン消費を抑えるため)」と書いてある。
必要かどうかは Claude に判断させて、関係がありそうなら自分で開かせる。
今朝この記事を書くセッションを開いたときも、最初に届いたのはメモ6件の場所と日付だけだった。
対になるのが PostCompact のフックだ。
会話が長くなって圧縮されると、その要約を .claude/handoff.md に書き出す。
次のセッションでは SessionStart のフックがこのファイルを見つけるので、圧縮で消えかけた経緯をたどり直せる。
僕は、メモを書く仕組みと読ませる仕組みを別々のイベントに分けたのがよかったと思う。
作ってみて決めた3つのこと
1つ目は、失敗しても必ず 0 で終わらせることだ。
UserPromptSubmit のフックが 2 で終わると、こちらの指示が Claude に届かなくなる。
知らせるだけのフックで作業が止まっては困るので、僕のスクリプトは例外が起きても 0 で抜けるように書いている。
2つ目は、何もないときは何も出さないことだ。
足した文は、そのぶん毎回 Claude が読む量になる。
モデルの提案のフックも、重いとも軽いとも言えない指示のときは何も返さない。
3つ目は、フックの中身を必ず自分で読むことだ。
公式のリファレンスには、コマンドのフックは自分のユーザー権限そのままでシェルコマンドを実行する、とはっきり書いてある。
自分のアカウントで触れるファイルなら、読むのも消すのもできてしまう。
人のリポジトリを開くときは、.claude/settings.json にフックが入っていないかを先に見ておきたい。
まとめ
フックは、AIに「覚えておいて」と頼む代わりに、決まった時点で必ず動くプログラムを置く仕組みだ。
僕の6本は、どれも作業を止めずに一言知らせるだけになっている。
規約ファイルに書いても守られない日がある決まりごとは、フックに移せないかを一度考えてみてほしい。
関連する記事:引き継ぎメモの書き方|後任は、次のセッションの自分になる/Claude Codeのサブエージェントを25個作った結果|自動で走らせるのをやめた/Claude Codeのスクラッチパッドとは
出典
ほかにも書いています
受託・note・スタンプこういう仕組みを作る相談を受けています
毎日の更新・データ集め・集計の自動化/3万円〜収益がいくらだったか、どの施策が外れたか
note / 個人の視点で掘り下げていますスタンプラリーに挑戦する
行った場所は、現地チェックインで記録に残せます※受託の相談とnoteは、運営者が個人で受けている・書いているものです。
