Follow Discord
Sweep 27 Oct 2026 · 19:04Z Build v2.1.312 531 read Stable v2.1.308 Latest v2.1.312 Next v2.1.312 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · claude-code

Plugin manifest reference changedplugins/manifest-reference

Nearest release: v2.1.309, published 2 hours after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Upstream edited this page at 22 Oct 2026 17:58 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 22 Oct 2026 18:07 UTC.

Upstream edited
Recorded here
Lines+37added
Lines−35removed
From line 10 where the diff opens
First seen 25 Sep 2026 this site's first read of the page
Recorded edits16to this page, all time

The whole hunk

from line 10, old and new numbered
/
lines
from line 10
1010>
1111> These cases are covered on other pages:
1212>
13> * **Learning to build a plugin**: start with [Create a plugin](/docs/en/plugins/create)
14> * **What each component does at runtime**: see [Plugin components](/docs/en/plugins/components)
13> * **Learning to build a plugin**: start with [Create a plugin](/docs/en/plugins/create.md)
14> * **What each component does at runtime**: see [Plugin components](/docs/en/plugins/components.md)
1515 
1616Start at the section that matches what you're looking up:
1717 
from line 19
1919* A `userConfig` option or a `channels` entry: the [User configuration](#user-configuration) and [Channels](#channels) schemas
2020* `${CLAUDE_PLUGIN_ROOT}` or another variable a plugin can reference: [Environment variables](#environment-variables)
2121* Where each component's files go: [Standard layout](#standard-layout)
22* A message from `claude plugin validate`: the [troubleshooting page](/docs/en/plugins/troubleshooting) lists each message with its fix and links to the relevant sections on this page
22* A message from `claude plugin validate`: the [troubleshooting page](/docs/en/plugins/troubleshooting.md) lists each message with its fix and links to the relevant sections on this page
2323 
2424## Manifest file
2525 
from line 139
139139| [`dependencies`](#dependencies) | Array of strings or objects | Plugins that must be enabled for this one to work |
140140| [`settings`](#settings) | Object | Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect |
141141| [`userConfig`](#user-configuration) | Object | Values Claude Code prompts the user for when the plugin is enabled |
142| `types` | Path | A `.d.ts` file that declares the `$.state` values and `$` nouns of a [mod](/docs/en/plugins/mods/reference#files) |
142| `types` | Path | A `.d.ts` file that declares the `$.state` values and `$` nouns of a [mod](/docs/en/plugins/mods/reference.md#files) |
143143| [`channels`](#channels) | Array of objects | Message channels the plugin provides, each bound to one of its MCP servers |
144144| `skills` | Path, or array of paths | Directories to scan for skills, each a directory of `<name>/SKILL.md` folders or one folder holding `SKILL.md` directly. `"."` names the plugin root. Adds to the default `skills/` scan |
145145| [`commands`](#commands) | Path, array of paths, or object | Flat `.md` command files, directories of them, or an object map of command name to `source` or `content`. Replaces the default `commands/` scan |
from line 148
148148| [`mcpServers`](#mcpservers) | Path, object, or array of either | `.json` MCP config files, `.mcpb` or `.dxt` bundles, or inline server configs keyed by name. Loaded together with `.mcp.json`; a server name declared later replaces an earlier one |
149149| [`lspServers`](#lspservers) | Path, object, or array of either | `.json` LSP config files or inline server configs keyed by name. Loaded together with `.lsp.json` |
150150| `outputStyles` | Path, or array of paths | Output style files or directories. Replaces the default `output-styles/` scan |
151| `workflows` | Path, or array of paths | [Workflow](/docs/en/workflows#distribute-a-workflow-in-a-plugin) `.js` files or directories. Replaces the default `workflows/` scan |
151| `workflows` | Path, or array of paths | [Workflow](/docs/en/workflows.md#distribute-a-workflow-in-a-plugin) `.js` files or directories. Replaces the default `workflows/` scan |
152152| `experimental` | Object | Container for `themes`, `monitors`, and `evals`, whose manifest shape may still change |
153153| `experimental.themes` | Path, or array of paths | Theme files or directories. Replaces the default `themes/` scan. A top-level `themes` key still loads, with a `claude plugin validate` warning |
154154| [`experimental.monitors`](#monitors) | Path, or inline array | A `.json` file holding the monitors array, or the array itself. Defaults to `monitors/monitors.json`. A top-level `monitors` key still loads, with a `claude plugin validate` warning. Monitors run only in interactive sessions, and not on Amazon Bedrock, Google Cloud's Agent Platform, or Microsoft Foundry |
155| `experimental.evals` | Path, or array of paths | Directory that holds the plugin's [eval cases](/docs/en/plugin-evals#use-a-different-eval-directory) when it isn't the default `evals/`. `claude plugin eval --eval-dir` overrides it |
155| `experimental.evals` | Path, or array of paths | Directory that holds the plugin's [eval cases](/docs/en/plugin-evals.md#use-a-different-eval-directory) when it isn't the default `evals/`. `claude plugin eval --eval-dir` overrides it |
156156 
157157In the Type column, a path is a string relative to the plugin root, such as `"./custom/commands"`.
158158 
from line 177
177177 
178178The name shown in UI in place of `name`. It may contain spaces and any casing, and it isn't used for namespacing or lookup.
179179 
180For a marketplace-installed plugin, a `displayName` on the [marketplace entry](/docs/en/plugins/marketplace-reference#plugin-entries) takes precedence over this value.
180For a marketplace-installed plugin, a `displayName` on the [marketplace entry](/docs/en/plugins/marketplace-reference.md#plugin-entries) takes precedence over this value.
181181 
182182### `version`
183183 
184A version string, not checked against semver. Setting it pins the plugin to that version until you change it; see [Versions and updates](/docs/en/plugins/loading#versions-and-updates). A plugin with a [`command` source](/docs/en/plugins/marketplace-reference), a plugin from a [marketplace hosted on claude.ai](/docs/en/plugins/install#add-from-claude-ai), and a plugin [loaded in place](/docs/en/plugins/loading#find-plugins-on-disk) from a marketplace added from a local path aren't pinned by this field.
184A version string, not checked against semver. Setting it pins the plugin to that version until you change it; see [Versions and updates](/docs/en/plugins/loading.md#versions-and-updates). A plugin with a [`command` source](/docs/en/plugins/marketplace-reference), a plugin from a [marketplace hosted on claude.ai](/docs/en/plugins/install.md#add-from-claude-ai), and a plugin [loaded in place](/docs/en/plugins/loading.md#find-plugins-on-disk) from a marketplace added from a local path aren't pinned by this field.
185185 
186186### `metadata`
187187 
from line 189
189189 
190190### Directory listing fields
191191 
192Anthropic's directory reads the `icon`, `documentationUrl`, `supportUrl`, `privacyPolicyUrl`, and `termsOfServiceUrl` fields from `plugin.json` for your plugin's listing when you [submit the plugin](/docs/en/plugins/publish#submit-to-anthropics-directory). Claude Code ignores them at load time. Set them only in `plugin.json`. In a [marketplace entry](#marketplace-entries-and-the-manifest), `claude plugin validate` reports each one as an unknown field.
192Anthropic's directory reads the `icon`, `documentationUrl`, `supportUrl`, `privacyPolicyUrl`, and `termsOfServiceUrl` fields from `plugin.json` for your plugin's listing when you [submit the plugin](/docs/en/plugins/publish.md#submit-to-anthropics-directory). Claude Code ignores them at load time. Set them only in `plugin.json`. In a [marketplace entry](#marketplace-entries-and-the-manifest), `claude plugin validate` reports each one as an unknown field.
193193 
194194Set `icon` to the path of an image file inside the plugin, such as `./logo.png`, and each of the four URL fields to an `https://` URL.
195195 
196`claude plugin validate` accepts these fields without a warning on Claude Code v2.1.281 or later. Earlier versions print an `Unknown field` warning for each one, so a `--strict` run fails on those versions.
196> [!NOTE]
197>
198> `claude plugin validate` doesn't report these fields in `plugin.json` as unknown on Claude Code v2.1.281 or later. Earlier versions print an `Unknown field` warning for each one, so a `--strict` run fails on those versions.
197199 
198200### `defaultEnabled`
199201 
from line 205
203205 
204206### `dependencies`
205207 
206Plugins that must be enabled for this one to work. Each entry is `"name"`, `"name@marketplace"`, or `{ "name": "...", "marketplace": "...", "version": "..." }`. Bare names resolve against this plugin's own marketplace. See [dependency constraints](/docs/en/plugins/dependencies).
208Plugins that must be enabled for this one to work. Each entry is `"name"`, `"name@marketplace"`, or `{ "name": "...", "marketplace": "...", "version": "..." }`. Bare names resolve against this plugin's own marketplace. See [dependency constraints](/docs/en/plugins/dependencies.md).
207209 
208210### `settings`
209211 
210Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect; other keys are dropped at load. A `settings.json` at the plugin root takes precedence over this key. See [Default settings](/docs/en/plugins/components#default-settings).
212Settings Claude Code applies while the plugin is enabled. Only `agent` and `subagentStatusLine` take effect; other keys are dropped at load. A `settings.json` at the plugin root takes precedence over this key. See [Default settings](/docs/en/plugins/components.md#default-settings).
211213 
212214## Component path forms
213215 
214Every component key accepts a path relative to the plugin root. `hooks`, `mcpServers`, `lspServers`, and `experimental.monitors` also accept inline configuration, `commands` also accepts an object map, and `mcpServers` also accepts MCP bundle paths and URLs. The examples that follow show each accepted shape once. For what each component does at runtime, see [Plugin components](/docs/en/plugins/components).
216Every component key accepts a path relative to the plugin root. `hooks`, `mcpServers`, `lspServers`, and `experimental.monitors` also accept inline configuration, `commands` also accepts an object map, and `mcpServers` also accepts MCP bundle paths and URLs. The examples that follow show each accepted shape once. For what each component does at runtime, see [Plugin components](/docs/en/plugins/components.md).
215217 
216218### Path-only fields
217219 
from line 255
253255 
254256### `hooks`
255257 
256`hooks` takes a `.json` file path, an inline hooks object in the same shape as [`hooks` in `settings.json`](/docs/en/hooks#configuration), or an array mixing both. For hook events and handler fields, see the [hooks reference](/docs/en/hooks#hook-events).
258`hooks` takes a `.json` file path, an inline hooks object in the same shape as [`hooks` in `settings.json`](/docs/en/hooks#configuration), or an array mixing both. For hook events and handler fields, see the [hooks reference](/docs/en/hooks.md#hook-events).
257259 
258260A hooks file wraps the event map in a top-level `"hooks"` key, the shape [`hooks/hooks.json`](/docs/en/plugins/components#hooks) uses. A file that contains only the event map, without that wrapper, fails to load. An inline object is the event map itself, with no wrapper.
259261 
from line 298
296298 
297299### `mcpServers`
298300 
299`mcpServers` takes a `.json` file path, an MCP bundle path or URL, an inline map, or an array mixing them. For server config fields, see [plugin-provided MCP servers](/docs/en/mcp#plugin-provided-mcp-servers).
301`mcpServers` takes a `.json` file path, an MCP bundle path or URL, an inline map, or an array mixing them. For server config fields, see [plugin-provided MCP servers](/docs/en/mcp.md#plugin-provided-mcp-servers).
300302 
301303Claude Code loads `.mcp.json` at the plugin root first, then each declared shape in order. A server name declared later replaces an earlier one.
302304 
from line 352
350352}
351353```
352354 
353For the language servers Anthropic publishes as plugins and how the servers behave at runtime, see [Code intelligence](/docs/en/plugins/code-intelligence).
355For the language servers Anthropic publishes as plugins and how the servers behave at runtime, see [Code intelligence](/docs/en/plugins/code-intelligence.md).
354356 
355357### `monitors`
356358 
from line 393
391393* **`skills`**: also accepts `"."`. Both `"."` and `"./"` denote the plugin root. Before v2.1.221, `"."` failed manifest validation, so use `"./"` when the plugin must load on earlier versions
392394* **`mcpServers`**: also accepts an `https://` bundle URL
393395 
394`experimental.evals` isn't a component path, so the rules in this section don't cover it, and `claude plugin eval` checks the value when it runs instead. It names a directory below the plugin root, such as `"quality/evals"`, with or without the `./` prefix. With an array, only the first entry is used. For what the value accepts and what happens with an unusable one, see [Use a different eval directory](/docs/en/plugin-evals#use-a-different-eval-directory).
396`experimental.evals` isn't a component path, so the rules in this section don't cover it, and `claude plugin eval` checks the value when it runs instead. It names a directory below the plugin root, such as `"quality/evals"`, with or without the `./` prefix. With an array, only the first entry is used. For what the value accepts and what happens with an unusable one, see [Use a different eval directory](/docs/en/plugin-evals.md#use-a-different-eval-directory).
395397 
396398### Containment and existence
397399 
from line 484
482484 
483485### Where values are stored
484486 
485Non-sensitive values are saved under [`pluginConfigs`](/docs/en/settings-reference#pluginconfigs) in the user's `settings.json`. Sensitive values go to the platform's secure credential store instead. The [settings page](/docs/en/settings-reference#pluginconfigs) lists which settings files `pluginConfigs` is read from.
487Non-sensitive values are saved under [`pluginConfigs`](/docs/en/settings-reference#pluginconfigs) in the user's `settings.json`. Sensitive values go to the platform's secure credential store instead. The [settings page](/docs/en/settings-reference.md#pluginconfigs) lists which settings files `pluginConfigs` is read from.
486488 
487489### Reference a saved value
488490 
489491Reference a saved value where the plugin needs it, in one of two forms:
490492 
491* **`${user_config.KEY}`**: substituted in MCP server config, LSP server config, [exec-form](/docs/en/hooks#exec-form-and-shell-form) hook `args`, and skill and agent content. In skill and agent content, only non-sensitive values are substituted, and a sensitive value there becomes a placeholder
493* **`${user_config.KEY}`**: substituted in MCP server config, LSP server config, [exec-form](/docs/en/hooks.md#exec-form-and-shell-form) hook `args`, and skill and agent content. In skill and agent content, only non-sensitive values are substituted, and a sensitive value there becomes a placeholder
492494* **`CLAUDE_PLUGIN_OPTION_<KEY>`**: exported to hook processes for every option, with `<KEY>` uppercased. A shell-form hook reads `$CLAUDE_PLUGIN_OPTION_API_TOKEN` for `api_token`
493495 
494496### Fields that run through a shell
495497 
496Shell-form hook commands, monitor commands, and MCP [`headersHelper`](/docs/en/mcp#use-dynamic-headers-for-custom-authentication) reject `${user_config.*}`. A component that references it in one of these fields fails with an [error](/docs/en/errors#plugin-command-references-user-config) instead of running, because the field's value is passed to a shell that would re-parse the substituted value.
498Shell-form hook commands, monitor commands, and MCP [`headersHelper`](/docs/en/mcp#use-dynamic-headers-for-custom-authentication) reject `${user_config.*}`. A component that references it in one of these fields fails with an [error](/docs/en/errors.md#plugin-command-references-user-config) instead of running, because the field's value is passed to a shell that would re-parse the substituted value.
497499 
498500The table shows how the value can reach each of these fields instead.
499501 
500502| Field | How the value can reach it |
501503| :- | :- |
502| Shell-form hook commands | Use [exec form](/docs/en/hooks#exec-form-and-shell-form) with `args`, or read `CLAUDE_PLUGIN_OPTION_<KEY>` from the hook's environment |
504| Shell-form hook commands | Use [exec form](/docs/en/hooks.md#exec-form-and-shell-form) with `args`, or read `CLAUDE_PLUGIN_OPTION_<KEY>` from the hook's environment |
503505| Monitor commands | Not through Claude Code. Monitor processes don't receive `CLAUDE_PLUGIN_OPTION_<KEY>`, so the monitor script has to obtain the value on its own |
504506| MCP `headersHelper` | Not through Claude Code. The helper's environment carries `CLAUDE_PLUGIN_ROOT`, `CLAUDE_CODE_MCP_SERVER_NAME`, and `CLAUDE_CODE_MCP_SERVER_URL` but no option values, so the helper script has to obtain the value on its own |
505507 
506508## Channels
507509 
508`channels` declares the message channels a plugin provides, such as a bridge to a chat app. When you declare one, Claude Code can prompt for the channel's configuration when the plugin is enabled. For how the server injects messages, see the [channels reference](/docs/en/channels-reference#package-as-a-plugin).
510`channels` declares the message channels a plugin provides, such as a bridge to a chat app. When you declare one, Claude Code can prompt for the channel's configuration when the plugin is enabled. For how the server injects messages, see the [channels reference](/docs/en/channels-reference.md#package-as-a-plugin).
509511 
510512Each entry is a strict object bound to one of the plugin's MCP servers, with these fields:
511513 
from line 555
553555| `${CLAUDE_PLUGIN_DATA}` | `~/.claude/plugins/data/<id>/`, created on first reference and kept across plugin updates. `<id>` is the plugin identifier with every character other than a letter, digit, `_`, or `-` replaced by `-` | Installed dependencies such as `node_modules`, generated code, and caches |
554556| `${CLAUDE_PROJECT_DIR}` | The project root | Project-local scripts and config files |
555557 
556`${CLAUDE_PLUGIN_ROOT}` changes when the plugin updates, so don't write state there. For where the root moves and when the old directory is cleaned up, see the [loading page](/docs/en/plugins/loading).
558`${CLAUDE_PLUGIN_ROOT}` changes when the plugin updates, so don't write state there. For where the root moves and when the old directory is cleaned up, see the [loading page](/docs/en/plugins/loading.md).
557559 
558By default, Claude Code deletes the `${CLAUDE_PLUGIN_DATA}` directory when you uninstall the plugin from the last place it's installed. For `--keep-data` and the other cases where it stays, see [plugin uninstall](/docs/en/plugins/cli-reference#plugin-uninstall).
560By default, Claude Code deletes the `${CLAUDE_PLUGIN_DATA}` directory when you uninstall the plugin from the last place it's installed. For `--keep-data` and the other cases where it stays, see [plugin uninstall](/docs/en/plugins/cli-reference.md#plugin-uninstall).
559561 
560562### Where each variable resolves
561563 
from line 578
576578 
577579Keep each substituted path a single argument:
578580 
579* **Hook commands**: use [exec form](/docs/en/hooks#exec-form-and-shell-form) with `args` so each path is one argument with no quoting
581* **Hook commands**: use [exec form](/docs/en/hooks.md#exec-form-and-shell-form) with `args` so each path is one argument with no quoting
580582* **Shell-form hooks and monitor commands**: wrap the variable in double quotes so a path with spaces stays one word
581583 
582584If you leave one of these variables outside quotes in a shell-form command in a hooks file, `claude plugin validate` warns about it unless the hook sets [`shell`](/docs/en/hooks#command-hook-fields) to `"powershell"`.
from line 613
611613| Manifest | `.claude-plugin/plugin.json` | Plugin metadata and configuration. Optional |
612614| Skills | `skills/` | One `<name>/SKILL.md` per skill. A plugin with `SKILL.md` at its root, no `skills/`, and no `skills` key loads as a single skill |
613615| Commands | `commands/` | Flat Markdown command files. Prefer `skills/` for new plugins |
614| Agents | `agents/` | Agent Markdown files. Subfolders are part of the [agent name](/docs/en/plugins/components#agents) |
616| Agents | `agents/` | Agent Markdown files. Subfolders are part of the [agent name](/docs/en/plugins/components.md#agents) |
615617| Hooks | `hooks/hooks.json` | Hook configuration |
616618| MCP servers | `.mcp.json` | MCP server definitions |
617619| LSP servers | `.lsp.json` | LSP server configurations |
from line 656
654656└── .lsp.json
655657```
656658 
657To click through this layout and read what each file does, open the [plugin explorer](/docs/en/plugins/components#explore-the-plugin-directory).
659To click through this layout and read what each file does, open the [plugin explorer](/docs/en/plugins/components.md#explore-the-plugin-directory).
658660 
659661A `CLAUDE.md` at the plugin root isn't loaded as context, and `claude plugin validate` warns when it finds one. To include instructions that load into Claude's context, put them in a skill.
660662 
661663## Marketplace entries and the manifest
662664 
663A [marketplace entry](/docs/en/plugins/marketplace-reference) accepts [its own fields](/docs/en/plugins/marketplace-reference#plugin-entries), including `strict`, and every field on this page except the [directory listing fields](#directory-listing-fields).
665A [marketplace entry](/docs/en/plugins/marketplace-reference.md) accepts [its own fields](/docs/en/plugins/marketplace-reference.md#plugin-entries), including `strict`, and every field on this page except the [directory listing fields](#directory-listing-fields).
664666 
665667The `strict` field decides whether the entry may add components to a plugin that has its own `plugin.json`. It defaults to `true`.
666668 
from line 680
678680 
679681Some metadata fields have a fixed precedence regardless of `strict`:
680682 
681* **`defaultEnabled` and display fields**: the entry's `defaultEnabled` and its [display fields](/docs/en/plugins/marketplace-reference#entry-and-plugin-json) such as `displayName` override the manifest's
683* **`defaultEnabled` and display fields**: the entry's `defaultEnabled` and its [display fields](/docs/en/plugins/marketplace-reference.md#entry-and-plugin-json) such as `displayName` override the manifest's
682684* **`version`**: the manifest's `version` overrides the entry's
683685* **`name`**: when the entry lists the plugin under a different `name` than the manifest, `enabledPlugins` uses the entry name, and components are namespaced under the manifest name
684686 
685For the full precedence table, see [Strict mode](/docs/en/plugins/marketplace-reference).
687For the full precedence table, see [Strict mode](/docs/en/plugins/marketplace-reference.md).
686688 
687689## Next steps
688690 
689* [Add components to a plugin](/docs/en/plugins/components): what each component does at runtime, with an example that validates
690* [Marketplace reference](/docs/en/plugins/marketplace-reference): the entry fields a marketplace can set for your plugin
691* [Plugin commands reference](/docs/en/plugins/cli-reference#plugin-validate): `claude plugin validate` flags and output
692* [Troubleshoot plugins](/docs/en/plugins/troubleshooting#claude-plugin-validate-reports-errors): each validation message with its fix
691* [Add components to a plugin](/docs/en/plugins/components.md): what each component does at runtime, with an example that validates
692* [Marketplace reference](/docs/en/plugins/marketplace-reference.md): the entry fields a marketplace can set for your plugin
693* [Plugin commands reference](/docs/en/plugins/cli-reference.md#plugin-validate): `claude plugin validate` flags and output
694* [Troubleshoot plugins](/docs/en/plugins/troubleshooting.md#claude-plugin-validate-reports-errors): each validation message with its fix
693695 
Feedback