plugin-marketplaces.md +0 −1546 deleted
File Deleted View Diff
1> ## Documentation Index
2> Fetch the complete documentation index at: https://code.claude.com/docs/llms.txt
3> Use this file to discover all available pages before exploring further.
4
5# Create and distribute a plugin marketplace
6
7> Build and host plugin marketplaces to distribute Claude Code extensions across teams and communities.
8
9A **plugin marketplace** is a catalog that lets you distribute plugins to others. Marketplaces provide centralized discovery, version tracking, automatic updates, and support for multiple source types, including git repositories and local paths. This guide shows you how to create your own marketplace to share plugins with your team or community.
10
11Looking to install plugins from an existing marketplace? See [Discover and install prebuilt plugins](/docs/en/discover-plugins).
12
13## Overview
14
15Creating and distributing a marketplace involves:
16
171. **Create plugins**: build one or more plugins with skills, agents, hooks, MCP servers, or LSP servers. This guide assumes you already have plugins to distribute; see [Create plugins](/docs/en/plugins) for details on how to create them.
182. **Create the marketplace file**: define a `marketplace.json` that lists your plugins and where to find them. See [Create the marketplace file](#create-the-marketplace-file).
193. **Host the marketplace**: push to GitHub, GitLab, or another git host. See [Host and distribute marketplaces](#host-and-distribute-marketplaces).
204. **Share with users**: users add your marketplace with `/plugin marketplace add` and install individual plugins. See [Discover and install plugins](/docs/en/discover-plugins).
21
22Once your marketplace is live, you can update it by pushing changes to your repository. Users refresh their local copy with `/plugin marketplace update`.
23
24## Walkthrough: create a local marketplace
25
26This example creates a marketplace with one plugin: a `quality-review` skill for code reviews. You'll create the directory structure, add a skill, create the plugin manifest and marketplace catalog, then install and test it.
27
28<Steps>
29 <Step title="Create the directory structure">
30 ```bash theme={null}
31 mkdir -p my-marketplace/.claude-plugin
32 mkdir -p my-marketplace/plugins/quality-review-plugin/.claude-plugin
33 mkdir -p my-marketplace/plugins/quality-review-plugin/skills/quality-review
34 ```
35 </Step>
36
37 <Step title="Create the skill">
38 Create a `SKILL.md` file that defines what the `quality-review` skill does.
39
40 ```markdown my-marketplace/plugins/quality-review-plugin/skills/quality-review/SKILL.md theme={null}
41 ---
42 description: Review code for bugs, security, and performance
43 ---
44
45 Review the code I've selected or the recent changes for:
46 - Potential bugs or edge cases
47 - Security concerns
48 - Performance issues
49 - Readability improvements
50
51 Be concise and actionable.
52 ```
53 </Step>
54
55 <Step title="Create the plugin manifest">
56 Create a `plugin.json` file that describes the plugin. The manifest goes in the `.claude-plugin/` directory.
57
58 ```json my-marketplace/plugins/quality-review-plugin/.claude-plugin/plugin.json theme={null}
59 {
60 "name": "quality-review-plugin",
61 "description": "Adds a quality-review skill for quick code reviews",
62 "version": "1.0.0",
63 "author": {
64 "name": "Your Name"
65 }
66 }
67 ```
68
69 <Note>
70 Setting `version` means users only receive updates when you change this field, so bump it on every release. A plugin with a [`command` source](#command-sources) isn't pinned by this field. Neither is a plugin [loaded in place](/docs/en/plugins-reference#plugin-caching-and-file-resolution) from a marketplace added as a local directory. If you omit `version`, the version comes from the next source in [version management](/docs/en/plugins-reference#version-management).
71 </Note>
72 </Step>
73
74 <Step title="Create the marketplace file">
75 Create the marketplace catalog that lists your plugin.
76
77 ```json my-marketplace/.claude-plugin/marketplace.json theme={null}
78 {
79 "name": "my-plugins",
80 "owner": {
81 "name": "Your Name"
82 },
83 "plugins": [
84 {
85 "name": "quality-review-plugin",
86 "source": "./plugins/quality-review-plugin",
87 "description": "Adds a quality-review skill for quick code reviews"
88 }
89 ]
90 }
91 ```
92 </Step>
93
94 <Step title="Add and install">
95 From the directory that contains `my-marketplace`, start Claude Code and run the following commands. The install command opens a plugin details view where you select an installation scope to confirm the install. Check the install summary: if it reports `Run /reload-plugins to activate.`, see [Apply plugin changes without restarting](/docs/en/discover-plugins#apply-plugin-changes-without-restarting).
96
97 ```shell theme={null}
98 /plugin marketplace add ./my-marketplace
99 /plugin install quality-review-plugin@my-plugins
100 ```
101 </Step>
102
103 <Step title="Try it out">
104 Select some code in your editor and run your new skill. Plugin skills are namespaced with the plugin name.
105
106 ```shell theme={null}
107 /quality-review-plugin:quality-review
108 ```
109 </Step>
110</Steps>
111
112To learn more about what plugins can do, including hooks, agents, MCP servers, and LSP servers, see [Plugins](/docs/en/plugins).
113
114<Note>
115 **How plugins are installed**: when users install a plugin, Claude Code copies the plugin directory to a cache location, unless the plugin loads in place. A [`command` source in link mode](#copy-mode-and-link-mode) loads in place, and so does a [relative path source](#relative-paths) in a marketplace added from a local directory. Copied plugins can't reference files outside their directory using paths like `../shared-utils`, because those files won't be copied.
116
117 If you need to share files across plugins, use symlinks. See [Plugin caching and file resolution](/docs/en/plugins-reference#plugin-caching-and-file-resolution) for details.
118</Note>
119
120## Create the marketplace file
121
122Create `.claude-plugin/marketplace.json` in your repository root. This file defines your marketplace's name, owner information, and a list of plugins with their sources.
123
124Each plugin entry needs at minimum a `name` and a `source` that tells Claude Code where to fetch it from. See the [full schema](#marketplace-schema) below for all available fields.
125
126```json theme={null}
127{
128 "name": "company-tools",
129 "owner": {
130 "name": "DevTools Team",
131 "email": "devtools@example.com"
132 },
133 "plugins": [
134 {
135 "name": "code-formatter",
136 "source": "./plugins/formatter",
137 "description": "Automatic code formatting on save",
138 "version": "2.1.0",
139 "author": {
140 "name": "DevTools Team"
141 }
142 },
143 {
144 "name": "deployment-tools",
145 "source": {
146 "source": "github",
147 "repo": "company/deploy-plugin"
148 },
149 "description": "Deployment automation tools"
150 }
151 ]
152}
153```
154
155## Marketplace schema
156
157### Required fields
158
159| Field | Type | Description | Example |
160| :-------- | :----- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------------------------------ |
161| `name` | string | Marketplace identifier in kebab-case, with no spaces, control characters, or bidirectional-formatting characters. This is public-facing: users see it when installing plugins (for example, `/plugin install my-tool@your-marketplace`). Each user can register only one marketplace per name: when they add a second marketplace with the same name, Claude Code replaces the first. To publish multiple plugins under one marketplace name, list them all in a [single `marketplace.json`](#create-the-marketplace-file). | `"acme-tools"` |
162| `owner` | object | Marketplace maintainer information. See [Owner fields](#owner-fields) | |
163| `plugins` | array | List of available plugins | See [Plugin entries](#plugin-entries) |
164
165<Note>
166 **Reserved names**: the following marketplace names are reserved for official Anthropic use and can't be used by third-party marketplaces: `claude-code-marketplace`, `claude-code-plugins`, `claude-plugins-official`, `claude-plugins-community`, `claude-community`, `anthropic-marketplace`, `anthropic-plugins`, `agent-skills`, `anthropic-agent-skills`, `knowledge-work-plugins`, `life-sciences`, `claude-for-legal`, `claude-for-financial-services`, `financial-services-plugins`, `first-party-plugins`, `claude-tag-plugins`, `healthcare`. Names that impersonate official marketplaces, such as `official-claude-plugins` or `anthropic-plugins-v2`, are also blocked. Reserving these names prevents a third-party marketplace from presenting itself as an Anthropic-published source.
167
168 Claude Code re-checks reserved names every time it loads a marketplace, not only when you add one. A marketplace that was registered under one of these names before the name became reserved stops loading and reports that it is [registered from an untrusted source](/docs/en/errors#marketplace-is-registered-from-an-untrusted-source). Remove that marketplace and re-add it from the official Anthropic source. A third-party marketplace affected by a newly reserved name loads again as soon as you re-add it under a different name. Before v2.1.205, `first-party-plugins` and `healthcare` weren't reserved, and a marketplace already registered under a reserved name kept loading. Before v2.1.265, `claude-tag-plugins` wasn't reserved.
169
170 You also can't name a marketplace `npm`, `pip`, `uv`, `cargo`, `github`, or `gh`, in any casing. This check requires Claude Code v2.1.275 or later.
171</Note>
172
173### Owner fields
174
175| Field | Type | Required | Description |
176| :------ | :----- | :------- | :------------------------------------------- |
177| `name` | string | Yes | Name of the maintainer or team |
178| `email` | string | No | Contact email for the maintainer |
179| `url` | string | No | Website, GitHub profile, or organization URL |
180
181### Optional fields
182
183| Field | Type | Description |
184| :------------------------------------ | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
185| `$schema` | string | JSON Schema URL for editor autocomplete and validation. Claude Code ignores this field at load time. |
186| `description` | string | Brief marketplace description |
187| `version` | string | Marketplace manifest version |
188| `metadata.pluginRoot` | string | Directory that Claude Code resolves bare plugin source names under. See [Relative paths](#relative-paths). Requires Claude Code v2.1.239 or later. |
189| `allowCrossMarketplaceDependenciesOn` | array | Other marketplaces that plugins in this marketplace may depend on. Dependencies from a marketplace not listed here are blocked at install. See [Depend on a plugin from another marketplace](/docs/en/plugin-dependencies#depend-on-a-plugin-from-another-marketplace). |
190| `renames` | object | Map from a former plugin `name` to its current name, or to `null` if the plugin was removed. Lets existing users migrate automatically when you rename or remove an entry in `plugins`. See [Rename or remove a plugin](#rename-or-remove-a-plugin). Requires Claude Code v2.1.193 or later. |
191
192`description` and `version` are also accepted under `metadata` for backward compatibility.
193
194## Plugin entries
195
196Each plugin entry in the `plugins` array describes a plugin and where to find it. You can include any field from the [plugin manifest schema](/docs/en/plugins-reference#plugin-manifest-schema), such as `description`, `version`, `author`, `commands`, and `hooks`, plus these marketplace-specific fields: `source`, `category`, `tags`, `strict`, `relevance`, `headers`, and `headersHelper`.
197
198### Required fields
199
200| Field | Type | Description |
201| :------- | :------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
202| `name` | string | Plugin identifier in kebab-case, with no spaces, control characters, or bidirectional-formatting characters. This is public-facing: users see it when installing (for example, `/plugin install my-plugin@marketplace`). |
203| `source` | string\|object | Where to fetch the plugin from (see [Plugin sources](#plugin-sources) below) |
204
205### Optional plugin fields
206
207**Standard metadata fields:**
208
209| Field | Type | Description |
210| :--------------- | :------ | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
211| `displayName` | string | Human-readable name shown in UI surfaces. When neither the entry nor the plugin's `plugin.json` sets one, users see the plugin's `name`. May contain spaces and any casing. Not used for namespacing or lookup. |
212| `description` | string | Brief plugin description |
213| `version` | string | Plugin version. If set (here or in `plugin.json`), the plugin is pinned to this string and users only receive updates when it changes. A plugin with a [`command` source](#command-sources) isn't pinned by either field. Neither is a plugin [loaded in place](/docs/en/plugins-reference#plugin-caching-and-file-resolution) from a marketplace added as a local directory. If set in neither place, the version comes from the next source in [version management](/docs/en/plugins-reference#version-management). |
214| `author` | object | Plugin author information (`name` required; `email` and `url` optional) |
215| `homepage` | string | Plugin homepage or documentation URL |
216| `repository` | string | Source code repository URL |
217| `license` | string | SPDX license identifier (for example, MIT, Apache-2.0) |
218| `keywords` | array | Tags for plugin discovery and categorization |
219| `metadata` | object | Free-form object for your own fields, such as entitlement or catalog data. Claude Code doesn't read it. Before v2.1.222, `claude plugin validate` reported the key as an unrecognized field. |
220| `category` | string | Plugin category for organization |
221| `tags` | array | Tags for searchability |
222| `strict` | boolean | Controls whether `plugin.json` is the authority for component definitions (default: true). See [Strict mode](#strict-mode) below. |
223| `relevance` | object | Signals that tell Claude Code when to suggest this plugin to users. Takes effect only for marketplaces an administrator allowlists in managed settings. See [Recommend plugins for your org](/docs/en/plugin-relevance). |
224| `defaultEnabled` | boolean | Whether the plugin is enabled after install (default: true). Set to `false` to install the plugin disabled until the user opts in. Takes precedence over the same field in the plugin's `plugin.json`. See [Default enablement](/docs/en/plugins-reference#default-enablement). |
225
226Both the entry and the plugin's own `plugin.json` can set the display fields `displayName`, `description`, `author`, `homepage`, `repository`, `license`, and `keywords`. In plugin listings and details, before and after install:
227
228* For a field you set on the entry, users see the entry's value, even when `plugin.json` sets a different one.
229* For a field the entry leaves unset, users see the `plugin.json` value.
230
231Before install, Claude Code can read `plugin.json` only for entries with a [relative-path source](#relative-paths), whose plugin files live inside the marketplace itself. For an entry with any other source type, users see only the entry's own fields until they install the plugin.
232
233**Component configuration fields:**
234
235| Field | Type | Description |
236| :----------- | :------------- | :------------------------------------------------------------- |
237| `skills` | string\|array | Custom paths to skill directories containing `<name>/SKILL.md` |
238| `commands` | string\|array | Custom paths to flat `.md` skill files or directories |
239| `agents` | string\|array | Custom paths to agent files |
240| `hooks` | string\|object | Custom hooks configuration or path to hooks file |
241| `mcpServers` | string\|object | MCP server configurations or path to MCP config |
242| `lspServers` | string\|object | LSP server configurations or path to LSP config |
243
244**Archive authentication fields:**
245
246Set these when the entry has an [`archive` source](#zip-archives) on a server that requires credentials.
247
248| Field | Type | Description |
249| :-------------- | :----- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
250| `headers` | object | HTTP headers Claude Code sends when it downloads this entry's archive. Overrides the marketplace's headers of the same name. Requires Claude Code v2.1.238 or later. |
251| `headersHelper` | string | Command that prints the HTTP headers for this entry's archive download as one JSON object, for a credential that expires. See [Authenticate archive downloads](#authenticate-archive-downloads). The entry must also set [`"strict": false`](#strict-mode). Requires Claude Code v2.1.238 or later. |
252
253## Plugin sources
254
255Plugin sources tell Claude Code where to get each individual plugin listed in your marketplace. These are set in the `source` field of each plugin entry in `marketplace.json`.
256
257Claude Code copies each installed plugin into the local versioned plugin cache at `~/.claude/plugins/cache`, unless the plugin loads in place. A [`command` source in link mode](#copy-mode-and-link-mode) loads in place, and so does a [relative path source](#relative-paths) in a marketplace added from a local directory. Claude Code also [installs the plugin's eligible Node.js package dependencies](/docs/en/plugins-reference#node-js-package-dependencies) into the cached copy. See [Plugin caching and file resolution](/docs/en/plugins-reference#plugin-caching-and-file-resolution) for how a plugin loaded in place from a local-directory marketplace picks up your edits.
258
259| Source | Type | Fields | Notes |
260| ------------- | --------------------------------------- | ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
261| Relative path | `string` (for example, `"./my-plugin"`) | none | Local directory within the marketplace repo. Must start with `./`, unless you write a [bare name under `metadata.pluginRoot`](#relative-paths). Claude Code resolves the path relative to the marketplace root, not the `.claude-plugin/` directory |
262| `github` | object | `repo`, `ref?`, `sha?` | |
263| `url` | object | `url`, `ref?`, `sha?` | Git URL source |
264| `git-subdir` | object | `url`, `path`, `ref?`, `sha?` | Subdirectory within a git repo. Clones sparsely to minimize bandwidth for monorepos |
265| `npm` | object | `package`, `version?`, `registry?` | npm package, fetched with your npm client and unpacked without running install scripts |
266| `archive` | object | `url`, `sha256?` | Zip archive downloaded over HTTPS. Works without git or npm on the user's machine. Requires Claude Code v2.1.224 or later |
267| `command` | object | `command`, `timeout?`, `mode?` | Plugin directory produced by running a local command, re-run once per session to pick up changes. Requires Claude Code v2.1.229 or later |
268
269<Note>
270 **Marketplace sources vs plugin sources**: These are different concepts that control different things.
271
272 * **Marketplace source**: where to fetch the `marketplace.json` catalog itself. Set when users run `/plugin marketplace add` or in `extraKnownMarketplaces` settings. Git-based marketplace sources support `ref` (branch/tag) but not `sha`.
273 * **Plugin source**: where to fetch an individual plugin listed in the marketplace. Set in the `source` field of each plugin entry inside `marketplace.json`. Git-based plugin sources support both `ref` (branch/tag) and `sha` (exact commit).
274
275 For example, a marketplace hosted at `acme-corp/plugin-catalog` (marketplace source) can list a plugin fetched from `acme-corp/code-formatter` (plugin source). The marketplace source and plugin source point to different repositories and are pinned independently.
276</Note>
277
278The git-based source types below are `github`, `url`, and `git-subdir`. When both `ref` and `sha` are set on any of them, the `sha` is the effective pin. Claude Code fetches and checks out the pinned commit directly.
279
280On most git hosts, including GitHub, GitLab, and Bitbucket, this means installation succeeds even if the branch or tag named by `ref` has since been deleted upstream, as long as the commit is still reachable from the repository. Some servers, such as AWS CodeCommit, don't support fetching commits by SHA. On those servers the `ref` must still exist and the pinned commit must be reachable from it.
281
282If you distribute plugins through **Organization settings > Plugins**, only some source types are allowed. See [Distribute through organization settings](#distribute-through-organization-settings).
283
284### Relative paths
285
286For plugins in the same repository, use a path starting with `./`:
287
288```json theme={null}
289{
290 "name": "my-plugin",
291 "source": "./plugins/my-plugin"
292}
293```
294
295Paths resolve relative to the marketplace root, which is the directory containing `.claude-plugin/`. The source `./plugins/my-plugin` therefore points to `<repo>/plugins/my-plugin`, even though `marketplace.json` lives at `<repo>/.claude-plugin/marketplace.json`. Don't use `../` to reference paths outside the marketplace root. On macOS and Linux, Claude Code refuses an entry path with a backslash anywhere past the leading `./`, so write the separators as `/` on every platform.
296
297A bare name is a single directory name with no `/`, such as `"formatter"`. To write bare names instead of `./` paths, set [`metadata.pluginRoot`](#optional-fields) to the directory they resolve under. With `"pluginRoot": "./plugins"`, Claude Code resolves `"source": "formatter"` to `./plugins/formatter`. Requires Claude Code v2.1.239 or later.
298
299`metadata.pluginRoot` must itself be a relative path inside the marketplace. Claude Code ignores it for a source that already starts with `./`. A source that contains a `/`, such as `team-a/formatter`, isn't a bare name and still needs the `./` prefix, even when `metadata.pluginRoot` is set.
300
301<Note>
302 Claude Code resolves relative paths against a local copy of the marketplace, so they work when users add your marketplace from a git source or a local directory. If users add your marketplace via a direct URL to the `marketplace.json` file, relative paths won't resolve, because Claude Code downloads only that file. For URL-based distribution, use any other [plugin source](#plugin-sources) instead. See [Troubleshooting](#plugins-with-relative-paths-fail-in-url-based-marketplaces) for details.
303</Note>
304
305### GitHub repositories
306
307```json theme={null}
308{
309 "name": "github-plugin",
310 "source": {
311 "source": "github",
312 "repo": "owner/plugin-repo"
313 }
314}
315```
316
317You can pin to a specific branch, tag, or commit:
318
319```json theme={null}
320{
321 "name": "github-plugin",
322 "source": {
323 "source": "github",
324 "repo": "owner/plugin-repo",
325 "ref": "v2.0.0",
326 "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
327 }
328}
329```
330
331| Field | Type | Description |
332| :----- | :----- | :-------------------------------------------------------------------- |
333| `repo` | string | Required. GitHub repository in `owner/repo` format |
334| `ref` | string | Optional. Git branch or tag (defaults to repository default branch) |
335| `sha` | string | Optional. Full 40-character git commit SHA to pin to an exact version |
336
337### Git repositories
338
339```json theme={null}
340{
341 "name": "git-plugin",
342 "source": {
343 "source": "url",
344 "url": "https://gitlab.com/team/plugin.git"
345 }
346}
347```
348
349You can pin to a specific branch, tag, or commit:
350
351```json theme={null}
352{
353 "name": "git-plugin",
354 "source": {
355 "source": "url",
356 "url": "https://gitlab.com/team/plugin.git",
357 "ref": "main",
358 "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
359 }
360}
361```
362
363| Field | Type | Description |
364| :---- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------- |
365| `url` | string | Required. Full git repository URL (`https://` or `git@`). The `.git` suffix is optional, so Azure DevOps and AWS CodeCommit URLs without the suffix work |
366| `ref` | string | Optional. Git branch or tag (defaults to repository default branch) |
367| `sha` | string | Optional. Full 40-character git commit SHA to pin to an exact version |
368
369### Git subdirectories
370
371Use `git-subdir` to point to a plugin that lives inside a subdirectory of a git repository. Claude Code uses a sparse, partial clone to fetch only the subdirectory, minimizing bandwidth for large monorepos.
372
373```json theme={null}
374{
375 "name": "my-plugin",
376 "source": {
377 "source": "git-subdir",
378 "url": "https://github.com/acme-corp/monorepo.git",
379 "path": "tools/claude-plugin"
380 }
381}
382```
383
384You can pin to a specific branch, tag, or commit:
385
386```json theme={null}
387{
388 "name": "my-plugin",
389 "source": {
390 "source": "git-subdir",
391 "url": "https://github.com/acme-corp/monorepo.git",
392 "path": "tools/claude-plugin",
393 "ref": "v2.0.0",
394 "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
395 }
396}
397```
398
399The `url` field also accepts a GitHub shorthand (`owner/repo`) or SSH URLs (`git@github.com:owner/repo.git`).
400
401| Field | Type | Description |
402| :----- | :----- | :------------------------------------------------------------------------------------------------------- |
403| `url` | string | Required. Git repository URL, GitHub `owner/repo` shorthand, or SSH URL |
404| `path` | string | Required. Subdirectory path within the repo containing the plugin (for example, `"tools/claude-plugin"`) |
405| `ref` | string | Optional. Git branch or tag (defaults to repository default branch) |
406| `sha` | string | Optional. Full 40-character git commit SHA to pin to an exact version |
407
408### npm packages
409
410An npm source can name any package on the public npm registry or on a private registry your team hosts. Claude Code resolves the package with your npm client, downloads the tarball, and unpacks it into the plugin cache.
411
412The package's install scripts, such as `preinstall` or `postinstall`, never run, and its dependencies aren't installed during the fetch.
413
414If the package ships a supported lockfile beside its `package.json`, Claude Code installs those [Node.js package dependencies](/docs/en/plugins-reference#node-js-package-dependencies) in a separate step, also with scripts disabled. Otherwise, publish the plugin with everything it needs already built. An MCP server that needs other packages can launch through `npx`, which installs them at first run.
415
416```json theme={null}
417{
418 "name": "my-npm-plugin",
419 "source": {
420 "source": "npm",
421 "package": "@acme/claude-plugin"
422 }
423}
424```
425
426To pin to a specific version, add the `version` field:
427
428```json theme={null}
429{
430 "name": "my-npm-plugin",
431 "source": {
432 "source": "npm",
433 "package": "@acme/claude-plugin",
434 "version": "2.1.0"
435 }
436}
437```
438
439To install from a private or internal registry, add the `registry` field:
440
441```json theme={null}
442{
443 "name": "my-npm-plugin",
444 "source": {
445 "source": "npm",
446 "package": "@acme/claude-plugin",
447 "version": "^2.0.0",
448 "registry": "https://npm.example.com"
449 }
450}
451```
452
453| Field | Type | Description |
454| :--------- | :----- | :------------------------------------------------------------------------------------------- |
455| `package` | string | Required. Package name or scoped package (for example, `@org/plugin`) |
456| `version` | string | Optional. Version or version range (for example, `2.1.0`, `^2.0.0`, `~1.5.0`) |
457| `registry` | string | Optional. Custom npm registry URL. Defaults to the system npm registry (typically npmjs.org) |
458
459### Zip archives
460
461Use `archive` to distribute a plugin as a zip file that Claude Code downloads over HTTPS, so installs work without git or npm on the user's machine. Host the file on any static file server or artifact repository, such as an S3 bucket, an Artifactory generic repository, or nginx. Requires Claude Code v2.1.224 or later. On versions v2.1.120 through v2.1.223, installing the plugin fails with `This plugin uses a source type your Claude Code version does not support. Update Claude Code and try again.`; on older versions, a marketplace containing an `archive` entry fails to load entirely.
462
463This entry installs the plugin from a zip file on an artifact server:
464
465```json theme={null}
466{
467 "name": "my-plugin",
468 "source": {
469 "source": "archive",
470 "url": "https://artifacts.example.com/claude-plugins/my-plugin-2.1.0.zip"
471 }
472}
473```
474
475When you build the zip, you can zip the plugin's contents directly or zip the plugin folder itself. Claude Code looks for `.claude-plugin/` at the top of the archive, then inside a single top-level folder, so both layouts install:
476
477```text theme={null}
478my-plugin.zip my-plugin.zip
479├── .claude-plugin/ └── my-plugin/
480│ └── plugin.json ├── .claude-plugin/
481└── commands/ │ └── plugin.json
482 └── commands/
483```
484
485Claude Code doesn't look deeper than one folder, so a plugin nested further down fails to install. Claude Code refuses archives larger than 256 MiB.
486
487To pin the exact file, add a `sha256` field with the archive's digest:
488
489```json theme={null}
490{
491 "name": "my-plugin",
492 "source": {
493 "source": "archive",
494 "url": "https://artifacts.example.com/claude-plugins/my-plugin-2.1.0.zip",
495 "sha256": "6bfa50e3d2e00c052b46abe51fff89346ac803e45771f76dcf6df1ab74cca5e1"
496 }
497}
498```
499
500If the downloaded file doesn't match the pin, Claude Code refuses the install and reports [`Plugin archive integrity check failed`](/docs/en/errors#plugin-archive-integrity-check-failed).
501
502Archive sources accept these fields:
503
504| Field | Type | Description |
505| :------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
506| `url` | string | Required. HTTPS URL of the zip archive. Claude Code rejects `http://` URLs, along with loopback, link-local, and cloud-metadata hosts. Every redirect hop must satisfy the same rules, or Claude Code refuses the download |
507| `sha256` | string | Optional. SHA-256 digest of the archive as 64 hex characters, uppercase or lowercase. Claude Code verifies every download against it and refuses the install on a mismatch |
508
509The `sha256` digest also serves as the plugin's version when neither `plugin.json` nor the marketplace entry declares one. See [Version management](/docs/en/plugins-reference#version-management). If you declare a `version`, that version string is the update signal, so after changing the zip and its digest, bump the version too, or users keep the cached copy.
510
511#### Authenticate archive downloads
512
513To authenticate an archive download, such as a download from a private registry, set the HTTP headers Claude Code sends with it. Set `headers` on the `url` source you registered the marketplace from, such as an [`extraKnownMarketplaces`](/docs/en/settings-reference#extraknownmarketplaces) entry. On Claude Code v2.1.238 or later, you can set it on the plugin's entry instead, beside `source`.
514
515If the value you would put in `headers` is short-lived, such as a token your registry mints on request, set a `headersHelper` command in the same place instead. Claude Code runs the command and sends the JSON object it prints as that place's headers. Requires Claude Code v2.1.238 or later.
516
517The place you choose decides which downloads get the headers and when Claude Code runs the command:
518
519| Place | Downloads that get the headers | When Claude Code runs a `headersHelper` set there |
520| :----------------------- | :----------------------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
521| Marketplace `url` source | Archive downloads on the marketplace URL's origin, meaning the same scheme, host, and port | Before each fetch of the marketplace's `marketplace.json` and before each archive download on that origin. Claude Code reuses one run's output for up to 60 seconds |
522| Plugin entry | That entry's download only | Only when a user installs or updates that one plugin by itself and [accepts the command](#how-users-accept-a-headershelper-command) |
523
524Where both places set a header of the same name, Claude Code sends the entry's value. Within one place, a header the command prints overrides a header of the same name listed in `headers`.
525
526##### Add a headersHelper to a plugin entry
527
528This entry sets `headersHelper` beside `source`. It also sets `"strict": false`, which Claude Code requires of a `marketplace.json` entry that sets `headersHelper`. With [`"strict": false`](#strict-mode), the marketplace entry is the plugin's entire definition, so a user can review what the plugin contains before accepting the command:
529
530```json theme={null}
531{
532 "name": "my-plugin",
533 "description": "Formatting commands for internal services",
534 "strict": false,
535 "commands": "./commands",
536 "source": {
537 "source": "archive",
538 "url": "https://registry.example.com/plugins/my-plugin-2.1.0.zip"
539 },
540 "headersHelper": "/opt/bin/mint-registry-token.sh"
541}
542```
543
544To check the entry, run `claude plugin install my-plugin@your-marketplace`. Claude Code shows you the command and the archive URL, and downloads the zip after you accept.
545
546Before v2.1.238, Claude Code downloaded an entry's archive without its `headers` or `headersHelper`, so an install that relied on them failed with `HTTP 401 while downloading plugin archive from`, followed by the URL, with the registry's status code in place of 401.
547
548#### Write the headersHelper command
549
550Whether you set `headersHelper` on a marketplace's `url` source or on a plugin entry, write the command to meet these requirements:
551
552* **Command text**: at most 500 characters of printable ASCII, with no run of four or more spaces.
553* **Output**: print one JSON object of header names and string values on stdout, then exit 0 within 10 seconds.
554* **Shell and working directory**: Claude Code runs the command through `sh`, or `cmd.exe` on Windows, from the configuration directory, `~/.claude` or [`CLAUDE_CONFIG_DIR`](/docs/en/env-vars#variables). Give an absolute path or a command on `PATH`, because a relative path resolves against that directory, not the user's project.
555* **Variables Claude Code removes**: from the environment of a command set in a `marketplace.json` entry or in a project's `.claude/settings.json` or `.claude/settings.local.json`, Claude Code removes every variable whose name contains a word such as `TOKEN`, `SECRET`, `KEY`, or `AUTH`, including `ANTHROPIC_API_KEY`. Claude Code doesn't apply this removal to a command set in user settings, a `--settings` file, or managed settings.
556* **Variables Claude Code sets**: `CLAUDE_CODE_MARKETPLACE_URL` and `CLAUDE_CODE_MARKETPLACE_NAME` for a `url` source's command, and `CLAUDE_CODE_PLUGIN_NAME` and `CLAUDE_CODE_PLUGIN_ARCHIVE_URL` for an entry's command. `CLAUDE_CODE_MARKETPLACE_NAME` is unset on the first fetch after a user adds a marketplace by URL, because that fetch is what supplies the name.
557
558A command that mints a bearer token prints an object like this one:
559
560```json theme={null}
561{"Authorization": "Bearer eyJhbGciOiJSUzI1NiJ9"}
562```
563
564#### When Claude Code skips a headersHelper command or drops its output
565
566Claude Code doesn't run a `headersHelper` command, or drops headers that came from `headers` or from the command's output, in these situations:
567
568* **Command fails**: if the command exits non-zero, runs past 10 seconds, or prints anything other than a JSON object of string values, Claude Code doesn't make the fetch or download it ran the command for.
569* **Marketplace URL doesn't start with `https://`**: Claude Code doesn't run that `url` source's command and sends only the headers listed in its `headers` field.
570* **Redirect leaves the origin**: when a download is redirected off the archive URL's origin, Claude Code drops the `headers` values and command output of both the marketplace `url` source and the plugin entry.
571* **Entry sets a routing or identity header**: Claude Code drops request-routing and client-identity names such as `Host`, `Cookie`, and `X-Forwarded-*` from an entry's `headers` and command output, and keeps authentication names such as `Authorization`. Claude Code filters every `marketplace.json` entry this way, and an [inline settings entry](/docs/en/settings-reference#extraknownmarketplaces) depending on which file declares it.
572* **Command set in an `--add-dir` directory's settings**: Claude Code ignores it, on a `url` source and on an [inline plugin entry](/docs/en/settings-reference#extraknownmarketplaces) alike, and sends only that file's `headers`.
573* **Managed settings block the command**: setting [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources) to `true` blocks `headersHelper` commands, and [`allowManagedHooksOnly`](/docs/en/settings-reference#allowmanagedhooksonly) blocks them too unless `disableCommandPluginSources` is explicitly `false`. Under either block, Claude Code still runs the command for a marketplace that managed settings themselves declare.
574
575#### How users accept a headersHelper command
576
577A user accepts a plugin entry's command each time they install or update that one plugin by itself, from the plugin's own view in `/plugin` or with `claude plugin install` or `claude plugin update`. Claude Code shows the command and the archive URL, and runs the command only after the user accepts.
578
579In a non-interactive shell, pass [`--yes`](/docs/en/plugins-reference#plugin-install) to accept the command. To accept only the command that a previous `--json` run displayed, pass [`--accept-command`](/docs/en/plugins-reference#plugin-install) with the `sha256` the run reported.
580
581Claude Code runs only the command it showed, for the archive URL it showed. If the entry's command or archive URL changed in between, Claude Code refuses the install or update. A change in the query string alone doesn't count.
582
583##### Installs and updates that refuse the command instead of asking
584
585On any operation other than a single-plugin install or update, Claude Code neither runs an entry's command nor downloads its archive, so the plugin stays at its installed version or stays uninstalled. What the user sees depends on the operation:
586
587* **Installing several plugins at once, from a plugin suggestion, or as another plugin's dependency**: Claude Code refuses the plugin that has the command and points the user at that plugin's own view in `/plugin`. The other plugins in a bulk install still install. A plugin that depends on the refused plugin fails to install until the user installs the refused plugin by itself.
588* **Background auto-update, or session start for a plugin whose archive was never downloaded**: Claude Code lists the plugin in the `/plugin` Errors tab so the user knows to install or update it by hand. An auto-update that finds the entry still advertises the installed version lists nothing.
589
590##### When a marketplace `url` source's command runs
591
592A marketplace `url` source's `headersHelper` is declared in a settings file, such as an [`extraKnownMarketplaces`](/docs/en/settings-reference#extraknownmarketplaces) entry, rather than in the catalog the marketplace publishes, so Claude Code doesn't ask the user to accept it on each install or update. The settings file that declares it decides when Claude Code runs it:
593
594| Settings file | When Claude Code runs the command |
595| :---------------------------------------------------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
596| User settings, a `--settings` file, or a managed settings file on the machine | Without asking, including during a background marketplace refresh |
597| A project's `.claude/settings.json` or `.claude/settings.local.json` | Only after the user accepts the [workspace trust dialog](/docs/en/permissions#what-runs-before-you-trust-a-folder) for that folder itself. A `-p` or SDK session doesn't count as accepting it, and neither does trust granted to a parent folder |
598| Server-managed settings | Only after the user approves the delivered settings in the [security approval dialog](/docs/en/server-managed-settings#security-approval-dialogs) |
599
600In a `-p` or SDK session, Claude Code can't show the security approval dialog. It applies the other delivered settings, but the marketplace fetch, and any archive download that needs the command, fails until a user has approved in an interactive session.
601
602For an [inline plugin entry](/docs/en/settings-reference#extraknownmarketplaces) in one of these files, Claude Code requires the same folder trust or settings approval as for a marketplace-level command in that file, and the user also accepts the entry's command on each install or update.
603
604### Command sources
605
606Use `command` when a locally installed tool produces the plugin directory, such as an IDE that renders its plugin for the currently selected toolchain. Claude Code runs the command when the user installs the plugin and re-runs it in the background once per session, so your users pick up the tool's changed output without reinstalling. Requires Claude Code v2.1.229 or later. On v2.1.120 through v2.1.228, installing the plugin fails with `This plugin uses a source type your Claude Code version does not support. Update Claude Code and try again.`, and on older versions the whole marketplace fails to load.
607
608This entry installs the plugin from whatever directory the tool prints:
609
610```json theme={null}
611{
612 "name": "my-plugin",
613 "source": {
614 "source": "command",
615 "command": "my-tool claude-plugin-path"
616 }
617}
618```
619
620Claude Code runs the command through the platform shell, `sh` on macOS and Linux or `cmd.exe` on Windows, from the user's home directory. The command must print exactly one line on stdout and exit with code 0. That line is the absolute path of a directory that contains the complete plugin by the time the command exits, and the path may change between runs.
621
622Claude Code stops a command that runs longer than `timeout` seconds, and the install or update fails. Claude Code also refuses the printed path in these cases, and the install or update fails the same way:
623
624* The directory has no plugin content at its top level, such as a `.claude-plugin/` directory or a `skills/`, `commands/`, `agents/`, or `hooks/` directory
625* The directory is the one Claude Code was started in, or one of its parents
626* On Windows, the path is a UNC path
627
628Command sources accept these fields:
629
630| Field | Type | Description |
631| :-------- | :----- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
632| `command` | string | Required. Shell command that prints the plugin directory's absolute path as a single line on stdout and exits 0. Must be printable ASCII, at most 500 characters, with no runs of four or more spaces, so users can review the whole command they're asked to accept |
633| `timeout` | number | Optional. Whole number of seconds to wait for the command before giving up (default: 60, maximum: 600) |
634| `mode` | string | Optional. `"copy"` (default) copies the printed directory into the plugin cache. `"link"` uses the printed directory in place. See [Copy mode and link mode](#copy-mode-and-link-mode) |
635
636#### Copy mode and link mode
637
638With the default `"mode": "copy"`, Claude Code copies the printed directory into the versioned plugin cache and derives the [plugin version](/docs/en/plugins-reference#version-management) from a hash of the directory's contents. Your tool can delete or rewrite the directory after the command exits, and a re-run that produces identical content counts as up to date. Claude Code refuses to install a directory larger than 256 MiB or containing more than 20,000 entries.
639
640Set `"mode": "link"` for large plugin directories that shouldn't be copied, such as a rendered SDK export. Claude Code fills the plugin's cache entry with a link to each top-level entry of the printed directory and uses the files in place, so nothing is copied, file contents aren't hashed, and the size limits don't apply. The install fails if a top-level entry is a symlink that points outside the printed directory. Claude Code also skips the [Node.js package dependency install](/docs/en/plugins-reference#node-js-package-dependencies) for a link-mode plugin, so print a directory that already contains any `node_modules` the plugin needs.
641
642Keep the printed directory in place for as long as the plugin stays installed, because Claude Code loads the plugin through those links at every startup. Claude Code derives the [plugin version](/docs/en/plugins-reference#version-management) from the printed directory's real path and its top-level entries, not the files inside, so print a different path to signal new content. In a session started in the printed directory or anywhere below it, Claude Code doesn't load the plugin at all.
643
644Claude Code doesn't support link mode on Windows and refuses to install a link-mode plugin there. Declare `"mode": "copy"` instead.
645
646#### How users accept the command
647
648Claude Code runs your command on the user's machine, so it binds every run to the user's explicit acceptance:
649
650* When users install the plugin from its details screen in `/plugin`, or install or update it with `claude plugin install` or `claude plugin update` in an interactive terminal, Claude Code shows them the exact command string first and records the accepted command for that installation. A `claude plugin update` that can proceed on the recorded acceptance of the same command shows nothing.
651* In a non-interactive shell, such as a provisioning script, pass `--yes` to `claude plugin install` or `claude plugin update` to accept the command it prints. To accept only the command that a previous `--json` run displayed, pass [`--accept-command`](/docs/en/plugins-reference#plugin-install) with the `sha256` the run reported.
652* Every other path runs only the command the user already accepted. This includes updates started from `/plugin` and the background runs described in [When Claude Code re-runs the command](#when-claude-code-re-runs-the-command). When none was accepted, Claude Code refuses to run the command and tells the user how to review it. Claude Code never installs a command-sourced plugin as a dependency of another plugin, so users install it themselves first.
653* If you change the entry's `command`, or switch its `mode`, users keep the version they already have and Claude Code stops re-running the command. In interactive sessions, the `/plugin` Errors tab shows the new command until the user reviews and accepts it by running `claude plugin update <plugin>@<marketplace>`.
654
655Administrators can block command sources across an organization with the managed setting [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources). If an organization sets [`allowManagedHooksOnly`](/docs/en/settings-reference#allowmanagedhooksonly), Claude Code blocks command sources by default.
656
657#### When Claude Code re-runs the command
658
659The printed directory reflects the tool's state at the time the command ran, so Claude Code runs the command again at these times:
660
661* Every time the user installs or updates the plugin
662* Once per session for each enabled command-sourced plugin, in the background, shortly after the session starts. This run doesn't go through marketplace auto-update, so it doesn't depend on the marketplace's [auto-update setting](/docs/en/discover-plugins#configure-auto-updates)
663* At startup or on `/reload-plugins`, when an enabled plugin's installed version is missing from the plugin cache
664
665Claude Code skips the two background runs when the user sets [`CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC`](/docs/en/env-vars). Explicit installs and updates still run the command with that variable set.
666
667When the command's hashed output has changed, Claude Code installs the result as a new version and reloads it in the running interactive session, switching [the same components that `/reload-plugins` switches](/docs/en/plugins-reference#environment-variables). The user sees a notification that the plugin was reloaded. If reloading in place would invalidate the session's prompt cache, Claude Code instead prompts the user to run `/reload-plugins`, which [warns about the cache cost and applies when rerun with `--force`](/docs/en/prompt-caching#enabling-or-disabling-a-plugin).
668
669### Advanced plugin entries
670
671This example shows a plugin entry using many of the optional fields, including custom paths for commands, agents, hooks, and MCP servers:
672
673```json theme={null}
674{
675 "name": "enterprise-tools",
676 "source": {
677 "source": "github",
678 "repo": "company/enterprise-plugin"
679 },
680 "description": "Enterprise workflow automation tools",
681 "version": "2.1.0",
682 "author": {
683 "name": "Enterprise Team",
684 "email": "enterprise@example.com"
685 },
686 "homepage": "https://docs.example.com/plugins/enterprise-tools",
687 "repository": "https://github.com/company/enterprise-plugin",
688 "license": "MIT",
689 "keywords": ["enterprise", "workflow", "automation"],
690 "category": "productivity",
691 "commands": [
692 "./commands/core/",
693 "./commands/enterprise/",
694 "./commands/experimental/preview.md"
695 ],
696 "agents": ["./agents/security-reviewer.md", "./agents/compliance-checker.md"],
697 "hooks": {
698 "PostToolUse": [
699 {
700 "matcher": "Write|Edit",
701 "hooks": [
702 {
703 "type": "command",
704 "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh"
705 }
706 ]
707 }
708 ]
709 },
710 "mcpServers": {
711 "enterprise-db": {
712 "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
713 "args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"]
714 }
715 },
716 "strict": false
717}
718```
719
720Key things to notice:
721
722* **`commands` and `agents`**: you can specify multiple directories or individual files. Paths are relative to the plugin root and must stay inside it.
723 * Claude Code rejects a path that resolves outside the plugin directory, such as `./../shared.md`, with a [`path escapes plugin directory`](/docs/en/errors#path-escapes-plugin-directory) error, and still loads the plugin without that component
724* **`${CLAUDE_PLUGIN_ROOT}`**: use this variable in hook commands and MCP server configs to reference files within the plugin's installation directory.
725 * See the [substitution table](/docs/en/plugins-reference#environment-variables) for which config fields substitute it per server type
726 * For dependencies or state that should survive plugin updates, use [`${CLAUDE_PLUGIN_DATA}`](/docs/en/plugins-reference#persistent-data-directory) instead
727* **`strict: false`**: since this is set to false, the plugin doesn't need its own `plugin.json`. The marketplace entry defines everything. See [Strict mode](#strict-mode) below.
728
729By default, a plugin's skills load from the `skills/` directory under its `source`. Paths listed in the `skills` field add to that scan:
730
731```json theme={null}
732"skills": ["./skills/", "./extra-skills/"]
733```
734
735When several plugin entries share one `skills/` folder at the marketplace root (`source: "./"`), list specific subdirectories instead so each entry loads only its own skills:
736
737```json theme={null}
738"source": "./",
739"skills": ["./skills/code-review", "./skills/docs"]
740```
741
742With a marketplace-root `source`, the listed paths are the complete set for that entry, and other directories in the shared `skills/` folder don't load. Listing `./skills/` itself, or the plugin root, keeps the full scan. If none of the listed paths exist, the default scan runs instead.
743
744### Strict mode
745
746The `strict` field controls whether `plugin.json` is the authority for component definitions (skills, agents, hooks, MCP servers, output styles).
747
748| Value | Behavior |
749| :--------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------- |
750| `true` (default) | `plugin.json` is the authority. The marketplace entry can supplement it with additional components, and both sources are merged. |
751| `false` | The marketplace entry is the entire definition. If the plugin also has a `plugin.json` that declares components, that's a conflict and the plugin fails to load. |
752
753**When to use each mode:**
754
755* **`strict: true`**: the plugin has its own `plugin.json` and manages its own components. The marketplace entry can add extra skills or hooks on top. This is the default and works for most plugins.
756* **`strict: false`**: the marketplace operator wants full control. The plugin repo provides raw files, and the marketplace entry defines which of those files are exposed as skills, agents, hooks, etc. Useful when the marketplace restructures or curates a plugin's components differently than the plugin author intended.
757
758## Host and distribute marketplaces
759
760When users add a marketplace hosted in a git repository, or install a git-based plugin it lists, Claude Code clones that marketplace or plugin repository onto their machine. The clone never downloads [Git LFS](https://git-lfs.com) content, so LFS-tracked files arrive as pointer files. Keep the files your plugins need out of LFS.
761
762### Host on GitHub (recommended)
763
764GitHub is the recommended way to host and distribute a marketplace:
765
7661. **Create a repository**: set up a new repository for your marketplace
7672. **Add marketplace file**: create `.claude-plugin/marketplace.json` with your plugin definitions
7683. **Share with teams**: users add your marketplace with `/plugin marketplace add owner/repo`
769
770**Benefits**: built-in version control, issue tracking, and team collaboration features.
771
772### Host on other git services
773
774Any git hosting service works, such as GitLab, Bitbucket, and self-hosted servers. Users add with the full repository URL:
775
776```shell theme={null}
777/plugin marketplace add https://gitlab.com/company/plugins.git
778```
779
780### Private repositories
781
782Claude Code supports installing plugins from private repositories. If you distribute your marketplace through [**Organization settings > Plugins**](https://claude.ai/admin-settings/plugins) instead, your git credentials aren't involved: organization sync reads the marketplace repository through your organization's GitHub or GitLab connection on claude.ai. See [Distribute through organization settings](#distribute-through-organization-settings) for which plugin sources can be private.
783
784#### Commands you run
785
786When you run `/plugin marketplace add`, `/plugin install`, `/plugin update`, or `/plugin marketplace update`, Claude Code uses your existing git credential helpers, so HTTPS access via `gh auth login`, macOS Keychain, or `git-credential-store` works the same as in your terminal. SSH access works as long as the host is already in your `known_hosts` file and the key is loaded in `ssh-agent`, since Claude Code suppresses interactive SSH prompts for the host fingerprint and key passphrase. GitHub `owner/repo` shorthand sources clone over SSH by default; set [`CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1`](/docs/en/env-vars#variables) to clone them over HTTPS instead.
787
788#### Background auto-updates
789
790The background refresh checks the marketplace's remote for new commits with your configured git credential helpers, the same as the commands you run. For SSH remotes, a key loaded in `ssh-agent` authenticates the check. Claude Code runs the check non-interactively: it turns off git's terminal prompts and askpass programs, and tells credential helpers not to prompt. Whether the check can authenticate to a private repository over HTTPS depends on your helper:
791
792* A helper that can supply a stored credential without prompting authenticates the check. Git Credential Manager, the macOS Keychain helper, and `git-credential-store` work this way once they hold a credential for the host.
793* A helper that needs to prompt you can't answer in the background. The update fails quietly and the existing checkout stays in place, so your plugins keep working from the last synced state. Run `/plugin marketplace update <name>` to refresh the marketplace with your credentials.
794
795When the check finds the checkout up to date, Claude Code leaves it as it is. When the check finds new commits, or fails because it can't reach or authenticate to the remote, Claude Code clones the marketplace again and swaps the new clone in. If that clone fails, the existing checkout stays in place. The re-clone can [time out on large repositories](#git-operations-time-out).
796
797Two settings make private marketplaces behave predictably:
798
799* Set `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1` to keep the existing checkout without attempting the re-clone when the background check can't reach or authenticate to the remote. Your plugins keep working from the last synced state, and manual updates with `/plugin marketplace update` still authenticate with your credentials.
800* Configure a git credential helper, for example with `gh auth setup-git` for GitHub, so the background check and the re-clone can authenticate without prompting.
801
802Setting a provider token such as `GITHUB_TOKEN` in your environment doesn't by itself enable background authentication. Tokens take effect only through a configured credential helper, for example the `gh` CLI's helper, which reads `GH_TOKEN` and `GITHUB_TOKEN`.
803
804<Note>
805 In CI/CD environments, configure a git credential helper before installing plugins from private repositories. On GitHub Actions, export a token with read access to the marketplace repository as `GH_TOKEN`, then run `gh auth setup-git`. The default workflow token can only access the workflow's own repository, so a private marketplace in another repository needs a personal access token or app token.
806</Note>
807
808### Distribute through organization settings
809
810If you distribute plugins through [**Organization settings > Plugins**](https://claude.ai/admin-settings/plugins) on a Team or Enterprise plan, these source rules apply:
811
812* On github.com and gitlab.com, the marketplace repository must be private or internal. Organization sync reads the repository through the connection that matches its host:
813 * **github.com**: the Claude GitHub App
814 * **Your GitHub Enterprise Server host**: your organization's [GitHub Enterprise App](/docs/en/github-enterprise-server#admin-setup)
815 * **gitlab.com or your self-managed GitLab instance**: the access token in your organization's [GitLab configuration](#sync-a-gitlab-hosted-marketplace) for that host
816* Each plugin source must be of type `github`, `url`, or `git-subdir`, or a [relative path](#relative-paths) that starts with `./`. If you list a plugin by bare name under `metadata.pluginRoot`, organization sync rejects it as an unsupported source, so write the path out, such as `./plugins/deploy-tools`.
817* A plugin source can be private in three cases:
818 * A github.com source that shares the marketplace repository's owner
819 * A source on your organization's GitHub Enterprise host with the GHE App installed on the repository
820 * A `url` or `git-subdir` source on the same GitLab host as the marketplace repository. On gitlab.com, the source must also be under the same top-level group or user namespace as the marketplace repository.
821* Any other plugin source must be a public repository on github.com, gitlab.com, or bitbucket.org, which organization sync fetches without credentials. Organization sync rejects plugin sources on hosts these rules don't cover.
822
823See [Manage plugins for your organization](https://support.claude.com/en/articles/13837433) for the admin workflow.
824
825To include private plugins, place the plugin folders inside the marketplace repository and reference them with a [relative path](#relative-paths). Organization sync packages each plugin during distribution, so users never need access to a separate source repository.
826
827For example, this `marketplace.json` plugin entry references a plugin you committed at `plugins/deploy-tools` in the marketplace repository:
828
829```json theme={null}
830{
831 "name": "deploy-tools",
832 "source": "./plugins/deploy-tools"
833}
834```
835
836#### Sync a GitLab-hosted marketplace
837
838To sync a marketplace from gitlab.com or a self-managed GitLab instance, an [Owner](/docs/en/server-managed-settings#access-control) first adds a GitLab configuration for that host at [**Organization settings > Claude Code**](https://claude.ai/admin-settings/claude-code). GitLab configurations are in public beta and apply only to plugin marketplace sync. Adding one doesn't make GitLab repositories available to [cloud sessions](/docs/en/claude-code-on-the-web#limitations). See [Manage plugins for your organization](https://support.claude.com/en/articles/13837433) for the setup steps.
839
840When you add the marketplace, enter the project's HTTPS URL, such as `https://gitlab.example.com/platform/claude-plugins`. Projects in nested subgroups work. Organization sync reads the project's default branch. If you turn on **Sync automatically**, only pushes to the default branch start a sync.
841
842#### Keep executables out of the top-level bin directory
843
844Don't include a top-level `bin/` directory in any plugin you distribute through organization settings. claude.ai rejects a plugin that has one, whether the plugin arrives by marketplace sync or by direct upload:
845
846* **Marketplace sync**: organization sync rejects that plugin and syncs the rest of the marketplace. The error message starts with `Plugin contains a top-level bin/ directory`.
847* **Direct upload**: if you upload the plugin in [**Organization settings > Plugins**](https://claude.ai/admin-settings/plugins) instead, claude.ai rejects the upload with the same message.
848
849Keep executables in another directory, such as `scripts/`, and reference them as `${CLAUDE_PLUGIN_ROOT}/scripts/<name>` from your [skills, hooks, or MCP server configs](/docs/en/plugins-reference#environment-variables).
850
851### Require marketplaces for your team
852
853You can configure your repository so Claude Code adds your marketplace for team members once they [trust the project folder](/docs/en/permissions#what-runs-before-you-trust-a-folder), with no separate prompt. Add your marketplace to `.claude/settings.json`:
854
855```json theme={null}
856{
857 "extraKnownMarketplaces": {
858 "company-tools": {
859 "source": {
860 "source": "github",
861 "repo": "your-org/claude-plugins"
862 }
863 }
864 }
865}
866```
867
868You can also specify which plugins should be enabled by default:
869
870```json theme={null}
871{
872 "enabledPlugins": {
873 "code-formatter@company-tools": true,
874 "deployment-tools@company-tools": true
875 }
876}
877```
878
879For full configuration options, see [Plugin settings](/docs/en/settings-reference#plugin-settings).
880
881<Note>
882 If you use a local `directory` or `file` source with a relative path, the path resolves against your repository's main checkout. When you run Claude Code from a git worktree, the path still points at the main checkout, so all worktrees share the same marketplace location. Marketplace state is stored once per user in `~/.claude/plugins/known_marketplaces.json`, not per project.
883</Note>
884
885### Pre-populate plugins for containers
886
887For container images and CI environments, you can pre-populate a plugins directory at build time so Claude Code starts with marketplaces and plugins already available, without cloning anything at runtime. Set the `CLAUDE_CODE_PLUGIN_SEED_DIR` environment variable to point at this directory.
888
889To layer multiple seed directories, separate paths with `:` on Unix or `;` on Windows. Claude Code searches each directory in order and uses the first seed that contains a given marketplace or plugin cache.
890
891The seed directory mirrors the structure of `~/.claude/plugins`:
892
893```
894$CLAUDE_CODE_PLUGIN_SEED_DIR/
895 known_marketplaces.json
896 marketplaces/<name>/...
897 cache/<marketplace>/<plugin>/<version>/...
898```
899
900To build a seed directory, run Claude Code once during image build, install the plugins you need, then copy the resulting `~/.claude/plugins` directory into your image and point `CLAUDE_CODE_PLUGIN_SEED_DIR` at it.
901
902To skip the copy step, set `CLAUDE_CODE_PLUGIN_CACHE_DIR` to your target seed path during the build so plugins install directly there:
903
904```bash theme={null}
905CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin marketplace add your-org/plugins
906CLAUDE_CODE_PLUGIN_CACHE_DIR=/opt/claude-seed claude plugin install my-tool@your-plugins
907```
908
909Then set `CLAUDE_CODE_PLUGIN_SEED_DIR=/opt/claude-seed` in your container's runtime environment so Claude Code reads from the seed on startup.
910
911At startup, Claude Code registers marketplaces found in the seed's `known_marketplaces.json` into the primary configuration, and uses plugin caches found under `cache/` in place without re-cloning. This works in both interactive mode and non-interactive mode with the `-p` flag.
912
913Behavior details:
914
915* **Read-only**: Claude Code never writes to the seed directory.
916* **Auto-updates disabled**: seed marketplaces don't auto-update.
917* **Seed entries take precedence**: marketplaces declared in the seed overwrite any matching entries in the user's configuration on each startup. To opt out of a seed plugin, use `/plugin disable` rather than removing the marketplace.
918* **Path resolution**: Claude Code locates marketplace content by probing `$CLAUDE_CODE_PLUGIN_SEED_DIR/marketplaces/<name>/` at runtime, not by trusting paths stored inside the seed's JSON. This means the seed works correctly even when mounted at a different path than where it was built.
919* **Mutation is blocked**: running `/plugin marketplace remove` or `/plugin marketplace update` against a seed-managed marketplace fails with guidance to ask your administrator to update the seed image.
920* **Composes with settings**: if `extraKnownMarketplaces` or `enabledPlugins` declare a marketplace that already exists in the seed, Claude Code uses the seed copy instead of cloning.
921
922### Managed marketplace restrictions
923
924For organizations requiring strict control over plugin sources, administrators can restrict which plugin marketplaces users are allowed to add using the [`strictKnownMarketplaces`](/docs/en/settings-reference#strictknownmarketplaces) setting in managed settings. To also reject the CLI flags that sideload plugins, agents, and MCP servers for a single run, pair it with [`disableSideloadFlags`](/docs/en/settings-reference#disablesideloadflags). To allowlist which marketplaces' plugins can appear as contextual install suggestions, set [`pluginSuggestionMarketplaces`](/docs/en/settings-reference#pluginsuggestionmarketplaces).
925
926`strictKnownMarketplaces` matches the marketplace a plugin comes from, not the entries inside it, so users can still install a plugin with a [`command` source](#command-sources) from an allowed marketplace. To block command sources as well, set [`disableCommandPluginSources`](/docs/en/settings-reference#disablecommandpluginsources).
927
928When `strictKnownMarketplaces` is configured in managed settings, the restriction behavior depends on the value:
929
930| Value | Behavior |
931| ------------------- | ------------------------------------------------------------------------------------------------ |
932| Undefined (default) | No restrictions. Users can add any marketplace |
933| Empty array `[]` | Complete lockdown. Blocks every marketplace source, including the official Anthropic marketplace |
934| List of sources | Allowlist enforced. Users can add only marketplaces that match an entry |
935
936#### Common configurations
937
938Disable all marketplace additions, including the official Anthropic marketplace:
939
940```json theme={null}
941{
942 "strictKnownMarketplaces": []
943}
944```
945
946Claude Code downloads the plugins [synced from claude.ai](/docs/en/plugins-reference#synced-plugins) from your account rather than from a marketplace, so this lockdown doesn't cover them. To stop those as well, set [`syncClaudeAiPlugins`](/docs/en/settings-reference#syncclaudeaiplugins) to `false` in managed settings, or turn off Skills for your organization on claude.ai.
947
948Allow only the official Anthropic marketplace. Matching for a single-repository entry is exact, so this entry doesn't cover `ref` or `path` variants of the same repository:
949
950```json theme={null}
951{
952 "strictKnownMarketplaces": [
953 {
954 "source": "github",
955 "repo": "anthropics/claude-plugins-official"
956 }
957 ]
958}
959```
960
961With this entry, Claude Code keeps an already-registered official marketplace available and, on a fresh machine, registers the marketplace automatically the first time you start Claude Code interactively.
962
963Automatic registration doesn't cover every machine. It most commonly misses:
964
965* Non-interactive environments that run before the machine's first interactive launch.
966* Machines where Claude Code already ran interactively under a policy that blocked the marketplace, such as the empty-array lockdown. Claude Code records the blocked attempt and doesn't retry after the policy changes.
967
968On these machines, add the marketplace to [`extraKnownMarketplaces`](/docs/en/settings-reference#extraknownmarketplaces) in the same `managed-settings.json` so Claude Code registers it automatically, or run `claude plugin marketplace add anthropics/claude-plugins-official`.
969
970Allow specific marketplaces only:
971
972```json theme={null}
973{
974 "strictKnownMarketplaces": [
975 {
976 "source": "github",
977 "repo": "acme-corp/approved-plugins"
978 },
979 {
980 "source": "github",
981 "repo": "acme-corp/security-tools",
982 "ref": "v2.0"
983 },
984 {
985 "source": "url",
986 "url": "https://plugins.example.com/marketplace.json"
987 }
988 ]
989}
990```
991
992Allow every marketplace repository under a GitHub organization with an [owner-wildcard](/docs/en/settings-reference#owner-wildcards) entry. Owner wildcards require Claude Code v2.1.223 or later.
993
994```json theme={null}
995{
996 "strictKnownMarketplaces": [
997 {
998 "source": "github",
999 "repo": "acme-corp/*"
1000 }
1001 ]
1002}
1003```
1004
1005Allow all marketplaces from an internal git server using regex pattern matching on the host. This is the recommended approach for [GitHub Enterprise Server](/docs/en/github-enterprise-server#plugin-marketplaces-on-ghes) or self-hosted GitLab instances:
1006
1007```json theme={null}
1008{
1009 "strictKnownMarketplaces": [
1010 {
1011 "source": "hostPattern",
1012 "hostPattern": "^github\\.example\\.com$"
1013 }
1014 ]
1015}
1016```
1017
1018Allow filesystem-based marketplaces from a specific directory using regex pattern matching on the path:
1019
1020```json theme={null}
1021{
1022 "strictKnownMarketplaces": [
1023 {
1024 "source": "pathPattern",
1025 "pathPattern": "^/opt/approved/"
1026 }
1027 ]
1028}
1029```
1030
1031Use `".*"` as the `pathPattern` to allow any filesystem path while still controlling network sources with `hostPattern`.
1032
1033<Note>
1034 `strictKnownMarketplaces` restricts what users can add, but doesn't register marketplaces on its own. To register an allowed marketplace for users automatically, add it to [`extraKnownMarketplaces`](/docs/en/settings-reference#extraknownmarketplaces) in the same `managed-settings.json`.
1035
1036 The official Anthropic marketplace is the only one Claude Code registers on its own, and only when the allowlist allows it. Automatic registration also misses some machines, such as non-interactive environments and machines where an earlier policy blocked it. To cover those machines, add the official marketplace to `extraKnownMarketplaces` as well. For the two settings side by side, see the [`strictKnownMarketplaces` reference](/docs/en/settings-reference#strictknownmarketplaces).
1037</Note>
1038
1039#### How restrictions work
1040
1041Restrictions are checked before any network or filesystem operation. The check runs on marketplace add and on plugin install, update, refresh, and auto-update. If a marketplace was added before the policy was configured and its source no longer matches the allowlist, Claude Code refuses to install or update plugins from it. The same enforcement applies to `blockedMarketplaces`.
1042
1043Where the two lists are enforced depends on where you set them:
1044
1045* **The claude.ai admin console**: Claude Code enforces both lists in the sessions that [read server-managed settings](/docs/en/managed-settings#where-and-when-a-policy-applies). claude.ai also checks them when anyone in your organization adds a new marketplace from a git repository on claude.ai, or from **Customize** in the Claude Desktop app outside its Code tab. That covers a marketplace a member adds for their own account and one added for the whole organization under [**Organization settings > Plugins**](https://claude.ai/admin-settings/plugins). claude.ai refuses a repository that the allowlist doesn't admit or that the blocklist names. It doesn't re-check a marketplace that was added in either place before you set the lists, and it doesn't check uploaded plugins.
1046* **A managed settings file, OS-level policy, or other managed source**: Claude Code enforces both lists where it reads that source. claude.ai doesn't read it.
1047
1048To block every marketplace repository under a GitHub owner, use the owner-wildcard form in a `blockedMarketplaces` entry: `{ "source": "github", "repo": "untrusted-org/*" }`. Requires Claude Code v2.1.223 or later. For the matching rules, which differ between the blocklist and the allowlist, see [Owner wildcards](/docs/en/settings-reference#owner-wildcards).
1049
1050When a user adds an `https://` repository URL that Claude Code [clones rather than fetches](/docs/en/discover-plugins#add-from-other-git-hosts), such as a bare `github.com` or `gitlab.com` repository URL, Claude Code also checks it against the `url` entries in `blockedMarketplaces`. Claude Code blocks the addition if an entry names the same URL. In that comparison, Claude Code ignores the `.git` suffix and any ref the user appends after `#`. Requires Claude Code v2.1.232 or later. Before v2.1.232, Claude Code matched a `url` entry only against a URL it fetched as a hosted `marketplace.json` file.
1051
1052The allowlist uses exact matching for most source types, apart from owner-wildcard `github` entries. For a marketplace to be allowed, all specified fields must match:
1053
1054* For GitHub sources: `repo` is required, either naming one repository or using the owner-wildcard form `owner/*` to cover every repository under that owner. For how wildcard entries match, including the case rules, see [Owner wildcards](/docs/en/settings-reference#owner-wildcards). For single-repository entries, `ref` must match exactly or be absent from both the marketplace source and the allowlist entry, and the same rule applies to `path`
1055* For URL sources: the full URL must match exactly
1056* For `hostPattern` sources: the marketplace host is matched against the regex pattern
1057* For `pathPattern` sources: the marketplace's filesystem path is matched against the regex pattern
1058
1059The allowlist's exact matching treats URLs that differ only by a trailing slash, a `.git` suffix, or the `ssh://` and `https://` scheme as different values. If your organization's marketplace can be cloned by more than one URL form, prefer a `hostPattern` entry over a literal URL so the `https://`, `ssh://`, and `user@host:path` forms all match.
1060
1061A [marketplace hosted on claude.ai](/docs/en/discover-plugins#add-from-claude-ai) is matched by host: a `hostPattern` entry that matches `claude.ai` governs it, in `strictKnownMarketplaces` and in `blockedMarketplaces`. On the allowlist, such an entry doesn't admit a member's personal claude.ai uploads. Requires Claude Code v2.1.273 or later.
1062
1063Because `strictKnownMarketplaces` is set in [managed settings](/docs/en/managed-settings), individual users and project configurations can't override these restrictions.
1064
1065For complete configuration details including all supported source types and comparison with `extraKnownMarketplaces`, see the [strictKnownMarketplaces reference](/docs/en/settings-reference#strictknownmarketplaces).
1066
1067### Version resolution and release channels
1068
1069Plugin versions determine cache paths and update detection: if the resolved version matches what a user already has, `/plugin update` and auto-update skip the plugin. For git-based sources, if you omit `version`, Claude Code uses the source's resolved commit SHA, so users get an update whenever that commit changes; this is the simplest setup for internal or actively developed plugins. See [Version management](/docs/en/plugins-reference#version-management) for the full resolution order, including `archive` sources.
1070
1071<Warning>
1072 Setting `version` pins the plugin for every source type except [`command`](#command-sources), whose version always includes a hash of what the command produced. A plugin [loaded in place](/docs/en/plugins-reference#plugin-caching-and-file-resolution) from a marketplace added as a local directory isn't pinned either. If you declare `"version": "1.0.0"` in `plugin.json` and push new commits without changing that string, existing users of those sources keep the cached copy, because Claude Code sees the same version. Bump the field on every release, or omit it to fall back to the resolved version.
1073
1074 Avoid setting `version` in both `plugin.json` and the marketplace entry. Claude Code always uses the `plugin.json` value without warning, so a stale manifest version can mask a version you set in `marketplace.json`.
1075</Warning>
1076
1077#### Set up release channels
1078
1079To support "stable" and "latest" release channels for your plugins, you can set up two marketplaces that point to different refs or SHAs of the same repo. You can then give each user group its own marketplace through managed settings in one of two ways:
1080
1081* Deploy separate [endpoint-managed settings](/docs/en/managed-settings#delivery-mechanisms), such as a managed settings file or an MDM profile, to each group's devices. [How Claude Code combines managed sources](/docs/en/managed-settings#precedence-within-the-managed-tier) says whether the per-group file or profile applies on a device that also has an organization-wide source.
1082* Define one [Claude apps gateway policy](/docs/en/claude-apps-gateway-config#managed) per group. The gateway applies the first policy whose match rule fits a user, so order the policies so that each user reaches their group's policy. A group policy's `extraKnownMarketplaces` replaces the catch-all policy's map rather than merging with it, so list every marketplace the group needs in the group's policy, not only its channel marketplace.
1083
1084Server-managed settings from the admin console [apply to every user in your organization](/docs/en/server-managed-settings#current-limitations), so they can't carry a per-group assignment.
1085
1086<Warning>
1087 Each channel must resolve to a different version. If you use explicit versions, `plugin.json` must declare a different `version` at each pinned ref. If you omit `version`, the distinct commit SHAs already distinguish the channels. If two refs resolve to the same version string, Claude Code treats them as identical and skips the update.
1088</Warning>
1089
1090##### Example
1091
1092```json theme={null}
1093{
1094 "name": "stable-tools",
1095 "plugins": [
1096 {
1097 "name": "code-formatter",
1098 "source": {
1099 "source": "github",
1100 "repo": "acme-corp/code-formatter",
1101 "ref": "stable"
1102 }
1103 }
1104 ]
1105}
1106```
1107
1108```json theme={null}
1109{
1110 "name": "latest-tools",
1111 "plugins": [
1112 {
1113 "name": "code-formatter",
1114 "source": {
1115 "source": "github",
1116 "repo": "acme-corp/code-formatter",
1117 "ref": "latest"
1118 }
1119 }
1120 ]
1121}
1122```
1123
1124##### Assign channels to user groups
1125
1126Assign each marketplace to its user group through the per-group endpoint-managed settings or gateway policy described under [Set up release channels](#set-up-release-channels). For example, the stable group receives:
1127
1128```json theme={null}
1129{
1130 "extraKnownMarketplaces": {
1131 "stable-tools": {
1132 "source": {
1133 "source": "github",
1134 "repo": "acme-corp/stable-tools"
1135 }
1136 }
1137 }
1138}
1139```
1140
1141The early-access group receives `latest-tools` instead:
1142
1143```json theme={null}
1144{
1145 "extraKnownMarketplaces": {
1146 "latest-tools": {
1147 "source": {
1148 "source": "github",
1149 "repo": "acme-corp/latest-tools"
1150 }
1151 }
1152 }
1153}
1154```
1155
1156#### Pin dependency versions
1157
1158A plugin can constrain its dependencies to a semver range so that updates to a dependency don't break the dependent plugin. See [Constrain plugin dependency versions](/docs/en/plugin-dependencies) for the `{plugin-name}--v{version}` git-tag convention, range syntax, and how multiple constraints on the same dependency are combined.
1159
1160### Rename or remove a plugin
1161
1162A plugin's `name` is its stable identifier. Users reference it in `enabledPlugins`, `pluginConfigs`, and `/plugin install` commands, so changing it breaks every existing install. To change the label shown in the UI without breaking installs, set [`displayName`](#optional-plugin-fields) and keep `name` unchanged.
1163
1164If you must change a plugin's `name`, or you remove a plugin from the `plugins` array, add a top-level `renames` entry so existing users migrate instead of seeing a `plugin-not-found` error. Automatic migration requires Claude Code v2.1.193 or later. Map each former name to its current name, or to `null` if the plugin no longer exists. The following example renames `formatter` to `code-formatter` and records that `legacy-linter` was removed:
1165
1166```json theme={null}
1167{
1168 "name": "acme-tools",
1169 "owner": { "name": "Acme" },
1170 "plugins": [
1171 { "name": "code-formatter", "source": "./plugins/code-formatter" }
1172 ],
1173 "renames": {
1174 "formatter": "code-formatter",
1175 "legacy-linter": null
1176 }
1177}
1178```
1179
1180When a user starts Claude Code with the old name still in their settings, Claude Code follows the `renames` map:
1181
1182* If the entry points to a new name, Claude Code loads the plugin under its new name and shows a one-line notice such as `Renamed to "code-formatter" in the "acme-tools" marketplace`. It then rewrites the old key to the new key in the user, project, and local settings scopes for both `enabledPlugins` and `pluginConfigs`, so the notice appears once.
1183* For a `null` entry, Claude Code drops the old key and the notice reports that the plugin was removed from the marketplace.
1184* If the renamed plugin uses a remote source such as `github` or `npm`, Claude Code reports `plugin-cache-miss` after the rename and the user must run `/plugin install` once to fetch it under the new name.
1185
1186Treat `renames` as append-only history: keep old entries in place even after you expect every user to have migrated. Claude Code follows chains, so if you later rename `code-formatter` to `formatter-pro`, add a second entry rather than editing the first. A user who still has the original `formatter` enabled then resolves through both entries to `formatter-pro`.
1187
1188Run `claude plugin validate .` after editing the map; it rejects any entry whose chain forms a cycle or doesn't terminate at `null` or a name listed in `plugins`.
1189
1190<Note>
1191 Managed and policy settings are read-only to Claude Code, so plugins enabled there can't be rewritten automatically. The renamed plugin still loads each session, but the rename notice recurs until an administrator updates `enabledPlugins` in the managed settings file to use the new name. The same applies to plugins enabled through other read-only sources such as `--add-dir`.
1192</Note>
1193
1194Earlier versions of Claude Code ignore the `renames` field and report `plugin-not-found` for the old name.
1195
1196## Validation and testing
1197
1198Test your marketplace before sharing. Validation checks file structure; to test whether a plugin changes what Claude does on realistic prompts, run its eval suite with [`claude plugin eval`](/docs/en/plugin-evals) before you publish a new version.
1199
1200From your marketplace directory, validate the JSON syntax:
1201
1202```bash theme={null}
1203claude plugin validate .
1204```
1205
1206Or from within Claude Code:
1207
1208```shell theme={null}
1209/plugin validate .
1210```
1211
1212Add the marketplace for testing:
1213
1214```shell theme={null}
1215/plugin marketplace add ./path/to/marketplace
1216```
1217
1218Install a test plugin to verify everything works:
1219
1220```shell theme={null}
1221/plugin install test-plugin@marketplace-name
1222```
1223
1224For complete plugin testing workflows, see [Test your plugins locally](/docs/en/plugins#test-your-plugins-locally). For technical troubleshooting, see [Plugins reference](/docs/en/plugins-reference).
1225
1226## Manage marketplaces from the CLI
1227
1228Claude Code provides non-interactive `claude plugin marketplace` subcommands for scripting and automation. These are equivalent to the `/plugin marketplace` commands available inside an interactive session.
1229
1230### Plugin marketplace add
1231
1232Add a marketplace from a GitHub repository, git URL, remote URL, or local path.
1233
1234```bash theme={null}
1235claude plugin marketplace add <source> [options]
1236```
1237
1238**Arguments:**
1239
1240* `<source>`: GitHub `owner/repo` shorthand, git URL, remote URL to a `marketplace.json` file, or local directory path. To pin to a branch or tag, append `@ref` to the GitHub shorthand or `#ref` to a git URL
1241
1242A URL must include its scheme. As of Claude Code v2.1.196, a host typed without one, such as `gitlab.example.com/team/plugins`, is rejected as an invalid `owner/repo` shorthand and the error tells you to add `https://` or use `./` for a local path. Earlier versions misread it as a GitHub repository path and fail at clone time with a GitHub not-found error.
1243
1244**Options:**
1245
1246| Option | Description | Default |
1247| :-------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------ |
1248| `--scope <scope>` | Where to declare the marketplace: `user`, `project`, or `local`. See [Plugin installation scopes](/docs/en/plugins-reference#plugin-installation-scopes) | `user` |
1249| `--sparse <paths...>` | Limit checkout to specific directories via git sparse-checkout. Useful for monorepos | |
1250| `--claudeai` | Read the argument as the name of a [marketplace hosted on claude.ai](/docs/en/discover-plugins#add-from-claude-ai) instead of a source. Requires Claude Code v2.1.273 or later | |
1251
1252Add a marketplace from GitHub using `owner/repo` shorthand:
1253
1254```bash theme={null}
1255claude plugin marketplace add acme-corp/claude-plugins
1256```
1257
1258Pin to a specific branch or tag with `@ref`:
1259
1260```bash theme={null}
1261claude plugin marketplace add acme-corp/claude-plugins@v2.0
1262```
1263
1264Add from a git URL on a non-GitHub host:
1265
1266```bash theme={null}
1267claude plugin marketplace add https://gitlab.example.com/team/plugins.git
1268```
1269
1270Add from a remote URL that serves the `marketplace.json` file directly:
1271
1272```bash theme={null}
1273claude plugin marketplace add https://example.com/marketplace.json
1274```
1275
1276Add from a local directory for testing:
1277
1278```bash theme={null}
1279claude plugin marketplace add ./my-marketplace
1280```
1281
1282Declare the marketplace at project scope so it is shared with your team via `.claude/settings.json`:
1283
1284```bash theme={null}
1285claude plugin marketplace add acme-corp/claude-plugins --scope project
1286```
1287
1288For a monorepo, limit the checkout to the directories that contain plugin content:
1289
1290```bash theme={null}
1291claude plugin marketplace add acme-corp/monorepo --sparse .claude-plugin plugins
1292```
1293
1294Add a [marketplace hosted on claude.ai](/docs/en/discover-plugins#add-from-claude-ai) by the name printed in the `From claude.ai:` section of `claude plugin marketplace list`:
1295
1296```bash theme={null}
1297claude plugin marketplace add --claudeai claudeai-organization-library
1298```
1299
1300With `--claudeai`, the command refuses `--scope` and `--sparse`. The marketplace is hosted for your account, not declared in a settings file, so you can't share it through a project's `.claude/settings.json`.
1301
1302### Plugin marketplace list
1303
1304List all configured marketplaces.
1305
1306```bash theme={null}
1307claude plugin marketplace list [options]
1308```
1309
1310**Options:**
1311
1312| Option | Description |
1313| :------- | :------------- |
1314| `--json` | Output as JSON |
1315
1316With `--json`, each entry includes `name`, `source`, an `installLocation` field with the local cache path where the marketplace is stored, and source-specific fields: `repo` for GitHub sources, `url` for git and URL sources, and `path` for local sources. GitHub and git sources also include a `ref` field when the marketplace was added with a pinned branch or tag.
1317
1318An added [claude.ai marketplace](/docs/en/discover-plugins#add-from-claude-ai) has no local clone, so its entry carries its claude.ai identifiers, `marketplaceId` and `organizationUuid`, in place of `installLocation`.
1319
1320In terminal sessions where [plugins sync from your claude.ai account](/docs/en/plugins-reference#synced-plugins), the text listing ends with a `From claude.ai:` section naming what claude.ai lists for your account beyond the marketplaces you've added. To add one of them, see [Add from claude.ai](/docs/en/discover-plugins#add-from-claude-ai). The `--json` output covers configured marketplaces only and leaves that section out. Requires Claude Code v2.1.273 or later.
1321
1322### Plugin marketplace remove
1323
1324Remove a configured marketplace. The alias `rm` is also accepted.
1325
1326```bash theme={null}
1327claude plugin marketplace remove <name> [options]
1328```
1329
1330**Arguments:**
1331
1332* `<name>`: marketplace name to remove, as shown by `claude plugin marketplace list`. This is the `name` from `marketplace.json`, not the source you passed to `add`
1333
1334**Options:**
1335
1336| Option | Description | Default |
1337| :---------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | :----------- |
1338| `--scope <scope>` | Restrict removal to a single settings scope: `user`, `project`, or `local`. See [Plugin installation scopes](/docs/en/plugins-reference#plugin-installation-scopes). When omitted, the declaration is removed from every editable scope. When given, only that scope's declaration is removed; the shared state, cache, and installed plugin data are preserved when the marketplace is still declared in another scope | (all scopes) |
1339
1340<Warning>
1341 Removing a marketplace from its last remaining scope also uninstalls any plugins you installed from it. To refresh a marketplace without losing installed plugins, use `claude plugin marketplace update` instead.
1342</Warning>
1343
1344### Plugin marketplace update
1345
1346Refresh marketplaces from their sources to retrieve new plugins and version changes. A marketplace added with a branch or tag `ref` updates to the latest commit of that ref, not the repository's default branch.
1347
1348```bash theme={null}
1349claude plugin marketplace update [name]
1350```
1351
1352**Arguments:**
1353
1354* `[name]`: marketplace name to update, as shown by `claude plugin marketplace list`. Updates all marketplaces if omitted
1355
1356Both `remove` and `update` fail when run against a seed-managed marketplace, which is read-only. When updating all marketplaces, seed-managed entries are skipped and other marketplaces still update. To change seed-provided plugins, ask your administrator to update the seed image. See [Pre-populate plugins for containers](#pre-populate-plugins-for-containers).
1357
1358## Troubleshooting
1359
1360### Marketplace not loading
1361
1362**Symptoms**: Can't add marketplace or see plugins from it
1363
1364**Solutions**:
1365
1366* Verify the marketplace URL is accessible
1367* Check that `.claude-plugin/marketplace.json` exists at the specified path
1368* Ensure JSON syntax is valid using `claude plugin validate .` or `/plugin validate .` from the marketplace directory. To check skill, agent, and command frontmatter, see [Validate a plugin or a directory without a manifest](#validate-a-plugin-or-a-directory-without-a-manifest)
1369* For private repositories, confirm you have access permissions
1370
1371### Marketplace validation errors
1372
1373Run `claude plugin validate .` or `/plugin validate .` from your marketplace directory to check for issues. When pointed at a marketplace directory, the validator checks `marketplace.json` for schema errors, duplicate plugin names, and source path traversal. For each entry whose `source` is a local path, it also validates that plugin's own `plugin.json` and warns when the entry's `version` doesn't match the one in `plugin.json`. Problems found in a plugin's `plugin.json` are prefixed with the entry index, in the form `plugins[2] plugin.json →`.
1374
1375As of Claude Code v2.1.196, the per-entry pass also:
1376
1377* includes plugins whose `source` is `.`
1378* runs when `marketplace.json` is outside a `.claude-plugin` directory, resolving sources against the file's own directory
1379* reports each entry's problems even when another part of the file has schema errors
1380
1381Earlier versions skip plugins at the marketplace root and only descend from a `.claude-plugin/marketplace.json`.
1382
1383From a marketplace directory, Claude Code doesn't open the plugins' skill, agent, command, or hook files. To find errors in those files, see [Validate a plugin or a directory without a manifest](#validate-a-plugin-or-a-directory-without-a-manifest). The table below lists the most common errors from a marketplace directory, with the cause and fix for each:
1384
1385| Error | Cause | Solution |
1386| :------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1387| `No manifest found in directory. Expected .claude-plugin/marketplace.json or .claude-plugin/plugin.json` | The directory you named has no `.claude-plugin/marketplace.json` or `plugin.json`, and no skill, agent, or command files to check | Run from the marketplace root, or create `.claude-plugin/marketplace.json` with the required fields |
1388| `Invalid JSON syntax: Unexpected token...` | JSON syntax error in marketplace.json | Check for missing commas, extra commas, or unquoted strings |
1389| `Duplicate plugin name "x" found in marketplace` | Two plugins share the same name | Give each plugin a unique `name` value |
1390| `plugins[0].source: Path contains ".."` | A segment of the source path is `..` | Use paths relative to the marketplace root without `..` segments. See [Relative paths](#relative-paths) |
1391| `Marketplace name cannot contain control or bidirectional-formatting characters` | The marketplace `name` contains a Unicode bidirectional-formatting character or a control character, such as an escape or a newline | Remove the character from the name. Before v2.1.247, these characters produced the `Marketplace name impersonates an official Anthropic/Claude marketplace` error |
1392| `Plugin name cannot contain control or bidirectional-formatting characters` | A plugin `name` contains a Unicode bidirectional-formatting character or a control character, such as an escape or a newline | Remove the character from the name. Before v2.1.247, Claude Code didn't run this check |
1393
1394**Warnings** (non-blocking):
1395
1396* `Marketplace has no plugins defined`: add at least one plugin to the `plugins` array
1397* `No marketplace description provided`: add a top-level `description` to help users understand your marketplace
1398* `Plugin name "x" is not kebab-case`: rename to lowercase letters, digits, and hyphens only (for example, `my-plugin`). Claude Code accepts other forms, but the claude.ai marketplace sync rejects them.
1399* `Marketplace name "x" is reserved in Claude Desktop`: the marketplace is named `org`, `org-provisioned`, or `unknown`, in any casing. Claude Code accepts these names, but Claude Desktop's managed marketplace sync rejects the whole marketplace. Rename the marketplace. Before v2.1.221, `claude plugin validate` didn't run this check.
1400* `Marketplace name "x" is not accepted by Claude Desktop` or `Plugin name "x" is not accepted by Claude Desktop`: Claude Desktop accepts names of up to 128 characters made of letters, digits, `.`, `_`, and `-`, starting with a letter or digit. Claude Code accepts other forms, but Claude Desktop's managed marketplace sync rejects a marketplace whose name fails the check and silently drops a plugin entry whose name does. Rename the marketplace or plugin. Before v2.1.221, `claude plugin validate` didn't run these checks.
1401
1402#### Validate a plugin or a directory without a manifest
1403
1404To find skill, agent, and command files whose frontmatter doesn't parse, run `claude plugin validate` and name the directory that holds them. Claude Code doesn't look outside the directory you name. Every run except one against a plugin that has a `plugin.json` requires Claude Code v2.1.233 or later.
1405
1406##### Pick the directory to name
1407
1408Claude Code checks different files depending on which directory you name. Find what you want to check in the first column, and run that row's command:
1409
1410| To check | Run | Claude Code checks |
1411| :------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------------------------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1412| A plugin that has a `plugin.json` | `claude plugin validate ./plugins/my-plugin` | `plugin.json`, `hooks/hooks.json`, and the `skills`, `agents`, and `commands` directories at the plugin root |
1413| One directory of skills, agents, or commands, such as a plugin that has no `plugin.json` yet | `claude plugin validate .claude/skills`, `~/.claude/agents`, or `./my-plugin/agents` | Every skill, agent, or command file in that directory |
1414| A folder whose skill is its root `SKILL.md` | `claude plugin validate ./skills`, naming the `skills` directory that holds the folder | Each folder's root `SKILL.md`. The holding directory must be named `skills`; a folder under another name, such as `plugins/`, has no run that checks its root `SKILL.md` |
1415| A project's three directories at once | `claude plugin validate .claude`, or the project root when it has no `.claude-plugin/` manifest | `.claude/skills`, `.claude/agents`, and `.claude/commands` |
1416| Your user-level directories | `claude plugin validate ~/.claude` | `~/.claude/skills`, `~/.claude/agents`, and `~/.claude/commands` |
1417
1418##### Check a plugin whose skill is its root `SKILL.md`
1419
1420When you run `claude plugin validate` against a plugin directory, Claude Code doesn't check a `SKILL.md` at the plugin root. When the plugin sits in a directory named `skills`, run the command twice:
1421
1422* Name that `skills` directory to check the plugin's root `SKILL.md`.
1423* Name the plugin directory to check the rest.
1424
1425When the plugin sits under another name, such as `plugins/`, the `skills`-directory run isn't available, and no run checks its root `SKILL.md`.
1426
1427##### Check files behind symlinks
1428
1429When you run `claude plugin validate`, Claude Code doesn't follow symlinks inside the directory you name. What it does depends on where the link is:
1430
1431* **A linked `skills`, `agents`, or `commands` directory under the plugin or `.claude` root**: Claude Code warns that nothing in it was read.
1432* **A linked entry inside a `skills`, `agents`, or `commands` directory**: Claude Code skips it and warns, per directory, how many entries it skipped that a session would load.
1433* **The `skills`, `agents`, or `commands` directory you name is itself a symlink, or its parent `.claude` directory is**: Claude Code reports an error and checks nothing in it. Name the real directory instead.
1434
1435In two skills cases, the run passes with warnings. To check the linked files, run again and name a directory that holds them directly:
1436
1437* **A plugin whose `skills` directory [links to a sibling plugin's skills](/docs/en/plugins-reference#share-files-within-a-marketplace-with-symlinks)**: name the sibling plugin's directory.
1438* **A [symlinked skill entry](/docs/en/skills#where-skills-live) in `~/.claude/skills` or `.claude/skills`**: Claude Code follows the entry in a session. To check it, name a directory called `skills` that holds the real folder.
1439
1440##### Read the validation results
1441
1442A clean run ends with `Validation passed`.
1443
1444`No manifest found in directory` means Claude Code found no `plugin.json` or `marketplace.json` there, and no skill, agent, or command file in the directories it probes under it. Name the `skills`, `agents`, or `commands` directory that holds your files instead.
1445
1446Two of the errors Claude Code reports from these runs, with the fix for each:
1447
1448* `YAML frontmatter failed to parse: ...`: fix the YAML in the frontmatter block of the skill, agent, or command file. Until you do, a session reads no frontmatter fields from the file
1449* `Invalid JSON syntax: ...` on `hooks/hooks.json`: fix the JSON syntax. Until you do, a session loads the plugin without the hooks in that file. Claude Code reports this error only in a plugin run
1450
1451In a plugin run, Claude Code also warns about a `CLAUDE.md` at the plugin root. For paths you set through the [component path fields](/docs/en/plugins-reference#component-path-fields) in `plugin.json`, Claude Code checks that each path exists but doesn't read the files there.
1452
1453### Plugin installation failures
1454
1455**Symptoms**: Marketplace appears but plugin installation fails
1456
1457**Solutions**:
1458
1459* Verify plugin source URLs are accessible
1460* Check that plugin directories contain required files
1461* For GitHub sources, ensure repositories are public or you have access
1462* Test plugin sources manually by cloning/downloading
1463* If the source pins both `ref` and `sha`, a deleted upstream branch or tag doesn't block installation on most git hosts, including GitHub, GitLab, and Bitbucket. On servers that don't support fetching commits by SHA, such as AWS CodeCommit, the `ref` must still exist and the pinned commit must be reachable from it. If the install still fails, confirm the pinned commit still exists in the repository
1464
1465### Private repository authentication fails
1466
1467**Symptoms**: Authentication errors when installing plugins from private repositories
1468
1469**Solutions**:
1470
1471For manual installation and updates:
1472
1473* Verify you're authenticated with your git provider (for example, run `gh auth status` for GitHub)
1474* Check that your credential helper is configured: `git config --global credential.helper`
1475* Run `git ls-remote <marketplace-url>` to test whether git can authenticate on its own. If git asks for a username or password, store the credential first: for GitHub over HTTPS, run `gh auth setup-git`, and for SSH remotes, load your key into `ssh-agent`
1476
1477For background auto-updates:
1478
1479* The background check uses your configured git credential helpers but never prompts, so your helper must be able to answer with a stored credential. SSH remotes with a key loaded in `ssh-agent` also authenticate
1480* If your helper needs to prompt you, the background update fails quietly and the existing checkout stays in place. Sign in to your helper first so it holds a credential for the host. For GitHub, run `gh auth login`, then `gh auth setup-git`
1481* When the check finds new commits, or can't reach or authenticate to the remote, Claude Code re-clones the marketplace with the same credentials. The re-clone may time out on large repositories
1482* Set `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1` to keep the existing checkout without attempting the re-clone when the background check can't reach or authenticate to the remote
1483* If the re-clone times out on a large repository, increase the limit with [`CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS`](#git-operations-time-out)
1484* Or update private marketplaces manually with `/plugin marketplace update <name>`, which uses your credentials
1485
1486Before v2.1.280, the background check ran without your credential helpers and couldn't authenticate to private repositories over HTTPS.
1487
1488### Marketplace updates fail in offline environments
1489
1490**Symptoms**: In an offline or airgapped environment, the background marketplace refresh can't reach the remote and Claude Code repeatedly attempts a re-clone that can't succeed.
1491
1492**Cause**: The background refresh checks the marketplace's remote for new commits, and when the check can't reach the remote, Claude Code attempts to clone the marketplace again. Offline, the clone fails the same way and the existing checkout stays in place. Before v2.1.274, the refresh ran `git pull` in the existing checkout, moved the checkout aside to re-clone when the pull failed, and restored it afterward on a best-effort basis.
1493
1494The refresh runs in the background after startup, so it doesn't delay startup. Each session still repeats the failed attempt, and each git operation can wait out the [120-second timeout](#git-operations-time-out).
1495
1496**Solution**: Set `CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1` to skip the re-clone attempt and keep using the existing checkout when the check can't reach the remote:
1497
1498```bash theme={null}
1499export CLAUDE_CODE_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE=1
1500```
1501
1502For fully offline deployments where the repository will never be reachable, use [`CLAUDE_CODE_PLUGIN_SEED_DIR`](#pre-populate-plugins-for-containers) to pre-populate the plugins directory at build time instead.
1503
1504### Git operations time out
1505
1506**Symptoms**: Plugin installation or marketplace updates fail with a timeout error such as `Git clone timed out after 120s`.
1507
1508**Cause**: Claude Code uses a 120-second timeout for all git operations, including cloning plugin repositories and re-cloning a marketplace to update it. Large repositories or slow network connections may exceed this limit.
1509
1510**Solution**: Increase the timeout using the `CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS` environment variable. The value is in milliseconds:
1511
1512```bash theme={null}
1513export CLAUDE_CODE_PLUGIN_GIT_TIMEOUT_MS=300000 # 5 minutes
1514```
1515
1516### Plugins with relative paths fail in URL-based marketplaces
1517
1518**Symptoms**: Added a marketplace via a URL such as `https://example.com/marketplace.json`, but plugins with relative path sources like `"./plugins/my-plugin"` fail to install with `its marketplace entry path does not stay inside the marketplace directory`. Already-installed plugins fail to load with `Plugin source path refused`. Both messages have an [error reference entry](/docs/en/errors#marketplace-entry-path-does-not-stay-inside-the-marketplace-directory).
1519
1520**Cause**: adding a URL-based marketplace downloads only the `marketplace.json` file itself, and Claude Code doesn't fetch plugin files by relative path from that server. Relative paths in the marketplace entry reference files on the remote server that were not downloaded.
1521
1522**Solutions**:
1523
1524* **Use external sources**: change plugin entries to any [plugin source](#plugin-sources) other than a relative path:
1525 ```json theme={null}
1526 { "name": "my-plugin", "source": { "source": "github", "repo": "owner/repo" } }
1527 ```
1528* **Use a Git-based marketplace**: Host your marketplace in a Git repository and add it with the git URL. Git-based marketplaces clone the entire repository, making relative paths work correctly.
1529
1530### Files not found after installation
1531
1532**Symptoms**: Plugin installs but references to files fail, especially files outside the plugin directory
1533
1534**Cause**: Claude Code copies installed plugins to a cache directory, unless the plugin loads in place. A [`command` source in link mode](#copy-mode-and-link-mode) loads in place, and so does a [relative path source](#relative-paths) in a marketplace added from a local directory. Paths that reference files outside a copied plugin's directory (such as `../shared-utils`) won't work because those files aren't copied.
1535
1536**Solutions**: See [Plugin caching and file resolution](/docs/en/plugins-reference#plugin-caching-and-file-resolution) for workarounds including symlinks and directory restructuring.
1537
1538For additional debugging tools and common issues, see [Debugging and development tools](/docs/en/plugins-reference#debugging-and-development-tools).
1539
1540## See also
1541
1542* [Discover and install prebuilt plugins](/docs/en/discover-plugins) - Installing plugins from existing marketplaces
1543* [Plugins](/docs/en/plugins) - Creating your own plugins
1544* [Plugins reference](/docs/en/plugins-reference) - Complete technical specifications and schemas
1545* [Plugin settings](/docs/en/settings-reference#plugin-settings) - Plugin configuration options
1546* [strictKnownMarketplaces reference](/docs/en/settings-reference#strictknownmarketplaces) - Managed marketplace restrictions