メインコンテンツへスキップ

Claude Code modsとは:導入手順と、validateだけでは見えない権限

Claude Code modsは自分の権限で動き、askルールより先にツール呼び出しを許可できます。denyが守られるのは組織のガードがある環境だけです。

LaoZhang AI Team公開40 分で読めます
目次
Claude Code modsの権限。askルールは効かず、denyはガード次第で、validateの出力に加えてソースも読む

Claude Code modsは、Claude Codeのプロセスの中で動くJavaScript/TypeScriptの関数を収めたプラグインです。Anthropicが2026年10月1日に発表し、ターミナルのClaude Codeは2.1.287以降、Claude Desktopアプリに同梱されたClaude Codeは2.1.286以降で、最初から有効になっています。ツール呼び出しを止める・書き換える、プロンプトの上に独自の表示を出す、Claudeのターンを使わずに即実行される/コマンドを足す、といった改造ができます。ゲームのMODとは関係ありません。

入れる前に押さえておくべき点は1つです。modはあなたのユーザー権限のまま、サンドボックスの外で動きます。askルールなら確認が出るはずのツール呼び出しを先に許可でき、Read(.env)のようなdenyルールはmod自身のファイル読み取りを止めません。claude plugin validateの出力で「どの種類の操作をするか」までは分かりますが、「どのプログラムを起動し、どのファイルを読み、どこへ送るか」はソースを読むまで分かりません。

実行したこと:2026年10月6日、macOS上のClaude Code 2.1.288(Claude Desktopに同梱のCLI、未ログイン)で、ドキュメントのチュートリアルmodのvalidate・test・claude -p、空ディレクトリでの読み込み可否チェック、Anthropic公式サンプル3つのvalidateとソースの確認、マーケットプレイス追加からインストール・無効化・アンインストールまでを実行しました。インストール系は普段の~/.claudeとは別の設定ディレクトリで行っています。以下に載せる出力はこのときのものです。

実行していないこと:対話セッションは開いていません。そのため、ペインやバンドの描画、ホットリロード、/pluginに出るmods activeの行、Claudeにmodを書かせたときの承認画面は見ていません。デスクトップアプリのCodeタブ、VS Code拡張、Windows、Team/Enterpriseプランでのガードの挙動、コミュニティ製のmodも試していません。これらの部分はAnthropic公式のmodsドキュメント(日本語版「Mods の概要」)の記述にもとづきます。

modが要るのはどんなとき:settings hook・skill・MCPとの違い

modが必要になるのは、Claude Codeの画面そのものに手を入れたいときと、イベントの流れに割り込んで答えを差し替えたいときです。決まった処理でツール呼び出しを止めたり記録したりするだけなら、従来のsettings hook(settings.jsonに書くフック)で足ります。settings hookは廃止されておらず、modと並んで動きます。

用語が紛らわしいので先に整理します。公式ドキュメントは、settings.jsonに書くシェルコマンド型のフックを「settings hook」、modの中の関数を「hook」と呼び分けています。以下もこの呼び方に合わせます。

modsettings hookskillMCPサーバー
正体プラグイン内の関数。Claude Code自身のプロセスで呼ばれるライフサイクルイベントで実行されるシェルコマンド、HTTPリクエスト、プロンプトClaudeが読む指示を書いたSKILL.mdClaudeにツールを渡す外部プロセスやサービス
変えられるものツール呼び出し、プロンプト、コマンド、ターン、画面の描画ツール呼び出しやプロンプトを通すかどうか、引数と結果、Claudeに足す文脈Claudeが知っていること・やることClaudeが使えるツール
画面に描けるか描ける描けない描けない描けない
書くものJavaScriptかTypeScriptスクリプトとsettings.jsonの設定Markdown任意の言語のサーバー
選ぶ場面ペイン、プロンプトの上のバンド、独自コマンド、イベントの書き換えが欲しい手元のスクリプトでブロック・許可・記録したい同じ指示を何度も貼り付けているClaudeに外部システムを触らせたい

出典は公式ドキュメントの比較表です。1つのプラグインにmod、skill、MCPサーバーを同梱することもできます。

modにしかできないことを具体的に挙げると、次の5つです。

  • トランスクリプトの横のペインや、プロンプトの上のバンドに、タブ・ボタン・テキスト欄を描く
  • Claude Code自身が描く部分(ツール呼び出しの行、スピナー、Claudeが質問するダイアログ)を置き換える・装飾する
  • ツール呼び出しを保留してユーザーに尋ねる、ツールを実行せずに代わりの結果を返す、1つのリクエストだけ別のモデルに送る
  • Claudeが作業中でも、ターンを使わずにすぐ自分の関数を実行する/コマンドを足す
  • 同じファイル内の複数のhookで変数を共有する(1つのhookで数えた値を別のhookが表示する)

逆に、画面下部に情報を出したいだけならClaude Code Statusline 設定:経路、フィールド、スクリプト、修正手順のstatuslineスクリプトで済みます。settings hook・skill・スラッシュコマンドの選び方はClaude CodeのHooks・Skills・スラッシュコマンドを使い分ける:呼び出し方と設定例にまとめてあります。

modが動く環境:2.1.287以降、VS Codeとclaude -pでは描画なし

まずバージョンを確認します。ターミナルではシェルでclaude --versionを実行し、2.1.287以降なら対応しています。デスクトップアプリはClaude Codeを内蔵しているので、Codeタブのローカルセッションで/statusと入力し、Claude Codeの行が2.1.286以降かを見ます。古い場合の更新手順はClaude Codeのインストール方法:全プラットフォーム対応セットアップガイド(2026年版)を参照してください。

アーリーアクセス期間にCLAUDE_CODE_ENABLE_FUNCTION_HOOKSを設定していた場合は消して構いません。2.1.287以降はこの変数を無視するので、0にしてもmodは止まりません。

modのhookはプラグインを読み込むすべてのセッションで動きますが、描画が見えるのは一部の画面だけです。

Claude Codeを使う場所hookは動くかmodの描画は見えるか
ターミナルのclaude(エディタ内蔵ターミナル、JetBrainsプラグインを含む)動く見える
デスクトップアプリのCodeタブ(WSLセッションを除く)動く見える。ただしターミナル専用の要素は除く
デスクトップアプリのWSLセッション動かない。WSLセッションではプラグイン自体が使えない見えない
VS Code拡張のチャットパネル動く見えない
claude -pとAgent SDK動く見えない
claude.aiやモバイルアプリからのRemote Control手元のマシンのセッションで動く手元のターミナルに出る
クラウドセッションプラグインがクラウドセッションに引き継がれれば動く見えない

公式ドキュメントの表をもとにしています。VS Code拡張で「modを入れたのに何も表示されない」のは、この仕様どおりの挙動です。hookによるブロックや書き換えは効いているので、表示が出ないからといって無害とは限りません。

mod自体が読み込める状態かをclaude plugin testで確かめる

バージョンが足りていても、設定や組織のポリシーでmodが止められていることがあります。modを入れる前に、modのない空のディレクトリでclaude plugin testを実行すると状態が分かります。セッションもログインも要りません。2.1.288での出力は次のとおりでした。

claude plugin test: .../empty: no hooks module to load; there is no hooks/hooks.json naming one in "modules"

メッセージの意味は公式ドキュメントのトラブルシュートにあります。

メッセージに含まれる文字列意味
no hooks module to loadmodは読み込める。このディレクトリにテスト対象のmodがないだけ
hooks modules are turned off here自分の設定のdisableAllHooksか、組織のポリシーがmodを止めている
hooks modules are turned off in this processAnthropicがインストール済みmodをリモートで止めている。手元の設定では戻せない

組織がallowManagedModsOnlyで組織のmodだけを許可している場合、このチェックには出ません。その場合はmodを入れても読み込まれず、理由はデバッグログに出ます。

modの権限:askより先に許可でき、denyはガード次第

modは、インストールしたあなたのアカウントでできることを、ほぼすべてできます。公式ドキュメントが挙げている範囲は次のとおりです。

  • アカウントが触れる場所ならどこでもファイルを読み書きし、プログラムを起動し、ネットワークに接続する
  • 環境変数や設定ファイルを読む。そこに置いたAPIキーも含む
  • 送ったプロンプトと、Claudeのツール呼び出しをすべて見る
  • プロンプトやツール呼び出しを書き換える、あなたが入力したかのようにプロンプトを送る、別のセッションにメッセージを送る
  • 確認が出る前にツール呼び出しを許可する
  • あなたのプランやAPIキーでモデルを呼び出し、使用量を消費する

問題になりやすいのは、これらが既存の権限ルールとどういう順番で効くかです。ツール呼び出しを許可・拒否するのはtool.checkというhookで、tool.callのhookとPreToolUseのsettings hookのあとに、allow・ask・denyのどれかを返します。

守りたいものmodに対して効くか
askルールによる確認効かない。modが先に許可すれば確認は出ない
自分の設定ファイルやプラグインのPreToolUseによるブロック効かない。modはブロックされた呼び出しを許可できる。modがツールを実行せず自前の結果を返すと、これらのsettings hookはそもそも走らない
auto modeの分類器modが許可した呼び出しは分類器のチェックを通らずに実行される
denyルールガードが読み込まれる環境では効く(管理者がallowModsToOverrideDenyRulesを設定した場合を除く)。ガードがない環境で効くとは書かれていない
管理設定のPreToolUse効く。どのmodより先に走り、そのブロックは最終。modが呼び出しを書き換えると、書き換え後の呼び出しにもう一度かかる
mod自身の$.fsと$.processdenyルールの対象外。ガードがあっても、Read(.env)を拒否していても、modは$.fs.readで.envを読めるし、それを読むプログラムを起動できる
組織のネットワークポリシー$.http.fetchには効く。$.process.runで起動したプログラムには効かない
サンドボックス囲うのはClaudeが実行するBashコマンドだけ。modが起動したプロセスは外で動く
権限確認の画面modは見た目も表示内容も変えられない。ただし画面が出る前に許可・拒否はできる

ここでいうガードは、組み込みmodのcc-plugin-sec-defaultです。ユーザーが入れたどのmodより先に読み込まれ、ユーザーは止められません。読み込まれる条件は次のどちらかです。

  • マシンに管理設定(managed settings)がある
  • TeamかEnterpriseプランでClaude Codeにログインしている

APIキー、Amazon Bedrock、Google CloudのAgent Platform、Microsoft Foundryで使っている場合は、管理設定があるマシンでだけ読み込まれます。この2条件を素直に読むと、個人のProやMaxプランでログインしていて管理設定もないマシンでは、ガードは読み込まれないことになります。その環境では、denyルールがmodの許可より優先されるとはドキュメントに書かれていません。

modに対して効かない守り、ガード次第の守り、効く守りを3列で整理し、ガードの読み込み条件を添えた図

実際の判断に落とすと、次のようになります。

modを入れるのは、その作者が書いたスクリプトを自分のアカウントで常駐させるのと同じだと考えておくのが安全です。

インストール前の確認:validateのcalls行とソースを読む基準

modを入れる前に、コードを実行せずに中身を調べられます。手順は4段階です。

  1. プラグインのファイルを手元に取得する。たとえばgit clone https://github.com/OWNER/REPOでリポジトリを複製する
  2. シェルでclaude plugin validate ./some-modを実行する
  3. 出力のhooks:行とcalls:行を読む
  4. 下の表で「ソースを読む」に当たる呼び出しがあれば、その箇所のコードを読む

validateは、Claude Codeがmodを読み込むときと同じ静的解析を、コードを実行せずに行います。modがファイル・プロセス・ネットワーク・モデルに触れる手段はmods API(コード上の$)しかなく、validateが読み取れない書き方でAPIを使うmodはClaude Codeが読み込みを拒否します。つまりcalls:行は「このmodが使える能力」の一覧として信頼できます。足りないのは、その能力を何に使うかです。

インストール前に確認する4段階と、blast-radiusの$.process.runが実際に起動するsleepとbash -cの例

hooks:行で注意するのは次のイベントです。

  • tool.call、prompt.submit:すべてのツール呼び出しとプロンプトを見て、書き換えられる
  • session.append:会話の各行を、保存される前に書き換えられる
  • ui.render{component=AskUserQuestion}:Claudeがユーザーに質問するダイアログを描き直せる
  • tool.check:確認が出る前にツール呼び出しを許可・拒否できる。上の優先関係がそのまま当てはまる

calls:行は次の表で読みます。左2列は公式ドキュメントの説明、右列はソースを読むかどうかの目安です。

calls:に出る呼び出しできることソースで確かめること
$.process.run、$.process.spawnあなたとしてプログラムを起動する必ず読む。どのコマンドを、どの引数で起動するか
$.http.fetchネットワークに接続する必ず読む。送り先と、送る中身
$.fs.read、$.fs.writeアカウントが触れる場所ならどこでも読み書き読み書きするパス。ホームディレクトリ全体や秘密ファイルに届くか
$.env.get、$.settings.read環境変数と設定を読む。APIキーを含みうる出力のenv reads:行で変数名が分かる。名前が用途と合っているか
$.env.set以後に起動するコマンドやMCPサーバーの環境変数を変えるenv writes:行の変数名。PATHのように実行内容を変えるものか
$.model.completeあなたのプランかAPIキーでモデルを呼ぶ呼ぶ頻度とトリガー
$.prompt.submitあなたの言葉としてプロンプトを送れる送る文面と送るタイミング
$.session.send別のセッションやサブエージェントのClaudeにメッセージを送る送る相手と内容
$.mcp.call接続中のMCPサーバーのツールを呼ぶ。セッションの権限ルールに従うどのツールを呼ぶか

入れない判断の目安も置いておきます。$.http.fetchがあり、同時に$.fs.read・$.env.get・$.settings.readのどれかがあって、送り先と送る中身をソースで追えないmodは入れない。hooks:にtool.checkがあるのに、何を許可するのかが読み取れないmodも同様です。プラグインを更新すると中身のコードも変わるので、更新後にもう一度validateを通します。

Anthropic公式サンプル3つのvalidate結果

Anthropicはanthropics/claude-code-playgroundリポジトリのclaude-code/modsフォルダ(Anthropic公式のサンプルmod)でサンプルを公開しています。サポートなしで現状のまま共有されているものです。2026年10月1日のコミット569c5283を取得してvalidateにかけた結果は次のとおりです。

$ claude plugin validate claude-code/mods/token-weather
  ❯ ./token-weather.mjs hooks: session.start, turn.complete, ui.render{component=AbovePrompt}
  ❯ ./token-weather.mjs calls: $.session.usage (via takeReading), $.ui.invalidate (via takeReading), $.ui.resolve
✔ Validation passed

$ claude plugin validate claude-code/mods/blast-radius
  ❯ ./blast-radius.mjs hooks: tool.call{tool=Bash}, ui.render{component=Pane}, ui.render{component=AbovePrompt}
  ❯ ./blast-radius.mjs calls: $.clock.now, $.process.run, $.session.cwd, $.ui.close, $.ui.invalidate, $.ui.open, $.ui.resolve, $.ui.toast
✔ Validation passed

$ claude plugin validate claude-code/mods/replay-theater
  ❯ ./replay-theater.mjs hooks: session.start, command.run{command=replay}, tool.call, turn.start, turn.complete, ui.render{component=AbovePrompt}, ui.render{component=Pane}, ui.close
  ❯ ./replay-theater.mjs calls: $.clock.sleep (via openReplay), $.command.register, $.fs.exists (via stepsFor), $.fs.read (via stepsFor), $.session.cwd (via stepsFor), $.ui.close (via replayView), $.ui.invalidate, $.ui.open (via openReplay), $.ui.resolve
✔ Validation passed

3つとも合格で、$.http.fetch、$.env.get、$.model.completeはどれも呼んでいません。読み方の例を挙げます。

  • token-weather(プロンプトの上にコンテキストウィンドウの予報を出す):呼ぶのはセッションの使用量と描画だけ。ファイルにもネットワークにも触れない
  • replay-theater(直前のターンでClaudeが加えたファイル編集を/replayで順に見せる):$.fs.readがある。(via stepsFor)とあるので、どのファイルを読むかはstepsFor関数を見れば分かる
  • blast-radius(rm -rfやforce pushのような危険なシェルコマンドを保留し、影響を見せて実行かキャンセルかを選ばせる):$.process.runがある。ここはソースを読む必要がある

blast-radiusのソースで分かったこと

validateが示すのは「プログラムを起動する」という能力だけです。hooks/blast-radius.mjsを読むと、$.process.runで起動しているのは次の3種類でした。

  • 39行目と73行目:sleep。実行/キャンセルのボタンが押されるまで待つためのループで、ソースのコメントによれば、hook自身の持ち時間は10秒だが$の呼び出し中の時間はそこに数えられないため
  • 278行目:bash -cの補助スクリプト。cdの移動先を解決する
  • 337行目:bash -cの補助スクリプト。rmが消すことになるファイル数とバイト数を数える

保留の対象は、-rや-f付きのrm、git reset --hard、git push --force・-f・--force-with-lease・+ref、alembic upgrade、rails db:migrate、prisma migrate、manage.py migrateです。どれも、危険なコマンドを保留して影響を見せるという公式の説明に沿った使い方でした。同じ$.process.runでも、起動するのがcurlで、引数に環境変数を詰めていれば話はまったく違います。その違いはcalls:行には現れません。

試す・入れる・止める・外す:modの管理コマンド

1セッションだけ試す:--plugin-dir

インストールせずに試すなら、プラグインのディレクトリを--plugin-dirで渡します。そのセッションだけ読み込まれ、保存するとhookのコードがホットリロードされます。複数試すときはフラグを繰り返します。フラグを渡せないアプリでは、環境変数CLAUDE_CODE_PLUGIN_DIRSで同じことができます。

bash
git clone https://github.com/anthropics/claude-code-playground
cd claude-code-playground/claude-code/mods
claude --plugin-dir ./token-weather

token-weatherが実際にプロンプトの上に描画される様子は、対話セッションを開いていないので確認していません。

インストールする:マーケットプレイス名を付けて指定する

modはプラグインとして、マーケットプレイスからインストールします。指定はプラグイン名@マーケットプレイス名です。

  • セッション内:/plugin install token-weather@claude-code-playground-mods
  • シェル:claude plugin install token-weather@claude-code-playground-mods

シェルでインストールしたとき、すでにセッションを開いていれば、そのセッションで/reload-pluginsを実行すると読み込まれます。実行しなければ次の起動時から有効です。スコープの既定はユーザー単位で、--scope projectか--scope localで変えられます。

マーケットプレイスは/plugin marketplace addかclaude plugin marketplace addで追加します。指定できるのは、GitHubのowner/repo(#refで参照を指定可)、任意のgit URL、./か../で始まるローカルパス、ホストされたmarketplace.jsonのURLです。公式サンプルを複製したフォルダをマーケットプレイスとして追加し、インストールから削除までを2.1.288で実行した出力は次のとおりです。

$ claude plugin marketplace add ./
✔ Successfully added marketplace: claude-code-playground-mods (declared in user settings)

$ claude plugin install token-weather@claude-code-playground-mods --scope user
✔ Successfully installed plugin: token-weather@claude-code-playground-mods (scope: user)

$ claude plugin list
Installed plugins:
  ❯ token-weather@claude-code-playground-mods
    Version: 0.1.0
    Scope: user
    Status: ✔ enabled

$ claude plugin disable token-weather@claude-code-playground-mods
✔ Successfully disabled plugin: token-weather (scope: user)

$ claude plugin uninstall token-weather@claude-code-playground-mods
✔ Successfully uninstalled plugin: token-weather (scope: user)

ローカルの複製をマーケットプレイスにした場合、そのフォルダを移動・削除するとmodは読み込まれなくなります。

ターミナルのセッションで/pluginを開くと、タブの下に1 mod active · first-modのような薄い行で、読み込まれたmodの数と名前が出るとドキュメントにはあります。組み込みmodはこの行に含まれません。

止める・外す:範囲別の3つの方法

止めたい範囲方法一緒に止まるもの
1つのmod/pluginのInstalledタブ(Tabキーで切り替え)で無効化かアンインストール。シェルならclaude plugin disable/uninstallなし
1セッションだけ、入れたmodすべてclaude --safe-modeで起動ほかのカスタマイズも止まる
すべてのセッションで、入れたmodすべて~/.claude/settings.jsonに"disableAllHooks": true自分のsettings hookとカスタムstatusline。組織が管理するものは動き続ける

disableAllHooksで止まるのはmodのコードだけで、同じプラグインに入っているskill、コマンド、エージェント、MCPサーバーは読み込まれ続けます。プラグインごと外したいならアンインストールします。組み込みmodは、disableAllHooks、--bare、--safe-modeのどれでも止まりません。

組み込みmod:you-should-knowとsec-defaultの役割

Claude Code自身の機能の一部もmodとして作られています。/pluginのInstalledタブでBuilt-inの下に並び、更新やアンインストールはできません。

/pluginでの名前役割止め方
cc-plugin-agents-mdAGENTS.mdをプロジェクトの指示として読み込む/pluginで無効化、または読み込む指示ファイルを選ぶ
cc-plugin-diff/diffを引き受けてペインを描く/pluginで無効化。/diffは組み込みの版が答える
cc-plugin-plugin-authoringmod作成用のplugin-authoring skillをClaudeに渡す。modのコードは持たない/pluginで無効化
cc-plugin-sec-default組織が管理するものをユーザーのmodから守るガードユーザーは止められない
cc-plugin-telemetryClaude Codeと組み込みmodの分析記録を送る/pluginで無効化、またはDISABLE_TELEMETRYなどで分析を切る
cc-plugin-you-should-know長めの作業中に横で見張るエージェントを動かし、見落としそうなことをプロンプトの上に表示する既定で無効。/plugin enable cc-plugin-you-should-know@builtinで有効化し、止めるときは/pluginで無効化

diff、agents-md、sec-default、telemetryのソースはClaude Codeリポジトリのmodsフォルダ(Anthropic公式の組み込みmod)で公開されています。sec-defaultのコードは、ガードが実際に何を見ているかを確かめたいときに読めます。

modを自作する:Claudeに頼むか、3ファイルを自分で書く

Claudeに頼む場合:dev-modsに作られ、期限が来ると消える

対話セッションで欲しいmodを説明すると、Claudeが組み込みのplugin-authoring skillを使って書きます。/plugin-authoringで自分からskillを読み込ませることもできます。ドキュメントの例はmake a mod that shows the current git branch above the promptです。

  • ファイルは~/.claude/dev-mods/<セッションID>/<mod名>/に作られる。defaultとacceptEditsの権限モードでは~/.claudeが保護されたパスなので、ファイルごとに承認を求められる
  • 最初のファイルが保存されると、このセッションでホットリロードを有効にするかを聞かれる。有効にするとターンの終わりに読み込まれ、以後の変更もターンごとに反映される
  • 読み込まれるのは作ったセッションの中だけ。フォルダはcleanupPeriodDaysを過ぎると削除されるので、残したいなら~/mods/git-branchのような自分の場所へコピーし、claude --plugin-dir ~/mods/git-branchで読み込む
  • claude -p、dontAskモード、信頼していないワークスペース、modを無効にしたセッションでは読み込まれない

この流れはログインした対話セッションが必要なため、実行していません。

自分で書く場合:hooks.jsonのmodulesキーとregister関数

Node.jsもバンドラーもビルドも要りません。Claude Codeが.jsと.tsを直接読み込みます。ドキュメントのチュートリアルfirst-modは3ファイルで、ツール呼び出しを数えてスピナーの横に表示し、/tallyコマンドで件数を出します。

first-mod/
├── .claude-plugin/
│   └── plugin.json
└── hooks/
    ├── hooks.json
    └── register.js

plugin.jsonはマニフェストです。

json
{
  "name": "first-mod",
  "version": "0.1.0",
  "description": "Counts Claude's tool calls, shows the count beside the spinner, and adds a /tally command",
  "author": { "name": "Your Name" }
}

hooks/hooks.jsonのmodulesキーが、このプラグインをmodにしている部分です。

json
{
  "description": "The first-mod hooks module",
  "modules": ["./register.js"]
}

hooks/register.jsが本体です。各hookは($, e, next)を受け取ります。$がmods API、eがイベント、nextが次のハンドラ(ほかのmodとClaude Code本来の処理)です。

javascript
// 下のhookで共有するカウント
let calls = 0

// modが読み込まれたときに1回だけ呼ばれる
export function register(on) {
  // セッション開始時に/tallyコマンドを登録
  on('session.start', async ($, e, next) => {
    await $.command.register({
      name: 'tally',
      description: 'Show how many tool calls Claude has made',
    })
    return next(e)
  })

  // Claudeがツールを使う直前に毎回呼ばれる
  on('tool.call', async ($, e, next) => {
    calls += 1
    // 画面を描き直させて新しい件数を出す
    $.ui.invalidate('ui.render')
    // ツールは通常どおり実行させる
    return next(e)
  })

  // /tallyと入力したときだけ呼ばれる
  on('command.run', { command: 'tally' }, async () => {
    return { text: 'Claude has made ' + calls + ' tool calls since this mod loaded' }
  })

  // スピナーを描くたびに呼ばれ、語の後ろに件数を足す
  on('ui.render', { component: 'Spinner' }, async ($, e, next) => {
    return next({ ...e, props: { ...e.props, suffix: ' · tool calls: ' + calls + '…' } })
  })
}

tool.callとsession.startはnext(e)を返して流れをそのまま通し(観察)、ui.renderは中身を変えてnextに渡し(書き換え)、command.runはnextを呼ばずに自分で答えます(応答)。hookにできるのはこの3つの扱い方です。

2.1.288で実行した確認の出力です。

$ claude plugin validate ./first-mod
  ❯ ./register.js hooks: session.start, tool.call, command.run{command=tally}, ui.render{component=Spinner}
  ❯ ./register.js calls: $.command.register, $.ui.invalidate
✔ Validation passed

$ cd first-mod && claude plugin test
tests/first-mod.test.ts:
(pass) /tally reports the tool calls the mod has seen [64.48ms]
 1 pass
 0 fail
Ran 1 test across 1 file. [0.34s]

$ claude -p "/tally" --plugin-dir ./first-mod
first-mod: Claude has made 0 tool calls since this mod loaded

claude plugin testが実行しているのは、ドキュメントにあるテストファイルtests/first-mod.test.tsです。ツール呼び出しを2回発生させて/tallyの返答を確かめるもので、セッションもログインもネットワークも使いません。所要時間は実行のたびに変わります。最後のclaude -p "/tally"は、ログインしていないCLIでもそのまま答えました。command.runはモデルを呼ばずに返答するためです。

validateが落ちたときのエラー例

わざと壊したコピーで出たエラーです。イベント名を'tool.calls'と打ち間違えた場合:

✘ Found 1 error:
  ❯ modules../register.js: bad-mod: .../hooks/register.js:7: "tool.calls" is not an event; $ is always spelled $.noun.event(...) at the call site, on is always on("<event>", hook), and next.to always next.to(e, "<tier>")
✘ Validation failed

hooks.jsonのキーを"module"と打ち間違え、hooksキーもない場合:

✘ Found 1 error:
  ❯ root: hooks.json must have `hooks` (the hook matchers) or `modules` (hooks modules), or both
✘ Validation failed

ドキュメントのトラブルシュートには「modulesキーがない、または綴りが違うと、validateは通るがhooks行が出ない」とあります。2.1.288でhooksキーもmodulesキーもないhooks.jsonを試したところ、上のように不合格になりました。hooksキーがある場合は、ドキュメントの説明どおりになると考えられます。

静的解析に読ませるための書き方の決まりもあります。

  • $.store.get('notes')のように、mods APIは毎回$から省略せずに書く。const ui = $.uiのような代入や分割代入は不合格
  • onに渡すイベント名は文字列リテラルで書く。変数やループは不可
  • importはプラグインのディレクトリ内のファイルを相対パスで。外部パッケージはclaude-codeだけ使える。動的なimport()は不可
  • リロードのたびにregisterが呼び直され、モジュール変数はリセットされる。値を保つなら$.stateを使う
  • --plugin-dirで読み込むと、そのバージョンの型定義が.claude-plugin/types/に書き出される。ドキュメントと食い違うときは型定義が正しい

配布するとき:名前とバージョンの注意

少人数ならディレクトリかzipを渡し、チームなら自分のマーケットプレイス(たとえば非公開リポジトリ)に載せます。組織全体には管理者が管理設定で配布でき、誰にでも公開するなら公開リポジトリにするかAnthropicのディレクトリに申請します。claude-で始まるような、Anthropic製に見えるプラグイン名はvalidateで落ちます。イベントやメソッドはリリースごとに変わりうるので、READMEには動作を確かめたClaude Codeのバージョンを書いておきます。インストールしたコピーはバージョン単位でキャッシュされるため、開発中は--plugin-dirで元のディレクトリを読み込みます。

modが動かない原因の切り分け:validateとデバッグログ

modが壊れていても、Claude Codeはそのmodを飛ばしてセッションを続けます。そのため「壊れている」と「何もしていない」が同じに見えます。次の順で切り分けます。

症状確かめること
追加したコマンドも描画も何も出ないclaude --versionで2.1.287以降か。次にclaude plugin validateでイベント名の誤りや読めないモジュールがないか
どのmodも読み込まれない空ディレクトリでclaude plugin test。turned offと出たら設定かポリシーが止めている
初めて開いたディレクトリでだけ動かない対話セッションの信頼確認に答えていない
インストール済みのプラグインが1つも読み込まれない--safe-modeで起動していないか
VS Code拡張やclaude -pで表示が出ない仕様。hookは動いているが描画はされない
組織のPCで自分のmodだけ動かないデバッグログにallowManagedModsOnlyの行がないか。あれば管理者に相談する

読み込みを拒否された理由は、modの名前を含む1行で記録されます。出る場所はセッションによって違います。

  • --plugin-dirで開いた対話セッション(ホットリロード中):トランスクリプトに薄い行で出る
  • マーケットプレイスから入れたmodを使うセッションなど:デバッグログにだけ出る。claude --debugで起動して読む
  • claude -pと--plugin-dirの組み合わせ:標準エラー出力に出る

拒否の行はhooks module <名前> not loaded:で始まり、コロンの後が理由です。disableAllHooks in managed settings、only managed plugins and built-in plugins run、(--bare)、another plugin of that name loads first(同名のプラグインが先に読み込まれた)などがあります。ガードがmodの許可を退けた場合はtried to lift a deny rule in your settingsと出て、その呼び出しは拒否されたままです。詳しい一覧は公式ドキュメントの「mod のトラブルシューティング」にあります。

Claude Code modsの使用量・settings hook・探し方についての質問

Claude Code modsを入れると使用量は増えますか

hookが動くこと自体はモデルの呼び出しではなく、上の/tallyのようにモデルを使わずに完結するmodもあります。使用量に直結するのは、calls:行に$.model.completeが出るmodです。この呼び出しはあなたのプランかAPIキーでモデルを使います。$.prompt.submitでプロンプトを送るmodも、そのぶんClaudeのターンが走ります。どのタイミングで呼ぶかはソースで確かめます。

Claude Code modsが出たらsettings hookは使わなくなりますか

使い続けて問題ありません。組織向けのドキュメントには、settings hookについて廃止されるものは何もないと明記されています。手元のスクリプトでツール呼び出しをブロック・記録するだけなら、settings hookのほうが単純です。

コミュニティ製のClaude Code modsはどこで探せますか

第三者が運営するawesome-claude-code-mods(GitHubで公開されたmodの非公式カタログ)があり、2026年10月6日時点で2,685件の公開modをclaude plugin validateの出力付きで掲載しています。Anthropicの公式ディレクトリではなく独立したスキャンで、カタログ自身も「検証は安全な挙動を保証しない」と書いています。気になるmodが見つかったら、validateの出力を見るだけで済ませず、自分で複製してcalls:行とソースを確かめてください。目的別のskillやMCPを探しているなら、Claude Codeで最初に使うべきSkills 2026年版:ワークフロー別の公式スターターとClaude Codeで最初に入れるべきMCP 2026年版:ワークフロー別の初手のほうが近い答えです。

参考資料5

本文で参照している外部ページを、登場順に並べています。最終更新日:2026年10月6日。

  1. 1.Anthropic公式のmodsドキュメント(日本語版「Mods の概要」)code.claude.com/docs/ja/plugins/mods/overview
  2. 2.claude-code/modsフォルダ(Anthropic公式のサンプルmod)github.com/anthropics/claude-code-playground/tree/main/claude-code/mods
  3. 3.Claude Codeリポジトリのmodsフォルダ(Anthropic公式の組み込みmod)github.com/anthropics/claude-code/tree/main/mods
  4. 4.公式ドキュメントの「mod のトラブルシューティング」code.claude.com/docs/ja/plugins/mods/troubleshoot
  5. 5.awesome-claude-code-mods(GitHubで公開されたmodの非公式カタログ)github.com/karanb192/awesome-claude-code-mods
さらに読む: Claude Code
Claude Codeの流出事実と公開されているモデル・アカウント契約を並べて示す図
Claude Code

Claude Code ソース流出: BANリスク、現行モデル、アカウント構造を整理する (2026)

Claude Code では 2026 年 3 月に内部ソースコードの露出が実際に起きました。Anthropic は、これは外部侵害ではなくリリースのパッケージングミスであり、顧客データや認証情報は露出していないと説明しています。重要なのは、この事実を BAN の噂、古いモデル情報、Claude と Console の混同から切り分けることです。

15 分
Claude Code のバージョンと送信経路を確認し、古いパラメータを取り除く分岐図
Claude Code

Claude Code で top_p deprecated? まず Opus 4.7 の新しい request rule を確認

Claude Code の top_p deprecated は、実際に呼び出すモデルへ古いサンプリング指定が送られていないかを調べるのが出発点です。設定ファイルだけでなく、アダプタが組み立てた最後のリクエストから指定を省き、同じ作業が完了するか確認します。

19 分