Claude Code Skills vs Hooks 使い分けガイド|SKILL.md・PreToolUse・PostToolUse 完全解説

この記事のポイント
Claude Code の Skills は Claude が読んで当てはめる手順、Hooks はイベントで必ず動く処理です。2026年10月時点(v2.1.302)の公式仕様で、SKILL.md の全項目、33種類のフックイベント、PreToolUse・PostToolUse・UserPromptSubmit の実装例と安全設定を解説します。
Skills は Claude が読んで当てはめる「手順・知識」、Hooks は Claude の判断を通さずイベントで必ず動く「処理」だ。公式ドキュメントは「Claude Code はライフサイクルのイベントでフックを実行し、スキルは Claude が当てはめるためにコンテキストへ読み込む」と一文で区別している。毎回かならず起こしたい動作や、絶対に通したくない操作は Hooks に、Claude に考えて当てはめてほしい手順は Skills に置く。
2026年10月時点(最新版 v2.1.302、10月16日公開)の公式ドキュメントと changelog をもとに、SKILL.md の全項目、33種類のフックイベント、PreToolUse・PostToolUse・UserPromptSubmit の JSON と実装例、2026年6月以降の仕様変更、チームで入れるときの安全設定までを日本語で整理した。Claude Code を業務の開発フローに組み込みたいエンジニアや、チームの設定方針を決めるテックリード向けの内容だ。Claude Code そのものの概要は「Claude Codeとは?できること・料金・使い方・他ツール比較」にまとめている。

Skills・Hooks・CLAUDE.mdの三者比較
三者は「いつ読み込まれる(動く)か」と「強制力があるか」で分かれる。CLAUDE.md と Skills は Claude へのお願いで、Hooks(command 系)だけが強制になる。

比較項目 | CLAUDE.md | Skills(SKILL.md) | Hooks(command / http / mcp_tool) | Hooks(prompt / agent) | Claude Mods |
|---|---|---|---|---|---|
きっかけ | セッション開始時に常に読み込み |
| ライフサイクルのイベント | ライフサイクルのイベント | Claude Code 内部のイベント |
結果の安定性 | Claude の解釈次第 | Claude の解釈次第 | 毎回同じ(決定論的) | モデルが判断するのでぶれる | コード次第 |
コンテキスト消費 | 毎リクエスト全文 | 説明文は毎リクエスト、本文は使うときだけ | ゼロ(出力を返したときだけ) | ゼロ(同上)。ただし評価にモデル利用量を使う | 書き方次第 |
操作を止められるか | 止められない | 止められない | PreToolUse などで止められる | 止められる | 止められる・書き換えられる |
書く言語 | Markdown | YAML+Markdown | シェル・HTTP・MCP | 自然言語のプロンプト | JavaScript / TypeScript |
主な置き場所 |
|
|
|
| プラグイン内 |
Anthropic は公式ブログ「Steering Claude Code」(2026年6月18日)で、「本当のガードレールは決定論的であるべきで、強制の手段はフックと権限設定だ」と書いている。CLAUDE.md やスキルに「.env を編集しない」と書いても、それはお願いであって保証ではない。編集そのものを止める PreToolUse フックが強制になる。
一方で、両者は対立するものではない。公式の機能比較ページでも、lint を走らせる PostToolUse フックが結果を Claude に返し、/fix-lint スキルが直し方を教える、という併用例を挙げている。
「Claude に知ってほしい・考えて当てはめてほしい」のか、「毎回かならず起こしたい・止めたい」のか。この問いが Skills と Hooks を選ぶいちばん短い判断基準になる。
公式が示す「何をいつ足すか」
公式ドキュメント(features-overview)は、設定は一度に作らず、困ったことが起きた時点で足していく順序を勧めている。
こうなったら | 足すもの |
|---|---|
Claude が同じ慣習・コマンドを2回間違えた | CLAUDE.md |
毎回同じプロンプトを打ってタスクを始めている | ユーザーが呼ぶスキル |
同じ手順書を3回目に貼り付けた | スキル |
頼まなくても毎回何かを起こしたい | フック |
別のリポジトリにも同じ設定が要る | プラグイン |
重なったときの扱いも違う。スキルは同名なら上書き(managed(組織) > 個人 > プロジェクト)、フックはマージされ、どの設定ファイルに書いたものも該当イベントで全部動く。
CLAUDE.md の書き方は「CLAUDE.md 書き方ベストプラクティス」で解説している。なお Anthropic の公式ブログは、CLAUDE.md を200行以内に収めるよう勧めている。
Skills(SKILL.md)の仕組みと活用
Skills は、SKILL.md(YAML フロントマター+Markdown 本文)を置いたディレクトリだ。/skill-name で呼ぶか、Claude が関係するタスクだと判断したときに読み込む。2026年10月時点では Agent Skills オープン標準 に準拠し、Claude Code 独自の拡張項目を持つ。
旧来の .claude/commands/ のカスタムコマンドはスキルに統合された。既存の .claude/commands/deploy.md もそのまま動き、.claude/skills/deploy/SKILL.md と同じように使える。

出典: Anthropic 公式サイト
SKILL.md の作り方を一から知りたい場合は「Claude Code Skills 使い方完全ガイド」が詳しい。ここでは、Hooks と比べるときに押さえておきたい仕様に絞る。
ディレクトリ構造とスコープ
my-skill/
├── SKILL.md # メインの指示(必須)
├── reference.md # 詳しい資料。必要なときだけ読み込まれる(任意)
├── examples/
│ └── sample.md # 期待する出力の例(任意)
└── scripts/
└── validate.sh # 実行専用。中身はコンテキストに読み込まれない(任意)保存する場所で、使える範囲が変わる。
場所 | パス | 使える範囲 |
|---|---|---|
Enterprise | managed settings で指定するディレクトリ | 組織の全ユーザー |
Personal |
| 自分の全プロジェクト |
Project |
| そのリポジトリ |
Nested |
| そのサブディレクトリ。そこのファイルを初めて触ったときに読み込まれる |
追加ディレクトリ |
| そのセッション |
Plugin |
| プラグイン有効時。 |
同名のスキルがあると Enterprise > Personal > Project の順で優先される。プラグインのスキルは名前空間が付くので衝突しない。プラグインでの配布は「Agent Plugins 1.0.0とは?」も参考になる。
SKILL.mdフロントマター全フィールドリファレンス(2026年10月現在)
項目はすべて任意で、description だけは書くことが推奨されている。知らない項目を書いてもエラーにはならず、無視される。
---
name: draft-article # 「/」メニューに出る名前。省略時はディレクトリ名
description: | # 何をするか・いつ使うか。自動で読み込むかの判断に使われる
記事の下書きを作るとき。見出し案と本文を書く
when_to_use: | # 追加の発動条件(description と合わせて1,536文字まで)
ユーザーが「下書きして」「記事を書いて」と言ったとき
argument-hint: "[topic]" # 補完時に出るヒント
arguments: topic audience # $topic, $audience で参照できる名前付き引数
disable-model-invocation: true # true で Claude の自動読み込みを禁止
allowed-tools: # 呼び出したターンの間だけ確認なしで使えるツール
- Bash(git diff *)
- Write
disallowed-tools: # スキル有効中に使えなくするツール
- WebSearch
effort: high # low / medium / high / xhigh / max
context: fork # フォークしたサブエージェントで実行
agent: general-purpose # context: fork のときのサブエージェント種別
paths: # このファイルを触るときだけ自動で読み込む
- "docs/**/*.md"
---項目 | 内容 |
|---|---|
|
|
| 何をするか・いつ使うか。省略時は本文の最初の空でない行。 |
| 追加の発動条件。1,536文字の上限に合算される |
| 補完時のヒント(例 |
|
|
|
|
|
|
| 呼び出したターンの間だけ確認なしで使えるツール。次にユーザーがメッセージを送ると解除される |
| スキル有効中に使えなくするツール |
| スキル有効中(そのターンの残り)に使うモデル |
|
|
|
|
|
|
|
|
| 呼び出したときに登録され、そのセッションの残りの間有効なフック |
| 自動で読み込む対象を、一致するファイルに限る glob |
|
|
| 仕様上のメタデータ。Claude Code は受け付けるが動作には使わない( |
誤解しやすい点は3つある。
allowed-toolsは「スキル有効中」ではなく「呼び出したターンの間だけ」。次のメッセージで許可は消えるhooksはスキルが終わっても消えない。呼び出した時点で登録され、セッションの残りの間ずっと有効になる- 真偽値は
true/falseのほかyes/no/on/off/1/0も書ける(v2.1.218 以降)
もう一つ、共有を考えているスキルには注意がある。claude.ai へのアップロードや Skills API など Claude Code 以外で使う場合、使える項目は name / description / license / compatibility / metadata / allowed-tools だけで、context や hooks、paths などを書くとエラーになる。
description の書き方で、Claude がスキルを読み込むかどうかの精度が変わる。「ドキュメントを作る」のような抽象的な書き方では、別のスキルと取り違えたり、必要なときに読み込まなかったりする。「記事の下書きを作るとき」のように場面を具体的に書き、大事な用途を先頭に置く。
文字列置換変数
SKILL.md の本文では、次の変数が使える。
変数 | 内容 |
|---|---|
| 呼び出し時の引数すべて。本文のどこにも書かれていなければ、末尾に |
| N 番目の引数(0始まり) |
|
|
| 現在のセッションID |
| 現在の effort レベル |
| その SKILL.md があるディレクトリ |
| プロジェクトのルート |
| プラグインのスキルでのみ使える |
$ を文字として書くときは \$1.00 のようにエスケープする。
本文に !`git diff HEAD` のように書くと、スキルを送る前にコマンドを実行して出力を埋め込める(動的コンテキスト注入)。複数行なら ```! のブロックも使える。ただし次の点に気をつけたい。
- コマンドが失敗する(0以外で終わる)と、スキルの呼び出し全体が止まる。検索・比較系のコマンドが返す終了コード1は許容される。失敗しても構わないコマンドには
|| trueを付ける - コマンドは権限ルールで検査され、許可されていないものは呼び出しごと止まる。
allowed-toolsで先に許可しておけば通る - 組織で止めたい場合は managed settings で
"disableSkillShellExecution": trueを設定する。個人・プロジェクト・プラグインのスキルのコマンドが[shell command execution disabled by policy]に置き換わる
呼び出し制御マトリクス
disable-model-invocation と user-invocable の組み合わせで、誰がスキルを呼べるかを決められる。
設定 | ユーザーが呼べる | Claude が呼べる | 説明文がコンテキストに入るか | 向く用途 |
|---|---|---|---|---|
既定(どちらも書かない) | ○ | ○ | 常に入る | 汎用スキル |
| ○ | × | 入らない | デプロイなど副作用のある手動専用スキル |
| × | ○ | 常に入る | Claude が裏で使う参照用スキル |
デプロイや Slack への投稿のように副作用が大きいスキルには、disable-model-invocation: true を付けておく。付けないと、関係する会話の流れで Claude が自分から読み込むことがある。説明文がコンテキストに入らなくなるので、トークンの節約にもなる。
ほかにも、settings の skillOverrides("on" / "name-only" / "user-invocable-only" / "off")で他人が書いたスキルの見え方をファイルを触らずに変えたり、権限ルール Skill(name) で Claude が呼べるスキルを絞ったりできる。プロンプトに /write-tests /fix-issue 123 のように並べれば、最大6つまで重ねて呼べる。
スキルはコンテキストにどう残るか
スキルを呼ぶと、展開された SKILL.md が1つのメッセージとして会話に入り、以降のターンにも残る。ファイルを読み直すわけではないので、「一度だけ実行する手順」より「この作業中はずっと守る指示」として書くほうが向いている。
自動コンパクト(会話の圧縮)のときは、各スキルの直近の呼び出しが添付し直される。上限は1スキルにつき先頭5,000トークン、全体で25,000トークン。新しく呼んだものから埋まるので、古いスキルは残らないことがある。公式は SKILL.md を500行以内に収め、詳しい資料は reference.md などの別ファイルに分けるよう勧めている。
コンテキストの消費量を抑える工夫は「Claude Code コスト最適化完全ガイド」でも扱っている。
バンドルされたスキル一覧(2026年10月時点)
Claude Code には最初から入っているスキルがある。公式のスキルのページに名前が出ているのは次のとおり。disableBundledSkills でまとめて無効にもできる。
コマンド | 内容 |
|---|---|
| コードレビュー |
| デバッグ用のログを有効にして不具合を調べる |
| コードベース全体の大きな変更を並列で進める |
| プロンプトを繰り返し実行する |
| Claude API を使う実装の支援 |
| アプリを起動して動作を確かめる |
| コード変更を検証する |
| プロジェクト用の起動手順を記録する |
| コードを簡潔にする |
| インストール・拡張・CLAUDE.md・権限を点検する( |
| スキルの設定を点検する |
自作のスキルは、同じ名前のバンドルコマンドを置き換える(エイリアスは除く)。
Hooksの仕組みと全イベント一覧(33種類)
Hooks は、Claude Code のライフサイクルの決まった時点で自動実行される処理だ。シェルコマンドや HTTP リクエストを settings.json の hooks に書いておくと、Claude がその処理を選ぶかどうかに関係なく動く。ここが Skills との最大の違いになる。

設定の基本形は次のとおり。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/security-check.sh",
"onFailure": "block"
}
]
}
]
}
}フックは次の場所に書ける。どこに書いたものも置き換えではなくマージされ、すべて動く。
場所 | 範囲 |
|---|---|
| 自分の全プロジェクト |
| そのプロジェクト(リポジトリにコミットしてチームで共有できる) |
| そのプロジェクトの自分だけ(gitignore 対象) |
managed policy | 組織全体 |
プラグインの | プラグイン有効時 |
スキルのフロントマター | スキルを呼んだ時点で登録され、セッションの残りの間 |
サブエージェントのフロントマター | そのサブエージェントが動いている間 |
全イベントの細かな使い方は「Claude Code Hooks 使い方|PreToolUse/PostToolUse/Stop/SubagentStop 完全ガイド」で解説している。
セッション・ユーザー入力関連イベント
イベント | 発火するとき | 止められるか | マッチャー |
|---|---|---|---|
| セッションの開始・再開 | × |
|
|
| × |
|
| プロンプト送信後、Claude が処理する前 | ○ | なし(全プロンプトで発火) |
| 打ったコマンドがプロンプトに展開されるとき | ○ | コマンド名 |
| セッション終了 | × | 終了理由 |
SessionStart の compact は、会話の圧縮後に大事な情報を入れ直す用途でよく使われる。
ツール実行関連イベント(最重要)
ツールの実行前後を扱うイベントで、実務ではいちばんよく使う。
イベント | 発火するとき | 止められるか | 主な用途 |
|---|---|---|---|
| ツールの実行前 | ○ | 危険なコマンドの拒否、入力の書き換え、確認の要否の判断 |
| 権限の判断が要るとき |
| 自動承認・自動拒否のルール |
| auto モードが拒否したとき | × | 拒否の記録・通知 |
| ツールの実行が成功した後 | ×(実行は取り消せない)。 | フォーマット、lint、監査ログ |
| ツールが失敗した後 | × | エラーの記録、追加情報の注入 |
| 並列のツール呼び出しがまとめて終わり、次のモデル呼び出しの前 | ○ | まとめての検査 |
エージェント・タスク関連イベント
イベント | 発火するとき | 止められるか | マッチャー |
|---|---|---|---|
| サブエージェントの起動 | × | エージェント種別 |
| サブエージェントの終了 | ○ | エージェント種別 |
| Claude の応答が終わったとき | ○ | なし |
| API エラーでターンが終わったとき | × | エラー種別 |
| Agent Teams のメンバーがアイドルになる直前 | ○ | なし |
| タスクの作成・完了 | ○ | なし |
| 会話の圧縮の前・後 | ○ / × |
|
Agent Teams でのフックの使い方は「Claude Code Agent Teamsの使い方」で、サブエージェント全般は「Claude Code サブエージェント 使い方」で取り上げている。
ファイル・設定・その他イベント
イベント | 発火するとき | 止められるか |
|---|---|---|
| 通知を送るとき | × |
| 応答のテキストを表示している間 | ×(表示する文の差し替えはできる) |
| CLAUDE.md や | × |
| セッション中に設定ファイルが変わったとき | ○(policy_settings は除く) |
| 作業ディレクトリが変わったとき | × |
|
| × |
| 監視しているファイルが変わったとき | × |
| ワークツリーの作成・削除 | 0以外の終了で失敗させられる |
| モデルの切り替えを適用する前(v2.1.251 以降) | ○ |
| モデルを変えた後(v2.1.251 以降) | × |
| MCP サーバーが入力を求めたとき・その応答の後 | ○ |
これらを合わせると、2026年10月時点の公式のイベント一覧は33種類になる。最近の版で PreModelSwitch / PostModelSwitch / DirectoryAdded が加わっており、数は今後も増える可能性がある。
マッチャーパターンのルール
マッチャーの書き方 | 判定 | 例 |
|---|---|---|
| すべてに一致 | — |
英数字・ | 完全一致、または並べたどれか |
|
それ以外の文字を含む | JavaScript の正規表現(先頭・末尾は固定されない) |
|
大文字と小文字は区別される。マッチャーに対応していないイベント(UserPromptSubmit や Stop など)に書いても、エラーは出ずに無視される。
フックタイプ5種の選び方
タイプ | 動き方 | 既定のタイムアウト | 向くケース |
|---|---|---|---|
| シェルコマンド。入力は標準入力の JSON | 600秒 | 毎回同じ結果がほしい検査、整形、外部ツール |
| 入力 JSON を URL へ POST | 600秒 | チームで共有する監査サービス、Webhook |
| 接続済み MCP サーバーのツールを呼ぶ | 600秒 | MCP 経由の検証・記録 |
| モデルが1回評価し | 30秒 | 文脈を読んで判断したい評価 |
| ツールを使えるサブエージェントで検証(experimental) | 60秒 | ファイルを読んだりコマンドを実行したりして確かめる検証 |
UserPromptSubmit / PreModelSwitch / PostModelSwitch では command・http・mcp_tool の既定タイムアウトが30秒になり、SessionEnd は全体で1.5秒しか使えない(個別の timeout を延ばせば最大60秒)。
「Hooks は決定論的」とまとめられることが多いが、prompt と agent はモデルが判断するので結果がぶれる。毎回同じ結果が必要なガードには command / http / mcp_tool を使う。また prompt / agent はモデルを呼ぶので利用量を消費する(command は消費しない)。prompt / agent が使えるのは PreToolUse・PostToolUse・Stop・UserPromptSubmit など一部のイベントに限られ、SessionStart や Notification などでは使えない。
mcp_tool フックや MCP サーバーとの組み合わせは「Claude Code MCP連携ガイド」も参考になる。
共通で使える設定項目(2026年10月時点)
項目 | 内容 |
|---|---|
| 秒数でタイムアウトを変える |
|
|
|
|
| 初回に成功したらそのフックを外す。スキルのフロントマターでのみ有効 |
| コマンドを配列で渡し、シェルを通さずに実行する。クォートが要らない(Windows では |
| バックグラウンドで実行する。 |
|
|
if は手軽だが、公式は「ベストエフォート」としている。厳密に許可・拒否したいものは権限設定(permissions の allow / deny)に書く。
終了コードと出力の読まれ方
終了コード | 意味 |
|---|---|
| 成功。標準出力が JSON オブジェクト1つならそれを解釈し、そうでなければただのテキストとして扱う( |
| ブロック。標準エラー出力が理由になる。JSON を出していても exit 2 が優先 |
それ以外 | 止めないエラー。処理は続き、標準エラー出力の1行目が通知に出る |
フックには共通の入力として session_id、transcript_path、cwd、permission_mode、effort({"level": ...})、hook_event_name などが渡る。
PreToolUse|実行前の制御ゲート
PreToolUse は、Claude がツールを呼ぶ直前に発火し、許可・拒否・確認・入力の書き換えを決められるフックだ。どの権限モードの判定よりも先に動くので、セキュリティの関門として使える。

入力JSONスキーマ(stdin から受け取る)
{
"session_id": "abc123",
"transcript_path": "/path/to/transcript.jsonl",
"cwd": "/current/working/directory",
"permission_mode": "default",
"hook_event_name": "PreToolUse",
"tool_name": "Bash",
"tool_input": {
"command": "npm test",
"description": "テストを実行"
},
"tool_use_id": "toolu_01ABC123...",
"effort": { "level": "high" }
}tool_input の中身はツールで変わる。
ツール | tool_input の主な中身 |
|---|---|
|
|
|
|
|
|
|
|
permissionDecision 4種の動作と使い分け
値 | 動き | 典型的な使い道 |
|---|---|---|
| 確認を飛ばして実行する | テスト実行など安全とわかっている操作の自動承認 |
| 呼び出しを取り消し、理由を Claude に返す |
|
| ユーザーに確認を出す | 重要な操作の確認を必ず残す |
| あとで再開できるように中断する |
|
複数のフックが別々の答えを返したときは、deny > defer > ask > allow の順で強いものが採用される。
権限モードとの関係は、安全設計でいちばん影響の大きいポイントだ。
"deny"はbypassPermissionsや--dangerously-skip-permissionsで起動していても止まる。ユーザーが権限モードを変えても破れないルールを作れる- 逆に
"allow"は settings の deny ルールを越えられない。ネットワークパスの読み取りや、ユーザー操作が必須の MCP ツールの確認も消せない。フックは締めることはできても、緩めることはできない - auto モードでも、フックが
"ask"を返せば確認が出る
権限モードやサンドボックスの全体像は「Claude Codeのセキュリティと安全な使い方」、auto モードの注意点は「Claude Code auto モードとプロンプトインジェクション」で詳しく扱っている。
"defer" は v2.1.246 以降の機能で、-p モード専用だ。対話セッションでは警告が出て無視される。中断すると stop_reason: "tool_deferred" で終わり、claude -p --resume <session-id> で再開するとフックがもう一度動く。そのターンのツール呼び出しが1つのときだけ使える。
出力JSONスキーマ(stdout に書き出す)
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": ".env への書き込みはこのプロジェクトでは禁止です",
"additionalContext": "秘密情報は .env.example を編集し、値は担当者に依頼してください"
}
}項目 | 内容 |
|---|---|
|
|
| ask では確認画面に、deny では Claude に表示される。allow / defer ではデバッグログにだけ残る |
| ツールの引数を丸ごと置き換える(変えない項目も含めて返す)。返した入力に対して権限ルールがもう一度評価される |
| ツールの結果と一緒に Claude のコンテキストに入る |
permissionDecision は必ず hookSpecificOutput の中に書く。トップレベルに書くとエラーも出ずに無視される。トップレベルの decision / reason はこのイベントでは非推奨になっている。
updatedInput は v2.1.300 から、Claude 自身の入力と同じように検証されるようになった。知らないキーは捨てられ、不正な入力なら拒否される。複数のフックが同じツールの updatedInput を返すと、最後に終わったものが採用される。並列実行なので順番は決まらないため、同じツールの入力を書き換えるフックは1つにする。
実践例: .envファイルへの書き込みブロック
.claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-files.sh",
"onFailure": "block"
}
]
}
]
}
}.claude/hooks/protect-files.sh:
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
case "$FILE" in
*.env|*.env.*|*/package-lock.json)
jq -n --arg f "$FILE" '{
hookSpecificOutput: {
hookEventName: "PreToolUse",
permissionDecision: "deny",
permissionDecisionReason: ($f + " は直接編集できません")
}
}'
;;
esac
exit 0onFailure: "block" を付けておくと、jq が入っていない環境などでスクリプト自体が失敗したときに、編集をそのまま通さずに止められる。ガード目的のフックには付けておきたい。
PostToolUse|実行後の検証・監査ログ
PostToolUse はツールが成功した後に発火し、結果の検証・整形・記録に使う。ツールはすでに実行済みなので、操作を取り消すことはできない。ここが PreToolUse との決定的な違いだ。

追加入力フィールド(PreToolUseとの差分)
{
"tool_response": {
"stdout": "コマンドの標準出力",
"stderr": "",
"interrupted": false
},
"duration_ms": 1234
}tool_response にはツールごとの構造化された出力が入る。duration_ms は任意で、MCP ツールなら mcp_server も渡る(v2.1.274 以降)。
出力JSONスキーマ(2026年10月時点)
{
"decision": "block",
"reason": "ESLint で2件のエラーがあります。修正してから進めてください",
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": "エラーの詳細: src/api.ts:12 no-unused-vars"
}
}項目 | 置き場所 | 内容 |
|---|---|---|
| トップレベル | 理由をツール結果の横に添えて Claude に返す。元の出力も Claude に見える |
|
| Claude のコンテキストに追加する |
|
| Claude が見るツール結果を差し替える。出力の形式に合わないと組み込みツールでは無視される。副作用は取り消せず、テレメトリには元の出力が残る |
|
| MCP ツール専用(現在は |
|
| auto モードの分類器向けのメモ。Claude には見えない(v2.1.236 以降、1回2,000文字まで) |
decision と reason は hookSpecificOutput の中ではなくトップレベルに置く。PreToolUse の permissionDecision とは置き場所が逆なので、取り違えやすい。exit 2 で終わった場合も標準エラー出力が Claude に渡るが、ツールはすでに実行されている。
continueOnBlock の正しい使い方
continueOnBlock は prompt フック(type: "prompt")の設定項目で、command フックの出力 JSON に書くものではない。PostToolUse の hookSpecificOutput に入れる例を載せた解説も見かけるが、現行の公式リファレンスとは合わない。
prompt フックが ok: false を返すと、既定では PreToolUse・PostToolUse ともにそのターンが終わり、理由がチャットに警告として表示される。continueOnBlock: true にすると、理由を Claude に返してターンを続けさせられる。PreToolUse なら、command フックが permissionDecision: "deny" を返したときと同じ動きになる。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "prompt",
"prompt": "この変更がテストを削除・無効化していないか確認し、していれば ok を false にしてください",
"continueOnBlock": true
}
]
}
]
}
}agent フックにはこの項目がなく、常に continueOnBlock: true と同じ動きになる。v2.1.210 より前は prompt フックが PreToolUse で拒否してもターンが続いていたので、古い記事の説明とは挙動が違う点に注意したい。
実践例: ファイル編集後の自動Prettier実行
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
case "$FILE" in
*.ts|*.tsx|*.js|*.jsx)
npx prettier --write "$FILE" >/dev/null 2>&1
;;
esac
exit 0settings.json の PostToolUse に "matcher": "Edit|Write" で登録する。標準出力に何も出さなければ、コンテキストは消費しない。
実践例: lint の失敗を Claude に返す
#!/bin/bash
INPUT=$(cat)
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
case "$FILE" in
*.ts|*.tsx) ;;
*) exit 0 ;;
esac
if ! OUT=$(npx eslint "$FILE" 2>&1); then
jq -n --arg r "ESLint エラー: $OUT" '{decision: "block", reason: $r}'
fi
exit 0フックは lint を必ず走らせ、直し方は /fix-lint のようなスキルに書いておく。公式が挙げている「フックとスキルの併用」はこの形だ。
Stop イベントの無限ループ対策
#!/bin/bash
INPUT=$(cat)
if [ "$(echo "$INPUT" | jq -r '.stop_hook_active')" = "true" ]; then
exit 0 # すでに Stop フックで続行中なら抜ける
fi
# 通常の処理(テストが落ちていれば decision: "block" で作業を続けさせる など)
exit 0Stop フックは decision: "block" と reason を返すと Claude に作業を続けさせられる。stop_hook_active が true のときに抜けないと、続行と停止を繰り返すことになる。現在の Claude Code は、ツール呼び出しを挟まずに連続8回ブロックすると打ち切る(CLAUDE_CODE_STOP_HOOK_BLOCK_CAP で変更可)。それでも、公式の書き方どおり自分で抜ける処理を入れておくのが安全だ。なお Stop はユーザーが中断したときには発火せず、API エラーのときは StopFailure が発火する。
UserPromptSubmit|プロンプト処理前の制御
UserPromptSubmit は、ユーザーがプロンプトを送った後、Claude が処理を始める前に発火する。マッチャーに対応しておらず全プロンプトで動くので、入力の検査やコンテキストの自動注入の入口になる。

主な用途は、プロンプトの検査(禁止ワードや、プロジェクト外の依頼を止める)、コンテキストの自動注入(現在のブランチ、環境名、日付など)、プロンプトの記録(チームの利用状況の監査)だ。
押さえておきたい仕様は次のとおり。
- 入力の
promptに送信内容が入る。貼り付けた内容は展開済み decision: "block"で止められる。reasonはユーザーに表示され、コンテキストには入らないhookSpecificOutputのadditionalContextで情報を足せる。ただの標準出力もコンテキストに入る- プロンプト本文の書き換えはできない(足すことだけできる)
- 既定のタイムアウトは30秒。タイムアウトすると出力は捨てられる(
onFailure: "block"なら止まる) - v2.1.299 から、スキルやカスタムスラッシュコマンドが展開される前に動くようになった。プロンプトを止めれば、スキル内の
!コマンドも実行されない
実践例: Gitブランチ情報をコンテキストに自動注入
#!/bin/bash
BRANCH=$(git branch --show-current 2>/dev/null || echo "N/A")
ENV_NAME="${NODE_ENV:-development}"
jq -n --arg c "現在のブランチ: $BRANCH / 環境: $ENV_NAME" '{
hookSpecificOutput: {
hookEventName: "UserPromptSubmit",
additionalContext: $c
}
}'
exit 0文字列を手で組み立てると、ブランチ名に記号が入ったときに JSON の書式がおかしくなる。jq -n --arg で作ると安全だ。
実践例: 禁止ワードフィルタ
#!/bin/bash
INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.prompt // empty')
if echo "$PROMPT" | grep -qiE "本番DB|production database|DROP TABLE"; then
echo "本番DBへの直接操作は止めています。ステージング環境で試してください。" >&2
exit 2
fi
exit 0入力のフィールド名は prompt だ。user_prompt と書いた例も出回っているが、それでは値が取れずフィルタが働かない。
2026年6〜10月の主な変更点

出典: Anthropic 公式 GitHub(anthropics/claude-code)
2026年6月以降、Skills と Hooks のまわりは大きく変わった。日本語の解説記事にまだ反映されていないものが多いので、版ごとにまとめる。版と公開日は公式 changelog と npm で確認した(v2.1.302 は2026年10月16日公開。安定版タグ stable は v2.1.292)。
版 | 変更内容 |
|---|---|
2.1.210 | prompt フックが PreToolUse で拒否すると、既定でターンが終わるように。 |
2.1.211 | auto モードでも、フックの |
2.1.218 | スキルの |
2.1.236 | PostToolUse の |
2.1.246 | PreToolUse の |
2.1.251 |
|
2.1.283 |
|
2.1.287 | Claude Mods が登場 |
2.1.292 | フック出力内の |
2.1.295 |
|
2.1.296 |
|
2.1.299 | UserPromptSubmit がスキル展開前に動くように。スキルのフロントマターに書いた UserPromptSubmit は次のプロンプトから動く。Windows で Git Bash がないとき PreToolUse が素通りする問題、plan モードで PreToolUse が allow した書き込みが実行される問題を修正 |
2.1.300 | PreToolUse / PermissionRequest の |
2.1.301 | プラグイン・スキルのフックが |
2.1.302 | prompt / agent フックは同じイベントで同時に最大12個まで実行し、残りは待つ |
第3の選択肢「Claude Mods」とPreToolUseの関係
v2.1.287 から、プラグインに JavaScript / TypeScript の関数を入れて Claude Code の内部の動きを変えられる Claude Mods が加わった。公式ドキュメントはこれに合わせて、従来のフックを「settings hook」と呼び分けている。公式の使い分けは次のとおりだ。
選択肢 | 向く場面 |
|---|---|
settings hook(従来の Hooks) | 既存のスクリプトでイベントを止めたい・許したい・記録したい |
skill | 同じ指示を何度もチャットに貼っている |
mod | 画面にペインやカスタムコマンドを足したい、イベントを書き換えたい |
セキュリティの面で注意がある。自分で入れた Mod は、自分の PreToolUse フックがブロックした呼び出しを承認で上書きできる(managed settings のフックは除く)。Mod はサンドボックスの外でユーザーの権限で動き、環境変数や設定ファイルの秘密情報も読める。「PreToolUse で止めているから安全」という前提は、信頼できない Mod を入れると崩れる。入れる前に claude plugin validate で扱うイベントと呼び出しを確かめ、組織では allowManagedModsOnly で制限する。
Skillsから始め、必要ならHooksを追加する(判断フロー)
迷ったら、まずスキル(またはCLAUDE.md)で始め、「毎回かならず起きてほしい」「絶対に通したくない」とわかった処理だけをフックに移す。困ったことが起きてから足すという公式の導入順序とも合う。
この処理を設定したい
│
├── Claude に「知っていてほしい・考えて当てはめてほしい」?
│ ├── いつも関係する事実(ビルドコマンド、規約) → CLAUDE.md
│ ├── 特定のファイルを触るときだけの制約 → rules(paths 指定)/スキルの paths
│ └── 繰り返す手順・参照資料 → Skills(SKILL.md)
│
└── 「毎回かならず起こしたい・止めたい」?
├── 結果が毎回同じでなければ困る → Hooks(command / http / mcp_tool)
├── 文脈を読んで判断させたい → Hooks(prompt / agent)
└── ユーザーが明示的に呼ぶ作業 → Skills(disable-model-invocation: true)迷ったときに補助として使える質問は次のとおり。
- 毎回かならず実行しないと困るか? → はい: Hooks/いいえ: Skills
- Claude の判断に任せてよいか? → はい: Skills/いいえ: Hooks
- コードレビューの観点や手順書のような「知識」か? → はい: Skills
- 保存後のフォーマット、危険なコマンドの拒否、完了時の通知か? → はい: Hooks
- CLAUDE.md が長くなってきた? → 手順はスキルに、特定ファイルの制約は rules に切り出す
たとえるなら、CLAUDE.md は社員ハンドブック(いつも手元にある)、Skills は業務マニュアル(必要なときに開く)、Hooks は入館ゲートや自動ロック(人の判断に関係なく動く)だ。
実践ユースケース集

出典: Anthropic 公式 GitHub(anthropics/skills)
Skillsが適している処理
ユースケース | SKILL.md の設定例 |
|---|---|
PR のレビューチェックリスト |
|
社内 API の規約・仕様 |
|
バグ修正の手順書 |
|
デプロイ手順 |
|
データベースの分析 |
|
TypeScript を触るときだけの規約 |
|
PR の差分を前提にした作業 |
|
Hooksが適している処理
ユースケース | イベント | フックタイプ |
|---|---|---|
編集後の自動 Prettier |
|
|
|
|
|
|
|
|
入力待ちのデスクトップ通知 |
|
|
会話の圧縮後に重要情報を入れ直す |
|
|
圧縮前に会話をバックアップ |
|
|
すべての Bash コマンドの監査ログ |
|
|
ESLint の結果を Claude に返す |
|
|
テストを消していないかの確認 |
|
|
プロンプトにブランチ情報を足す |
|
|
完了時に Slack へ投稿 |
|
|
Skills × Hooks の連携パターン(スキル内フック)
SKILL.md のフロントマターに hooks を書くと、スキルにフックを同梱できる。チームで共有するスキルに入れておけば、スキルを使うだけで安全確認も一緒に有効になる。
---
name: database-analyst
description: データベースを分析するとき。読み取り専用のクエリだけを使う
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/check-readonly-sql.sh"
onFailure: block
SessionStart:
- hooks:
- type: command
command: "echo '分析対象は analytics スキーマのみ'"
once: true
---
データベース分析の手順をここに書く...使うときは次の3点を知っておきたい。
- スキル内のフックは、呼び出した時点で登録され、スキルの作業が終わってもセッションの残りの間ずっと有効になる。分析の後に別の作業をしても、Bash の検査は続く
once: trueは初回に成功するとそのフックを外す。この指定はスキルのフロントマターでしか有効にならない- プロジェクトのスキルに書いたフックは、スキルが呼ばれれば
-pモードでも動く。プロジェクトのサブエージェントに書いたフックは、フォルダーの信頼(workspace trust)を承認した後でないと動かない
セキュリティと制約事項

Hooks はユーザーと同じ権限でコマンドを実行する。公式リファレンスも「command フックはユーザーの全権限でシェルコマンドを実行し、アカウントが触れるファイルはすべて変更・削除・読み取りできる。追加する前にすべてのコマンドを確認・テストすること」と警告している。
フックの実行モデルと「allow」の限界
PreToolUse の "deny" は権限モードに関係なく働くが、"allow" を返しても settings の deny ルールや組織のポリシーより優先されない。フックで制限を強めることはできても、緩めることはできない。権限を広げたい場合は、フックではなく権限設定の allow ルールで行う。
信頼していないリポジトリと -p モード
対話セッションでは、フォルダーの信頼を承認するまで、どの settings ファイルのフックも実行されない(自分の ~/.claude/settings.json も含む)。一方、-p や SDK では信頼の確認画面が出ず、信頼済みとして扱われる。他人のリポジトリで claude -p を回すときは、先に .claude/ の中身を確かめるか、--bare や --settings '{"disableAllHooks": true}' でフックを無効にする。
シェルプロファイルの干渉問題
~/.zshrc や ~/.bashrc に無条件の echo があると、フックの標準出力の先頭にその文字が入り込み、JSON として読まれなくなる。exit 0 で終わるのでエラーも出ない。プロファイル側の出力を if [[ $- == *i* ]]; then ... fi で囲み、対話シェルのときだけ出すようにする。
フックが思ったとおりに動かないときの確認手順は次のとおり。
/hooksで、登録されたフックをイベント別に確認する(Only hooks from managed settings run hereと出たら、組織がallowManagedHooksOnlyを設定している)claude --debugで起動し、~/.claude/debug/<session-id>.txtを見る。v2.1.296 以降はHooks: PostToolUse:Write [...] finished with status 0 (31ms)のように各フックの所要時間も出る- スクリプト単体で試す:
echo '{"tool_name":"Bash","tool_input":{"command":"ls"}}' | ./my-hook.sh; echo $? - スキル側は
/doctor、/skill-doctor、/contextで確かめる
注意すべき制約一覧
PostToolUseは実行済みの操作を取り消せないUserPromptSubmitはプロンプトの本文を書き換えられない(足すことだけできる)- command フックが Claude に伝えられるのは標準出力・標準エラー出力・終了コードだけで、
/コマンドやツール呼び出しは起こせない - 同じツールの
updatedInputを複数のフックで書き換えると、結果が決まらない - 個別のフックを「設定を残したまま無効にする」方法はない(
disableAllHooksは全体のみ) ifをツール系以外のイベントに付けると、そのフックは動かない- command / http / mcp_tool の既定タイムアウトは600秒。
timeoutで変えられる agentタイプは experimental で、仕様が変わる可能性がある- スキルの説明文+
when_to_useは1,536文字で切られる。会話の圧縮後は1スキル5,000トークン・全体25,000トークンまでしか残らない - スキル内の
!コマンドが1つでも失敗すると、スキル全体が止まる
企業利用時の管理設定
組織で使うときは、managed settings で次の項目を使い分ける。
設定 | 効果 |
|---|---|
| 個人・プロジェクト・ローカル・プラグインのフックを止め、managed のフックだけを動かす |
| すべてのフックを止める(managed のフックを止めるには managed レベルで設定する) |
| HTTP フックの送り先と、ヘッダーに入れられる環境変数を制限する |
| スキル内の |
| スキルの見え方を変える、バンドルスキルを止める |
権限ルール | Claude が呼べるスキルを制限する |
| 組織が配った Mod だけを許可する |
managed settings は管理者が配るもので、ユーザーのローカル設定では上書きできない。チームで決めた禁止事項は、CLAUDE.md に書くだけで終わらせず、managed のフックや権限設定に置くのが公式ブログの考え方にも沿う。
Claude Code で作った試作や社内ツールを、社内の実データや既存システムにつないで業務で使う段階になると、フックによる操作制限だけでは足りない。権限管理、監査ログの保管、障害時に誰が直すかといった運用の決めごとも必要になる。進め方は「AIで作ったアプリを開発会社へ引き継ぐには」で整理している。
料金への影響
Skills と Hooks に追加料金はない。Claude Code が使えるプラン(2026年10月時点の公式料金ページでは Pro 月額20ドル、Max 月額100ドルから、Team・Enterprise など)か、API の従量課金で使える。
ただし、利用量への影響は機能ごとに違う。
機能 | 利用量への影響 |
|---|---|
command / http / mcp_tool フック | モデルを呼ばないので消費しない(出力を返せばその分のコンテキストは使う) |
prompt / agent フック | 発火するたびにモデルを呼ぶので消費する |
Skills | 説明文が毎リクエスト分のトークンになる。 |
日本円での料金やプランの選び方は「Claude料金を日本円で解説」にまとめている。
こんな人・チームに向いている / 向いていない
Skills(SKILL.md)を導入すべき人
- チーム独自のコーディング規約やレビュー手順をそろえたい
- PR 作成・ドキュメント生成・デプロイなどの繰り返し作業を1コマンドにしたい
- 複数のプロジェクトで同じ手順を個人スキルとして使い回したい
- CLAUDE.md が長くなって、必要なときだけ読ませたい情報が増えてきた
Hooks を導入すべき人
- ファイルを変えるたびに、フォーマッタや lint を確実に走らせたい
.envの編集や危険なコマンドを、権限モードに関係なく止めたい- すべてのコマンドの監査ログを残す必要がある(コンプライアンス要件)
- Agent Teams やサブエージェントを多用していて、タスク完了の条件を細かく決めたい
Skills・Hooks ともに今は見送ったほうがよい人
- Claude Code を使い始めたばかりで、CLAUDE.md での基本的な設定もまだ試していない(使い方は「Claude Codeの使い方ガイド」から)
- シェルスクリプトや JSON の扱いに慣れておらず、フックが思ったとおりに動かないときに原因を追えない
- チームの合意なしに、個人の判断でブロックするフックを共有設定に入れようとしている(ほかの人の作業が止まる)
- 500行を超える手順書を1つのスキルに詰め込もうとしている(会話の圧縮で後半が残らない)
- 出どころのわからないプラグインや Mod を、中身を確かめずに入れようとしている
よくある質問
Q. フックイベントは何種類ありますか? 18種や30種と書いてある記事を見たのですが?
2026年10月時点の公式リファレンスでは33種類です。2026年に入ってからも PostToolBatch、MessageDisplay、PreModelSwitch / PostModelSwitch、DirectoryAdded などが増えており、古い記事の数字はずれています。イベントは今後も増える見込みなので、実装前に公式の一覧を確かめてください。
Q. PreToolUse で allow を返せば、すべての権限確認を消せますか?
消せません。settings の deny ルールや組織のポリシーが優先され、ネットワークパスの読み取りなど一部の確認も残ります。逆に deny は --dangerously-skip-permissions で起動していても働くので、フックは「止める」用途で使うほうが確実です。
Q. continueOnBlock は command フックの出力に書けますか?
書けません。continueOnBlock は prompt フックの設定項目で、settings.json のフック定義("type": "prompt" と同じ階層)に書きます。command フックで同じ動き(止めた理由を Claude に返して作業を続けさせる)をしたい場合は、PreToolUse なら permissionDecision: "deny"、PostToolUse ならトップレベルの decision: "block" と reason を返します。
Q. スキルの allowed-tools に書いたツールは、スキルを使っている間ずっと確認なしで使えますか?
いいえ。許可は呼び出したターンの間だけで、次にユーザーがメッセージを送ると元に戻ります。長い作業で毎回確認を省きたいなら、権限設定の allow ルールに書くほうが確実です。
Q. ガード用のフックが落ちたら、操作は素通りしますか?
既定(onFailure: "continue")では、フックの起動失敗やタイムアウトは止めないエラーとして扱われ、操作は続きます。v2.1.295 以降は command / http フックに "onFailure": "block" を付けると、フックが失敗したときに操作を止められます。
Q. Hooks はリポジトリにコミットしてチームで共有できますか?
.claude/settings.json に書いたフックはコミットしてチームに配れます。自分だけの設定は .claude/settings.local.json か ~/.claude/settings.json に書きます。必ず守らせたいルールは、ユーザーが上書きできない managed settings に置くのが確実です。
Q. Claude Mods を入れると、Hooks は要らなくなりますか?
なりません。公式は、既存のスクリプトでイベントを止める・許す・記録するなら settings hook、画面の拡張やイベントの書き換えなら Mod、と分けています。Mod は自分の PreToolUse フックの拒否を上書きできるので、Mod を入れるならフックとの関係を確かめておく必要があります。
関連記事
Claude Code の基本は「Claude Codeとは?できること・料金・使い方・他ツール比較」で整理している。
SKILL.md の作り方・保存場所・配布方法は「Claude Code Skills 使い方完全ガイド」、全フックイベントの使い方は「Claude Code Hooks 使い方完全ガイド」で詳しく解説している。
権限モードや --dangerously-skip-permissions の扱いは「Claude Codeのセキュリティと安全な使い方」を参照してほしい。
Claude Code を含む AI コーディングツール全体の比較は「AIコーディングツール おすすめ 比較」、サブエージェントと組み合わせた自動化は「Claude Code Agent Teamsの使い方」で確認できる。
このツールを自社のシステムや業務にどう組み込むか、ご提案します
この記事の著者

AI革命
編集部
AI革命株式会社の編集部です。最新のAI技術動向から実践的な導入事例まで、企業のデジタル変革に役立つ情報をお届けしています。豊富な経験と専門知識を活かし、読者の皆様にとって価値のあるコンテンツを制作しています。
最新記事

Alexa+(アレクサプラス)とは?日本で提供開始|申し込み方法・料金(プライム無料/月額3,000円)・対応Echo・できること
2026/10/30

Mistral Large 4がオープンウェイト公開|ライセンス・API料金$0.70・必要GPU・GLM-5.3比較【2026年10月】
2026/10/30

Devin vs Claude Code 比較|料金・機能・使い分けの違いを徹底解説【2026年最新】
2026/04/12

DeepgramがDaily買収へ|Pipecatはどうなる?決まったこと・未定のこと・利用者別の対応
2026/10/30

OpenClawとは?できること・料金・使い方とClaude Codeとの違い【2026年最新】
2026/03/26

LINE公式アカウントの外部連携で予約・顧客管理とつなぐには|拡張ツールで足りる場合とMessaging APIで作る範囲・会員IDの紐付け
2026/10/15


