ankuro.dev
← ブログ一覧に戻る
【Claude Code中級編 #2】Hooksとは何か——Claude Codeの動作に割り込む
2026-03-21#Claude Code#AI#Hooks#自動化

【Claude Code中級編 #2】Hooksとは何か——Claude Codeの動作に割り込む

Claude Codeを使っていると、こんな場面が出てくる。

「ファイルを編集するたびにlintを走らせたい」「デプロイコマンドを実行したら通知を飛ばしたい」「特定のコマンドだけは確認なしに実行してほしくない」

CLAUDE.mdに書けば?と思うかもしれないが、CLAUDE.mdはあくまでClaudeへの「お願い」。Claudeが忘れたり無視したりする可能性がある。

Hooksは違う。Claude Codeの動作にシェルスクリプトで直接割り込む仕組みなので、必ず実行される。


Hooksの仕組み

HooksはClaude Codeがツールを実行するタイミングに、シェルコマンドを差し込める機能。

4種類のタイミングがある。

Hook 実行タイミング
PreToolUse Claude Codeがツールを実行する直前
PostToolUse Claude Codeがツールを実行した直後
Notification Claude Codeが通知を送るとき
Stop Claude Codeがレスポンスを終了するとき

最もよく使うのは PreToolUsePostToolUse

PreToolUse — ツール実行前に割り込めるので「このコマンドは実行前に確認する」「特定ファイルへの書き込みをブロックする」といった用途に使える。exitコードが0以外だとツールの実行がキャンセルされる。

PostToolUse — ツール実行後に走るので「ファイルを保存したらlintを実行」「コマンドが終わったらSlackに通知」といった後処理に使える。


設定ファイルの書き方

Hooksは settings.json に書く。

設定ファイルの場所:

スコープ パス
プロジェクト限定 .claude/settings.json
全プロジェクト共通 ~/.claude/settings.json

基本的な構造:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo 'ファイルを保存しました'"
          }
        ]
      }
    ]
  }
}

matcher — どのツールが実行されたときに反応するかを指定する。Write(ファイル書き込み)・Bash(シェル実行)・Edit(ファイル編集)など、Claude Codeのツール名を指定する。空文字列 "" にするとすべてのツールに反応する。

command — 実行するシェルコマンド。bashで実行されるので、シェルスクリプトの構文がそのまま使える。


最小構成の実装例

まずは「ファイルを保存したらログに記録する」だけのシンプルなHookを作ってみる。

.claude/settings.json

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write",
        "hooks": [
          {
            "type": "command",
            "command": "echo \"$(date '+%Y-%m-%d %H:%M:%S') - ファイルを書き込みました\" >> ~/.claude/hook-log.txt"
          }
        ]
      }
    ]
  }
}

これを設定してからClaude Codeにファイルを書かせると、 ~/.claude/hook-log.txt に記録が積み上がっていく。

2026-03-21 10:23:41 - ファイルを書き込みました
2026-03-21 10:24:15 - ファイルを書き込みました

地味だが、これが動けばHooksの仕組みを理解したと言える。Hooksは「何か起きたらコマンドを実行する」——それだけの仕組み。複雑に考えなくていい。


PreToolUseで実行をブロックする

もう一つ、PreToolUse でツールの実行をキャンセルする例。

rm -rf が含まれているコマンドは実行させない」というHook:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "if echo \"$CLAUDE_TOOL_INPUT\" | grep -q 'rm -rf'; then echo 'rm -rfは禁止されています' >&2; exit 1; fi"
          }
        ]
      }
    ]
  }
}

$CLAUDE_TOOL_INPUT はHookに渡される環境変数で、ツールへの入力内容が入っている。これをgrepして危険なコマンドを検出し、exit 1 で実行をキャンセルする。

CLAUDE.mdに「rm -rfは使わないで」と書いても従わない場面が出てくる。Hooksで強制すれば確実。


Hooksでできること・できないこと

できること

  • ツール実行前後にシェルコマンドを走らせる
  • exitコード1でツール実行をキャンセルする(PreToolUseのみ)
  • 環境変数 $CLAUDE_TOOL_INPUT でツールへの入力を受け取る
  • ログ・通知・lint・フォーマットなどの自動化

できないこと

  • Claudeの返答内容を変更する
  • Hookの中からClaude Codeに返答を投げる
  • 複数ツールをまたいだ条件分岐(1つのHookは1つのトリガーに対応)

Hooksはあくまで「ツールの実行タイミングに割り込むもの」。Claudeの思考プロセスに介入する機能ではない。


まとめ

  • HooksはClaude Codeのツール実行タイミングにシェルコマンドを差し込む仕組み
  • PreToolUse(実行前)と PostToolUse(実行後)が主な用途
  • settings.jsonmatchercommand を書くだけで動く
  • CLAUDE.mdの「お願い」と違い、必ず実行される

次回は実用的なHook実装例——lint自動実行・Slack通知・ログ収集——を具体的なコードで紹介する。


第1回:CLAUDE.mdを育てる——チームで使える指示書の作り方第3回:Hooksで自動化する——保存前バリデーション・通知・ログ