Claude Media
Claude Codeプラグインソースの使い分け — GitHub・Git・npm・zip・コマンド

Claude Codeプラグインソースの使い分け — GitHub・Git・npm・zip・コマンド

marketplace.jsonのsourceフィールドが持つ7通り(相対パス・github・url・git-subdir・npm・archive・command)を、配布先の環境と組織同期の制約から選び分ける基準を示します。

marketplace.jsonのsourceフィールドが担う役割

Claude Codeのプラグインは、marketplace.jsonの各プラグインエントリが持つsourceフィールドで「どこから取得するか」を指定します。同じリポジトリ内の相対パスから、GitHub・任意のGitホスト・モノレポのサブディレクトリ・npmレジストリ・HTTPSでホストしたzip、さらにローカルコマンドが動的に生成するディレクトリまで、7通りの取得方法があります。

選ぶ起点は、配布先の端末に何が入っているかと、どの経路で配るかです。

プラグインの基本構造やインストール手順はClaude Codeプラグイン完全ガイドで扱っているので、marketplace.json自体を初めて書く場合はそちらを先に読むと流れがつかみやすくなります。

手順

配布先から逆算するソース型の選び方

  1. 1

    配る経路が組織同期か

    TeamまたはEnterpriseの管理画面から配るなら、選べるのは相対パス・github・url・git-subdirだけです。ここで候補が絞られます。

  2. 2

    配布先にgitがあるか

    あるならgithubかurl(GitHub以外のホスト)、モノレポの一部だけならgit-subdirです。同じリポジトリに同居させるなら相対パスで足ります。

  3. 3

    gitがなくnpmがあるか

    npmレジストリに公開済みのパッケージならnpmです。社内レジストリはregistryで指定します。

  4. 4

    どちらもないか、都度生成か

    HTTPSで取れるzipならarchive、ローカルのツールがディレクトリを作るならcommandです。

相対パスとgithubソース — 同じリポジトリと別リポジトリの基本形

最も単純なのは相対パスです。プラグインとマーケットプレイスが同じリポジトリにあるとき、./で始まる文字列だけで指定できます。

{ "name": "my-plugin", "source": "./plugins/my-plugin" }

パスはmarketplace.jsonが置かれているディレクトリ(.claude-plugin/の親)を基準に解決されます。../で外に出ることはできません。多数のプラグインを1リポジトリにまとめる場合は、metadata.pluginRootに共通の親ディレクトリを設定すると、各エントリのsourceをスラッシュを含まない裸のディレクトリ名だけで書けます(Claude Code v2.1.239以降が必要)。ただしteam-a/formatterのようにスラッシュを含む名前は裸の名前扱いにならず、pluginRootを設定していても./始まりで書く必要があります。

相対パスは、Claude Codeがマーケットプレイスのファイル一式を持っているときにだけ解決できます。解決できない書き方で出るエラーはmarketplace entry pathが拒否される原因で切り分けています。

  • gitソース・ローカルディレクトリ・ローカルファイルとして追加した場合: 解決できます
  • marketplace.jsonへの直接URLで追加した場合: Claude Codeはそのファイルだけを取得するため、解決できません。各プラグインにgithubやgit-subdirなどのオブジェクト形式を使います
  • settings(extraKnownMarketplacesなど)に書いた場合: 相対パスは受け付けられません

別リポジトリにあるプラグインを取得するときの基本形がgithubソースです。

{
  "name": "github-plugin",
  "source": { "source": "github", "repo": "owner/plugin-repo", "ref": "v2.0.0", "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0" }
}

repoだけが必須で、ref(ブランチ・タグ)は省略するとリポジトリの既定ブランチになります。shaは40文字の小文字のコミットSHAで、両方指定した場合はshaが優先されます。GitHub・GitLab・Bitbucketなど大半のgitホストでは、refが指す枝が後から削除されても、そのコミットにたどり着ける限りインストールは成功します。AWS CodeCommitのようにSHA指定のフェッチに対応しないサーバーでは、ref自体が存在し続けている必要があります。

urlとgit-subdirソース — GitHub以外のホストとモノレポ

GitHub以外のgitホスト(GitLab・Bitbucket・自前ホスト)を使う場合はurlソースを使います。フィールド構成はgithubソースとほぼ同じで、repoの代わりに完全なurlを指定します。

{
  "name": "git-plugin",
  "source": { "source": "url", "url": "https://gitlab.com/team/plugin.git", "ref": "main", "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0" }
}

urlにはhttps://・http://・file://・git@の形式を書けます。.git拡張子は省略できるので、Azure DevOpsやAWS CodeCommitのように拡張子なしURLを使うホストにも対応します。owner/repoの短縮形はこのソース型では受け付けられません。

モノレポの1ディレクトリだけをプラグインとして配りたい場合はgit-subdirソースが向きます。

{
  "name": "my-plugin",
  "source": { "source": "git-subdir", "url": "https://github.com/acme-corp/monorepo.git", "path": "tools/claude-plugin" }
}

pathのサブディレクトリだけをチェックアウトします。httpsやSSHのURLではサーバーにパーシャルクローンを要求するため、パーシャルクローンに対応するホストなら、大きなモノレポでも残りを丸ごとダウンロードせずに済みます。urlにはGitHubのowner/repo形式も使えます。同じリポジトリの一部ならgit-subdirではなく相対パスを選びます。

npmソース — レジストリ経由でインストールする形

npmパッケージとして配布済みのプラグインは、ユーザーのnpmクライアントで取得されます。

{
  "name": "my-npm-plugin",
  "source": { "source": "npm", "package": "@acme/claude-plugin", "version": "^2.0.0", "registry": "https://npm.example.com" }
}

packageが必須です。@acme/claude-plugin@2.0.0のようにバージョンを付けた名前や、パッケージのtarballへのhttpsリンクも書けます。versionにはバージョン、範囲指定、dist-tagを使え、省略するとlatestを取得します。registryは既定のレジストリにないパッケージで使います。

取得時にパッケージのinstallスクリプト(preinstallやpostinstall)は走らず、依存パッケージも取得の段階ではインストールされません。package.jsonの隣に対応するロックファイルがあれば、別の手順でスクリプトなしのまま依存を入れます。

packageの値は取得の前に検査され、次のものは拒否されます。

  • gitアドレス、フォルダーやfile:のパス、npm:のエイリアス
  • github.com・gitlab.com・bitbucket.orgなどにあるtarballリンク(GitHubのリリースのダウンロードも同じ)。GitLabのnpmレジストリのリンクだけは通ります
  • httpのtarballリンク。ただしインストールするユーザー自身の既定レジストリを指す場合は除きます

registryのURLも、ユーザー自身の既定レジストリを除いてhttpsが必要です。npmソースはユーザーの端末にnpmクライアントがあることが前提になる点が、次のarchiveソースとの分かれ目です。

archiveとcommandソース — gitもnpmも要らない配布と動的生成

gitもnpmも入っていない端末に配りたい場合はarchiveソースを使います。HTTPSでホストしたzipファイルをダウンロードしてインストールする形式で、HTTPSで静的ファイルを配れる場所ならどこでもホストできます(Claude Code v2.1.224以降が必要)。sha256フィールドでダイジェストを固定でき、--plugin-dirや--plugin-urlでの一時ロードを含めた設定手順はClaude Codeプラグインをzip配布するにまとめています。

{ "name": "my-plugin", "source": { "source": "archive", "url": "https://artifacts.example.com/my-plugin.zip" } }

プラグインのルートはzipの最上位でも、1階層下でも構いません。sha256は64桁の16進数で、設定するとダイジェストが合わないダウンロードを拒否します。URLはhttps://で、ループバック・リンクローカル・クラウドのメタデータ用ホストは指せません。サイズは256 MiBまで、応答を待つのは120秒まで、リダイレクトは5回までです。展開後の上限もあり、エントリ数は100,000、ファイル1つは512 MiB、合計は1 GiB、圧縮率は50倍までです。

ローカルにインストール済みのツールがプラグインディレクトリを都度生成する場合はcommandソースを使います。IDEが選択中のツールチェーンに合わせてプラグインを描画するような場面が典型例です。

{ "name": "my-plugin", "source": { "source": "command", "command": "my-tool claude-plugin-path", "timeout": 120 } }

コマンドはシェル(Windowsではcmd.exe)経由で、ユーザーのホームディレクトリから実行されます。標準出力にプラグインディレクトリの絶対パスを1行だけ出力し、timeout秒以内(1〜600秒、既定60秒)に終了コード0で終える必要があります(Claude Code v2.1.229以降が必要)。コマンド文字列はユーザーに全文が見せられるため、印字可能なASCIIで500文字以内、4つ以上連続するスペースは使えません。

インストールと更新のたびに実行され、バックグラウンドでも2つの契機で再実行されます。1つは、有効なコマンドソースのプラグインごとにセッションで1回、開始直後です。もう1つは、起動時か/reload-pluginsの時点で、有効なプラグインのインストール済みバージョンがキャッシュに無いときです。出力が変わっていれば新しいバージョンとして入れ直されます。環境変数CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFICを設定すると、この2つのバックグラウンド再実行は省略されます。明示的なインストールと更新では、コマンドは変わらず実行されます。取得したディレクトリをキャッシュへコピーする既定のcopyモードと、コピーせずそのまま使うlinkモードの違いは、copyが256 MiB・20,000エントリまでで、linkはWindowsで使えない点も含めClaude Codeプラグインのコマンドソースでマーケットプレイスを動的生成するで扱っています。

他のソース型と違い、コマンドソースは他のプラグインの依存として自動インストールされません。ユーザーが先に自分でインストールして、コマンドを承諾する必要があります。シェルのスクリプトから入れる場合は、承諾を代わりに答える人がいないためclaude plugin installに--yesを渡します。

使い分け早見表

ソース型前提環境ピン留め向く場面
相対パス前提環境マーケットプレイスと同一リポジトリピン留めリポジトリのコミット単位向く場面マーケットプレイスとプラグインをまとめて管理したいとき
github前提環境gitピン留めref / sha向く場面公開・社内のGitHubリポジトリで配るとき(最も一般的)
url(git)前提環境gitピン留めref / sha向く場面GitLab・Bitbucket・自前gitホストで配るとき
git-subdir前提環境git(パーシャルクローン)ピン留めref / sha向く場面モノレポの一部だけを配るとき
npm前提環境npmピン留めversion向く場面npmレジストリに公開済みのパッケージを配るとき
archive(zip)前提環境HTTPSのみ(git/npm不要)ピン留めsha256向く場面gitもnpmも無い端末、CI成果物をそのまま配るとき
command前提環境ローカルツールピン留めコンテンツハッシュ向く場面IDE等が都度生成するディレクトリを配るとき

更新が反映されない原因はバージョンの決まり方にある

プラグインの更新は、Claude Codeが計算するバージョンが変わったかどうかで検出されます。バージョンはplugin.jsonのversion、マーケットプレイスエントリのversionの順に採用され、どちらもなければソース型ごとの既定値になります。

バージョン

ソース型ごとの既定バージョン

  • github / url / git-subdir / 相対パス

    github / url / git-subdirでは、gitのコミットSHAを12文字に短縮した値で、git-subdirにはサブディレクトリのパスのハッシュも付きます。gitホストのマーケットプレイスの中にある相対パスは、インストールしたディレクトリのコミットSHAです。

  • archive

    SHA-256ダイジェストの先頭12文字です。エントリにsha256を書けばその値、書かなければダウンロードしたファイルのダイジェストが使われます。

  • npm / git管理外のローカルディレクトリ

    unknownになり、更新の有無を自動で追跡できません。

  • command

    エントリのversionは無視され、コマンドが作った中身から必ず導かれます。ハッシュのみ、またはマニフェストにversionがあれば<version>-<ハッシュ>の形です。

plugin.jsonに"version": "1.0.0"を書くと、作者が文字列を変えるまで、コミットを何度積んでもユーザーは同じキャッシュを使い続けます。コミットごとに更新を届けたいなら、plugin.jsonとエントリの両方からversionを外します。npmソースを継続的に更新したい場合は、plugin.jsonのversionを上げて運用します。

組織同期で通るソースは4つだけ

TeamプランやEnterpriseプランのOrganization settings > Plugins & skillsで、GitHubのリポジトリからプラグインを同期して配る場合、使えるソース型は絞られます。

くらべる

組織同期で通るソースと通らないソース

4種

通る

相対パス、github、url、git-subdir。ただし相手のリポジトリが非公開なら、次の3つのどれかを満たす必要があります。

3種

通らない

npm、archive、command。同期時に次のメッセージが出ることがあります: External plugin source type is not supported. Supported types: git-subdir, github, url

非公開のプラグインソースが通る条件は、次の3つです。

  • マーケットプレイスのリポジトリと同じオーナーのgithub.comのソース(Claude GitHub App経由で取得)
  • 自社のGitHub Enterpriseのホストにあり、GitHub Enterprise Appを入れたリポジトリ
  • GitLabのマーケットプレイスと同じホストにあるurlかgit-subdirのソース(gitlab.comでは最上位のグループかユーザーの名前空間まで同じであること)

これ以外のソースは認証なしで取得されるため、github.com・gitlab.com・bitbucket.orgの公開リポジトリでなければなりません。ほかのホストのソースは拒否されます。条件を満たさない非公開リポジトリのプラグインは、フォルダーごとマーケットプレイスのリポジトリへコピーし、エントリのsourceを相対パスに書き換えます。同じリポジトリの中で完結するので、同期の認証経路を別に用意する必要がなくなります。

組織配布の入口は、もう1つあります。managed settingsのstrictKnownMarketplacesで許可するマーケットプレイスを絞る方式です。Organization settingsのPlugins & skillsは、こちらのキーを設定しません。ここでオンにしたプラグインはCLIには同期済みのプラグインとして届き、別の制御を持ちます。

claude plugin validateは何を検査し、何を通すか

書いたエントリの形はclaude plugin validateで確かめられます。v2.1.289で、相対パス・github・git-subdir・npm・archive・commandを1つずつ並べたマーケットプレイスの出力は次のとおりです。形式として正しいので通ります。npmやarchiveの宛先が存在するかは見ません。

claude plugin validate .
⚠ Found 3 warnings:
 
  ❯ description: No marketplace description provided. Adding a description helps users understand what this marketplace offers
  ❯ plugins[0] plugin.json → description: No description provided. Adding a description helps users understand what your plugin does
  ❯ plugins[0] plugin.json → author: No author information provided. Consider adding author details for plugin attribution
 
✔ Validation passed with warnings

次に、ありがちな書き間違いを5つ並べたときの出力です。すべてsourceのエラーで、終了コードは1です。3番目の"../a"は..を含むことと./で始まらないことの2行で報告されるため、エラーは6行になります。

✘ Found 6 errors:
 
  ❯ plugins[3].source: Path contains "..": ../a. Plugin source paths are resolved relative to the marketplace root (the directory containing .claude-plugin/), not relative to marketplace.json. Use "./a" instead of "../a".
  ❯ plugins.0.source: Invalid string: must start with "./"
  ❯ plugins.1.source: Invalid input
  ❯ plugins.2.source: Invalid input
  ❯ plugins.3.source: Invalid string: must start with "./"
  ❯ plugins.4.source: Invalid input

エントリの中身は、0番目が"plugins/a"(./なし)、1番目がrepoのないgithub、2番目がpackageに../xを入れたnpm、3番目が"../a"、4番目がマーケットプレイス用の型であるgitをプラグインソースに書いたものです。この出力では、1番目・2番目・4番目がInvalid inputと報告されており、どのフィールドが悪いかまでは示されません。1番目なら必須フィールドの欠落、2番目なら..、4番目ならソース型の取り違えを疑います。

通ったからといって取得できるわけではありません。sourceの取得エラーは検証では出ず、インストールしたときに初めて表示されます。

まとめ

ソース型は、配布先の端末に入っているツールと組織同期で配るかどうかで絞れます。バージョン制約とタグ運用はClaude Codeプラグイン依存関係で、headersHelperのようなソースエントリの検証はマーケットプレイスのstrict modeとvalidateの使い方で扱っています。認証付きアーカイブの配り方はClaude CodeプラグインのheadersHelperで認証付きアーカイブを配るにあります。

この記事を共有:XはてブLinkedIn