Hooks(フック)は、Claude Codeが決まったタイミングで自動的に実行するコマンドです。
CLAUDE.md に書いた指示は守られないこともありますが、フックはClaudeの判断に関係なく必ず動きます。
- 書く場所:settings.json の hooks の中
- よく使うタイミング:ツールを使う前(PreToolUse)と使った後(PostToolUse)
- 止めたいとき:フックのコマンドを終了コード2で終わらせる
- 確認:対話中に /hooks で一覧を見る
この記事は、2026年9月29日時点の公式ドキュメントと、Windows上の Claude Code v2.1.284 で実際に動かした結果にもとづいています。
フックが動くタイミング
フックは、イベントと呼ばれるタイミングごとに設定します。
| イベント | 動くタイミング |
|---|---|
| SessionStart | セッションを始めたとき・再開したとき |
| UserPromptSubmit | こちらが指示を送った直後、Claudeが読む前 |
| PreToolUse | ツール(コマンドの実行やファイルの書き込み)を使う直前。止められる |
| PermissionRequest | ツールを使うのに許可が要るとき |
| PostToolUse | ツールを使い終えて成功したあと |
| PostToolUseFailure | ツールが失敗したあと |
| Notification | Claude Codeが通知を出すとき |
| SubagentStart・SubagentStop | サブエージェントが始まったとき・終わったとき |
| Stop | Claudeが返事を書き終えたとき |
ほかにも、圧縮の前や設定の変更時など、細かいイベントがあります。
settings.jsonの書き方
フックは、settings.json の hooks の中に、イベント名ごとに書きます。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{ "type": "command", "command": "python .claude/hooks/log_edit.py" }
]
}
]
}
}matcher は、どのツールのときに動かすかの指定です。
Write|Edit なら、ファイルを書いたときと直したときに動きます。
空にすると、そのイベントのたびに毎回動きます。
書くファイルは、自分の全プロジェクトならホームの .claude/settings.json、チームで共有するならプロジェクトの .claude/settings.json です。
すでに hooks がある場合は、丸ごと置き換えずに、イベント名を横に並べて足します。
フックに渡される情報
フックのコマンドには、イベントの中身がJSONで標準入力から渡されます。
{
"session_id": "abc123",
"cwd": "/Users/sarah/myproject",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test"
}
}上は公式ドキュメントに載っている例です。
tool_name で使うツールが、tool_input でその中身(コマンドやファイルのパス)が分かります。
例1:ファイルを書いたら記録する
Pythonで、書き込まれたファイルのパスを hooks.log に残すスクリプトを作りました。
import json, sys, datetime
data = json.load(sys.stdin)
path = data.get("tool_input", {}).get("file_path", "")
with open("hooks.log", "a", encoding="utf-8") as f:
f.write(f"{datetime.datetime.now():%H:%M:%S} {data['tool_name']} {path}\n")これを .claude/hooks/log_edit.py に置き、上の settings.json の PostToolUse から呼びます。
Claudeに hello.txt を作ってもらうと、hooks.log に次の1行が増えました。
13:24:17 Write C:\demo\hooks-demo\hello.txt同じ形で、ファイルを書いたあとに整形ツールやテストを動かせます。
例2:危ないコマンドを止める
PreToolUse のフックが終了コード2で終わると、そのツールの実行は止められます。
そのとき標準エラーに書いた文は、理由としてClaudeに伝わります。
import json, sys
data = json.load(sys.stdin)
cmd = data.get("tool_input", {}).get("command", "")
if "rm " in cmd:
print("rm は使わないでください。消すファイルは人が確かめます。", file=sys.stderr)
sys.exit(2){
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "python .claude/hooks/block_rm.py" }
]
}
]
}
}Claudeに「rm hello.txt で消して」と頼んだ結果です。
消せませんでした — `.claude/hooks/block_rm.py` の PreToolUse フックが `rm` をブロックしたためです(「rm は使わないでください。消すファイルは人が確かめます。」)。`hello.txt` は残っています。コマンドの実行を許可していても、フックが先に止めています。
文字列で見ているだけなので、実際に使うときは止めたいコマンドをもう少し丁寧に判定します。
終了コードとJSONの返し方
| 終わり方 | どうなるか |
|---|---|
| 終了コード0 | そのまま進む |
| 終了コード2 | その操作を止める。標準エラーの文が理由として伝わる(止められないイベントもある) |
| それ以外の終了コード | 止めずに進み、フックのエラーとして表示される |
もっと細かく決めたいときは、終了コード0で終わり、JSONを標準出力に書きます。
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "grep ではなく rg を使ってください"
}
}permissionDecision は、deny(止める)、allow(確認を省く)、ask(いつもどおり確認する)から選びます。
終了コード2とJSONは、1つのフックでどちらか片方だけを使います。
Windowsで入力待ちを知らせる
Claudeがこちらの入力を待っているときに知らせる例です。
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "powershell.exe -Command \"[System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); [System.Windows.Forms.MessageBox]::Show('Claude Code needs your attention', 'Claude Code')\""
}
]
}
]
}
}これは画面の隅の通知ではなくダイアログを開くので、ターミナルの後ろに隠れることがあります。
matcher を permission_prompt にすると、許可の確認で待っているときだけに絞れます。
動かないときの確かめ方
- 対話中に /hooks を開き、イベントの横に設定の数が出ているかを見る
- settings.json がJSONとして正しいか(末尾のカンマなど)を見る
- フックのコマンドをターミナルで単独で実行して動くかを見る
- claude –debug で起動し、フックの標準エラーの全文を見る
フックは、自分のPCの権限でそのままコマンドを実行します。
ほかの人が書いたプロジェクトの settings.json を使うときは、中身を読んでから信頼してください。
settings.json の置き場所と優先順位は、Claude Codeのsettings.jsonの場所と優先順位で紹介しています。
まとめ
- フックは、Claudeの判断に関係なく決まったタイミングで必ず動く
- settings.json の hooks に、イベント名・matcher・コマンドを書く
- イベントの中身はJSONで標準入力から受け取る
- PreToolUse で終了コード2を返すと、その操作を止められる
- 動かないときは /hooks と claude –debug で確かめる
参考:Claude Code公式ドキュメント「Automate actions with hooks」(2026年9月29日に確認)。
