本文へ移動
Claude Tips

プラグインを作って配る

プラグインを一から作る手順、コンポーネントごとの書き方、依存関係、マーケットプレイスの作成・ホスト・公開、組織への配布と管理設定、コスト計測までまとめます。

プラグインは、スキル・エージェント・フック・MCP サーバーなどと、名前を決める plugin.json(マニフェスト)をまとめたディレクトリです。Claude Code が1つの単位として読み込むので、チームで共有する、複数のプロジェクトへ入れる、バージョン付きで公開する、といったことができます。使う側の手順はプラグインを使う、フィールドやコマンドの全表はプラグインのリファレンスにあります。

このページで分かること#

  • 空のディレクトリから最初のプラグインを作り、マーケットプレイスなしで試す方法
  • 既存の .claude/ の設定をプラグインに移す方法
  • コンポーネント(スキル・コマンド・エージェント・フック・MCP・LSP・実行ファイル・設定・テーマ・チャネル・モニター)の書き方と、ユーザー設定・パス変数
  • プラグイン同士の依存関係とバージョン範囲
  • マーケットプレイスの作成・ホスト・更新・改名、公開、組織への配布と管理設定
  • コストと利用の計測、CLI やプロジェクトからのおすすめ表示

プラグインにするかを決める#

スキル・エージェント・フック・MCP サーバーは、プロジェクトやホームのディレクトリで単体でも動きます。1つのプロジェクトか自分だけに使うあいだは、その形のままで足ります。チームで共有する、複数のプロジェクトへ入れる、バージョン付きで公開する、というときにプラグインにします。

単体の設定をプラグインへ移すと、置き場所と名前が変わります。

  • 置き場所:プラグインのルート(プラグイン自身のディレクトリ)の下の skills/・agents/・hooks/hooks.json・.mcp.json
  • 名前:プラグインのスキルとエージェントには、プラグイン名が接頭辞に付く(/my-plugin:hello)。2つのプラグインが同じ hello を持っても衝突しない

最初のプラグインを作る#

スキル1つだけのプラグイン(あいさつ)を作り、--plugin-dir(インストールせず、1セッションだけ読み込む)で動かします。作業は、プラグインを置きたいディレクトリで行います。置き場所はどこでもよく、パスを Claude Code に渡して使います。

bash
mkdir -p my-first-plugin/.claude-plugin

my-first-plugin/.claude-plugin/plugin.json:

json
{
  "name": "my-first-plugin",
  "description": "A greeting plugin to learn the basics",
  "version": "1.0.0",
  "author": {
    "name": "Your Name"
  }
}
フィールド 内容
name 必須。プラグインの識別子で、スキルとエージェントの接頭辞になる。空白を入れない
description /plugin でユーザーに見える説明
version 省略可。設定すると、変えるまでユーザーはその版にとどまる(設定するか省くかは、マーケットプレイスの節を見る)
author 作者表示。name が必須で、email と url は省略可

.claude-plugin/ に入れるのは plugin.json だけです。スキルは my-first-plugin/ 直下の、そのフォルダの隣に置きます。スキルは skills/<名前>/SKILL.md です。

bash
mkdir -p my-first-plugin/skills/hello

my-first-plugin/skills/hello/SKILL.md:

markdown
---
name: hello
description: Greet the user with a friendly message
disable-model-invocation: true
---

Greet the user warmly and ask how you can help them today.

disable-model-invocation: true は、Claude が自分でスキルを動かさない指定です。Claude に動かさせたいスキルでは、この行を外します。コマンドの名前は、プラグイン名とスキル名を組み合わせた /my-first-plugin:hello です(フロントマターはスキル)。

検証して、プラグインを付けて起動します。

bash
claude plugin validate ./my-first-plugin
claude --plugin-dir ./my-first-plugin

✔ Validation passed が出れば通っています。✘ Validation failed なら、結果の行より上の各行が直すフィールドを示します。起動したら /my-first-plugin:hello を実行すると、Claude があいさつを返します。プラグインは --plugin-dir を付けて始めたセッションでだけ読み込まれます。

ヒント

大きなプラグインを Claude と一緒に雛形から作って検証するには、公式マーケットプレイスの plugin-dev プラグインを入れ、/plugin-dev:create-plugin に作りたいものの説明を続けて実行します。設計・作成・検証を案内してくれます。

プラグインの配置#

コンポーネントの種類ごとに、プラグインルート(--plugin-dir に渡すディレクトリ)の下の決まった場所に置きます。使うものだけ作ります。

場所 内容
.claude-plugin/plugin.json マニフェスト。--plugin-dir で読み込むプラグインにマニフェストが無いと、ディレクトリ名がプラグイン名になる
skills/ スキルごとに <name>/SKILL.md のディレクトリ
commands/ 平らな Markdown ファイル。スキルの古い形。新しいプラグインでは skills/ を使う
agents/ サブエージェントごとに1つの Markdown ファイル
hooks/hooks.json フックの設定。トップに "hooks" キーを置き、その値は設定ファイルの hooks と同じ形
.mcp.json MCP サーバーの定義

注意

.claude-plugin/ に入れるのは plugin.json だけです。そこに置いたコンポーネントは読み込まれません。プラグインルートはプラグイン自身のディレクトリで、~/.claude/ そのものではありません。~/.claude/.mcp.json に置いた .mcp.json は読み込まれません。

完全な配置の一覧はプラグインのリファレンスにあります。

配る方法の選び方#

作ったプラグインは、手元にしかありません。他の人へ渡す方法は3つです(詳細は下の「公開する」)。

  • 数人へ直接渡す:ディレクトリか .zip を渡す。公開は不要
  • 自分のマーケットプレイスに載せる:チームがマーケットプレイスを1度追加すれば、名前で入れて更新も受けられる
  • Anthropic のディレクトリへ提出する:審査後、claude.ai と Cowork で追加でき、アカウント経由で Claude Code にも届く

マーケットプレイスなしで開発する#

書いている途中のプラグインは、マーケットプレイスなしで、ディスクか URL から直接読み込めます。

方法 内容
--plugin-dir ディレクトリか .zip を1セッションだけ読み込む
--plugin-url URL の .zip を取得して1セッションだけ読み込む
CLAUDE_CODE_PLUGIN_DIRS フラグを足せないときに、絶対パスを環境変数で渡す(v2.1.280 以降)
claude plugin init ~/.claude/skills/ の下に、毎セッション読み込まれるプラグインの雛形を作る

読み込み方が違う同名のプラグインがあるときにどちらが残るかは、プラグインのリファレンスの名前の衝突の節にあります。

1セッションだけ読み込む#

どの方法でも設定ファイルには何も書かれず、そのセッションだけです。セッション中にファイルを編集したら /reload-plugins で反映します。

bash
claude --plugin-dir ./my-first-plugin --plugin-dir ./other-plugin.zip
claude --plugin-dir ./plugins
claude --plugin-url https://example.com/my-first-plugin.zip
  • --plugin-dir は繰り返して複数読み込める。ディレクトリでも .zip でもよい
  • プラグインを並べたフォルダ(--plugin-dir ./plugins)を渡すと、直下の各サブフォルダのうち .claude-plugin/plugin.json を持つものが、別々のプラグインとして読み込まれる(v2.1.265 以降)。フォルダ自身に .claude-plugin/ もコンポーネントも無いときにこの扱いになり、それ以外は、マニフェストの無いサブフォルダも含め、エラーなしで飛ばされる
  • .claude-plugin/marketplace.json を置いたフォルダでも、その .claude-plugin/ に plugin.json が無ければプラグインのフォルダが読み込まれる(v2.1.281 以降)。marketplace.json は読まれず、そこから入れる・有効にすることはない
  • 対話セッションでは、フォルダに足したサブフォルダが、マニフェストができた時点で新しいプラグインとして読み込まれ、消したものは外れる。プロンプトキャッシュが無効になるなら変更を保留し、/reload-plugins で反映するよう案内する
  • --plugin-url は起動時に .zip をダウンロードする。複数なら、フラグを繰り返すか、引用符で囲んだ1つの引数に空白区切りで並べる。信頼できるアーカイブだけを指す。取得に失敗するか不正なら、プラグインなしで起動し、/plugin の「Errors」タブに読み込みエラーが残る
  • CLAUDE_CODE_PLUGIN_DIRS のパスは --plugin-dir と同じに読み込まれ、--plugin-dir のものに足されます。プロジェクトやローカルの設定では、この変数は設定できません
  • 管理設定で --plugin-dir と CLAUDE_CODE_PLUGIN_DIRS を止められます(下の組織の節)。依存するプラグインと一緒に試す方法は、下の依存関係の節にあります

毎セッション読み込む#

~/.claude/skills/ の下にあるフォルダで、.claude-plugin/plugin.json を持つものは、フラグもインストールもなしに毎セッションプラグインとして読み込まれます。

bash
claude plugin init my-tool

~/.claude/skills/my-tool/ を作り、.claude-plugin/plugin.json とルートの SKILL.md を置きます。✔ Created plugin "my-tool" at ~/.claude/skills/my-tool と、It will auto-load next session as my-tool@skills-dir. Run /reload-plugins to load it now. が出ます。--with skills で skills/ の下にスキルの雛形も作れます(--with のほかの値はプラグインのリファレンス)。

  • ルートの SKILL.md は個人のスキルでもあるため、/my-tool で呼ぶ(/my-tool:my-tool ではない)。プラグイン内の skills/ のスキルには接頭辞が付く(/my-tool:example)
  • 読み込みを止めるには、ディレクトリを消すか、claude plugin disable my-tool@skills-dir を実行する。ID の skills-dir は、マーケットプレイス名の代わりに入る名前(スキルのディレクトリから読み込まれるため)
  • リポジトリの全員に読み込ませるには、<project>/.claude/skills/<name>/ に同じ構成(.claude-plugin/plugin.json を含む)を自分で作る(読み込まれる条件はプラグインのリファレンス)

試して直す#

変更が反映されないときは、次の順に確かめます。

  1. シェルで claude plugin validate <path>。マニフェストと、全スキル・エージェント・コマンドのファイルのフロントマターを検査し、Validation passed で終了コード 0。--strict を付けると警告でも失敗する
  2. 動いているセッションで /reload-plugins。ディスクの編集を反映し、件数つきの Reloaded: の行を1行出す。その後、/plugin-name:skill で呼べるか、/plugin の「Installed」タブにあるかで確かめる
  3. 同じセッションで /plugin。「Installed」タブに、プラグインと詳細に見つかったコンポーネントが出る。「Errors」タブに、読み込みに失敗したものと理由(マニフェストが指す存在しないパスなど)が出る
  4. シェルで claude plugin list。セッション限りのものとスキルディレクトリのものが別の節に、Status: ✔ loaded か読み込みエラーつきで出る。開発中のものも出すには、plugin list の前に --plugin-dir とパスを渡す

MCP サーバーは、セッションで /mcp を実行して状態を見ます(MCP サーバーをつなぐ)。フックは、対応するイベントを起こして確かめます(たとえば、ファイルの編集を頼んで PostToolUse のフックを動かす)。その後でデバッグログを読めば、どのフックが一致したか、終了コード、出力が分かります(フックのリファレンス)。

症状 原因と対処
「Errors」タブに <component> path not found: <path>(例:commands path not found) マニフェストの commands・skills・agents・hooks のパスが何も指していない。パスを直すかディレクトリを作り、/reload-plugins
マーケットプレイスのルートへ --plugin-dir を向けても plugins/ の下のプラグインが読み込まれない(エラーも出ない) --plugin-dir はプラグインのルート(.claude-plugin/plugin.json とコンポーネントのディレクトリがある場所)を取る。marketplace.json は読まれない。1つのプラグインのフォルダに向けるか、マーケットプレイスを追加する
プラグインは読み込まれるがスキルが無い skills/ が .claude-plugin/ の中にあるか、マニフェストの skills がファイルを指している。skills/ をプラグインのルートへ移し、各 skills の項目を SKILL.md を含むディレクトリに向けて /reload-plugins
userConfig のダイアログが出ない ダイアログは、セッション内の /plugin 経由のインストールの一部。--plugin-dir やシェルの claude plugin install では出ない。読み込んだうえで、セッションで /plugin configure <plugin-name> を実行して開く

エラーごとの詳しい対処はプラグインのリファレンスのトラブルシューティングの表にあります。

ヒント

エラーなく読み込まれるプラグインでも、Claude の動きを狙いどおりに変えているとは限りません。シェルの claude plugin eval が、プラグインあり・なしでテストケースを動かして差を採点します(プラグインの評価(evals))。

既存の .claude/ の設定を変換する#

プロジェクトの .claude/ にあるスキル・エージェント・フックは、書き直さずにプラグインへ移せます。.claude/ を含むプロジェクトのルートで、次を実行します(cp のパスがそこからの相対のため)。

bash
mkdir -p my-plugin/.claude-plugin
cp -r .claude/commands my-plugin/
cp -r .claude/agents my-plugin/
cp -r .claude/skills my-plugin/

cp は、持っているディレクトリのぶんだけ実行します。my-plugin/.claude-plugin/plugin.json には、name・description・version を書きます。ls -a my-plugin で、コピーしたディレクトリが .claude-plugin と並ぶことを確かめます。

フックが .claude/settings.json か .claude/settings.local.json にあるなら、my-plugin/hooks/hooks.json を作り、設定ファイルの hooks オブジェクトをそのまま入れます(形は同じです)。

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [{ "type": "command", "command": "jq -r '.tool_input.file_path' | xargs npm run lint:fix" }]
      }
    ]
  }
}

claude --plugin-dir ./my-plugin で読み込み、各コンポーネントを新しい名前で確かめます。/deploy だったスキルは /my-plugin:deploy、reviewer だったエージェントは my-plugin:reviewer、フックは対応するイベントを起こします。元のファイルが .claude/ に残っているあいだは、プラグインのコピーと並んで読み込まれます。

  • スキルとエージェント:接頭辞があるので衝突せず、/deploy と /my-plugin:deploy のどちらも使える。Claude は reviewer と my-plugin:reviewer を2つのサブエージェントとして見る
  • フック:接頭辞が無いので、設定ファイルと hooks/hooks.json の両方にあると、イベントのたびに2回動く

動くと確かめたら、.claude/ の元のファイルと、設定ファイルの hooks オブジェクトを消します。

コンポーネントを足す#

各コンポーネントには、プラグイン内の既定のフォルダ、それを置き換えるか足すマニフェストのキー(任意)、ユーザーに見える名前があります。足したら、動いているセッションで /reload-plugins を実行するか、新しいセッションを始めます。読み込む前にファイルを確かめるには、プラグインのディレクトリでシェルから claude plugin validate . を実行します。

コンポーネント 既定の場所 マニフェストのキー
スキル skills/<name>/SKILL.md skills(既定の skills/ に足される)
コマンド commands/<file>.md commands(commands/ の走査を置き換える)
エージェント agents/<name>.md agents(agents/ の走査を置き換える)
フック hooks/hooks.json hooks(両方読み込まれる)
MCP サーバー .mcp.json mcpServers(同名なら、マニフェスト側が置き換える)
LSP サーバー .lsp.json lspServers(.lsp.json に足される。同名はマニフェスト側が置き換える)
実行ファイル bin/ なし
既定の設定 settings.json settings
テーマ themes/<slug>.json experimental.themes
出力スタイル output-styles/<name>.md outputStyles
ワークフロー workflows/<name>.js workflows(workflows/ の走査を置き換える)
チャネル (MCP サーバーに結び付ける) channels
モニター monitors/monitors.json experimental.monitors
ユーザー設定 なし userConfig

マニフェスト(plugin.json)が無くても、Claude Code はプラグインを読み込みます。マニフェストで必須のフィールドは name だけです。

スキル#

スキルは、説明が作業に合うときに Claude が読み込む SKILL.md で、ユーザーがコマンドとして実行することもできます。スキルごとに skills/ の下の専用ディレクトリに置きます。

markdown
---
description: Reviews a pull request for style and test coverage. Use when asked to review code.
---

Review the changed files. Report style problems first, then missing tests.

読み込むと /my-plugin:review で動きます。

  • コマンド名は /<plugin>:<directory>。フロントマターの name を設定すると、最後の部分を置き換え、プラグインの接頭辞は残る
  • 誰が呼べるか(Claude・ユーザー・両方)はフロントマターで決まる
  • 既定の skills/ の外のディレクトリは、skills マニフェストキーに並べる。commands や agents と違い、既定の skills/ の走査に足される
  • skills/ もマニフェストの skills も無ければ、プラグインルートの SKILL.md が1つのスキルとして読み込まれる。マーケットプレイスから入れると、スキル名が、プラグイン名ではなくキャッシュのディレクトリ名になってしまうので、フロントマターに name を書く
  • 指示を入れるにはスキルとして書く。プラグインルートの CLAUDE.md は読み込まれず、claude plugin validate は CLAUDE.md at the plugin root is not loaded as project context と警告する

毎回守らせたい規則は、スキルではなくフックとして足します(フックの使い方)。

コマンド#

コマンドは、名前で実行する1つの Markdown ファイルです。スキルの古い形で、新しい作業ではスキルを使います。.claude/commands/ から移すファイルのために commands/ を使います。commands/<file>.md は /<plugin>:<file> になり、サブディレクトリは名前の区切りを足します(commands/db/migrate.md は /my-plugin:db:migrate)。フロントマターはスキルと同じです。

別の場所に置きたいとき、または短いコマンドを Markdown ファイルなしで plugin.json の中に定義したいときは、commands キーを設定します。この場合は commands/ を走査しません。値は、パス、パスの配列、または、コマンド名を source(ファイル)か content(本文)に対応づけるオブジェクトです。

json
{
  "name": "my-plugin",
  "commands": {
    "about": {
      "content": "Summarize what this repository does in three sentences.",
      "description": "Summarize the repository"
    }
  }
}

エージェント#

サブエージェントは、専用の指示とコンテキストウィンドウで Claude が仕事を任せる別のアシスタントです。agents/ の下の Markdown ファイル1つが1体を定義します。

markdown
---
name: security-reviewer
description: Reviews code changes for security issues. Use after edits to authentication or input handling.
model: sonnet
---

You are a security reviewer. Read the changed files and report injection, authentication, and secrets-handling risks.

このエージェントは my-plugin:security-reviewer という名前で、@agent-my-plugin:security-reviewer で明示的に呼べます。名前の形は <plugin>:<name> で、<name> はフロントマター、無ければファイル名です。agents キーは agents/ の走査を置き換えます。

  • サブフォルダ:agents/ の下のサブフォルダも再帰的に読み込まれ、プラグイン名・サブフォルダ名・ファイル名がコロンでつながる(agents/review/security.md は my-plugin:review:security)。フロントマターの name はファイル名の部分だけを置き換え(name: audit なら my-plugin:review:audit)、マニフェストの agents に並べたファイルは、サブフォルダ名なしで読み込まれる("agents": "./custom/review/security.md" なら my-plugin:security)
  • 使えるフロントマター:name・description・model・effort・maxTurns・tools・disallowedTools・skills・memory・background・omitClaudeMd・isolation・color、および experimental の cacheTtl キー。isolation の有効な値は "worktree" だけ
  • 無視されるフィールド:permissionMode・hooks・mcpServers・initialPrompt。エージェントのファイルは単独ではフックや MCP サーバーを足せないので、プラグインのフックと MCP サーバーとして足す
  • フロントマターを解釈できないと、エージェントは全フィールドを無視して読み込まれ、ファイル名が名前に、Agent from my-plugin plugin が説明になる。見つけるには claude plugin validate

フック#

フックは、ファイル編集のあとなど、ライフサイクルの節目で自動的に動くものです。シェルコマンド・HTTP リクエスト・MCP ツールの呼び出し・モデルへのプロンプト・サブエージェントが使えます。プラグインのルートの hooks/hooks.json に、トップの "hooks" キーで置きます。形は settings.json の hooks と同じなので、既存の設定のフックをそのままコピーできます。

json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/format.sh\""
          }
        ]
      }
    ]
  }
}

scripts/format.sh を置いて実行可能にします。PostToolUse のフックが 0 で終わるとトランスクリプトには何も出ないので、動いたかはデバッグログかスクリプト自身の変更で確かめます。hooks/hooks.json とマニフェストの hooks キーの両方に書いたものが読み込まれます。イベントとペイロードはフックのリファレンスです。

  • プラグインのフックは、そのプラグインのスキルやコマンドが使われるのを待たず、セッションがプラグインを読み込むときに登録され、以後、イベントで動く。動く場面を絞るには matcher を狭める
  • 環境:どのフックのプロセスにも CLAUDE_PLUGIN_ROOT と CLAUDE_PLUGIN_DATA、ユーザー設定の各値の CLAUDE_PLUGIN_OPTION_<KEY> が入る
  • 引用:command に args が無いとシェル経由で動くので、${CLAUDE_PLUGIN_ROOT} のパスは二重引用符で囲み、展開したパスを1語に保つ。args を渡す場合は、各要素が1つの引数として渡され、シェルを通らないので引用は要らない
  • 自分の MCP ツールへのマッチ:プラグインが宣言した MCP サーバーのツールは mcp__plugin_<plugin>_<server>__<tool> なので、マッチャーにはこの完全な名前を書く。サーバー名だけのマッチャーは発火しない

フックを、Claude Code の中で動き、画面にも描ける JavaScript の関数として書くには、同じ hooks/hooks.json の modules キーの下にモジュールのファイルを並べます。それを持つプラグインは Mod(モッド)です(Mod を作る・試す)。

動かないときはプラグインのリファレンスの「フックが発火しない」の対処を見ます。

MCP サーバー#

MCP サーバーは、外部のシステムのツールを Claude に与えます。プラグインルートの .mcp.json に、プロジェクトの .mcp.json と同じ形で宣言します。

json
{
  "mcpServers": {
    "db": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"]
    }
  }
}

mcpServers のラッパーを省いて、db をファイルの最上位に置くこともできます。読み込んで /mcp を実行すると、サーバーが plugin:my-plugin:db と出ます。claude plugin validate は .mcp.json を検査し、読み込み時に捨てられる項目をエラーにします(v2.1.281 以降)。マニフェストの mcpServers キーは、インラインのサーバー一覧、JSON ファイルへのパス、またはその配列を取り、.mcp.json と同名のサーバーはマニフェスト側が置き換えます。

  • サーバー名は plugin:<plugin>:<server>。mcp_tool フックでサーバーを指すときも同じ形(フックのリファレンス)
  • ツール名は mcp__plugin_<plugin>_<server>__<tool>(db サーバーの query なら mcp__plugin_my-plugin_db__query)。権限ルール(権限ルール)とフックのマッチャーに使う名前
  • ${CLAUDE_PLUGIN_ROOT} などのパス変数は command・args・env で置換される。args は1要素が1つの引数なので引用は要らない
  • /reload-plugins を実行して反映されるとき、設定が変わらないサーバーは接続を保ち、変わったものは再接続し、消したものは切断される
  • ローカルの stdio サーバーは、Claude Code と、自分のマシンで動く Cowork のセッションでは動くが、claude.ai では動かない。claude.ai にも届けるには、https:// の URL でリモートサーバーを参照する(claude.ai と Cowork がコネクタとしてユーザーに示す)

パッケージ化した MCPB サーバー#

mcpServers キーには、MCPB ファイル(拡張子 .mcpb または古い .dxt)としてパッケージ化したサーバーも指定できます。プラグイン内のパスか https:// の URL を渡します。

json
{
  "name": "my-plugin",
  "mcpServers": "./servers/db.mcpb"
}

サーバー名は、バンドルのマニフェストの name から取られます。バンドルのマニフェストは、サーバーがユーザーに求める設定を user_config ブロックで宣言できます。必須の設定が保存されていない同梱サーバーは起動せず、/plugin の「Errors」タブに Bundled MCP server "<name>" was not started: it needs configuration と出ます。値は、/plugin の「Installed」タブでプラグインを選んで「Configure」を選ぶか、インストール時にシェルで claude plugin install へ --config <server>.<key>=<value> を渡して与えます(v2.1.285 以降。プラグイン内にパッケージされたバンドルにだけ使えます)。トランスポートと認証はMCP サーバーをつなぐにあります。

LSP サーバー#

LSP サーバーは、言語の診断とコード移動を Claude に与えます。自分の言語を公式のコードインテリジェンスのプラグインが既に扱うなら、書かずにそれを入れます。無ければ、プラグインルートの .lsp.json で宣言します。

json
{
  "gopls": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}

ファイルは、サーバー名を直接その設定に対応づけます(地図の外側にラッパーのオブジェクトはありません)。command はバイナリの名前で、引数は args に置きます。extensionToLanguage には、. で始まる拡張子が少なくとも1つ要ります。

  • claude plugin validate はこのファイルを読まない。項目が1つでも不正だと、ファイル全体が読み込み時に飛ばされ、「Errors」タブに Invalid LSP server config for ".lsp.json" が出る
  • プラグインは接続を設定するだけで、サーバーのバイナリは入れない。command はユーザーの PATH から名前で起動され、無ければ起動に失敗し、claude --debug に LSP server <name> failed to start と出る
  • 同じ拡張子を2つの有効なサーバーが宣言すると、先に登録された方が扱い、もう一方はその拡張子に使われない(1つのプラグイン内でも2つのプラグインにまたがっても同じ)。「Errors」タブに LSP server "<name>" is not used for <ext> files が出る
  • lspServers キーは、同じ形のインラインの一覧、JSON ファイルへのパス、またはその配列を取り、.lsp.json のサーバーに足される。同名ならマニフェスト側が置き換える
  • ログは標準出力でなく標準エラーへ出す。Claude Code はサーバーの標準出力をプロトコルメッセージとしてだけ読み、メッセージヘッダーは 64 KiB、本文は 32 MiB まで受ける。どちらかを超えるか、プロトコル以外を標準出力に書くと切断され、restartOnCrash と maxRestarts の上ではクラッシュとして数えられる。--debug では原因がデバッグログに出る

transport・タイムアウト・再起動などのフィールドはプラグインのリファレンスにあります。

実行ファイル#

プラグインルートの bin/ のファイルは、プラグインが有効なあいだ、Bash ツールのシェルの PATH に入り、Claude が素のコマンドとして実行できます。

bash
#!/bin/bash
echo "hello from my-plugin"

chmod +x bin/hello-plugin で実行可能にして読み込みます。bin/ はユーザー自身の PATH の項目のあとに来るので、プラグインが git や ls などのシステムのコマンドを隠すことはできません。claude.ai と Cowork は、トップレベルに bin/ があるプラグインを入れません(claude.ai の組織設定で配るものも同様)。

既定の設定#

プラグインが有効なあいだの既定値は、プラグインルートの settings.json、またはマニフェストの settings キーのインラインの同じオブジェクトで与えます。効くのは agent と subagentStatusLine の2つで、ほかのキーは捨てられます。agent は、プラグイン自身のエージェントをメインスレッドとして動かします。

json
{
  "agent": "security-reviewer"
}

同じキーが複数の場所にあるときの規則は次のとおりです。

  • ファイルがマニフェストに優先:両方があり、settings.json が対応キーを1つ以上設定していれば、settings.json が適用され、マニフェストの settings は無視される
  • ユーザーの設定がプラグインの既定に優先:設定の出どころの中で、プラグインの既定は最下層。ユーザー自身の ~/.claude/settings.json の agent が上書きする
  • 2つのプラグインが同じキーを設定:あとに読み込まれたプラグインの値が使われ、claude --debug に overrides setting が出る

agent の設定は設定キー一覧、subagentStatusLine はステータスラインを見ます。

テーマと出力スタイル#

プラグインは、カラーテーマと出力スタイルを持てます。どちらも、ユーザー自身のものと同じ選択画面に出ます。マニフェストのキーを設定すると、フォルダの走査を置き換えます。

コンポーネント 保存先 形式 出る場所 マニフェストのキー
テーマ themes/<slug>.json ユーザーが ~/.claude/themes/ に書くカスタムテーマと同じ形式 /theme(ファイルの name で) experimental.themes
出力スタイル output-styles/<name>.md name と description のフロントマターを持つカスタム出力スタイルの形式 /output-style(<plugin>:<name>) outputStyles

プラグインのテーマは読み取り専用で、ユーザーが /theme で編集すると、自分のテーマのディレクトリにコピーとして保存されます。次のテーマは、ダークのプリセットで、プロンプトのアクセントとエラー文字の色を変えます(出力スタイル、ターミナル・表示・音声入力)。

json
{
  "name": "Dracula",
  "base": "dark",
  "overrides": {
    "claude": "#bd93f9",
    "error": "#ff5555"
  }
}

チャネル#

チャネルは、チャットアプリのような外部のシステムが、セッションへメッセージを送れるようにします。プラグインでは、チャネルは MCP サーバーの1つと、それに結び付き自身の設定を求められる channels の項目でできています。

json
{
  "name": "my-plugin",
  "mcpServers": {
    "telegram": {
      "command": "node",
      "args": ["${CLAUDE_PLUGIN_ROOT}/server.js"],
      "env": { "BOT_TOKEN": "${user_config.bot_token}" }
    }
  },
  "channels": [
    {
      "server": "telegram",
      "userConfig": {
        "bot_token": {
          "type": "string",
          "title": "Bot token",
          "description": "Telegram bot token",
          "sensitive": true
        }
      }
    }
  ]
}

server は mcpServers のキーと一致する必要があります。チャネルごとの userConfig は、トップレベルの userConfig と同じ形です。

モニター#

モニターは、セッションのあいだ背景で動くシェルコマンドです。出力は通知として Claude に届き、Claude が頼まれなくても、ログや状態の変化に反応できます。monitors/monitors.json に置きます。

json
[
  {
    "name": "error-log",
    "command": "tail -F ./logs/error.log",
    "description": "Application error log"
  }
]

コマンドは、セッションを始めた作業ディレクトリのシェルで動きます。

  • 対話セッションだけ:プラグインのモニターは対話セッションで始まり、-p の非対話では始まらない。API プロバイダやテレメトリの設定で Monitor ツールが使えなくなるセッションでも始まらない(ツール一覧)
  • ユーザー設定は使えない:command が受け取るのはパス変数と環境の ${ENV_VAR} で、${user_config.*} は受け取らない。参照するモニターは起動せず、モニターのプロセスは CLAUDE_PLUGIN_OPTION_<KEY> も受け取らない
  • セッション中の無効化:セッション中にプラグインを無効にしても、すでに動いているモニターは止まらない。セッションの終了で止まる
  • experimental.monitors キーが、同じ配列のインラインか JSON ファイルへのパスを取り、monitors/monitors.json の代わりに読まれる

when トリガーなどのフィールドはプラグインのリファレンスにあります。

ユーザーに設定値を尋ねる#

プラグインがユーザーから必要とする値は、マニフェストの userConfig に宣言します。ユーザーが settings.json を自分で編集せずに済みます。各オプションはダイアログに、title をラベル、description をその下に出します。トークンやパスワードには "sensitive": true を設定します。入力が伏せられ、値は settings.json ではなく安全な保管場所に保存されます。

json
{
  "name": "my-plugin",
  "userConfig": {
    "api_url": {
      "type": "string",
      "title": "API URL",
      "description": "Base URL of your team's API"
    },
    "api_token": {
      "type": "string",
      "title": "API token",
      "description": "Token for your team's API",
      "sensitive": true
    }
  }
}

ダイアログは対話の /plugin の機能で、ユーザーが次のことをすると、未設定のオプションについて開きます。

  • /plugin でプラグインをインストールする
  • セッション内で /plugin install <plugin>@<marketplace> を実行する
  • /plugin の「Installed」タブでプラグインを有効にする

いつでも開くには /plugin configure <plugin>@<marketplace> を実行します。VS Code 拡張の「Manage plugins」のダイアログは、インストール後に未設定のオプションをフォームで尋ね、プラグインの行の歯車のアイコンで全オプションのフォームを開き直せます(VS Code と JetBrains)。シェルの claude plugin install は userConfig の値を尋ねません。値は、インストール時に --config KEY=VALUE で1つずつ渡すか、あとで JSON のオブジェクトを claude plugin configure --values-stdin へパイプします。オプションが未設定のままだと、claude plugin install は userConfig options not yet set の行を出します。オプションのフィールド、値の保存先、コンポーネントからの参照の仕方、${user_config.*} を受け付けないフィールドはプラグインのリファレンスにあります。

パスの参照とデータの保存#

プラグインがどこに入るかは分からないので、固定のパスではなく次の変数でファイルとデータを参照します。スキル・コマンド・エージェントの本文、フックとモニターのコマンド、MCP と LSP の設定で置換され、フック・MCP・LSP のプロセスにも環境変数として渡されます。

変数 内容
${CLAUDE_PLUGIN_ROOT} プラグインのインストール先。版ごとにキャッシュのディレクトリが違うので、更新でパスが変わる。ここに状態を書かない
${CLAUDE_PLUGIN_DATA} 更新後も残るディレクトリ(node_modules・仮想環境・キャッシュ用)。~/.claude/plugins/data/<id>/ に解決され、最初に参照されたときに作られる
${CLAUDE_PROJECT_DIR} プロジェクトのルート。フックが受け取る値と同じ

データのパスの <id> は、プラグインの識別子の、英数字・_・- 以外をすべて - に置き換えたものです(my-plugin@my-marketplace は my-plugin-my-marketplace)。Windows では、置換されたパスは、シェルがバックスラッシュをエスケープと読まないよう、スラッシュを使います。

マーケットプレイスから入れたプラグインでは、条件に合う Node.js のパッケージ依存を、キャッシュするときに自動で入れます。自分で入れるなら、次の SessionStart のフックが、初回と、更新で package.json が変わったあとに、node_modules を ${CLAUDE_PLUGIN_DATA} へ入れます。

json
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "diff -q \"${CLAUDE_PLUGIN_ROOT}/package.json\" \"${CLAUDE_PLUGIN_DATA}/package.json\" >/dev/null 2>&1 || (cd \"${CLAUDE_PLUGIN_DATA}\" && cp \"${CLAUDE_PLUGIN_ROOT}/package.json\" . && npm install) || rm -f \"${CLAUDE_PLUGIN_DATA}/package.json\""
          }
        ]
      }
    ]
  }
}

最初のセッションのあと、~/.claude/plugins/data/<id>/node_modules ができます。MCP サーバーは、env の NODE_PATH を ${CLAUDE_PLUGIN_DATA}/node_modules にして使えます。どのフィールドがどの変数を置換するかは、プラグインのリファレンスにあります。

プラグインの依存関係#

プラグインは、自分が頼る他のプラグイン(MCP サーバーやスキルを呼ぶもの)を依存として宣言できます。バージョンの制約(^2.0 や ~2.1.0 のような semver の範囲)を付けないと、依存はマーケットプレイスが出す最新の版を追い続けます。依存が MCP ツールの名前を変えた版を出すと、更新した全員のプラグインが壊れます。git ベースの取得元の依存に ~2.1.0 のような制約を付けると、そのプラグインを入れたユーザーは 2.1.x のパッチを受け続け、2.2 には進みません。自分の都合で上げるなら、新しい版で試してから、範囲を広げた版を出します。

依存を宣言する#

.claude-plugin/plugin.json の dependencies 配列に並べます。次は、制約なし1つと、制約つき1つです。

json
{
  "name": "deploy-kit",
  "version": "3.1.0",
  "dependencies": [
    "audit-logger",
    { "name": "secrets-vault", "version": "~2.1.0" }
  ]
}

項目は文字列(プラグイン名のみ、または別のマーケットプレイスで解決する "name@marketplace")か、オブジェクトです。文字列だけなら、そのマーケットプレイスが提供する版に頼ります。オブジェクトのフィールドは、どれも文字列です。

フィールド 内容
name 必須。依存のプラグイン名(マーケットプレイスの項目の名前)。marketplace を指定しない限り、宣言するプラグインと同じマーケットプレイスで探す
version semver の範囲(~2.1.0・^2.0・>=1.4・=2.1.0)。範囲に合う最も高い git タグで入るので、依存の保守者はリリースにタグを付ける必要がある
marketplace name を解決する別のマーケットプレイス。別マーケットプレイスへの依存は許可リストで制御される

範囲は、2.0.0-beta.1 のようなプレリリースの版には合いません。^2.0.0-0 のようにプレリリースの接尾辞を付けると、含められます。

チーム向けにまとめる#

name と dependencies 配列だけを持つマニフェストのプラグインを公開すると、それを入れるだけで依存がすべて入ります。次は、プラットフォームチームが、役割別のバンドルを社内のマーケットプレイスで出す例です。

json
{
  "name": "backend-standard",
  "version": "1.0.0",
  "description": "Standard plugin set for backend engineers",
  "dependencies": [
    "secrets-vault",
    "deploy-kit",
    { "name": "db-migrate", "version": "^3.0" },
    "oncall-runbook"
  ]
}

あとで足すには、依存を足した新しい backend-standard を出します。そのマーケットプレイスが既定で自動更新でないなら、エンジニアはマーケットプレイスの自動更新をオンにするか(次の自動更新で、バンドルが新しい版へ上がり、足された依存も入る)、手動で更新します(シェルの claude plugin update backend-standard、開いているセッションで /reload-plugins)。組織の全員に配るには、管理者が管理設定の enabledPlugins に入れます。

別のマーケットプレイスへの依存#

既定では、宣言するプラグインのマーケットプレイスと別のマーケットプレイスの依存は、ユーザーが同じスコープでその依存をすでに入れて有効にしていない限り、入りません。ユーザーが確認していない取得元から、静かにプラグインが入るのを防ぐためです。許可するには、ルートのマーケットプレイス(ユーザーが入れるプラグインをホストするもの)の marketplace.json に、allowCrossMarketplaceDependenciesOn として対象のマーケットプレイス名を足します。ルートの許可リストだけが適用されます。

json
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "allowCrossMarketplaceDependenciesOn": ["your-shared-marketplace"],
  "plugins": [
    {
      "name": "deploy-kit",
      "source": "./deploy-kit",
      "dependencies": [
        { "name": "audit-logger", "marketplace": "your-shared-marketplace" }
      ]
    }
  ]
}

欠けているか対象を含まないと、依存は入りません。依存がマーケットプレイスの項目で宣言されていると、インストール自体が Dependency "audit-logger@your-shared-marketplace" (required by deploy-kit@your-marketplace) is in marketplace "your-shared-marketplace", which is not in the allowlist で始まるメッセージで拒否されます。plugin.json で宣言されていると、依存なしでインストールが終わり、そのプラグインの読み込みが失敗します。許可リストの確認は、すでに有効な依存には適用されません。

依存と一緒に手元で試す#

プラグインとその依存を同時に開発しているなら、両方を --plugin-dir で読み込みます。

bash
claude --plugin-dir ./my-dependency --plugin-dir ./my-plugin

手元の依存が、プラグインの依存の項目を満たすので、マーケットプレイスから入れる必要はありません。

  • version は不要:手元の plugin.json に version が無くてよく、バージョン制約は手元のコピーには照合されない
  • マーケットプレイス名を指す項目も、v2.1.242 以降は手元のコピーに一致する
  • 手元の依存を無効にしたり、依存の --plugin-dir を付けずに始めたりすると、依存をマーケットプレイスから入れるまで、プラグインは読み込まれない。無効にしたときは is disabled — enable it or remove the dependency で終わるエラーで、次の読み込みで無効になる(依存が <name>@inline と出るのは --plugin-dir のコピーのこと)。フラグなしで始めたときは、依存が未インストールと報告される
  • 両方が1つの親フォルダにあるなら、そのフォルダを1回 --plugin-dir に渡せる(v2.1.265 以降。フォルダ自身がプラグインでなければ、.claude-plugin/plugin.json を持つ各子フォルダを読み込む)

他のプラグインに頼られるプラグインをリリースする#

バージョンの範囲は、プラグインをホストするリポジトリの git タグに対して解決されます。リリースには <plugin-name>--v<version> のタグを付けます(<version> はそのコミットの plugin.json の version)。接頭辞があるので、1つのマーケットプレイスのリポジトリに複数のプラグインが、それぞれ独立した版の履歴を持てます。タグを付けるのは、marketplace.json のプラグインの取得元が指すリポジトリです。

  • github・url・git-subdir の取得元:プラグイン自身のリポジトリ。作者がタグを作る
  • ./plugins/secrets-vault のような相対パス:マーケットプレイスのリポジトリ。マーケットプレイスの保守者がタグを作る

プラグインのディレクトリで、origin リモートを設定したうえで、claude plugin tag を使います。

bash
claude plugin tag --push

マニフェストからタグ名を作り、作る前に次を確認します。プラグインの検証、プラグインのディレクトリがマーケットプレイスのチェックアウトの中にあるときの plugin.json と項目の版の一致、プラグインのディレクトリの下の作業ツリーがきれいなこと、タグがまだ無いこと。成功すると Created tag secrets-vault--v2.1.0 と出て、--push なら Pushed to origin も出ます。--push なしでは、実行する git push のコマンドが表示されます。--dry-run で、何も作らずに計画だけ見られます。git tag secrets-vault--v2.1.0 を直接打ってもよいですが、plugin.json とマーケットプレイスの項目の version は、自分で合わせておきます。残りのフラグはプラグインのリファレンスにあります。

npm・archive・command の取得元の依存には、タグによる解決は効かず、制約は取得する版を決めません。ただし読み込み時に照合され、入っている版が満たさなければ、依存するプラグインは無効になります。検査される版は依存の plugin.json の version なので、制約をかける前にそこへ設定します(version が無い plugin.json は、どの制約も満たしません)。command の取得元の依存は Claude Code が自分では入れないので、ユーザーが先に入れます。依存の headersHelper も実行しないので、項目に headersHelper がある依存は、依存するプラグインより先に、ユーザーが入れます。claude plugin install のほか、次の操作も欠けた依存を入れ、同じ制限が当てはまります。/reload-plugins、依存するプラグインのマーケットプレイスの自動更新、依存するプラグインへの claude plugin install のやり直し、claude plugin marketplace add。

制約の解決のされ方#

{ "name": "secrets-vault", "version": "~2.1.0" } を宣言するプラグインを入れると、依存は、secrets-vault をホストするリポジトリの、~2.1.0 を満たす最も高い secrets-vault--v のタグで入ります。範囲を満たすタグが無いときは、入れるのに失敗するか、マーケットプレイスの現在のコピーを使います。

  • 自分のリポジトリを持つプラグイン:Dependency "secrets-vault@your-marketplace" has no git tag satisfying を含むメッセージで失敗する
  • 相対パスで参照されるプラグイン:マーケットプレイスの現在のコピーを使い、制約は読み込み時に照合される。範囲の外なら、依存するプラグインは無効のままで、claude plugin list に Requires "secrets-vault@your-marketplace" ~2.1.0, installed 3.0.0 と出る
  • 相対パスのプラグインを持つマーケットプレイスを、ローカルのフォルダとして追加したときも、そのフォルダが git リポジトリなら、そのタグで制約を解決する(v2.1.196 以降)。git リポジトリでないフォルダにはタグが無いので、そのときの内容から依存を入れる

どの版に解決したかは、シェルの claude plugin list で確かめます。タグで解決した依存は、2.1.0-8713c5b11005 のように、12文字のコミット接尾辞が付いた版で出ます。制約の検査は、そのコミットの plugin.json の版が遅れていても、タグの版で行われます。タグを別のコミットへ強制的に動かしたときは、次のインストールで、古いキャッシュを使い回さずに、そのコミットの内容を取り直します。

複数のプラグインが同じ依存を制約するときは、すべての範囲を満たす最も高い版に解決されます。

プラグイン A の要求 プラグイン B の要求 結果
^2.0 >=2.1 2.1.0 以上の最も高い 2.x のタグで1つ入り、両方が読み込まれる
~2.1 ~3.0 B のインストールが has conflicting version requirements で失敗する。A と依存は元のまま
=2.1.0 なし 依存は 2.1.0 のまま。A が入っているあいだ、自動更新は新しい版を飛ばす

自動更新は、制約のある依存を、マーケットプレイスの最新ではなく、入っている全プラグインの範囲を満たす最も高い git タグで取得します。範囲が重ならなければ、その依存を現在の版のままにし、「Errors」タブに制約するプラグインを名指しする項目が出ます。重なっていてもその範囲にタグが無ければ、マーケットプレイスの現在のコピーを取得し、そのコピーの version がどれかの範囲の外なら更新を見送ります。その依存を制約する最後のプラグインをユーザーが消すと、依存は版の範囲の制約を外れ、次の更新から、マーケットプレイスの項目を追います。自動で入った、もう要らない依存は claude plugin prune で消します(プラグインを使う、プラグインのリファレンス)。

マーケットプレイスを作る#

マーケットプレイスは、.claude-plugin/marketplace.json を持つディレクトリかリポジトリで、プラグインの一覧と各取得元を載せます。git ホストへ置けば、アクセスできる人が1コマンドで登録して入れられます。リポジトリは非公開にでき、載せる数に制限はなく、管理者が全マシンに必須にすることもできます。数人に1つだけ渡すなら、ディレクトリか .zip を渡せば足ります。手元で自分だけが使うなら、--plugin-dir かスキルのディレクトリです。

手元で一巡する#

次の手順で、手元にマーケットプレイスを作り、プラグインを足し、登録して、そこから入れます。ここまで通れば、ホストした後にユーザーが行う流れと同じです。例には、上の my-first-plugin を使います。

  1. マーケットプレイスのディレクトリを作る。プラグインを plugins/ の下へコピーし、その場所で有効かを検証する

    bash
    mkdir -p my-marketplace/.claude-plugin my-marketplace/plugins
    cp -r my-first-plugin my-marketplace/plugins/
    claude plugin validate ./my-marketplace/plugins/my-first-plugin
    
  2. my-marketplace/.claude-plugin/marketplace.json を作る。必須は name・owner・plugins の配列。plugins の各オブジェクトが項目で、name と source が要る。source は、マーケットプレイスのルート(.claude-plugin/ を含むディレクトリ)からのパスで書く

    json
    {
      "name": "my-marketplace",
      "description": "Plugins for my team",
      "owner": {
        "name": "Your Name"
      },
      "plugins": [
        {
          "name": "my-first-plugin",
          "source": "./plugins/my-first-plugin",
          "description": "A greeting plugin to learn the basics"
        }
      ]
    }
    
  3. マーケットプレイスを検証する(JSON の構文・必須フィールド・各項目)

    bash
    claude plugin validate ./my-marketplace
    
  4. 追加して入れる。✔ Successfully added marketplace: my-marketplace (declared in user settings) のあと、✔ Successfully installed plugin: my-first-plugin@my-marketplace (scope: user) と出る。インストール ID は、項目の name・@・マーケットプレイスの name

    bash
    claude plugin marketplace add ./my-marketplace
    claude plugin install my-first-plugin@my-marketplace
    
  5. 確かめる。claude plugin list に my-first-plugin@my-marketplace が Status: ✔ enabled で出る。claude plugin details my-first-plugin の Component inventory に Skills (1) hello が出る。セッションで /my-first-plugin:hello を実行する

セッション内でも、/plugin marketplace add ./my-marketplace で同じように登録できます。

項目を足す#

配るプラグインは、marketplace.json の plugins 配列の1オブジェクトです。2つ目を足すなら2つ目のオブジェクトを足します。

フィールド 内容
name 入れるときに @ の前に打つ識別子(使える文字はプラグインのリファレンス)
source Claude Code がプラグインを取得する場所。マーケットプレイスのディレクトリ内なら相対パスの文字列、外なら取得元のオブジェクト
description /plugin でマーケットプレイスを閲覧するときに、プラグインの横に出る1行

項目には、plugin.json のどのフィールドも書けます(自分の plugin.json を持つプラグインとの関係はプラグインのリファレンス)。

新しいマーケットプレイスで失敗するインストールの多くは、相対パスを誤ったディレクトリから書いたか、項目の名前が plugin.json の name と違うことが原因です。

  • 相対パスは、マーケットプレイスのルート(.claude-plugin/ を含むディレクトリ)から書く。.. で出ない。.. を含むパスは claude plugin validate が Path contains "..": ./../plugins/my-first-plugin で始まるメッセージで無効と報告する。存在しないディレクトリへのパスは検証を通り、claude plugin install が Source path does not exist: <path>(<path> は確認した絶対パス)で失敗する
  • 項目の名前とマニフェストの名前を同じにする。項目の名前は、インストール ID(<entry-name>@<marketplace>)、claude plugin list の表示、設定ファイルの enabledPlugins のキーになる。マニフェストの名前は、プラグインのスキルの接頭辞と、claude plugin details が取る名前になる。2つが違い、マニフェストの名前で入れると、Plugin "<manifest-name>" not found in marketplace "<marketplace>" と出る

取得元の選び方#

取得元 使う場面 source の最小値
相対パス プラグインのファイルがマーケットプレイスのディレクトリの中 "./plugins/my-first-plugin"
github プラグインが自分の GitHub リポジトリ { "source": "github", "repo": "your-org/my-first-plugin" }
git-subdir プラグインがモノレポなど他のリポジトリのサブディレクトリ { "source": "git-subdir", "url": "your-org/monorepo", "path": "tools/my-first-plugin" }

git-subdir の url は、git の URL か owner/repo の GitHub 略記を取ります。ほかに、任意のホストの git を URL で指す url、HTTPS でダウンロードする zip の archive、npm パッケージの npm、インストールするマシンでコマンドを実行して作ったディレクトリの command があります。各取得元のフィールドと、git ベースの取得元を ref や sha に固定する方法はプラグインのリファレンスにあります。

検証と試験#

編集のたびにシェルで claude plugin validate ./my-marketplace を実行し、共有する前に自分のマシンから入れて試します。検証とインストールでは、見つかる問題が違います。

claude plugin validate は、マーケットプレイスのディレクトリの中のファイルだけを読みます。報告するのは次のものです。

  • JSON の構文エラー(json: Invalid JSON syntax: <reason>)
  • 必須フィールドの欠け(owner: Invalid input など)
  • 命名の規則に反するマーケットプレイスまたはプラグインの名前
  • .. を含む相対 source
  • 最上位か項目の未知のフィールド(警告)
  • 相対パスの各プラグインの plugin.json の問題(plugins[N] plugin.json → <field>: <message>)

検証が報告しない問題は、追加やインストールのときに出ます。公式マーケットプレイスの名前と同じ名前(claude-plugins-official など)は検証を通りますが、追加すると The name '<name>' is reserved for official Anthropic marketplaces で始まるメッセージで拒否されます。github や git-subdir などのリモートの取得元は、インストール時に初めて取得されるので、repo や path の誤りはそのとき出ます。存在しないディレクトリを指す相対 source も、インストールで失敗します。

手元のディレクトリを相対パスの source で追加した場合、Claude Code はプラグインのファイルを my-marketplace/plugins/ から直接読みます。編集は、次のセッション開始時か、セッションで /reload-plugins を実行したときに、version を変えずに反映されます。ホストしたマーケットプレイスから入れた人は、プラグインのキャッシュにあるコピーを使います。やり直すには、シェルで claude plugin marketplace remove my-marketplace を実行します(マーケットプレイスを外し、そこから入れたプラグインも削除されます)。

ホストする#

自分のマシンで入れられたら、マーケットプレイスのディレクトリを git ホストに置きます。使う人は、GitHub のリポジトリなら claude plugin marketplace add <owner>/<repo> を、そうでなければリポジトリの URL で同じコマンドを実行します。以下は、ホストする人向けです。

ホスト ユーザーがセッションで実行する ユーザーに必要なもの
GitHub /plugin marketplace add your-org/your-marketplace git。非公開リポジトリなら、下の「非公開のマーケットプレイスへのアクセス」
GitLab・Bitbucket・GitHub Enterprise Server など /plugin marketplace add https://gitlab.example.com/team/plugins.git git と、そのマシンからホストへのアクセス。owner/repo の略記は常に github.com を指すので、完全な URL を伝える
ホストした marketplace.json の URL /plugin marketplace add https://plugins.example.com/marketplace.json URL への HTTPS アクセス(カタログ自体に git は不要)
共有ファイルシステムのディレクトリ /plugin marketplace add /Volumes/shared/claude-plugins パスへの読み取りアクセス

GitHub か git URL のマーケットプレイスの、ブランチかタグを固定するには、your-org/your-marketplace#stable のように #<ref> を付けるよう伝えます。成功すると Successfully added marketplace: your-marketplace と出ます。名前はリポジトリ名ではなく、marketplace.json の name から取られます。ユーザーは /plugin install code-formatter@your-marketplace のように入れます。

  • リポジトリの全員に登録する:そのリポジトリで一度、シェルから claude plugin marketplace add your-org/your-marketplace --scope project を実行し、書かれた .claude/settings.json をコミットする。フォルダを信頼した各メンバーに登録される
  • URL でホストするときは、相対パスの項目を避ける:素の marketplace.json の URL で追加されると、そのファイルだけがダウンロードされる。source が ./plugins/formatter のような相対パスの項目は、インストールで its marketplace entry path does not stay inside the marketplace directory となり失敗する。各項目に単独で取得できる取得元(github のリポジトリや archive の URL)を与えるか、リポジトリ全体を clone できる git ホストに置く
  • Git LFS を使わない:git ホストのマーケットプレイスや git ベースのプラグインは、ユーザーのマシンへ clone される。clone は LFS の中身をダウンロードしないので、LFS で追跡したファイルはポインタファイルのまま届く
  • 共有ファイルシステムのディレクトリでは、相対パスの取得元のプラグインを、コピーせず直接読む。編集は、次のセッション開始か /reload-plugins で、更新の手順も版の更新もなしに見える

URL の marketplace.json と archive の取得元には、ダウンロードの上限があります。

ファイル ダウンロードの最大 サーバーの応答の待ち時間 リダイレクト
url のマーケットプレイスの取得元の marketplace.json 5 MiB 10秒 別のオリジンへのリダイレクトは https:// で、loopback・link-local・クラウドメタデータのホストを指せない。https:// から http:// へのリダイレクトは失敗
archive の取得元の zip 256 MiB 120秒 最大5回。どのリダイレクト先も https:// で、loopback・link-local・クラウドメタデータのホストを指せない

別のオリジンへリダイレクトされたリクエストには、マーケットプレイスの取得元や項目に設定したヘッダーは付きません。アーカイブのダウンロード後は、展開が次のいずれかの上限を超えるとインストールが失敗します。項目数100,000(ファイルとディレクトリ)、1ファイルの展開後512 MiB、展開後の合計1 GiB、zip の50倍を超える圧縮率。

マーケットプレイス内でファイルを共有する(シンボリックリンク)#

プラグインとマーケットプレイスの他の部分でファイルを共有するには、プラグインのディレクトリの中にシンボリックリンクを作ります。プラグインをキャッシュにコピーするとき、リンク先の位置で扱いが変わります。

  • プラグイン自身のディレクトリの内側:相対シンボリックリンクとして保たれ、実行時にコピーされた先を指し続ける
  • 同じマーケットプレイスの別の場所:リンクを解決し、リンク先の内容がキャッシュにコピーされる。メタプラグインの skills/ が、他のプラグインのスキルを指す使い方ができる
  • マーケットプレイスの外:安全のため飛ばされる

ローカルのパスから入れたプラグインと、mode が既定の copy の command の取得元では、プラグイン自身のディレクトリの内側に解決されるリンクだけが保たれ、ほかは飛ばされます。Windows では、管理者のコマンドプロンプトから mklink /D を使うか、開発者モードを有効にします。

bash
ln -s ../../shared-plugin/skills/foo ./skills/foo

組織の設定で配る#

Team か Enterprise のプランでは、ユーザーが自分で追加するのではなく、claude.ai の「Organization settings > Plugins & skills」でマーケットプレイスを配れます。組織の同期は、claude.ai 上の組織の GitHub か GitLab の接続でリポジトリを読むので、ユーザーの git の資格情報は関わりません。/plugin marketplace add よりリポジトリに厳しく、次の制約があります。

  • github.com と gitlab.com では、マーケットプレイスのリポジトリは非公開か内部であること
  • プラグインの取得元は、一部の種類だけを受け付ける
  • トップレベルに bin/ があるプラグインは claude.ai が拒否し、残りは同期される。エラーは Plugin contains a top-level bin/ directory で始まる。実行ファイルは scripts/ のような別のディレクトリに置き、フックや MCP の設定から ${CLAUDE_PLUGIN_ROOT}/scripts/<name> で参照する

非公開のマーケットプレイスへのアクセス#

ユーザーが追加・インストール・更新するとき、Claude Code はユーザーのマシンで、対話のプロンプトを切った git を実行し、そのマシンにすでにある資格情報に頼ります。Claude Code 自身は git のトークンを持たず、marketplace.json にも置く欄がありません。SSH か HTTPS かは、ユーザーに送る追加コマンドの形で決まります。

  • GitHub の owner/repo:ssh -T git@github.com で試し、成功すれば SSH で clone。失敗するか SSH の clone が失敗したら HTTPS。GitHub の SSH 鍵が無いマシンは、CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1 で試行を飛ばして HTTPS にできる
  • git@host:path.git:SSH
  • https://example.com/repo.git:HTTPS

SSH は、鍵がパスフレーズの入力なしで使えること(ssh-agent に読み込んでおくなど)と、ホストが known_hosts にあることが要ります。HTTPS は、git の資格情報ヘルパーを有効のままにしつつ入力を禁じるので、ヘルパーがすでに保存している資格情報は使え、聞かれる資格情報は失敗します。GitHub では gh auth login のあと gh auth setup-git で保存できます。GitHub Enterprise Server のホストは、ユーザーのマシンからそのホストへの git アクセスが必要です。

git ホストのアカウントが無いユーザーは、marketplace.json の URL や共有ディレクトリで配られるマーケットプレイスは追加できますが、入れられるのは、項目の取得元にも届くプラグインだけです。非公開の github リポジトリを指す項目は、それらのユーザーには失敗します。git のアカウントが要らない取得元は次のとおりです。

  • archive:HTTPS でダウンロードする zip。git もアカウントも不要で、URL へのネットワークアクセスだけ(v2.1.224 以降)。各アーカイブを sha256 で固定して、変わったダウンロードを拒否させる
  • 公開の git リポジトリ:項目が https:// の URL を与えるなら、url や git-subdir の取得元を資格情報なしで HTTPS で clone する。github の取得元や、owner/repo で書いた git-subdir は、GitHub の SSH 鍵が無いユーザーが CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1 を設定する

同じネットワーク内のチームなら、共有ファイルシステムの directory のマーケットプレイスも、git のアカウントなしで使えます。

背景の自動更新は、非公開のマーケットプレイスでオンのとき、新しいコミットの確認に、ユーザーが設定した git の資格情報ヘルパーを使い、入力を求めません。SSH のリモートは ssh-agent の鍵で、保存済みの資格情報がある HTTPS のリモートは(Git Credential Manager・macOS キーチェーン・git-credential-store)それで確認できます。入力が要るヘルパーは背景では答えられず、更新は静かに失敗して既存のチェックアウトが残り、プラグインは最後に同期した状態で動きます。確認後は、最新ならそのまま、新しいコミットが見つかった・到達や認証に失敗したときは、マーケットプレイスを clone し直して置き換えます(clone に失敗したら既存のチェックアウトが残ります。大きなリポジトリではタイムアウトしうる)。最新に保つには、資格情報を保存するか(GitHub は gh auth login のあと gh auth setup-git)、CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1 を設定して、到達・認証に失敗したときに clone し直さず既存のチェックアウトを保ちます。環境変数の GITHUB_TOKEN などを設定するだけでは、背景の確認は認証されません。トークンは、gh の CLI のヘルパーのように、資格情報ヘルパーを通じて効きます。

会社全体に展開する#

展開には、マーケットプレイスの持ち主・管理設定を扱う管理者・各ユーザーが関わります。管理者なしでも、各ユーザーが自分で追加して入れれば展開できます。

誰が すること
マーケットプレイスの持ち主 会社だけが読めるリポジトリにカタログを置き、ホストに合う追加コマンドを送り、各自のマシンに必要なものを伝える
管理者 管理設定の extraKnownMarketplaces と enabledPlugins で、マーケットプレイスを登録して全員向けにプラグインを有効にし、そこで autoUpdate も設定する
各ユーザー 非公開の git リポジトリへの読み取りアクセスと、マシンに保存済みの資格情報が要る。管理者がいなければ、追加とインストールのコマンドも自分で実行する

git ホストのアカウントが無い人には、git アカウント不要の取得元、事前に作ったプラグインディレクトリ(下の「コンテナと CI に種をまく」)、claude.ai の組織設定のいずれかで届けます。

更新を届ける#

変更は、マーケットプレイスの背景の自動更新がオンなら自動で、そうでなければユーザーが更新したときに届きます。どちらも、プラグインの計算された版が変わったときにだけ、新しいコピーが届きます。

背景の自動更新は、マーケットプレイスでは既定でオフで、marketplace.json にはオンにするフィールドがありません。ユーザーが /plugin の「Marketplaces」でそのマーケットプレイスを選び、「Enable auto-update」を選ぶか、管理者が管理設定の extraKnownMarketplaces の項目に "autoUpdate": true を設定します。自動更新が無いと、ユーザーは、セッションで /plugin marketplace update <name> か、シェルで claude plugin update <plugin>@<name> を実行したときに変更を受け取ります。

新しい版を出すには、プラグインの version を変えます。計算される版は、plugin.json、次にマーケットプレイスの項目、の順で決まります。マーケットプレイスをローカルのパスから追加した場合にその場で読み込まれる(in place)プラグインは、version に制御されず、セッションの開始のたびに現在のファイルを読み込みます。インプレース読み込みと command 取得元を除くすべてのインストールでは、version をリリースごとに上げるか、省くかのどちらかにします。

  • version をリリースごとに上げる:文字列が変わるまで、ユーザーはキャッシュしたコピーのまま。"version": "1.0.0" のままコミットを押しても届かない
  • version を省く:ユーザーはコミットを追う。plugin.json とマーケットプレイスの項目の両方から version を外す

plugin.json とマーケットプレイスの項目の両方に version を設定しないでください。両方にあると、警告なしに plugin.json の値が使われ、claude plugin validate が Entry declares version "<a>" but <path>/plugin.json says "<b>" として報告します。

版を固定するには、各項目が指すものを選びます。

  • プラグインの項目の ref と sha:github・url・git-subdir の取得元で、ref がブランチかタグ、sha がコミット
  • 追加コマンドの #<ref>:your-org/your-marketplace#stable を追加したユーザーは、そのブランチかタグのカタログを受け取る
  • <plugin>--v<version> のタグ:依存の版の範囲がこのタグに対して解決される

command 取得元のコマンドを変える、または mode を切り替えると、各ユーザーが新しいコマンドを承認するまで実行されません。Claude Code が実行するのは、ユーザーがインストールか前回の更新で承認した、そのままのコマンドだけです。ユーザーのマーケットプレイスのコピーに変更が届くと、そのユーザーは、新しいコマンドの背景実行が止まり、/plugin の「Errors」タブに新しいコマンドと実行すべき claude plugin update が出ます。端末でそのコマンドを実行して承認してもらいます。

リリースチャンネル#

安定版と先行版の2つの系統を出すには、同じプラグインの別の ref を指す2つのマーケットプレイスをホストし、ユーザーに好きな方を追加してもらいます。Claude Code にはリリースチャンネルの概念が無く、1つのマーケットプレイスが同時に出せる各プラグインの版は1つです。2つの marketplace.json は、name を変えます(同じ名前の2つは同時に登録できません)。

json
{
  "name": "stable-tools",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": { "source": "github", "repo": "your-org/code-formatter", "ref": "stable" } }
  ]
}

もう1つの latest-tools は "ref": "latest" です。2つの ref の plugin.json の版を変えるか、version を省いてコミット SHA で区別します。更新は版の比較で検出されるので、版を変えずに動かした ref では、ユーザーはキャッシュのままです。ユーザーに選ばせずにグループへ割り当てるには、管理者が各グループに対応する extraKnownMarketplaces を与えます。

名前の変更と削除#

プラグインの name は識別子で、ユーザーが enabledPlugins と pluginConfigs の設定キーと /plugin install で参照するので、変えると既存のインストールがすべて壊れます。/plugin に見えるラベルだけ変えるには、plugin.json の displayName を設定し、name はそのままにします。

どうしても name を変えるとき、または plugins から項目を消すときは、marketplace.json のトップレベルに renames のマップを足し、既存のユーザーを Plugin "<name>" not found in marketplace にせず移行させます。旧名を新名に、プラグインが無くなったなら null に対応づけます。

json
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "plugins": [
    { "name": "code-formatter", "source": "./plugins/code-formatter" }
  ],
  "renames": {
    "formatter": "code-formatter",
    "legacy-linter": null
  }
}

押したあと、古い名前を有効にしているユーザーは、次のどれかを見ます。

  • 名前を変えた項目:新しい名前で読み込まれる。claude plugin list と /plugin の詳細に Renamed to "code-formatter" in the "your-marketplace" marketplace が1回出て、user・project・local の各スコープの enabledPlugins と pluginConfigs の古いキーが新しいキーに書き換わる
  • null の項目:古いキーがそれらのスコープから消え、Removed from the "your-marketplace" marketplace と出る
  • 管理設定で有効にしている場合:新しい名前で読み込まれるが、管理設定は書き換えられないので、管理者が enabledPlugins を更新するまで、通知が繰り返される

git のリポジトリや URL から追加したマーケットプレイスでは、名前を変えたプラグインは、ユーザーがセッションで /plugin install code-formatter@your-marketplace を一度実行するまで、Plugin "<name>" not cached at <path> と出ます。renames は追記だけの履歴として扱い、全員が移行したあとも古い項目を残します。もう一度名前を変えるときは、最初の項目を編集せず、2つ目の項目を足します(Claude Code は最も古い名前から連鎖をたどります)。編集後にシェルで claude plugin validate . を実行すると、循環する連鎖や、null か plugins の名前以外で終わる連鎖が renames.<name>: chain does not resolve で拒否されます。

削除したプラグインをユーザーのマシンから消すには、marketplace.json のトップレベルに "forceRemoveDeletedPlugins": true を設定します。無いと、削除したプラグインは入ったままで、セッションが読み込むときに Plugin "<name>" not found in marketplace と出ます。あると、セッションの開始のたびに、(1) ユーザーが入れたものを項目と renames と比べ、どちらにも無いものを削除済みとみなし、(2) 削除済みの各プラグインを user・project・local のスコープから削除し(管理設定だけで入れたものは残る)、(3) /plugin の「Flagged」の見出しの下に、状態 Removed from marketplace で並べます。

アーカイブのダウンロードを認証する#

プライベートレジストリからのような archive のダウンロードを認証するには、Claude Code が送る HTTP ヘッダーを設定します。headers は2か所に置けます。マーケットプレイスの url の取得元(extraKnownMarketplaces の項目のような、マーケットプレイスを登録した取得元)と、プラグインの項目(v2.1.238 以降、source の隣)です。値が短命なとき(レジストリが要求ごとに作るトークンなど)は、headers の代わりに headersHelper コマンドを設定します。Claude Code がコマンドを実行し、出力した JSON オブジェクトをその場所のヘッダーとして送ります(v2.1.238 以降)。

置く場所 ヘッダーを受けるダウンロード その場所の headersHelper を実行するとき
マーケットプレイスの url の取得元 マーケットプレイスの URL と同じオリジン(同じスキーム・ホスト・ポート)のアーカイブのダウンロード marketplace.json の取得の前と、そのオリジンのアーカイブのダウンロードの前。1回の出力を最大60秒再利用する
プラグインの項目 その項目のダウンロードだけ ユーザーがそのプラグインを単独でインストールか更新し、コマンドを承認したときだけ

両方の場所に同名のヘッダーがあるときは、項目の値が送られます。1つの場所の中では、コマンドが出力したヘッダーが、headers の同名のものを上書きします。次の項目は、source の隣に headersHelper を置き、headersHelper を設定する marketplace.json の項目に Claude Code が要求する "strict": false も設定しています。

json
{
  "name": "my-plugin",
  "description": "Formatting commands for internal services",
  "strict": false,
  "source": {
    "source": "archive",
    "url": "https://registry.example.com/plugins/my-plugin-2.1.0.zip"
  },
  "headersHelper": "/opt/bin/mint-registry-token.sh"
}

確かめるには、シェルで claude plugin install my-plugin@your-marketplace を実行します。コマンドとアーカイブの URL が示され、承認すると zip がダウンロードされます。どちらに置く場合も、コマンドは次の条件を満たします。

  • コマンドの文字列:印字可能な ASCII で500文字まで。空白が4つ以上続かない
  • 出力:標準出力にヘッダー名と文字列の値の JSON オブジェクトを1つ出し、10秒以内に終了コード 0 で終わる
  • シェルと作業ディレクトリ:sh(Windows では cmd.exe)で実行される。作業ディレクトリは設定ディレクトリ(~/.claude か CLAUDE_CONFIG_DIR)なので、絶対パスか PATH 上のコマンドにする
  • 外される変数:marketplace.json の項目、またはプロジェクトの .claude/settings.json・.claude/settings.local.json で設定したコマンドでは、名前が資格情報らしい変数が環境から外される(MCP の headersHelper と同じ規則。MCP サーバーをつなぐ)。資格情報はファイルか資格情報ストアから読ませる。ユーザー設定・--settings のファイル・管理設定のコマンドには適用されない
  • Claude Code が設定する変数:url の取得元のコマンドには CLAUDE_CODE_MARKETPLACE_URL と CLAUDE_CODE_MARKETPLACE_NAME、項目のコマンドには CLAUDE_CODE_PLUGIN_NAME と CLAUDE_CODE_PLUGIN_ARCHIVE_URL。URL でマーケットプレイスを追加した直後の最初の取得では、名前をその取得が与えるため CLAUDE_CODE_MARKETPLACE_NAME は未設定
json
{"Authorization": "Bearer eyJhbGciOiJSUzI1NiJ9"}

次の場合、コマンドは実行されないか、ヘッダーが捨てられます。

  • コマンドの失敗:非ゼロの終了、10秒超過、文字列の値のオブジェクト以外の出力があると、そのコマンドを実行する対象の取得かダウンロードは行われない
  • マーケットプレイスの URL が https:// で始まらない:その url の取得元のコマンドは実行されず、headers に書いたヘッダーだけが送られる
  • リダイレクトでオリジンを出た:リダイレクトされた要求には、マーケットプレイスの url の取得元も項目も、headers の値もコマンドの出力も付かない
  • ルーティングや識別のヘッダー:Host・Cookie・X-Forwarded-* などの、要求のルーティングとクライアント識別の名前は、項目の headers とコマンドの出力から落とされ、Authorization などの認証の名前は残る。この絞り込みはすべての marketplace.json の項目に適用される
  • --add-dir のディレクトリの設定にあるコマンド:url の取得元でも、インラインのプラグインの項目でも無視され、そのファイルの headers だけが送られる
  • 管理設定による遮断:disableCommandPluginSources を true にすると headersHelper のコマンドが止まり、allowManagedHooksOnly も、disableCommandPluginSources が明示的に false でない限り止める。どちらの場合も、管理設定自身が宣言するマーケットプレイスでは、コマンドが実行される

ユーザーは、プラグインの項目のコマンドを、そのプラグインを単独でインストールか更新するたびに承認します(/plugin のそのプラグインの画面か、claude plugin install・claude plugin update)。非対話のシェルでは --yes で承認し、前の --json の実行が表示したコマンドだけを承認するには、実行が報告した sha256 を --accept-command に渡します。Claude Code は、示したコマンドを、示したアーカイブ URL に対してだけ実行します。その間に項目のコマンドかアーカイブ URL が変わっていたら、インストールか更新を拒否します(クエリ文字列だけの変更は数えません)。

単一プラグインのインストールか更新以外では、Claude Code は項目のコマンドを実行せず、アーカイブもダウンロードしません(プラグインは入っているときの版のまま、未インストールならそのまま)。複数プラグインの一括インストール、プラグインの提案、他のプラグインの依存としてのインストールでは、そのプラグインを拒否して /plugin のそのプラグインの画面を案内し(一括の残りは入る。拒否されたプラグインに依存するものは、ユーザーがそれを単独で入れるまで失敗する)、背景の自動更新や、アーカイブをまだダウンロードしていないプラグインのセッション開始では「Errors」タブに載せます。

マーケットプレイスの url の取得元の headersHelper は、マーケットプレイスが出すカタログではなく、extraKnownMarketplaces の項目のような設定ファイルに宣言します。そのため各インストールや更新で承認を求めず、宣言した設定ファイルが、実行する場面を決めます。

設定ファイル コマンドを実行するとき
ユーザー設定、--settings のファイル、マシン上の管理設定のファイル 確認なし。背景のマーケットプレイスの更新を含む
プロジェクトの .claude/settings.json か .claude/settings.local.json そのフォルダ自体のワークスペースの信頼ダイアログを承認したあとだけ。-p や SDK のセッションは承認とみなされず、親フォルダの信頼も数えない
サーバー管理設定 対話セッションで、配信された設定をセキュリティの承認ダイアログで承認したあとだけ

これらのファイルのインラインのプラグインの項目にも、そのファイルのマーケットプレイスレベルのコマンドと同じフォルダの信頼か設定の承認が要り、ユーザーは、インストールや更新のたびに項目のコマンドも承認します。

依存とおすすめ#

項目は他のプラグインへの依存を宣言できます(semver の範囲、別のマーケットプレイスからの依存は、マーケットプレイスの allowCrossMarketplaceDependenciesOn に載せたときだけ入る。上の依存関係の節)。プロジェクトに合うときに Claude Code がプラグインを提案する仕組みは、下の「プロジェクトに応じておすすめする」にあります。

マーケットプレイスにできないことと近い手段#

marketplace.json にフィールドが無い要望には、次の近い手段があります。

  • 他に入れるものを制限する:マーケットプレイスの許可リストは管理設定の strictKnownMarketplaces
  • ユーザーが頼まなくても入れる・有効にする:項目のフィールドでは入れられない。管理設定の enabledPlugins が、全マシンに対して行う
  • ユーザーによって見せる項目を変える:項目に対象者のフィールドは無く、追加した全員が全カタログを見る。対象者ごとに別のマーケットプレイスをホストする
  • 非推奨の印を付ける:非推奨の状態は無い。項目を消して、renames でその名前を null に対応づけ、必要なら forceRemoveDeletedPlugins を設定する
  • ユーザーの自動更新をオンにする:各ユーザーが /plugin の「Marketplaces」から、または管理者が管理設定の autoUpdate で
  • git の資格情報を運ぶ:マーケットプレイスのフィールドに git のトークンを置く場所は無い。archive の取得元なら、項目に headers か headersHelper を設定できる

公開する#

プラグインを公開するとは、マーケットプレイス(プラグインの一覧と取得元を載せる JSON のカタログ)に載せて、他の人が名前で入れて更新を受けられるようにすることです。自分のマーケットプレイスを運営するか、Anthropic のディレクトリへ提出します。公開せずに共有するだけなら、プラグインのディレクトリか .zip を渡して、読み込んでもらいます。

経路 入れられる人 必要なもの 更新が自動で届くか
マーケットプレイスなし フォルダか .zip を送った相手 プラグインのフォルダ 届かない。渡したコピーを読み込む
自分のマーケットプレイス リポジトリに届く人(チームが clone できる非公開のものでもよい) .claude-plugin/marketplace.json がプラグインを載せている git リポジトリなどのホスト オフ
Anthropic のディレクトリ claude.ai や Cowork で追加する人。アカウントの同期で Claude Code にも読み込まれる プラグインを持つ GitHub リポジトリと、提出に使う有料の claude.ai プラン 届く(押した版が公開されたあと)

自動更新は、ユーザー側のマーケットプレイスごとの設定で、背景で新しい版を取得します。

公開前の準備#

名前・版・検証・マーケットプレイスからのインストールで、リリースがユーザーに動くかが決まります。最初のリリースの前と、以降のリリースの前に確かめます。

  1. 永続する名前を選ぶ:ユーザーは name@marketplace で入れ・有効にし・設定するので、名前を変えると、既存のインストールすべてにとって別のプラグインになる。deploy-helper のような kebab-case にする(それ以外は claude plugin validate が警告する)。永続的に使い、ユーザーに見えるラベルは plugin.json の displayName に設定する
  2. 版の付け方を決める:plugin.json に version を設定し、変えずにコミットを押すと、claude plugin update が <name> is already at the latest version (1.0.0). と出して、ユーザーは古いコピーのまま。リリースのたびに version を上げるか、git ホストのマーケットプレイスでは省いて、コミット SHA を使わせる
  3. 検証する:シェルで claude plugin validate --strict ./your-plugin。通れば ✔ Validation passed。CI では --strict を付けたままにする。未知のマニフェストのフィールドや version が無い警告でも終了コード 1 で失敗する。前の手順で version を省くなら外す。コンポーネントのパスが ./ で始まらないものも報告される。フックのコマンドと MCP サーバーの設定の中では、ファイルを ${CLAUDE_PLUGIN_ROOT}/... で参照する
  4. ローカルのマーケットプレイスから入れる:プラグインを載せたローカルのマーケットプレイスを claude plugin marketplace add ./path-to-marketplace で追加し、そこから入れて、セッションで読み込まれるか確かめる。入れたものがソースのディレクトリを読み込むのか、キャッシュのコピーを読み込むのかは、プラグインのリファレンスの「インプレースとコピー」で分かる
  5. ユーザーに見えるメタデータを埋める:plugin.json の description・author・homepage・repository と、プラグインのルートの README.md。homepage は URL として解釈できる必要がある
  6. 評価のスイートがあれば実行する:シェルで claude plugin eval。プラグインのテストケースを動かして採点し、変更による劣化に気づける(プラグインの評価(evals))

マーケットプレイスなしで共有する#

プラグインが git リポジトリにあるなら、相手が clone してチェックアウトを読み込むか、リリースに添付した .zip を --plugin-url に向けて起動できます。次の版を得るには、引き直すかダウンロードし直します。リポジトリにないなら、ディレクトリか .zip を送ります。相手は、1セッションだけ claude --plugin-dir ./deploy-helper(パスは clone・展開したフォルダ・.zip そのもの)で読み込むか、毎セッション読み込むために .claude-plugin/plugin.json ごと ~/.claude/skills/ の下へ移します。同じリポジトリに .claude-plugin/marketplace.json を足すと、名前で入れてコマンドで更新できます。

CLI や SDK を保守していて、自分のツールと一緒にプラグインを出すなら、プラグインをマーケットプレイスに公開し、インストーラかインストール後のメッセージで、ユーザーが要る2つのコマンド(claude plugin marketplace add <source>、続いて claude plugin install <name>@<marketplace>)を実行するか表示します。ツールを使うときのセッション内の案内は、下の「CLI からおすすめする」にあります。

自分のマーケットプレイスで公開する#

.claude-plugin/marketplace.json を git リポジトリに足せば、公開は完了で、申請フォームはありません。プラグイン自身のリポジトリに置いても、別のリポジトリに置いてもかまいません。プラグインのリポジトリから公開するなら、plugin.json の隣の .claude-plugin/ に置き、source が "./"(リポジトリのルート)の項目を1つ書きます。項目の name は、plugin.json と同じにします。

json
{
  "name": "your-marketplace",
  "owner": { "name": "Your Name" },
  "plugins": [
    { "name": "deploy-helper", "source": "./" }
  ]
}

押す前に、リポジトリで claude plugin validate . を実行します。リポジトリをクローンできる人なら誰でも入れられるので、非公開のリポジトリなら、マーケットプレイスも非公開です。ユーザーには、シェルで追加して入れるよう伝えます。

  • 追加(1回):claude plugin marketplace add your-org/your-marketplace(引数は GitHub の owner/repo の略記・URL・パス)
  • インストール:claude plugin install deploy-helper@your-marketplace
  • セッション内で一度に:/plugin install deploy-helper --marketplace your-org/your-marketplace(v2.1.275 以降)

更新は、ユーザーが求めたとき(シェルで claude plugin update deploy-helper@your-marketplace。マーケットプレイスを更新して、プラグインの版が変わっていれば新しいコピーを入れる)と、マーケットプレイスの自動更新がオンのとき(既定ではオフ。オンなら、セッション開始の少しあとに claude plugin update と同じことをする)に届きます。新しい版を出すには、plugin.json が version を設定しているなら、増やして押します。

Anthropic のディレクトリへ提出する#

Anthropic のディレクトリは、claude.ai と Cowork で、プラグインとコネクタを追加するために見るカタログです。1つの掲載が、claude.ai・Cowork・Claude Code に届きます。提出は、claude.ai/directory/manage の開発者ポータルから行います。

公式マーケットプレイス(claude-plugins-official)は、ディレクトリのポータルでは提出を受け付けません。Anthropic のパートナー窓口と話しているなら、そこに公式マーケットプレイスへの掲載を尋ねます。

提出の手順です。

  1. 提出できるかを確かめる:有料の claude.ai プランが要ります。Pro と Max は自分のアカウントから提出します。Team と Enterprise は Owner が提出でき、Enterprise では、Owner が「Organization settings > Roles」のカスタムロールで「Directory」の権限を他のメンバーへ付与できます。
  2. プラグインをローカルで検証する:シェルで claude plugin validate ./your-plugin --strict を実行し、マニフェストのエラーを手元で見つけます。ポータルには CLI が確認しない追加のディレクトリの規則があるので、手元で通ってもポータルの検証が通るとは限りません。提出の前に直すチェックの一覧は、claude.com の「Plugin pre-submission checklist」にあります。
  3. 何がどこで読み込まれるかを確かめる:一部のコンポーネントは Claude Code 専用で、claude.ai や Cowork では読み込まれません。アプリごとの対応表で、Claude Code の外のユーザーに何が届くかを確かめます。
  4. 開発者ポータルで提出する:claude.ai/directory/manage を開き、claude.com の「Submit a plugin」の手順に従います。

残りの流れは claude.com の文書にあります。各版が公開前にどう扱われるか(Prepare for review)、公開した版を新しい版へ更新する方法(Update a published plugin)、提出できるもの(プラグインと MCP サーバーのコネクタ)、ポータルができる前の提出フォームで出したプラグインの移し方です。

ディレクトリから入れた人は、アカウントにプラグインを持ち、Claude Code は <name>@synced として読み込みます(プラグインを使う)。

リリース・名前の変更・削除#

自分のマーケットプレイスから公開していて、plugin.json が version を設定しているなら、版を増やして押します。ほかのプラグインが自分のプラグインに版の範囲を宣言しているなら、リリースを git でタグ付けします(範囲はタグに対して解決される)。無ければタグは要りません。タグはプラグインのディレクトリでシェルから claude plugin tag を実行して作ります({name}--v{version} のタグ。--push で origin に送る)。公開済みのプラグインの name は変えません。変えると、旧名で記録された既存のインストールが失われます。どうしても変えるときは、marketplace.json の renames で移行させます(上の「名前の変更と削除」)。

CLI からおすすめする#

自分の CLI や SDK を保守していて、公式マーケットプレイスにそのプラグインがあるなら、Claude Code の中で動いているときに、<claude-code-hint /> という1行のタグを標準エラーへ出して、インストールのおすすめを出せます。Claude Code は Bash と PowerShell のツールの出力からその行を除いてからモデルに渡し、ユーザーに1度だけのインストールの確認を出します。これは、プラグインが claude-plugins-official か、Anthropic の公式のマーケットプレイス名を持つほかのマーケットプレイスに載っているときだけ使えます(コミュニティの claude-community は含まれません)。

CLAUDECODE か CLAUDE_CODE_CHILD_SESSION が設定されているときだけ出します。人が直接 CLI を動かしたときには出ません。

  • CLAUDECODE:Claude Code が Bash・PowerShell ツールで動かすコマンドとフックのコマンドで 1 を設定する(全バージョン)。IDE 拡張も、統合ターミナルに設定するので、CLAUDECODE だけで判定すると、人がそのターミナルで自分で動かしたときにも出る
  • CLAUDE_CODE_CHILD_SESSION:Claude Code が自分で起動するサブプロセスだけに設定される(v2.1.172 以降)。その版を要求できるなら、こちらを使う
javascript
if (process.env.CLAUDECODE) {
  process.stderr.write(
    '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />\n',
  )
}
python
import os, sys

if os.environ.get("CLAUDECODE"):
    print(
        '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />',
        file=sys.stderr,
    )
go
if os.Getenv("CLAUDECODE") != "" {
    fmt.Fprintln(os.Stderr,
        `<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />`)
}
bash
if [ -n "$CLAUDECODE" ]; then
  printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fi

example-cli を、公式マーケットプレイスでのプラグイン名に置き換えます。Claude Code は各プラグインに1度しか確認しないので、呼び出しごとに出してかまいません。確かめるには、CLAUDECODE=1 example-cli を端末で実行して標準エラーにタグの行が出ること、変数なしで実行して余分な出力が無いことを見ます。

属性 内容
v プロトコルのバージョン。1 だけ
type ヒントの種類。plugin だけ
value name@marketplace の形のプラグイン識別子

3つとも必須で、値は二重引用符で囲んでも囲まなくてもよく、囲まない値に空白は入れられません。タグは1行を占める必要があり、行の途中に埋め込んだものは無視されます。v や type が未対応でも、その行は出力から除かれます。

確認が出る条件は次のとおりで、すべてを満たす必要があります。

  • 対話の端末セッションだけ。claude -p・サブエージェント・フックのコマンドの出力では、タグは除かれて確認は出ない
  • 公式でインストール可能:value が、Claude Code が公式マーケットプレイスのローカルのコピーに見つけたプラグインで、まだ入っておらず、ポリシーが止めていない
  • 分析がオン:DISABLE_TELEMETRY・DO_NOT_TRACK・CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC を設定したセッションや、Amazon Bedrock のような、テレメトリを自動でオプトアウトするサードパーティのプロバイダでは出ない
  • 頻度の上限:1セッションに1回、プラグインごとに答えにかかわらず生涯1回、そのマシンで確認したプラグインが100件に達したあとは出ない
  • 止められていない:ユーザーが「No, and don't show plugin installation hints again」を選んでいない
  • ローカルで人がいるセッション:ワークスペースがローカルで、無人で動いていない。--cloud で始めたセッション、リモートコントロールを提供しているセッション、エージェントチームのチームメイトでは出ない

条件を満たすと「Plugin recommendation」ダイアログが出て、プラグイン名・マーケットプレイス・説明と、「Yes, install」「No」「No, and don't show plugin installation hints again」の3択が出ます。ダイアログは、Claude が動かしたシェルコマンドの最初の語を示すので、ユーザーが食い違いに気づけます。「Yes, install」はユーザースコープに入れ、「No, and don't show…」はそのユーザーへの今後のヒントを止め、30秒答えなければ「No」と数えます。

プロジェクトに応じておすすめする(relevance)#

マーケットプレイスの項目に relevance ブロックを足すと、ユーザーの作業が、あなたの定義したシグナルに合うとき、Claude Code が組織のマーケットプレイスのプラグインを提案します。シグナルには、作業ディレクトリ、Claude が読んだファイル、Claude が動かしたコマンドがあります。マーケットプレイスの運営者が relevance を書き、管理者が管理設定でそのマーケットプレイスを許可リストに入れます。許可リストに入るまで、ユーザーには提案が出ません。

シグナルの照合は、ユーザーのマシンの中で行われ、ネットワークの通信は増えません。どのシグナルが合ったか、その値は、Anthropic にもマーケットプレイスの運営者にも報告されません。シグナルが合い、プラグインが未導入のとき、Claude Code は次の3か所で提案します(自動でインストールすることはなく、ユーザーが必ず確認します)。

  • スピナーのヒント:Claude が応答しているあいだ、スピナーの下に /plugin install のコマンド付きのメッセージが出る
  • セッション開始の通知:cwd のシグナルが作業ディレクトリに合うと、最初のメッセージを送る前に1行の通知が出る
  • /plugin の「Discover」タブ:プラグインが「Discover」の一覧の先頭に固定される

スピナーのヒントとセッション開始の通知は、ユーザーかプロジェクトが spinnerTipsEnabled を false にしたとき、または excludeDefault を付けた spinnerTipsOverride が組み込みのヒントを置き換えたときに出なくなります。「Discover」の固定は、どちらの設定にも影響されません。

json
{
  "name": "your-marketplace",
  "owner": { "name": "Your Org" },
  "plugins": [
    {
      "name": "terraform-helpers",
      "source": "./plugins/terraform-helpers",
      "description": "Your organization's Terraform conventions and helpers",
      "relevance": {
        "topic": "Terraform",
        "signals": {
          "cli": ["terraform"],
          "filesRead": ["**/*.tf"]
        }
      }
    }
  ]
}

どのシグナルも合わないあいだは、プラグインは「Discover」の一覧の通常の位置にあり、スピナーのヒントには出ません。古いクライアントは、認識しない relevance のフィールドを無視して、マーケットプレイスを読み込みます。一方、認識するフィールドの値が上限を超えると、プラグインの項目全体が無効になり、直すまでユーザーはそのプラグインを入れられません(claude plugin validate が同じ上限を報告します)。

relevance のフィールドは次のとおりです。

フィールド 型 内容
topic 文字列 任意。スピナーのヒントの「Working with topic?」に入る語句。既定はプラグイン名のハイフン区切りの各語を大文字始まりにしたもの。64文字まで
signals オブジェクト プラグインが関係するときを決める照合条件。1つ以上設定しないと提案されない

signals のフィールドは次のとおりです。

フィールド 型 内容と上限
cwd 文字列の配列 セッションの作業ディレクトリに対する glob。10パターン、各256文字
cli 文字列の配列 このセッションで Claude が動かしたシェルコマンドの、コマンド名(["terraform"])。完全一致。10項目、各64文字
hosts 文字列の配列 このセッションの Bash コマンドの http:// か https:// の URL に見えたホスト名(["registry.terraform.io"])。スキーム・ポート・パスなしの小文字のホスト名だけ。大文字小文字を区別しない完全一致。20項目、各128文字
filesRead 文字列の配列 このセッションで Claude が読んだファイルのパスに対する glob(["**/*.tf"])。スラッシュに正規化され、大文字小文字を区別しない。10パターン、各256文字
manifestDeps オブジェクトの配列 このセッションで Claude が読んだパッケージのマニフェストの依存。各項目は { "file": "...", "pattern": "..." } で、どちらも正規表現。10項目、各値256文字まで。512 KB を超えるマニフェストのファイルは飛ばされる

filesRead と manifestDeps は、このセッションで Claude が書いたか編集したファイル、プロジェクトの自動で読み込まれる CLAUDE.md のメモリファイルにも照合されます。

  • cwd:セッション開始時、最初のメッセージの前に合うことができる唯一のシグナル。パターンは作業ディレクトリの絶対パスに照合され、git リポジトリの中なら、リポジトリのルートからの相対パスにも照合される。スラッシュに正規化し、大文字小文字は区別しない。どのパターンも、そのディレクトリ自身と配下に合うので、infra・infra/・infra/** は同じ動き
  • cli:Claude が動かす各シェルコマンドについて、先頭の環境変数の代入と sudo のあとの最初のトークンを1つのコマンド名として記録する。複合コマンドは先頭のコマンドだけで、cd infra && terraform plan は terraform でなく cd を記録する
  • manifestDeps:各項目は JavaScript の RegExp のソース文字列を2つ組にする。file はマニフェストファイルのパスに対して大文字小文字を区別せずに照合する(パスはたいてい絶対パスなので、先頭でなく末尾に固定する。このシグナルではパスの区切りは正規化されず、Windows ではバックスラッシュ)。pattern はそのファイルの中身に対して大文字小文字を区別して照合する
json
{
  "name": "your-plugin",
  "source": "./plugins/your-plugin",
  "relevance": {
    "signals": {
      "manifestDeps": [
        {
          "file": "[/\\\\]package\\.json$",
          "pattern": "\"your-sdk\"\\s*:"
        }
      ]
    }
  }
}

この例の file は、[/\\\\] でスラッシュとバックスラッシュの両方に合い、\\. でドットをそのままの文字にしています。JSON では、正規表現の各バックスラッシュを2つ書きます。公開前に、マーケットプレイスのディレクトリに対してシェルで claude plugin validate ./my-marketplace を実行して、relevance ブロックを確かめます。relevance と relevance.signals の未知のキーは警告、relevance の値がオブジェクトでないものはエラー、signals.hosts の項目がスキーム・ポート・パスを含むものは拒否されます。各結果にはフィールドのパスが付き、出力は Validation passed・Validation passed with warnings・Validation failed のいずれかで終わります。

管理者は、管理設定でマーケットプレイスを許可リストに入れます。pluginSuggestionMarketplaces にマーケットプレイス名を足し、Anthropic の公式のマーケットプレイス以外には、マーケットプレイスの取得元も、その名前の extraKnownMarketplaces の項目か strictKnownMarketplaces の項目で宣言します。マーケットプレイスが登録されていないマシンや、許可リストの名前で別の取得元から登録されているマシンでは、提案は出ません(関係のない取得元が許可リストの名前で登録して、組織全体にプラグインを提案させることを防ぐ確認です)。

json
{
  "extraKnownMarketplaces": {
    "your-marketplace": {
      "source": {
        "source": "github",
        "repo": "your-org/your-marketplace"
      }
    }
  },
  "pluginSuggestionMarketplaces": ["your-marketplace"]
}

公式のマーケットプレイスの名前は公式の取得元からしか登録できないので、取得元の宣言は要らず、名前だけ許可します({ "pluginSuggestionMarketplaces": ["claude-plugins-official"] })。ユーザーに見える内容は次のとおりです。

  • スピナーのヒント:Working with Terraform? Install the terraform-helpers plugin: に続けて /plugin install terraform-helpers@your-marketplace
  • セッション開始の通知:plugin suggestion: terraform-helpers@your-marketplace · /plugin
  • 「Discover」タブ:ほかの結果の上に、合ったシグナルを示す注記(suggested for this directory・suggested for terraform commands など)つきで固定される

同じプラグインの提案の頻度には、次の上限があります。

  • スピナーのヒントとセッション開始の通知を合わせて、3セッションに最大1回
  • セッション開始の通知は、スピナーのヒントと通知の合計の表示回数が2回になったら出なくなる
  • プラグインを入れたあとは、どちらも繰り返さない
  • 「Discover」タブの固定は、プラグインのシグナルが合っているあいだにユーザーが初めてタブを開いたときに行われる。Claude Code はそれを ~/.claude.json に記録し、そのマシンで以後 /plugin を開くたびに、プラグインは通常の順序で出る

組織のプラグイン管理(管理設定)#

管理設定は、組織のすべてのマシンで、Claude Code がどのプラグインを入れて許すかを決めます。ユーザーは上書きできません。claude.ai の管理画面からのサーバー管理設定か、MDM や managed-settings.json のファイルによるエンドポイント管理設定で配ります。この節の制御の多くは、管理設定からのときだけ効きます。管理者向けで、ここの設定が管理するのは Claude Code です(組織への導入と管理設定)。claude.ai と Cowork でメンバーが使えるプラグインの制御と、claude.ai の管理画面「Organization settings > Plugins & skills」は別で、後者がオンにしたものは、同期されたプラグインとして Claude Code に届き、この節のキーは設定しません。

配信の仕組みと、どれが適用されるか#

管理設定は、次の3つの配信のどれかでマシンに届きます。

  • サーバー管理設定:「Organization settings > Claude Code > Managed settings」で、プラグインのキーを JSON として設定する。Claude の組織の Owner ロールが必要。クラウドセッションは、プラグインを入れる前にこの設定を取得する
  • MDM のポリシー:macOS は、最上位のキーが設定のキーの plist を配る。Windows は、JSON ドキュメント全体を文字列でレジストリの値に置く
  • 管理設定のファイル:プラットフォームのシステムのパスに managed-settings.json を置く。隣の managed-settings.d/ のドロップインのディレクトリにファイルも足せる

claude.ai の Teams か Enterprise の組織があり、デバイスのすべてが MDM 下でないなら、サーバー管理設定を使い、そうでなければ MDM かファイルを使います。既定では、マシンで適用されるのは3つのうちの1つだけで、ポリシーのキーを届ける最初のもの(サーバー管理設定、MDM、ファイルの順)を使います。サーバー管理設定が関係のないキーを1つでも届けると、そのマシンでは、すべての配信元から読まれるキーを除いて、MDM かファイルのプラグインのキーは無視されます。すべての配信元を適用するには managedSourcesBehavior を "merge" にします。

マーケットプレイスとプラグインを必須にする#

extraKnownMarketplaces に、マーケットプレイス自身の marketplace.json の name をキーとして追加し、enabledPlugins に plugin-name@marketplace-name で各プラグインを足します。各マーケットプレイスの項目は、種類を示す source フィールドを持つ source オブジェクトを持ちます(github など)。

json
{
  "extraKnownMarketplaces": {
    "your-marketplace": {
      "source": { "source": "github", "repo": "your-org/your-marketplace" },
      "autoUpdate": true
    }
  },
  "enabledPlugins": {
    "code-formatter@your-marketplace": true,
    "deploy-helper@your-marketplace": true
  }
}

設定が届くと、次のセッションの開始時に、Claude Code がマーケットプレイスを登録して2つのプラグインを入れます。ユーザーは /plugin で見られ、自分のスコープで無効にしても読み込みは止まりません(管理設定がほかのどのスコープより優先されるため)。プラグインをすべてのスコープで止めて、マーケットプレイスの一覧からも隠すには、管理設定の enabledPlugins で false にします。

  • autoUpdate:true なら背景で更新し続け、false なら止める
  • source:github は取得元の種類の1つ。git の取得元は GitLab や社内ホスト用の url を取り、url の取得元はホストした marketplace.json のアドレスを取る
  • 非公開の git リポジトリなら、各ユーザーに読み取りアクセスが要る。git ホストのアカウントが無いユーザーには、下の「コンテナと CI に種をまく」を使う
  • 管理設定の項目は、同名のマーケットプレイスの項目や --plugin-dir のコピーを上書きする。マーケットプレイスは、優先度の低い同名の項目を置き換え、2つの項目のフィールドは合成されない
  • 公式マーケットプレイス claude-plugins-official は、そのプラグインを enabledPlugins で true にしていれば extraKnownMarketplaces の項目が要らない(name@claude-plugins-official の項目がそれだけでマーケットプレイスを宣言する)。公式のプラグインを1つも有効にせず、全マシンに登録したいなら、明示的な項目を与える

リポジトリの貢献者だけを対象にするには、そのリポジトリの .claude/settings.json に extraKnownMarketplaces と enabledPlugins を設定します。extraKnownMarketplaces の項目は、貢献者が信頼したフォルダでだけ適用され、信頼していないフォルダでは、何も表示せず無視されます。

  • 対話セッション:貢献者がそのフォルダのワークスペースの信頼ダイアログを承認したあとに、マーケットプレイスが登録される
  • 非対話の -p の実行:ユーザーがすでに対話で信頼を承認したフォルダ、または ~/.claude.json に hasTrustDialogAccepted を設定したフォルダでだけ適用される

マーケットプレイスが相対パスで載せたプラグインは、リポジトリの extraKnownMarketplaces が適用されると、マーケットプレイスのコピーから読み込まれます。項目が外部の取得元(プラグイン自身の GitHub リポジトリなど)を指すプラグインは、リポジトリの設定だけでは入らず、貢献者が claude plugin install <name>@<marketplace> --scope project を実行するまで、Plugin "<name>" is enabled in project settings but isn't installed と出ます。ローカルの directory か file の取得元に相対パスを使うと、パスはリポジトリのメインのチェックアウトに対して解決されます(git の worktree から実行しても、メインのチェックアウトを指すので、すべての worktree が同じマーケットプレイスの場所を共有します)。依存関係のあるバンドルを展開するには、バンドルのプラグインを enabledPlugins に入れます。

画面 管理設定の extraKnownMarketplaces と enabledPlugins リポジトリの .claude/settings.json
端末(対話) 設定を受け取る全マシンで、セッションの開始時に適用 extraKnownMarketplaces は信頼のあとに適用、enabledPlugins はセッション開始時に適用
-p と CI セッション開始時に適用(インストールは背景で実行) extraKnownMarketplaces は信頼したフォルダだけ、enabledPlugins は適用
クラウドセッション Anthropic がホストする環境では、サーバー管理設定だけがセッションに届き、セッションはそれを待ってからプラグインを入れる。MDM のポリシーと管理設定のファイルはユーザーのマシンに残る 「Cloud session」のタブの内容を見る(プラグインを使う)

-p と CI の実行では、マーケットプレイスとプラグインが背景で入るので、最初のターンにプラグインが無いことがあります。CLAUDE_CODE_SYNC_PLUGIN_INSTALL=1 を設定すると、最初のクエリの前にインストールを待ちます。届いたかの確認は、1台なら Claude Code を起動して /plugin で一覧を見ます。CI なら claude -p を --output-format stream-json --verbose で実行し、init イベントの plugins に読み込まれたプラグインが出ます。

コンテナと CI に種をまく#

実行時に clone できないコンテナイメージや CI ランナーには、ビルド時にプラグインのディレクトリを作っておき、CLAUDE_CODE_PLUGIN_SEED_DIR でそこを指します。Claude Code は、起動時にその種のマーケットプレイスを登録し、clone せずにその場でプラグインのキャッシュを読み込みます。git ホストのアカウントが無いユーザーにも使えます。

補足

CI/CD では、非公開のリポジトリからプラグインを入れる前に、git の資格情報ヘルパーを設定します。GitHub Actions では、マーケットプレイスのリポジトリへの読み取りアクセスを持つトークンを GH_TOKEN として書き出し、gh auth setup-git を実行します。既定のワークフローのトークンは、そのワークフロー自身のリポジトリにしかアクセスできないので、別のリポジトリの非公開のマーケットプレイスには、個人アクセストークンかアプリのトークンが要ります。

  1. ビルド時に種へ入れる:CLAUDE_CODE_PLUGIN_CACHE_DIR を種のパスにして、マーケットプレイスとプラグインを ~/.claude/plugins でなくそこへ入れる

    bash
    CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin marketplace add your-org/your-marketplace
    CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin install code-formatter@your-marketplace
    

    種は ~/.claude/plugins と同じ配置(known_marketplaces.json・marketplaces/<name>/・cache/<marketplace>/<plugin>/<version>/)で、ビルドしたのと別のパスにマウントしてもよい

  2. 実行時に種を指す:コンテナの環境に CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/claude-seed を設定する。複数の種は、Unix は :、Windows は ; で区切って並べ、特定のマーケットプレイスかプラグインのキャッシュを含む最初の種が使われる

  3. プラグインを有効にする:種のプラグインは、それだけでは有効にならない。読み込みたいプラグインごとに、管理設定かリポジトリの .claude/settings.json の enabledPlugins を設定する

種を確かめるには、イメージの中で claude -p を --output-format stream-json --verbose で実行します。init イベントの plugins で、読み込まれた各プラグインの path が種の下(/opt/claude-seed/cache/your-marketplace/code-formatter/1.0.0 など)になります。種のマーケットプレイスには次の規則があります。

  • 読み取り専用:Claude Code は種に書き込まず、種のマーケットプレイスでは autoUpdate を強制的にオフにする
  • 種が優先:起動のたびに、種で宣言されたマーケットプレイスが、同名のユーザーの項目を上書きする。ユーザーが種のプラグインを断るには、マーケットプレイスの削除ではなく claude plugin disable
  • 更新と削除は失敗:種のマーケットプレイスへの claude plugin marketplace update <name> と、--scope なしの remove は、種のディレクトリを名指しするメッセージで失敗する
  • ポリシーは効く:許可リストとブロックリストは、種のマーケットプレイスの記録された取得元も確認する。種をビルドした取得元を許可する

外向きの git のアクセスが無い環境では、種と、共有マウント上の directory か file のマーケットプレイスの取得元を組み合わせ、CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 も設定します(これはプラグインの自動更新も止めます)。プロキシが使えるなら、必要な変数はネットワークと LLM ゲートウェイにあります。

利用者が入れられるものを制限する#

管理設定の許可リスト strictKnownMarketplaces とブロックリスト blockedMarketplaces が、プラグインを入れられるマーケットプレイスの取得元(Claude Code が取得する git リポジトリ・URL・ローカルのパス)を決めます。どちらのリストも、プラグインが来たマーケットプレイスの取得元に照合され、そのマーケットプレイス内のプラグインの項目には照合されません。公式と自分のものを許す一般的な形は、下の例にあります。disableSideloadFlags と組み合わせると、ローカルのディレクトリや URL からの読み込みも止められます。

リストは、ダウンロードの前と、セッションの開始時にもう一度適用されます。

  • ダウンロードの前:ユーザーがマーケットプレイスを追加するときと、すべてのインストール・更新・リフレッシュ・自動更新で適用される
  • セッション開始時:すでに入っているプラグインにも適用され、マーケットプレイスの取得元が合わなくなったプラグインは読み込まれない。/plugin には Marketplace "<name>" is not in the allowed marketplace list か Marketplace "<name>" is blocked by enterprise policy と出る

リストが強制される場所は、設定した場所で変わります。claude.ai の管理画面からなら、サーバー管理設定を読むセッションで Claude Code が強制し、claude.ai も、組織の誰かが claude.ai の git リポジトリか Claude Desktop アプリの Code タブの外の「Customize」から新しいマーケットプレイスを追加するときに確認します(メンバー自身のアカウントのもの、組織全体のもののどちらも)。許可リストが認めないリポジトリ、ブロックリストが名指しするリポジトリを拒否しますが、リストを設定する前に追加されたものは確認し直さず、アップロードされたプラグインも確認しません。管理設定のファイルや OS レベルのポリシーなど、ほかの管理の配信元からなら、Claude Code がそれを読む場所で強制し、claude.ai は読みません。許可リストがあるあいだ、または skills-dir 以外の取得元をブロックリストが指すあいだは、Claude Code が見つけられないマーケットプレイスのプラグインは読み込まれず、/plugin は not-found でなくポリシーのエラーを示します(典型は、誰も登録していないマーケットプレイスの古い enabledPlugins の項目)。

プラグインのポリシーのキーは次のとおりです。

キー 強制すること できないこと
strictKnownMarketplaces マーケットプレイスの取得元の許可リスト。[] は公式も含め全取得元を止める。別名は allowedMarketplaces マーケットプレイスを登録しない。許可したマーケットプレイス内の項目を制限しない。--plugin-dir を止めない
blockedMarketplaces マーケットプレイスの取得元のブロックリスト。許可リストの前に確認される 合わない取得元ですでに登録されたマーケットプレイスを止めない
syncClaudeAiPlugins false で、各ユーザーのアカウントから claude.ai の同期されたプラグインをダウンロード・読み込みしなくなる(v2.1.273 以降) 同期されたプラグイン1つを切らない。それには enabledPlugins で "<name>@synced": false
enabledPlugins true で強制的に有効、false で全スコープで止めて隠す マーケットプレイスが登録されていない、許可されていないプラグインは入れない
disableSideloadFlags --plugin-dir・--plugin-url・--agents・Agent SDK の plugins オプション・SDK 以外の --mcp-config を起動時に拒否し、CLAUDE_CODE_PLUGIN_DIRS のフォルダも同様に拒否する .mcp.json・claude mcp add・SDK 提供のサーバーは制限しない。allowedMcpServers と組み合わせる
disableCommandPluginSources command の取得元(インストールするマシンでコマンドを実行してプラグインのディレクトリを作るもの)のプラグインのインストール・更新・読み込みを止める。未設定なら allowManagedHooksOnly の値を取る 他の取得元の種類には影響しない
allowManagedHooksOnly 動くフックを制限する ユーザーが自分で有効にしたプラグインのフックは信頼しない
allowManagedModsOnly 組織のものと数えられない、インストール済みの Mod の読み込みを止める Mod を含むプラグインのインストールは止めない。止めるなら、この表のマーケットプレイスのキーを使う
strictPluginOnlyCustomization プラグイン・管理設定・Claude Code の組み込みに由来しないスキル・エージェント・フック・MCP サーバーを止める。true で4種類すべて、skills・agents・hooks・mcp の配列(["skills", "hooks"])で一部 ユーザーが入れるプラグインは制限しない。strictKnownMarketplaces と組み合わせる
pluginSuggestionMarketplaces プラグインがインストールの提案として出てよいマーケットプレイス 組み込みのヒントには影響しない
pluginTrustMessage プラグインのインストール前に /plugin が出す信頼の警告に、自分の文を追記する 警告自身の文は変えない
allowedChannelPlugins チャネルのメッセージを送ってよいプラグインの既定のリストを置き換える。channelsEnabled: true が必要 チャネルを見る
CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL=1 対話の端末セッションが公式マーケットプレイスを自動登録するのを止める 登録済みのものは外さない。この変数なしでも、許可リストとブロックリストが同じ自動登録を止める。一度これを設定して始めたマシンは、変数を外しても自動登録が再開しない

表のうち enabledPlugins・syncClaudeAiPlugins・CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL・allowManagedModsOnly を除くキーは、管理設定のキーです。enabledPlugins はどのスコープにも設定でき、管理設定がロックします。syncClaudeAiPlugins は各ユーザーも自分のユーザー設定かローカル設定に置けます。CLAUDE_CODE_DISABLE_OFFICIAL_MARKETPLACE_AUTOINSTALL は、管理設定の env ブロックで配る環境変数です。allowManagedModsOnly は組み込みのプラグインのオプションで、管理設定の pluginConfigs の下に置きます(Mod を使う)。各設定キーは設定キー一覧にあります。strictKnownMarketplaces は allowedMarketplaces、extraKnownMarketplaces は additionalMarketplaces とも書けます(v2.1.232 以降で、古いクライアントは無視するので、混在する環境のファイルでは正規の名前を使う。両方の綴りを設定したら、正規のキーの値が使われる)。

許可リストは、次の取得元オブジェクトのリストで設定します。ほとんどは完全一致で、hostPattern と pathPattern は正規表現として、github のオーナーのワイルドカードはオーナーで照合します。

  • github:{ "source": "github", "repo": "your-org/approved-plugins" }。ref と path は任意
  • github のオーナーのワイルドカード:{ "source": "github", "repo": "your-org/*" } はそのオーナー配下のすべてのリポジトリに合う。* はリポジトリ名全体の位置に置く。*/plugins や your-org/tools-* は不正として無視され、何にも合わない(v2.1.223 以降)
  • git:{ "source": "git", "url": "https://gitlab.example.com/tools/plugins.git" }。ref と path は任意
  • url:{ "source": "url", "url": "https://plugins.example.com/marketplace.json" }。headers は任意
  • file と directory:{ "source": "file", "path": "/opt/marketplace/marketplace.json" } か { "source": "directory", "path": "/opt/marketplace/plugins" }。絶対パス
  • hostPattern:{ "source": "hostPattern", "hostPattern": "^github\\.example\\.com$" }。github・git・url の取得元のホストに照合される。パターンはホスト名のどこにでも合うので、ホスト全体に合わせるなら ^ と $ で固定する。github の取得元は常に github.com とみなされる。開発者が自分のマーケットプレイスを作る GitHub Enterprise Server や GitLab のホストに使う
  • pathPattern:{ "source": "pathPattern", "pathPattern": "^/opt/approved/" }。file と directory の取得元の path に照合される。パターンはパスのどこにでも合うので、ディレクトリの接頭辞に固定するには ^ で始める。".*" はローカルのすべてのパスを許す
  • skills-dir:{ "source": "skills-dir" } は、許可リストがあるあいだもスキルのディレクトリのプラグインを読み込み続け、マーケットプレイスには合わない

照合の規則は次のとおりです。url の項目は url の値で合い、headers は比較されません。github と git の項目は、repo か url、ref、path がすべて一致するか、両側で無い必要があります。ref の無い項目は ref: "main" の取得元を覆いません。your-org/your-marketplace の項目は、同じリポジトリを clone する git の URL を覆いません。末尾のスラッシュ、.git の接尾辞、https:// の代わりの ssh:// は別の値です。マーケットプレイスを複数の URL で clone できるなら、hostPattern の項目を選びます。オーナーのワイルドカードの項目は ref の厳密な規則に従い、項目が固定しない限り、リポジトリ内のどの path にも合います(ワイルドカードの照合は、許可リストでは大文字小文字を区別します)。

スキルのディレクトリのプラグインは、ユーザーが ~/.claude/skills/ かプロジェクトの .claude/skills/ に、.claude-plugin/plugin.json を持つフォルダとして置くものです。{ "source": "skills-dir" } の項目なしで許可リストを設定すると、読み込まれなくなります(.claude-plugin/plugin.json が無い SKILL.md だけの普通のスキルは、読み込まれ続けます)。claude.ai がホストするマーケットプレイスは、ホストで照合されます。許可・ブロックするには、claude.ai に合う hostPattern の項目を、strictKnownMarketplaces か blockedMarketplaces に足します。許可リストでは、そのような項目は、組織の claude.ai のマーケットプレイスと claude.ai の既定のマーケットプレイスを許可しますが、メンバー自身の claude.ai のアップロードでできたものや、スコープを claude.ai が示さなかったものは許可しません(v2.1.273 以降)。空の許可リスト [] は、公式も含めすべてのマーケットプレイスの取得元を締め出しますが、claude.ai から同期されたプラグイン(各ユーザーのアカウントからダウンロードされる)は止めません。それも止めるには、管理設定で syncClaudeAiPlugins を false にするか、claude.ai で組織のスキルをオフにします。

blockedMarketplaces は strictKnownMarketplaces と同じ取得元オブジェクトを取り、先に確認されるので、両方にある取得元はブロックされます。ブロックリストの照合は、許可リストより広くなります。

  • git の URL は正規化され、1つの github.com リポジトリの git@ と https:// の形、.git の接尾辞、末尾のスラッシュが、すべて同じ項目に合う
  • github の項目は同等の git の URL もブロックし、逆も同じ
  • owner/* の項目は、オーナーの比較が大文字小文字を区別しない
  • ref や path の無い項目は、合うリポジトリのすべての ref と path をブロックする
json
{
  "blockedMarketplaces": [
    { "source": "github", "repo": "untrusted-org/*" }
  ]
}

blockedMarketplaces の url の項目は、ユーザーが追加した https:// のリポジトリ URL(fetch でなく clone されるもの、たとえば素の github.com や gitlab.com のリポジトリ URL)にも適用され、項目が名指しすると追加できません。.git の接尾辞と、ユーザーが # のあとに付ける ref は無視して照合されます(v2.1.232 以降)。ここの { "source": "skills-dir" } の項目は、~/.claude/skills/ とプロジェクトの .claude/skills/ の両方からのスキルのディレクトリのプラグインの読み込みを止めます。この項目だけを名指しするブロックリストは、有効な制限とは数えないので、Claude Code が見つけられないマーケットプレイスのプラグインを読み込ませなくする動きはしません。

多くの組織は、公式マーケットプレイスと自分のものを許可し、全マシンに登録します。次のポリシーは、両方を許可し、両方を登録し、2つのプラグインを強制的に有効にして、--plugin-dir を拒否します。

json
{
  "strictKnownMarketplaces": [
    { "source": "github", "repo": "anthropics/claude-plugins-official" },
    { "source": "github", "repo": "your-org/*" },
    { "source": "skills-dir" }
  ],
  "extraKnownMarketplaces": {
    "claude-plugins-official": {
      "source": { "source": "github", "repo": "anthropics/claude-plugins-official" }
    },
    "your-marketplace": {
      "source": { "source": "github", "repo": "your-org/your-marketplace" }
    }
  },
  "enabledPlugins": {
    "code-formatter@your-marketplace": true,
    "deploy-helper@your-marketplace": true
  },
  "disableSideloadFlags": true
}

このポリシーのマシンでは、リスト外の取得元(/plugin marketplace add https://example.com/other-marketplace.git など)の追加が、is blocked by enterprise policy と許可された取得元を含むメッセージで失敗し、claude --plugin-dir ./x は disableSideloadFlags を名指しするメッセージで終了します。許可リストや公式マーケットプレイスの自己登録に頼らず、このポリシーのように、両方のマーケットプレイスを明示的な extraKnownMarketplaces の項目で登録します。

  • 許可リストは何も登録しない:登録するのは extraKnownMarketplaces の項目で、その項目自身が許可リストを通る必要がある。許可リストが合わない取得元の管理されたマーケットプレイスは登録されない
  • 公式マーケットプレイスが自己登録するのは対話の端末セッションだけで、そこでも許可リストが許すときだけ。-p の実行や、クラウドセッションにつないだ端末は登録しない
  • 止められた試みは記憶される:公式マーケットプレイスを止めたポリシー([] の締め出しもその1つ)の下で動いたことがあるマシンは、その試みを記録し、ポリシーが変わっても再試行しない。そのマシンが再び登録するのは、上のポリシーのような extraKnownMarketplaces の項目、公式のプラグインの enabledPlugins の項目、手動の /plugin marketplace add のどれかを通すときだけ

更新のポリシー#

自動更新は、オンのマーケットプレイスについて、起動後に背景で動きます。マーケットプレイスごとに決めるには、管理設定の extraKnownMarketplaces の項目に "autoUpdate": true か false を設定します。管理設定の項目がこのフィールドを設定すると、ユーザーの /plugin での切り替えは Auto-update for '<name>' is set by で始まるエラーで拒否され、未設定ならユーザーの切り替えが保たれます。全マーケットプレイスの自動更新を止めるには、管理設定の env ブロックに DISABLE_AUTOUPDATER を設定します(この変数は Claude Code 自身の更新も止めます)。

json
{
  "env": {
    "DISABLE_AUTOUPDATER": "1"
  }
}

Claude Code 自身の更新だけを止めてプラグインの自動更新を残すには、同じブロックに "FORCE_AUTOUPDATE_PLUGINS": "1" を足します。プラグインの自動更新を止める他の環境変数も、同じように効きます。DISABLE_AUTOUPDATER は command の取得元のプラグインを含みません。Claude Code は、有効なそれぞれのコマンドをセッションごとに再実行し、出力が変わっていればインストールします(何が止めるかはプラグインのリファレンス)。

安定版と先行版のチャンネルをユーザーのグループに割り当てるには、同じプラグインの別の ref を指す2つのマーケットプレイスをホストし、各グループに別々のエンドポイント管理設定かゲートウェイのポリシーで、それぞれのマーケットプレイスを与えます。管理画面のサーバー管理設定は組織の全ユーザーに適用されるので、グループごとに別の設定を割り当てられません。

  • 各グループのデバイスに、管理設定のファイルや MDM のプロファイルなど、別々のエンドポイント管理設定を配る
  • Claude apps gateway のポリシーを、グループごとに1つ定義する(Claude apps gateway)。ゲートウェイは、ユーザーに合う最初のポリシーを適用するので、各ユーザーが自分のグループのポリシーに当たる順に並べる。そのポリシーの extraKnownMarketplaces のマップは他のポリシーと合成されないので、チャンネルのマーケットプレイスだけでなく、そのグループに必要なマーケットプレイスをすべて並べる
json
{
  "extraKnownMarketplaces": {
    "stable-tools": {
      "source": { "source": "github", "repo": "your-org/stable-tools" }
    }
  }
}

先行版のグループには latest-tools を与えます。

監査#

OpenTelemetry のイベントと Analytics API で、組織が何を入れて動かしているかが分かります。マーケットプレイスを承認する前に、プラグインがマシンで何を実行でき、各階層が何を許すかをプラグインを使うの信頼の節で確かめます。

  • claude_code.plugin_installed が各インストールを、claude_code.plugin_loaded が、セッション開始時の各有効なプラグインを記録する。どちらも、OTEL_LOG_TOOL_DETAILS=1 を設定しない限り、サードパーティのプラグインとマーケットプレイスの名前を伏せるか省く
  • Enterprise プランでは、GET /v1/organizations/analytics/plugins が、Claude Code と Cowork にまたがる、プラグインごと・日ごとのインストールと呼び出しの数を返す。ユーザーか RBAC のグループでまとめられる。プラグイン名なしで Anthropic に届いた活動は、集約した1つの third-party の行に出る。キーの要件は利用状況の計測にある

管理設定でできないこと#

セキュリティレビューからのこれらの要望には、現在の設定スキーマに専用のキーがありません。近い手段は次のとおりです。

  • ユーザーやグループごとの対象化:プラグインのキーは、設定を受け取る全ユーザーに適用される。サーバー管理設定は組織に1つの設定を届ける。グループごとのポリシーには、別々のエンドポイント管理設定かゲートウェイのポリシー
  • 許可したマーケットプレイス内の項目の制限:許可リストは取得元に照合する。許可したマーケットプレイスから1つのプラグインを止めるには、管理設定の enabledPlugins で false
  • /plugin を隠す:コマンドを止めるキーは無い。近いのは、自分のマーケットプレイスだけを指す許可リスト、提供するプラグインの管理された enabledPlugins、disableSideloadFlags の組み合わせ
  • --plugin-dir を許可リストで制御する:許可リストは --plugin-dir を覆わない。disableSideloadFlags が覆う
  • claude.ai のプラグインの切り替えをこれらのキーで強制する:「Organization settings > Plugins & skills」はここのキーを設定しない。そこでメンバーや組織がオンにしたものは、独自の制御を持つ同期されたプラグインとして CLI に届く

ポリシーの切り分け#

マシンでプラグインのポリシーが期待どおりに動かないときは、まず次を確かめます。

  • 管理設定のファイルが解析できない:managed-settings.json が正しい JSON でないと、Claude Code はファイル名を名指しするエラーを出して起動を拒否する。解析できても1つの項目だけが不正なファイルは、残りのポリシーを保つ(エラー一覧)
  • 管理された設定の出どころが読み込まれていない:/status を実行し、Setting sources の行に Enterprise managed settings があるか見る。無ければその出どころは読み込まれていない
  • ユーザーが blocked by enterprise policy と言う:メッセージがマーケットプレイスかその取得元を名指しし、許可リストなら許可された取得元も並べる
  • ユーザーが ~/.claude/settings.json で無効にしたプラグインが読み込まれ続ける:管理された enabledPlugins の項目のように、別の設定の出どころが再び有効にしている。/plugin と claude plugin list に、その設定の出どころつきで Disabled in ~/.claude/settings.json but still loads と出る

コストと利用を計測する#

有効なプラグインのあるセッションはどれも、そのスキル・エージェント・コマンドの名前と説明を Claude のコンテキストへ入れ、そのトークンは、プラグインが使われるかどうかにかかわらずユーザーの使用量に数えられます。プラグインがコンテキストに足す量を見るには、プラグインの名前を付けて claude plugin details を実行します(動いているセッションのプロンプトでなく、シェルで)。プラグインは読み込まれている必要があります(インストール済み・スキルのディレクトリ・同じコマンドの --plugin-dir:claude --plugin-dir ./formatter plugin details formatter)。

text
formatter 1.0.0
  Description: Formats and lints code on save
  Source: formatter@my-marketplace

Component inventory
  Skills (3)  format-all, format-code, lint-fix
  Agents (1)  style-reviewer
  Hooks (1)  PostToolUse  (harness-only — no model context cost)
  MCP servers (1)  formatter-tools  (tool schemas resolved at runtime; not counted)
  LSP servers (0)

Projected token cost
  Always-on:   ~146 tok   added to every session

Per-component (rounded)
  component       always-on  on-invoke
  format-code           ~40        ~30
  lint-fix              ~50        ~30
  style-reviewer        ~40        ~40
  format-all           < 20        ~30

  On-invoke cost is paid each time a skill or agent fires.
  Token counts are estimates and may differ from actual usage.
  • Component inventory:Claude Code がプラグインに見つけたもの。コマンドはスキルと一緒に数えられる(format-all は Skills の下に出る)。フックと MCP サーバーにはコストの見積もりも、コンポーネントごとの行も出ない。プラグインの MCP ツールが足す量は、プラグインを有効にしたセッションで /context を実行し、MCP tools のカテゴリを読む(コンテキスト)
  • Always-on:プラグインのスキル・エージェント・コマンドの名前と説明が、プラグインが有効なすべてのセッションに、何も動かなくても足すトークン。全ユーザーが負う数で、減らす対象
  • Per-component:1つのスキル・エージェント・コマンドを、常時のぶんと、そのコンポーネントが動くときだけ読み込まれる本文の呼び出し時のコストに分ける。常時の列で、最も大きく寄与するものが分かる

保守しているプラグインなら、常時の数字は次のように減らせます。数字は、各コンポーネントの名前と、フロントマターの description と when_to_use を数えます。スキルとエージェントの説明を短くする、大きなプラグインを分けてユーザーが要るコンポーネントだけを入れられるようにする、です。スキルの説明は、Claude が要求と照合する対象でもあるので、短くするとスキルが発火しなくなることがあります。説明を削ったら、評価のスイートの tool_used: Skill のグレーダーで発火を確かめます(プラグインの評価(evals))。単に使うだけなら、無効にするか削除します。

公式マーケットプレイスのプラグインは、インストール前にコストをユーザーに見せます。/plugin でマーケットプレイスのプラグインの一覧からプラグインを選ぶと、詳細に「Context cost」の節が出て、Every turn: の行と When invoked: の行が出ます。常時の数字が2,000トークン以上だと、Every turn: の行が強調されます。自分のマーケットプレイスのプラグインには「Context cost」の節がありません。

利用状況は、Claude Code がプラグインの作者に報告しません。利用は、プラグインを入れた各人のマシンに記録されるので、分かることは相手との関係で変わります。

  • その組織の Claude Code を管理している:OpenTelemetry のイベントと Analytics API が、全マシンのインストールとスキルの起動を数える
  • 聞ける同僚:各ユーザーの Claude Code が、そのユーザー自身に、まだ使っているかを4か所で示す。/plugin のパネル、/skill-doctor、/doctor、/usage。どれも自分のマシンのセッションのプロンプトで実行するコマンド
  • どちらでもない:そのプラグインについて Claude Code からの利用のシグナルは得られない

Anthropic のディレクトリに載せたプラグインの利用は、claude.com の「Track published plugin usage」を見ます。

  • /plugin の「Installed」タブでは、マーケットプレイスから入れたプラグインが、14日以上かつ10セッション使われないと、「Not used recently」の見出しの下に動き、詳細に Last used: の行も出る。この見出しが出ないのは、--plugin-dir かスキルのディレクトリから読み込んだもの、管理設定で有効にしたものや種のディレクトリからマウントされたもの、テーマ・出力スタイル・モニター・ワークフローを含むもの(追跡される呼び出しなしに使われているため)。プラグインの言語サーバーは、診断を出すか、コード移動の要求に答えたときに使われたと数えられるので、サーバーが動いている LSP プラグインは未使用に出ない。ユーザーの組織が strictKnownMarketplaces を設定していると、見出しも Last used: の行も出ない
  • /skill-doctor:各スキルのコストと使われる頻度を見る。スキルの一覧にあるのに一度も呼ばれていないスキル(プラグインのものを含む)に印が付く。対話セッションでは、レポートが /plugin の管理画面の「Stats」タブで開く(スキル)
  • /doctor:ユーザーが入れたスキル・MCP サーバー・プラグインを一覧にし、使われていないものを無効にするよう勧める(スラッシュコマンド一覧)
  • /usage:Pro・Max・Team・Enterprise のプランで、最近の使用量を、スキル・サブエージェント・プラグイン・MCP サーバーごとに、合計に占める割合で配分する(コストを抑える)

組織の全マシンを測るには、OpenTelemetry のイベント(自分のバックエンドへ、exporter を設定したあとに出る)か Analytics API(Anthropic の記録から返り、exporter は不要)を使います。

知りたいこと OpenTelemetry のイベントか属性
どのプラグインがどこから入ったか claude_code.plugin_installed(インストールごとに1つ)
どのプラグインが何セッションで有効か claude_code.plugin_loaded(セッション開始時の、有効なプラグインごとに1つ)
どのスキルが起動し、どのプラグインのものか claude_code.skill_activated(プラグインのスキルには plugin.name と marketplace.name)
プラグインのフックが報告する内容 claude_code.hook_plugin_metrics(公式マーケットプレイスのプラグインのフックについてだけ出る)
プラグインの API の支出 コストカウンターの plugin.name と marketplace.name(動いているスキルかサブエージェントがプラグインのものであるときに設定される)

公式マーケットプレイスのプラグインは、プラグイン名とマーケットプレイス名をそのままバックエンドへ報告します。ほかのプラグインの名前は、組織自身のマーケットプレイスのものも含め、既定で伏せられるか省かれます(どちらになるかはプラグインの信頼の階層で決まる。プラグインを使う)。一部のイベントで実名を得るには、テレメトリを出すマシンで OTEL_LOG_TOOL_DETAILS を 1 に設定します(たとえば、exporter を設定する管理設定の env ブロックで)。

イベント 既定 OTEL_LOG_TOOL_DETAILS=1
plugin_loaded plugin.name と marketplace.name が文字列 third-party 実名
plugin_installed・skill_activated plugin.name と marketplace.name は省かれる。skill_activated では skill.name が custom_skill 実名
コストカウンター plugin.name は third-party、marketplace.name は無し 実際の plugin.name。marketplace.name は無いまま

plugin_loaded では、既定でも plugin_id_hash が各プラグインを識別するので、別々のサードパーティのプラグインを数えられます。Enterprise プランでは、Analytics API が GET /v1/organizations/analytics/plugins で、Claude Code と Cowork にまたがる、プラグインごと・日ごとのインストールと呼び出しの数を返し、ユーザー・RBAC のグループ・プロダクトでまとめられます。リクエストは、read:analytics のスコープを持つ API キーで認証します(Primary Owner が作成する)。計測の詳細は利用状況の計測にあります。

公式ドキュメント(英語)

2026年10月5日時点の内容をもとに、日本語でまとめています。

ページの一覧