Claude Code

Claude Code hooksの使い方|仕組みから実践まで詳しく解説!

本記事にはプロモーション(広告)が含まる場合があります。

Claude Code hooksって、何ができるの?
hooks を設定してClaude Codeの作業を自動化したい!

Claude Codeを毎日使っていると、気になることが出てきます。

「ファイルを編集するたびに自分でフォーマッターを実行しないといけない」
「Claudeが長い作業を終えたのに気づかなかった」
「危険なコマンドを実行されそうになってヒヤッとした」

そこで使いたいのがClaude Code hooksです。hooksはClaude Codeのライフサイクルの特定タイミングで自動実行されるコマンドの仕組みで、設定ファイルに書いておくだけで繰り返し処理を自動化できます。

CLAUDE.mdが「Claudeへの指示」なら、hooksは「システムが必ず実行する自動処理の保証」です。

この記事でわかること

  • Claude Code hooksとは何か、何が自動化できるか
  • settings.jsonへの設定手順(3ステップ)
  • 主要イベント5つの使い分けと発火タイミング
  • 今すぐコピペできる実践レシピ3選と注意点
著者について

🧑‍💻

Web Engineer & AI Developer

ITエンジニア歴15年超。設計・実装・運用まで一気通貫でこなすエンジニア。最近はAIエージェント開発・今後のキャリアを軸に発信中。

AIエージェント開発
フルスタックエンジニア
インフラ構築・運用

Claude Code hooksとは?自動化できる3つのこと

「hooksって難しそう」と思う方も多いと思います。でも仕組み自体はシンプルです。「Claude Codeが〇〇をするときに、自動的に△△を実行する」——それだけです。難しいのは最初の設定ファイルの書き方だけで、構造がわかればすぐ使えます。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksでできること

  • ワークフローを自動で動かす
  • 危険な操作にガードレールをかける
  • ログや通知で作業を見える化する

ワークフローを自動で動かす

hooksの最も基本的な使い方は、繰り返し作業の自動化です。たとえば「Claude Codeがファイルを編集したら、自動でprettierを実行する」という設定が数行のJSONで書けます。

毎回手動でフォーマッターを実行していた手間がゼロになります。私も最初にこれを設定したとき、「Claude Codeがこんなに便利になるのか」と素直に驚きました。他にも「セッション開始時にGitブランチ情報をコンテキストに注入する」「実行ログを自動保存する」など、アイデア次第でいくらでも応用できます。

ポイント

hooksはCLAUDE.mdと役割が違います。CLAUDE.mdはClaudeが読んで判断する「指示書」hooksはシステムが自動実行する「決定論的な処理」です。「必ず実行させたい処理」はhooksで、「方針を伝えたい内容」はCLAUDE.mdで、と使い分けましょう。

危険な操作にガードレールをかける

hooksの重要な役割として、LLMの判断に頼らず危険な操作を確実にブロックするという使い方があります。

Claude Codeに「慎重に操作して」と指示しても、LLMは必ずしも毎回同じ判断をするとは限りません。でもhooksでブロック設定を書いておけば、rm -rf.envファイルの書き換えを決定論的に止められます。チームのルールをコード(.claude/settings.json)に書いてGit管理すれば、全員に同じガードレールが適用されます。

さらに、hooksによるブロックはbypassPermissionsモードでも機能します。どんな設定でもバイパスできないガードレールを作れる点が、CLAUDE.mdやpermissions設定との大きな違いです。

ログや通知で作業を見える化する

Claude Codeに長時間タスクを任せていると、「いつ終わったか気づかなかった」という体験が誰でも一度はあると思います。Notificationイベントを使えば、Claudeが入力待ちになったタイミングでデスクトップ通知を飛ばせます。

他にも「実行されたBashコマンドをすべてログファイルに記録する」設定も簡単です。後からセッションを振り返るとき、「Claudeがどのコマンドを実行したか」が一覧で確認できて便利です。

Claude Code hooksの使い方を3ステップで解説

「実際どうやって設定するの?」という疑問に答えます。Claude Code hooksの設定は、設定ファイルの場所さえ把握すれば、基本の設定は10分かかりません。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksの設定手順

  • 【ステップ1】設定ファイルを開く(場所の選び方)
  • 【ステップ2】hooksブロックをJSONで書く
  • 【ステップ3】/hooksコマンドで動作を確認する
Claude Code hooksの3ステップ設定フロー

【ステップ1】設定ファイルを開く(場所の選び方)

hooksはJSON形式の設定ファイル(settings.json)に記述します。どこに置くかによって「誰に適用されるか」が変わります。用途に合わせて選びましょう。

ファイルの場所 適用範囲 Gitコミット 用途
~/.claude/settings.json 全プロジェクト共通 しない 通知・個人の好み
.claude/settings.json そのプロジェクト できる チーム共有のルール
.claude/settings.local.json そのプロジェクト しない(gitignore) 個人の実験用

最初の練習なら~/.claude/settings.jsonがおすすめです。全プロジェクトに適用されるので一度設定すれば使い回せます。ファイルがまだない場合は新規作成してください。

すでに他の設定(permissions等)が書かれている場合は、ファイル全体を書き換えず既存の内容に"hooks"キーを追加する形で編集してください。

【ステップ2】hooksブロックをJSONで書く

設定ファイルを開いたら、hooksブロックを追加します。最初に動作確認しやすい「完了通知hook」を例にとります。macOSで「Claudeが入力待ちになったらデスクトップ通知を出す」最小設定はこうなります:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Linuxの場合はosascriptの部分をnotify-send 'Claude Code' 'Claude Code needs your attention'に置き換えてください。

すでにsettings.jsonに他のキーが存在する場合、hooksキーを兄弟として追加します:

{
  "permissions": { ... },
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          { "type": "command", "command": "osascript -e '...'" }
        ]
      }
    ]
  }
}

注意点

settings.jsonは末尾カンマとコメントが使えない標準JSON形式です。保存後に構文エラーがあるとhooksが一切読み込まれません。書いたら必ずJSON Lintなどで構文チェックしてから保存する習慣をつけてください。

【ステップ3】/hooksコマンドで動作を確認する

設定ファイルを保存したら、Claude Code上で/hooksと入力してください。登録されているhooksの一覧がイベント別に表示されます。設定したhookがリストに表示されていれば、読み込みは成功しています。

表示されない場合は以下をチェックしてください:

  • JSONの構文エラー(末尾カンマ・括弧の閉じ忘れ・ダブルクォートの不一致)
  • ファイルの保存場所が正しいか(パスのスペルミス)
  • イベント名のスペルが正しいか(PostToolUsePostTooluseにするなど大文字小文字の違い)

確認できたら実際に作業をしてhookが発火するかテストします。macOSで通知が表示されない場合は「システム設定 > 通知」でScript Editorへの通知権限をオンにしてください。

ポイント

/hooksメニューは読み取り専用です。hookの追加・変更・削除は設定JSONを直接編集するか、「settings.jsonのhooksを変更して」とClaude Codeに依頼する方法が使えます。

Claude Code hooksのJSON構造と書き方

基本の設定は書けても「matcherって何?」「exit codeをどう使うの?」と迷うことがあります。Claude Code hooksのJSONには決まった構造があるので、ここで整理しておきましょう。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksのJSON構造

  • イベント・matcher・commandの3層構造
  • exit codeで動作を制御する
  • JSON出力でより細かく制御する

イベント・matcher・commandの3層構造

hooksの設定はネストした3層構造になっています。最初は「どの括弧が何を意味するか」でつまずきやすいですが、構造がわかれば読めます。

{
  "hooks": {
    "PostToolUse": [        // ① イベント名:何のタイミングで発火するか
      {
        "matcher": "Edit|Write",  // ② matcher:どのツール呼び出し時か
        "hooks": [
          {
            "type": "command",     // ③ hookの種類(commandが基本)
            "command": "prettier --write ..."  // ④ 実行するコマンド
          }
        ]
      }
    ]
  }
}

matcherはそのhookを「どの操作のときに発火させるか」を絞るフィルターです。よく使うmatcherパターンはこちらです:

  • "Bash":Bashツール呼び出し時のみ
  • "Edit|Write":EditまたはWrite時(パイプ区切りでOR指定)
  • "*"または空文字:すべての場合
  • "mcp__github__.*":GitHubのMCPツール(正規表現も使える)

matcherを絞ることで「本当に必要なときだけhookを動かす」ことができます。typeは基本的に"command"(シェルコマンド実行)を使います。他にも"http"(HTTPエンドポイントへのPOST)や"prompt"(LLMによる判断)が使えます。

exit codeで動作を制御する

hookスクリプトの終了コード(exit code)が、Claude Codeへの「返答」になります。シンプルな使い方ならこの3つを覚えておけば十分です。

exit code 意味 動作
0 成功 処理は続行。stdoutの内容がClaudeのコンテキストに追加される
2 ブロック ツール実行・処理を中止。stderrの内容がClaudeへのフィードバックになる
その他 エラー 処理は続行されるが、トランスクリプトにエラーが表示される

exit 2でブロックするときは、stderrに理由を書いてください。その内容がClaudeにフィードバックとして渡るので、Claudeが状況を理解して別の方法を試みてくれます。以下はrm -rfを検知してブロックするシンプルな例です:

#!/bin/bash
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

if echo "$COMMAND" | grep -qE "rm -rf"; then
  echo "rm -rfは禁止されています。安全な削除方法を使ってください。" >&2
  exit 2
fi

exit 0

JSON出力でより細かく制御する

exit 2だけでなく、stdoutにJSONを出力することでより詳細な制御ができます。特にPreToolUseでは使い勝手がよいです。

「ブロックしてその理由をClaudeに伝える」場合、stdoutに以下のJSONを出力してexit 0を返します:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "grepよりrgの方が高速です。rg を使ってください"
  }
}

permissionDecisionに指定できる値は"deny"(拒否)、"allow"(承認・インタラクティブ確認をスキップ)、"ask"(ユーザーに確認を促す)の3つです。

注意点

exit 2とJSON出力を混在させないでください。exit 2のときはJSONが無視されます。ブロックにはexit 2(stderrに理由)を使うか、exit 0でJSON出力するか、どちらかに統一しましょう。

Claude Code hooksで使える主要イベント5つ

Claude Code hooksは20種類以上のイベントに対応しています。最初から全部覚える必要はありません。よく使う5つを押さえておくだけで、日常的な自動化はほぼカバーできます。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksの主要イベント

  • PreToolUse(ツール実行前に割り込む)
  • PostToolUse(ツール実行後に処理する)
  • Stop(Claude応答完了時に動かす)
  • SessionStart(セッション開始時に準備する)
  • Notification(通知タイミングをカスタムする)
Claude Code hooksのイベント発火タイミング図

PreToolUse(ツール実行前に割り込む)

Claude Codeがツールを実行しようとするとき、その直前に発火するイベントです。exit 2を返せばツール実行をブロックできるため、ガードレールとして最も強力です。matcherに"Bash"を指定すればBashコマンド実行前だけ、"Edit|Write"なら編集・書き込み前だけに絞れます。

「危険なコマンドを止める」「特定ファイルの書き換えを禁止する」「権限が必要な操作を自動承認する」などの使い方がメインです。

ポイント

PreToolUseはbypassPermissionsモードでも機能します。Claude Codeのどんな設定でもhooksのブロックはバイパスできません。これが他の権限設定との一番の違いです。

PostToolUse(ツール実行後に処理する)

ツールが正常に完了した直後に発火するイベントです。「実行後の後始末」に使います。自動フォーマット、ログ記録、出力の検証などが典型的なユースケースです。

重要な注意点として、PostToolUseはツールが動いた後なので「ロールバック」はできません。「止めたい」ならPreToolUseで事前に止める必要があります。matcherに"Edit|Write"を設定すれば「ファイル編集のたびにprettierを実行」のような自動化が作れます。

Stop(Claude応答完了時に動かす)

Claudeがそのターンの応答を終えようとするときに発火します。「完了通知」や「やり残し確認」に使うイベントです。

exit 2を返すと「まだ作業が残っています」というフィードバックをClaudeに渡せるので、「テストが全部通るまで止まらない」という設定も作れます。ただし8回連続でブロックすると強制的に終了するため、無限ループ防止の仕組みが必要です(注意点の節で詳しく解説します)。

SessionStart(セッション開始時に準備する)

セッションが始まったとき、または/clearコマンドでリセットされたときに発火します。stdoutに書いたテキストが自動でClaudeのコンテキストに追加されるため、「セッション開始時に毎回読ませたい情報」を注入するのに使えます。

matcher: "compact"を設定すると、Claude Codeのコンテキスト圧縮後だけに発火します。「圧縮で失われた重要なルールやコンテキストを再注入する」という使い方です。私はこれを使って「このプロジェクトはBunを使う・npmは使わない」というルールを圧縮後に再注入しています。

Notification(通知タイミングをカスタムする)

Claude Codeが通知を送信するときに発火します。主に「入力待ち」や「権限確認」のタイミングです。macOSならosascript、Linuxならnotify-sendでデスクトップ通知が作れます。

matcherを空にすると全通知タイミングで発火。"idle_prompt"にすると「作業完了してユーザーの入力を待っているとき」だけに絞れます。長時間タスクの離席中管理に特に便利なイベントです。

Claude Code hooksの実践レシピ3選

仕組みがわかったところで、Claude Code hooksをすぐ使えるレシピを3つ紹介します。コピペして自分の環境に合わせて調整してみてください。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksの実践レシピ

  • 【レシピ1】コード編集後に自動でフォーマット
  • 【レシピ2】危険なBashコマンドをブロック
  • 【レシピ3】完了時にデスクトップ通知

【レシピ1】コード編集後に自動でフォーマット

Claude Codeがファイルを編集するたびにprettierを自動実行するレシピです。TypeScript・JavaScript・CSSなどのフォーマット一貫性を保てます。jqコマンドが必要です(macOS: brew install jq、Ubuntu: apt-get install jq)。

.claude/settings.json(プロジェクト固有)または~/.claude/settings.json(全プロジェクト共通)に追加してください:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
          }
        ]
      }
    ]
  }
}

jq -r '.tool_input.file_path'でhookに渡されたJSON(stdinで受け取ります)からファイルパスを取り出して、prettierに渡しています。プロジェクトにprettierが入っていれば、ファイル保存のたびにスタイルが整います。

ポイント

prettierの代わりにeslint --fixgofmtなど、他のフォーマッターでも同じ仕組みが使えます。言語に合わせてコマンドを変えてください。

【レシピ2】危険なBashコマンドをブロック

rm -rf--forceオプションなど危険な操作をブロックするレシピです。プロジェクトの.claude/設定に入れておくとチームの安全ネットになります。

まずスクリプトファイルを作成します:

#!/bin/bash
# .claude/hooks/guard.sh

INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')

# ブロック対象のパターン
if echo "$COMMAND" | grep -qE "rm -rf|git push.*-f|git push.*--force"; then
  echo "危険なコマンドがブロックされました。" >&2
  echo "安全な代替方法を検討してください。" >&2
  exit 2
fi

exit 0

実行権限を付与します:

chmod +x .claude/hooks/guard.sh

.claude/settings.jsonに登録します:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/guard.sh"
          }
        ]
      }
    ]
  }
}

$CLAUDE_PROJECT_DIRはプロジェクトルートへのパスに自動で置き換わります。スクリプトへのパスに空白が含まれる場合に備えて、必ずダブルクォートで囲みましょう。

【レシピ3】完了時にデスクトップ通知

Claudeが入力待ちになったとき(作業完了時など)にデスクトップ通知を飛ばすレシピです。長時間タスクを他の作業と並行できるようになります。~/.claude/settings.jsonに追加すれば全プロジェクトで使えます。

macOSの場合:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
          }
        ]
      }
    ]
  }
}

Linuxの場合:

{
  "hooks": {
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "notify-send 'Claude Code' 'Claude Code needs your attention'"
          }
        ]
      }
    ]
  }
}

macOSで通知が表示されない場合は、ターミナルで一度osascript -e 'display notification "test"'を実行してから、「システム設定 > 通知」でScript Editorへの通知権限をオンにしてください。

Claude Code hooksを使うときの注意点3つ

Claude Code hooksは便利ですが、実際に使うと気をつけないとはまるポイントがあります。事前に知っておくと最初の失敗を減らせます。私自身がやらかした経験も含めて紹介します。

ここでは、以下の内容について詳しく解説します。

Claude Code hooksの注意点

  • PostToolUseではロールバックできない
  • exit 2を誤用するとループが起きる
  • チーム共有と個人設定を分ける

PostToolUseではロールバックできない

PostToolUseはツールが完了した後に発火するため、「やっぱりキャンセル」ができません。ファイルはすでに変更されているし、コマンドはすでに実行されています。

私も最初、「PostToolUseでブロックすれば後から止められる」と思っていましたが、それは誤りでした。ブロックしたいならPreToolUseで事前に止める必要があります。

役割を整理するとこうなります:

  • ブロック(止める):PreToolUseで行う
  • 後処理(実行後に何かする):PostToolUseで行う

この役割分担を意識するだけで、hookの設計がグッとシンプルになります。

exit 2を誤用するとループが起きる

Stopイベントでexit 2を返し続けると、Claudeは「まだ作業が残っている」と判断して作業を続けます。しかし8回連続でブロックすると強制的に終了します。

これを防ぐには、stop_hook_activeフィールドを確認する処理をStopフックのスクリプトに入れます:

#!/bin/bash
INPUT=$(cat)

# Stopフックのループ防止(8回目で強制通過)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
  exit 0
fi

# 通常の確認処理をここに書く
# ...

exit 0

stop_hook_activetrueのときはexit 0で通過させることで、無限ループを防げます。このフィールドのチェックを入れ忘れると、Stopフックを使うたびに「8回ループして強制終了」という動作になります。これは正直、最初に気づかなくてかなりハマりました。

チーム共有と個人設定を分ける

hooksを設定するとき、「どのファイルに書くか」を意識しておかないと、後でチームメンバーとの摩擦が生まれます。

たとえば「自分はprettierを使うが、チームメンバーはbiomeを使っている」という場合、自動フォーマットのhookを.claude/settings.jsonにコミットすると他のメンバーのワークフローを壊してしまいます。

ポイント

コミット対象(.claude/settings.json)には「チームで守るべきガードレール」のみ書く。個人の通知・フォーマットの好みは~/.claude/settings.json.claude/settings.local.jsonに分けましょう。

具体的な使い分けの目安はこうなります:

  • コミットしてよい:rm -rfのブロック、.envの保護、git force pushの禁止など全員に適用すべきルール
  • 個人設定にする:prettierの自動フォーマット、デスクトップ通知、個人のログ記録など

よくある質問

Q:Claude Code hooksとCLAUDE.mdの違いは何ですか?

A:CLAUDE.mdはClaudeへの「指示書」で、Claude自身が読んで判断します。一方hooksはClaude Codeのシステムが自動実行する「決定論的な処理」で、LLMの判断を介しません。「毎回確実に実行したい処理」はhooks、「Claudeに方針を伝えたい内容」はCLAUDE.md、と使い分けるのが基本です。

Q:hooks設定が効いているか確認する方法は?

A:Claude Code上で/hooksと入力すると、登録されているhooksの一覧が確認できます。それでも動かない場合はclaude --debug-file /tmp/claude.logでClaudeを起動してデバッグログを確認してください。どのhookがマッチしたか、終了コードやstderrの内容まで詳細に記録されています。

Q:Claude Code hooksはどのプランから使えますか?

A:Claude Code自体の利用には最低でもProプランへの加入が必要です(無料プランでは利用不可)。hooksはClaude Codeの設定機能なので、Claude Codeが使えるプランであれば追加料金なしで利用できます。Claude Codeの始め方についてはClaude Code 使い方|初心者向け3ステップ入門を参考にしてください。

まとめ

Claude Code hooksは「設定ファイルにJSONを書くだけで、決まった処理を自動化できる」仕組みです。難しく見えますが、最初の通知hookを1つ動かすだけでも「こういうことか」とすぐに理解できます。

設定の進め方としては、まずNotificationイベントから試してみるのがおすすめです。次にPostToolUseの自動フォーマット、その次にPreToolUseのガードレールと、少しずつ試していきましょう。一気に全部設定しようとするより、1つずつ動作確認しながら積み上げる方が確実です。

hooksを使いこなせると、Claude Codeが単なる「便利なAIアシスタント」から「自分のワークフローに組み込まれた自動化ツール」に変わります。あなたのワークフローで一番繰り返している手作業は何でしょうか?そこから自動化を始めてみてください。

Claude Codeの活用方法をさらに深掘りしたい方は、Claude Code Skillsの使い方|3ステップで迷わず始めようClaude Codeでのターミナルの使い方|苦手意識をなくそうも参考にしてみてください。