Claude Code plugin.jsonスキーマ完全リファレンス
plugin.jsonは省略可能で、書く場合もnameだけが必須フィールドです。メタデータ・コンポーネントパス・userConfig・channelsまで、全フィールドの型と挙動を一覧にします。
.claude-plugin/plugin.jsonは省略できます。省略した場合、コンポーネントは既定のディレクトリ構成から自動検出され、プラグイン名はディレクトリ名から決まります。書く場合でも必須フィールドはnameだけで、残りはすべて任意です。この「ほぼ全部が任意」という設計のせいで、実際にどのフィールドが何を制御するのかが公式ドキュメントの複数の節に分散しています。プラグインの基本構造や自作の最小手順はClaude Codeプラグイン完全ガイドにまとまっているので、本記事はマニフェストのフィールド1つずつの型と挙動をリファレンスとしてまとめます。
スキーマの全体像
フィールドをすべて使うと、plugin.jsonは次のような形になります。実際のプラグインでここまで埋めることはまれですが、どこに何を書けるかの見取り図として押さえておくと、以降の節で個々のフィールドを追うときに迷いません。
{
"name": "plugin-name",
"displayName": "Plugin Name",
"version": "1.2.0",
"description": "Brief plugin description",
"author": { "name": "Author Name", "email": "author@example.com" },
"homepage": "https://docs.example.com/plugin",
"repository": "https://github.com/author/plugin",
"license": "MIT",
"keywords": ["keyword1", "keyword2"],
"metadata": { "catalogId": "cat-123", "tier": "pro" },
"skills": "./custom/skills/",
"commands": ["./custom/commands/special.md"],
"agents": ["./custom/agents/reviewer.md"],
"hooks": "./config/hooks.json",
"mcpServers": "./mcp-config.json",
"outputStyles": "./styles/",
"lspServers": "./.lsp.json",
"experimental": {
"themes": "./themes/",
"monitors": "./monitors.json"
},
"dependencies": ["helper-lib", { "name": "secrets-vault", "version": "~2.1.0" }]
}必須フィールドとトップレベルの挙動
nameはkebab-caseの一意な識別子で、スペース・制御文字・双方向テキスト制御文字を含められません。UI上のコンポーネント名前空間に使われ、plugin-devという名前のプラグインのagent-creatorエージェントはplugin-dev:agent-creatorと表示されます。マーケットプレイスのエントリが別名でプラグインを一覧している場合、enabledPluginsのキーや/pluginが参照するのはマーケットプレイス側の名前です。
認識されないトップレベルフィールドは無視され、プラグインは問題なく読み込まれます。この挙動を利用して、plugin.jsonをVS Code拡張やCursorの拡張マニフェスト、npmのpackage.json、MCPB/DXTバンドルマニフェストと兼用できます。claude plugin validateは未認識フィールドを警告として報告するだけで、認識される名前に1〜2文字近ければ「もしかして」の候補も添えます。警告だけのプラグインは検証を通過し、実行時にも読み込まれます。
型が合わないフィールドの扱いはフィールドによって違います。ほとんどのフィールドは型が違うと読み込み自体が失敗し、claude plugin validateもエラーとして報告します(keywordsに配列でなく文字列を渡した場合など)。例外はexperimentalとmetadataで、オブジェクト以外の値は無視され警告どまりです。CIでタイプミスを本番前に検出したいときはclaude plugin validate ./my-plugin --strictを使います。--strictは警告をエラー扱いに格上げします。
claude plugin validate ./my-plugin --strictこのコマンドを1つCIに足すだけで、フィールド名の打ち間違いや型の取り違えを公開前に検出できます。--strictを付けなければ、これらは警告として表示されるだけでプラグイン自体は正常に動作するため、開発中は素のclaude plugin validateで様子を見て、リリース前のパイプラインでだけ--strictを足す運用が現実的です。
メタデータフィールド一覧
| フィールド | 型 | 内容 |
|---|---|---|
name | 型string | 内容必須。kebab-caseの一意な識別子 |
$schema | 型string | 内容エディタ補完用のJSON Schema URL。読み込み時には無視される |
displayName | 型string | 内容/pluginピッカーでの表示名。省略時はnameにフォールバック |
version | 型string | 内容セマンティックバージョン。設定するとその値にピン留めされる |
description | 型string | 内容プラグインの用途を短く説明 |
author | 型object | 内容name / email / urlを持つ作者情報 |
homepage | 型string | 内容ドキュメントURL |
repository | 型string | 内容ソースコードURL |
license | 型string | 内容ライセンス識別子(MITなど) |
keywords | 型array | 内容検索・発見用のタグ |
metadata | 型object | 内容自由形式。Claude Codeはこの値を一切読まず、プラグインの動作には影響しない |
defaultEnabled | 型boolean | 内容既定の有効状態。既定値はtrue |
versionを省略すると、マーケットプレイスエントリ側のversion、それも無ければgithub/url/git-subdirや相対パスのgitホスト型ソースの場合はコミットSHAが使われます。バージョン解決の詳細なフォールバック順序はClaude Codeプラグインの依存バージョンを固定するで扱っています。両方にversionがあるときはplugin.json側が優先されます。
defaultEnabled: falseは、インストール直後は無効な状態で配布したいプラグインに使います。外部サービスへ接続するなど、ユーザーが明示的に選んでから使わせたいプラグインが典型例です。ただしdefaultEnabledはあくまで「他に何も決めていないときのフォールバック」です。ユーザーがenabledPluginsに明示的な設定を書き込むと、以後のdefaultEnabled変更は既存ユーザーに影響しません。依存関係として他のプラグインから要求されている場合も、有効化時に明示設定が書き込まれ、defaultEnabledは無効になります。マーケットプレイスのエントリ側にも同名のdefaultEnabledを置けますが、その場合はplugin.json側の値よりマーケットプレイス側が優先されます。配布元を一元管理したいときは、plugin.jsonではなくマーケットプレイスエントリの側で制御すると意図がぶれません。
コンポーネントパスフィールド
| フィールド | 型 | 既定の扱い |
|---|---|---|
skills | 型string|array | 既定の扱い既定のskills/スキャンに追加される |
commands | 型string|array | 既定の扱い既定のcommands/を置き換える |
agents | 型string|array | 既定の扱い既定のagents/を置き換える |
workflows | 型string|array | 既定の扱い既定のworkflows/を置き換える |
outputStyles | 型string|array | 既定の扱い既定のoutput-styles/を置き換える |
hooks | 型string|array|object | 既定の扱い独自の合流ルールで既定と合算 |
mcpServers | 型string|array|object | 既定の扱い独自の合流ルールで既定と合算 |
lspServers | 型string|array|object | 既定の扱い独自の合流ルールで既定と合算 |
experimental.themes | 型string|array | 既定の扱い既定のthemes/を置き換える |
experimental.monitors | 型string|array | 既定の扱い既定のmonitors.jsonを置き換える |
userConfig | 型object | 既定の扱い有効化時にユーザーへ入力を求める値の定義 |
channels | 型array | 既定の扱いメッセージ注入チャンネルの宣言 |
dependencies | 型array | 既定の扱い他プラグインへの依存(バージョン制約つき) |
「置き換える」に分類されるフィールドは、指定した瞬間に既定ディレクトリのスキャンが止まります。既定を残したまま追加したい場合は、既定パス自身を配列に含めます。"commands": ["./commands/", "./extras/"]のように書けば、既定のcommands/を保ったままextras/も読み込みます。skillsだけは例外で、既定のskills/は常にスキャンされたうえで、指定したディレクトリが追加で読み込まれます。マーケットプレイスルートを指す特殊なエントリでは、この追加ルールが置き換えルールに切り替わる例外もあります。
パスフィールドは共通して、プラグインルートからの相対パスで./から始める必要があります(skillsだけ"."も許容)。デフォルトフォルダとマニフェストのキーが両方存在すると、claude plugin listと/pluginの詳細ビューが「使われていないフォルダがある」と警告しますが、マニフェスト側のパスでプラグインは正常に読み込まれます。
{
"commands": [
"./specialized/deploy.md",
"./utilities/batch-process.md"
],
"agents": [
"./custom-agents/reviewer.md",
"./custom-agents/tester.md"
]
}この例のように、commandsやagentsへ個別ファイルを列挙すれば、標準のcommands/・agents/ディレクトリを使わない独自の配置に変更できます。マニフェストのキーが既定フォルダの内側を指しているだけの場合("commands": ["./commands/deploy.md"]のような書き方)は、そのフォルダを明示的に指定しているとみなされ、警告は出ません。警告が出るのは、既定フォルダがまるごと無視される形でファイルが置き去りになっているときだけです。
userConfigとchannelsの要点
userConfigは、プラグイン有効化時にユーザーへ入力を求める値を宣言します。各キーはtype(string / number / boolean / directory / file)、title、descriptionが必須で、sensitive・required・default・multiple・min/maxが任意です。値は${user_config.KEY}としてMCP・LSPサーバー設定やhookのコマンドに埋め込め、非機密の値はSkillやAgentの本文にも埋め込めます。
ただしシェルで実行されるフィールド(シェル形式のhookコマンド・Monitorのコマンド・MCPのheadersHelper)は${user_config.*}の埋め込みを拒否します。設定値をそのままシェルへ渡すと任意のコマンド実行を許すことになるためで、代わりにCLAUDE_PLUGIN_OPTION_<KEY>環境変数として読むか、exec形式のhookでargsから渡します。
{
"userConfig": {
"api_endpoint": {
"type": "string",
"title": "API endpoint",
"description": "チームのAPIエンドポイント"
},
"api_token": {
"type": "string",
"title": "API token",
"description": "API認証トークン",
"sensitive": true
}
}
}非機密の値はユーザーのsettings.jsonにpluginConfigsとして保存され、機密値はmacOSではKeychain(失敗時は.credentials.jsonにフォールバック)、それ以外のプラットフォームでは.credentials.jsonに保存されます。Keychainの保存領域はOAuthトークンと共有で、合計約2KBの上限があるため、機密値は小さく保つ必要があります。
pluginConfigsを読みに行く設定ソースは3つに限られます。有効化時のプロンプトが書き込むユーザー設定、CLIの--settingsフラグやSDKのインライン設定、そして組織管理のmanaged settingsです。プロジェクトの.claude/settings.jsonや.claude/settings.local.jsonにpluginConfigsを書いても読まれません。クローンしたリポジトリ経由で値が紛れ込むのを防ぐための制限で、同じenabledPluginsキーはプロジェクト設定・ローカル設定でも引き続き有効になる点とは対照的です。詳しい設定例と機密値の扱いはClaude Code plugin userConfigの書き方で扱っています。
channelsは、Telegram・Slack・Discordのようにメッセージを会話へ注入するチャンネルをプラグインが宣言するためのフィールドです。各エントリのserverは、そのプラグインのmcpServersに定義されたキーと一致している必要があります。チャンネルごとにuserConfigと同じスキーマの入力を追加で求めることもできます。実装の具体例はClaude Code Channelsプラグイン化にまとめています。
環境変数の要点
| 変数 | 解決先 |
|---|---|
${CLAUDE_PLUGIN_ROOT} | 解決先プラグインのインストール先ディレクトリの絶対パス |
${CLAUDE_PLUGIN_DATA} | 解決先更新をまたいで残る永続ディレクトリ。初回参照時に作成される |
${CLAUDE_PROJECT_DIR} | 解決先プロジェクトルート |
3つとも、hookプロセスとMCP・LSPサーバーのサブプロセスに環境変数としてエクスポートされますが、文字列内へのプレースホルダー埋め込みが効くフィールドと効かないフィールドがあり、その対応関係とパス解決の優先順位はClaude Codeプラグインの環境変数とパスの解決ルールにまとめています。
この寛容な設計は何を狙っているか
plugin.jsonが未認識フィールドを許し、型エラーも一部のフィールドでは警告どまりにしているのは、単なる手抜きではありません。1つのファイルを複数のエコシステムのマニフェストとして同時に使い回せるようにする、という互換性への賭けです。npmのpackage.jsonやVS Code拡張のマニフェストと兼用できれば、プラグイン開発者は設定ファイルを2つ管理せずに済みます。
この賭けには代償もあります。寛容な検証は、フィールド名のタイポを実行時まで隠します。hoksと書いてもplugin.jsonは読み込まれ、しかしhookは一つも登録されません。CIにclaude plugin validate --strictを組み込まない限り、この種の見落としは公開後にユーザーからの報告で気づくことになります。寛容さと安全性はトレードオフの関係にあり、--strictを運用に組み込むかどうかでどちらを取るかが決まります。
同じ思想はuserConfigのシェル埋め込み拒否にも表れています。柔軟性を最優先するなら${user_config.*}をシェルコマンドにそのまま展開しても良さそうなものですが、実際には拒否してエラーにし、環境変数経由の間接参照を強制します。マニフェスト全体としては寛容さに寄せつつ、シェル実行という一点だけは頑なに塞ぐ。この非対称さが、plugin.jsonの設計判断を読み解く鍵になります。
よくある質問
plugin.json自体が無いプラグインは動きますか
動きます。マニフェストが無い場合、Claude Codeはskills/・agents/・commands/などの既定ディレクトリを自動でスキャンし、プラグイン名はディレクトリ名から決まります。名前空間の衝突を避けたい、displayNameやauthorのようなメタデータを添えたい、既定と異なる場所にコンポーネントを置きたい、といった理由が出てきて初めてplugin.jsonが必要になります。
metadataフィールドに書いた値はClaude Codeの動作に影響しますか
影響しません。metadataはプラグイン作者が自分のツール(カタログ管理やライセンス階層の判定など)のために使う自由形式の領域で、Claude Code自身はこの値を読みません。オブジェクト以外の値を入れても読み込みエラーにはならず、claude plugin validateが警告を出すだけです。
まとめ
plugin.jsonはname以外すべて任意で、フィールドは大きく4系統に分かれます。作者情報や説明を持つメタデータ系、コンポーネントの場所を指すパス系(既定を置き換えるものと追加するものが混在)、ユーザー入力を扱うuserConfigとchannels、そしてバージョン解決に関わるversionとdependenciesです。未認識フィールドは警告のみで動作に影響しないため、他のマニフェストとの兼用も選択肢に入ります。タイポを本番前に検出したいならclaude plugin validate --strictをCIに組み込みます。依存関係のバージョン制約はClaude Codeプラグイン依存関係を参照してください。