👻

Claude Codeの新機能「Hooks」イベントトリガーとコマンド実行の解説

に公開

TL;DR 🚀

  • Hooksとは、Claude Codeの動作を特定のタイミングで実行されるシェルコマンドで拡張・カスタマイズする新機能。
  • ファイル編集後の自動フォーマットや、独自コーディング規約の強制(バリデーション)など、開発ワークフローを確定的に自動化できる。
  • 非常に強力な一方、ローカル環境でコマンドが直接実行されるため、セキュリティリスクを理解し、自己責任で安全に利用することが不可欠。

Hooksとは?

Claude Code Hooksとは、一言でいえば「Claude Codeの動作に割り込んで、ユーザーが定義した処理を自動で実行させる仕組み」です。

例えば、「Claudeがファイル(.ts)を編集し終わったら、自動でprettierを実行する」といったルールを定義できます。

これは、LLMに「フォーマットしてください」と曖昧にお願いするのとは全く異なります。Hooksはアプリケーションレベルのコードとして、設定されたルールを毎回確実に実行します。Git Hooksを使ったことがある方なら、コミット前に自動でリンターをかける、あの感覚に近いとイメージすると分かりやすいでしょう。

Hooksのメリット

  1. 確実性の向上: 「やってくれるといいな」という期待から、「必ず実行される」というルールに変わります。これにより、コード品質の一貫性が保たれます。
  2. 開発効率の劇的な向上: 「ファイル保存後にフォーマット」「特定のコマンドの利用を禁止」といった定型作業やレビューを自動化し、毎回プロンプトで指示する手間を省きます。
  3. 既存ワークフローとの統合: あなたやチームが普段から使っているLinter、Formatter、静的解析ツールなどを、Claude Codeの作業フローにシームレスに組み込めます。
  4. 強力なガバナンス: 「本番環境のファイルは編集禁止」「セキュリティ上問題のあるコマンドは実行させない」といった、プロジェクト固有のルールを強制できます。

具体的なユースケース

Hooksを使えば、アイデア次第で様々な自動化が可能です。

1. 自動コードフォーマット

ファイル編集後 (WriteやEditイベント後) に、prettierやgofmt、ruffなどを実行して自動でコードを整形します。

設定例 (.claude/settings.json):

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command",
            // Pythonファイルを編集したら自動でruffを実行し、整形と修正を行う
            "command": "ruff check . --fix"
          }
        ]
      }
    ]
}

2. カスタム通知

Claude Codeがユーザーの許可を待っている時などに、標準の通知ではなく、SlackやDesktop通知など、自分だけの通知方法にカスタマイズできます。
設定例 (.claude/settings.json):

{
  "hooks": {
    "Stop": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            // Macの音声読み上げ機能
            "command": "say -v Otoya \"Claude Code完了しました。\""
          }
        ]
      }
    ]
  }
}

3.操作ログの記録

コンプライアンスやデバッグ目的で、Claudeが実行したすべてのシェルコマンドをログファイルに記録します。
設定例 (.claude/settings.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit|MultiEdit",
        "hooks": [
          {
            "type": "command", 
            "command": "echo 'Hook fired' >> .claude-code-hooks.log"
          }
        ]
      }
    ]
  }
}

4. AIへの自動フィードバック (コーディング規約の強制)

Claudeがプロジェクトの規約に反するコードやコマンドを生成した場合、それをブロックし、「このコマンドではなく、こちらのコマンドを使ってください」と自動でフィードバックを与えられます。

5. カスタムパーミッション:

.envファイルやproductionディレクトリなど、触ってほしくない特定のファイルやディレクトリへの変更をブロックします。

Hooksの仕組みを深掘り

Hooksは いつ (Event) どのツールで (Matcher) 何をするか (Command) の3要素で構成されます。

実行のタイミング

フックは以下の4つの主要なイベントで実行されます。

イベント名 実行タイミング 主な用途
PreToolUse Claudeがツール(ファイル編集、コマンド実行など)を使おうとする 実行をブロック、内容を検証、フィードバック
PostToolUse ツールが正常に実行された コードフォーマット、後処理、ログ記録
Notification Claudeが通知を送るタイミング カスタム通知
Stop Claudeが一連の応答を完了したタイミング 処理を継続させる、最終チェック

特にPreToolUsePostToolUseが最もよく使われます。

実行の条件 (Matcher)

Matcherを使うと、特定のツールが使われたときだけフックが動くように絞り込めます。正規表現も使えるので、柔軟な指定が可能です。

  • Bash: シェルコマンド実行時
  • Write|Edit: ファイルの書き込み・編集時
  • mcp__github__.*: MCPのGitHub関連の全ツール実行時
    ※MCP ツールは、mcp__<server>__<tool> というパターンに従います。

デモ1: 実行コマンドをログに記録

実際に簡単なフックをデモをやってみます。ここでは、Claudeが実行したBashコマンドをログファイルに記録するフックを作成します。

前提条件: jq (コマンドライン用JSONプロセッサ) がインストールされていること。

  1. フック設定画面を開く
    Claude Codeの入力欄で /hooks と入力し、PreToolUse を選択します。

  2. Matcherを追加する
    + Add new matcher… を選択し、Bash と入力します。これでBashコマンドが実行される前のみフックが動くようになります。

  3. フックを追加する
    + Add new hook… を選択し、以下のコマンドを入力します。

    jq -r '"\(.tool_input.command) - \(.tool_input.description // "No description")"' >> ~/.claude/bash-command-log.txt
    

    (このコマンドは、フックから渡されるJSONデータからコマンドと説明を抽出し、ログファイルに追記しています)

  4. 設定を保存する
    保存場所として User settings を選びます。これでこのフックはプロジェクトを横断して有効になります。Escキーで設定を抜ければ登録完了です!

これで、ClaudeがBashコマンドを実行するたびに、その内容が ~/.claude/bash-command-log.txt に記録されるようになりました。

デモ2: HooksでAIに「ダメ出し」をする

Hooksの真骨頂は、ただコマンドを実行するだけでなく、Claudeの動作を制御できる点にあります。フックから返す終了コードJSON出力によって、Claudeにフィードバックを与えることができます。

  • 終了コード 0: 成功。通常通り処理を継続します。
  • 終了コード 2: ブロックPreToolUseの場合、ツールの実行を中止し、標準エラー出力をClaudeへのフィードバックとして渡します。
  • その他の終了コード: エラー。ユーザーにエラーを通知しますが、処理は継続します。

例えば、以下のようなPythonスクリプトをPreToolUseフックに設定したとします。

#!/usr/bin/env python3
import json, sys, re

# ... (中略: JSONを読み込む処理) ...

command = input_data.get("tool_input", {}).get("command", "")

# 'grep' を使おうとしたら...
if re.search(r"\bgrep\b", command):
    # 標準エラー出力にメッセージを出す
    print("プロジェクト規約: 'grep'の代わりに'rg'(ripgrep)を使用してください。", file=sys.stderr)
    # 終了コード'2'で終了し、コマンド実行をブロック
    sys.exit(2)

sys.exit(0)

このフックを設定しておくと、Claudeがgrepコマンドを使おうとした瞬間にフックがそれを検知し、実行をブロック。さらに「grepではなくrgを使ってください」というメッセージをClaudeにフィードバックします。Claudeはそのフィードバックを理解し、自律的にコマンドをrgに修正しようと試みます。

まさに、AIアシスタントを「しつける」ことができる強力な機能です。

【超重要】セキュリティに関する注意点

Hooksは非常に強力ですが、任意のシェルコマンドを自動実行するため、セキュリティリスクも伴います。

自己責任で利用してください:
あなたが設定したコマンドは、あなたのPC上であなたのユーザー権限で実行されます。悪意のある、あるいは不完全なコマンドは、データの損失やシステムの破損を引き起こす可能性があります。Anthropic社はHooksの使用によって生じたいかなる損害についても責任を負いません。

安全なフックを書くためのベストプラクティス:

  1. 入力を検証・無害化する: フックに渡されるデータを決して信用せず、必ず検証してください。
  2. 変数をクォートする: シェルスクリプトでは $VAR ではなく "$VAR" を使いましょう。
  3. パス トラバーサルを防ぐ: ファイルパスに .. が含まれていないかチェックしましょう。
  4. 絶対パスを使う: 実行するスクリプトやコマンドは、可能な限りフルパスで指定しましょう。
  5. 機密ファイルを避ける: .env.git/ ディレクトリ、秘密鍵などを扱う処理は慎重に行いましょう。

まとめ

Claude Code Hooksは、単なる便利機能にとどまりません。これは、AI開発アシスタントを自分のワークフローに完全に統合し、プログラマブルな開発環境へと昇華させるための鍵となります。

最初はファイルの自動フォーマットといった簡単なフックから始めて、徐々に独自のルールやワークフローを組み込んでいくのがおすすめです。

さあ、あなたもHooksを使って、自分だけの最強の開発アシスタントを育ててみませんか?

Discussion