MCP, plugins, skills, and hooks changedthird-party/claude-desktop/extensions
Nearest release: v2.1.283, published under an hour after upstream edited the page. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Upstream edited this page at 25 Sep 2026 18:00 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 22:07 UTC.
Upstream edited
Recorded here
Lines+59added
Lines−59removed
From line
6
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits19to this page, all time
The whole hunk
from line 6, old and new numbered
/
from line 6
66
77There are three layers, in order of precedence:
88
9| Layer | Provisioned by | Delivered via |
10| -------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
11| Managed MCP servers | Admin | `managedMcpServers` configuration key |
12| Organization plugins | Admin | A [plugin marketplace](#plugin-marketplaces-admin) hosted in git or over HTTPS (recommended), or a [system-wide directory](#organization-plugins-admin) on each device |
13| User extensions | End user | In-app Connectors and Plugins UI |
9| Layer | Provisioned by | Delivered via |
10| - | - | - |
11| Managed MCP servers | Admin | `managedMcpServers` configuration key |
12| Organization plugins | Admin | A [plugin marketplace](#plugin-marketplaces-admin) hosted in git or over HTTPS (recommended), or a [system-wide directory](#organization-plugins-admin) on each device |
13| User extensions | End user | In-app Connectors and Plugins UI |
1414
1515Admins can disable the user layer entirely; see [Controlling user extensions](#controlling-user-extensions).
1616
from line 91
9191
9292For short-lived header credentials, configure the helper per server:
9393
94| Key | Default | What it does |
95| ------------------------------- | ------- | ----------------------------------------------------------------------------------------- |
96| `headersHelper` | None | Executable that prints the request headers as a flat JSON object to stdout. |
97| `headersHelperTtlSec` | 300 | Seconds the returned headers stay valid. |
98| `headersHelperRefreshBufferSec` | 60 | Seconds before expiry that the helper re-runs. Set it above the helper's typical runtime. |
94| Key | Default | What it does |
95| - | - | - |
96| `headersHelper` | None | Executable that prints the request headers as a flat JSON object to stdout. |
97| `headersHelperTtlSec` | 300 | Seconds the returned headers stay valid. |
98| `headersHelperRefreshBufferSec` | 60 | Seconds before expiry that the helper re-runs. Set it above the helper's typical runtime. |
9999
100100The helper follows the [`inferenceCredentialHelper`](/docs/third-party/claude-desktop/credential-helper) execution model, with four differences: no arguments, a 30-second time limit, no `CLAUDE_HELPER_CONTEXT`, and no prompting for input. The helper applies only to servers provisioned through managed configuration and never replaces the `Authorization` header on `oauth` entries.
101101
from line 216
216216[{"source":"url","url":"https://plugins.acme.example.com/claude/marketplace.json","credentialKind":"inferenceCredential","installationPreference":"available"}]
217217```
218218
219| Field | Description |
220| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
221| `source` | **Required.** `"github"` (with `repo`), `"git"` (with `url`), or `"url"` (with `url` pointing at a hosted `marketplace.json`). |
222| `repo` | GitHub repository in `owner/name` format. `github` sources only. |
223| `url` | For `git` sources, the full HTTPS clone URL. For `url` sources, the HTTPS address of the `marketplace.json` file. Use a bare URL with no embedded credentials or query string, and set `credentialKind` for authentication. |
224| `ref` | Branch name, tag name, or full 40-character commit SHA. Git sources only. **Required, and must be a full commit SHA,** when `installationPreference` is `"auto_install"` or `"required"`. |
225| `path` | Subdirectory containing `.claude-plugin/marketplace.json` when not at the repository root. Git sources only. |
226| `manifestSha256` | 64-character hex SHA-256 of the exact `marketplace.json` file to accept. `url` sources only. **Required** when `installationPreference` is `"auto_install"` or `"required"`; a served manifest with any other digest is refused. |
227| `expectedName` | If set, the fetch is rejected unless the `name` in `marketplace.json` matches this value exactly, so a change to the manifest name cannot silently replace another configured marketplace. |
228| `credentialKind` | `"anonymous"` (default), `"userGit"`, `"credentialHelper"`, or (for `url` sources) `"inferenceCredential"`. See [Marketplace credentials](#marketplace-credentials). |
229| `credentialHelper` | Path to an executable that prints an access token on stdout. Required, and only valid, when `credentialKind` is `"credentialHelper"`. |
230| `installationPreference` | `"available"` (default), `"auto_install"`, or `"required"`. See [Marketplace installation preferences](#marketplace-installation-preferences). |
219| Field | Description |
220| - | - |
221| `source` | **Required.** `"github"` (with `repo`), `"git"` (with `url`), or `"url"` (with `url` pointing at a hosted `marketplace.json`). |
222| `repo` | GitHub repository in `owner/name` format. `github` sources only. |
223| `url` | For `git` sources, the full HTTPS clone URL. For `url` sources, the HTTPS address of the `marketplace.json` file. Use a bare URL with no embedded credentials or query string, and set `credentialKind` for authentication. |
224| `ref` | Branch name, tag name, or full 40-character commit SHA. Git sources only. **Required, and must be a full commit SHA,** when `installationPreference` is `"auto_install"` or `"required"`. |
225| `path` | Subdirectory containing `.claude-plugin/marketplace.json` when not at the repository root. Git sources only. |
226| `manifestSha256` | 64-character hex SHA-256 of the exact `marketplace.json` file to accept. `url` sources only. **Required** when `installationPreference` is `"auto_install"` or `"required"`; a served manifest with any other digest is refused. |
227| `expectedName` | If set, the fetch is rejected unless the `name` in `marketplace.json` matches this value exactly, so a change to the manifest name cannot silently replace another configured marketplace. |
228| `credentialKind` | `"anonymous"` (default), `"userGit"`, `"credentialHelper"`, or (for `url` sources) `"inferenceCredential"`. See [Marketplace credentials](#marketplace-credentials). |
229| `credentialHelper` | Path to an executable that prints an access token on stdout. Required, and only valid, when `credentialKind` is `"credentialHelper"`. |
230| `installationPreference` | `"available"` (default), `"auto_install"`, or `"required"`. See [Marketplace installation preferences](#marketplace-installation-preferences). |
231231
232232You can configure multiple marketplaces, and each appears as its own sub-tab under **Organization** in the **Directory**. If an admin-configured marketplace has the same `repo`, `url`, or manifest `name` as one the user added themselves, the admin entry replaces the user's.
233233
234234### Marketplace installation preferences
235235
236| `installationPreference` | Behavior |
237| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
238| `"available"` | Plugins appear in the Organization tab for users to install manually. Nothing is installed automatically. |
239| `"auto_install"` | Every plugin is installed automatically the first time the pinned `ref` is seen. Users can uninstall individual plugins; when you later change the `ref`, each plugin is installed again at the new revision. |
240| `"required"` | Every plugin is installed automatically and re-asserted on every sync. Users cannot uninstall or disable required plugins. |
236| `installationPreference` | Behavior |
237| - | - |
238| `"available"` | Plugins appear in the Organization tab for users to install manually. Nothing is installed automatically. |
239| `"auto_install"` | Every plugin is installed automatically the first time the pinned `ref` is seen. Users can uninstall individual plugins; when you later change the `ref`, each plugin is installed again at the new revision. |
240| `"required"` | Every plugin is installed automatically and re-asserted on every sync. Users cannot uninstall or disable required plugins. |
241241
242242<Warning>
243243 `"auto_install"` and `"required"` marketplaces must carry an admin-side content pin so the exact plugin content deployed to every device is deterministic and auditable. Git sources must set `ref` to a full 40-character commit SHA; Claude Desktop refuses to auto-install from a branch or tag name. `url` sources must set `manifestSha256` to the SHA-256 of the exact `marketplace.json` bytes and give every archive a `sha256`; Claude Desktop refuses a served manifest with a different digest and skips unpinned archives.
from line 273
273273
274274Claude Desktop fetches marketplaces on the host operating system, outside the Cowork VM. The credential is used only for this fetch and is never passed into the VM or exposed to the model.
275275
276| `credentialKind` | How it authenticates |
277| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
278| `"anonymous"` | No credential is sent. Use for public repositories or unauthenticated file hosts. |
279| `"userGit"` | Uses the git credential helpers already configured for the signed-in OS user (for example, `git-credential-manager`, macOS Keychain, or a GitHub CLI credential helper). Use when each user already has read access through their own account. For `url` sources, the same credential is sent as HTTP Basic on the manifest and archive requests. |
280| `"credentialHelper"` | Runs the executable at `credentialHelper`. If it prints a bare token, the token is used as the git password for username `x-access-token` (accepted by GitHub, GitLab, and Azure DevOps) and, for `url` sources, sent as `Authorization: Bearer <token>` on the manifest and archive requests. For hosts that need a particular username, print git-credential lines `username=<user>` and `password=<token>` instead (for example `x-token-auth` for Bitbucket Data Center access tokens, or `gitlab+deploy-token-N` for a GitLab deploy token); `url` sources then use HTTP Basic. Print `authtype=Bearer` and `credential=<token>` to force a bearer header. For `url` sources, the helper can instead print a flat JSON object of HTTP headers, such as `{"Authorization": "Bearer …", "X-Tenant": "acme"}` (the form a managed MCP server's `headersHelper` prints, not an inference credential helper's `{"token": …}` object), and Claude Desktop sends every header in it on each request to that marketplace. `github` and `git` sources refuse this form. Output that opens with `{` must be a valid header object, or the fetch is refused. Username forms require Claude Desktop 1.37937.0 or later. Otherwise follows the execution model of an [inference credential helper](/docs/third-party/claude-desktop/credential-helper). |
281| `"inferenceCredential"` | `url` sources only. Sends the credentials Claude Desktop already sends to your inference gateway or to your [bootstrap server](/docs/third-party/claude-desktop/bootstrap), so a marketplace hosted on either is private to signed-in members without a separate credential. On the gateway's origin it sends the same `Authorization` bearer as inference and works for [gateway single sign-on](/docs/third-party/claude-desktop/gateway#single-sign-on-with-your-identity-provider), a [credential helper](/docs/third-party/claude-desktop/credential-helper), and bearer-scheme API keys. On the bootstrap server's origin (Claude Desktop 1.37937.0 or later) it sends the bootstrap sign-in token or your `bootstrapHeaders` and `bootstrapHeadersHelper` headers. Claude Desktop sends a credential only when the marketplace URL is on one of those two origins. When there is nothing to send yet (no sign-in held and no bootstrap headers configured, or a gateway API key sent as `x-api-key` rather than a bearer), no request is made and the entry reports why in the diagnostic report. |
276| `credentialKind` | How it authenticates |
277| - | - |
278| `"anonymous"` | No credential is sent. Use for public repositories or unauthenticated file hosts. |
279| `"userGit"` | Uses the git credential helpers already configured for the signed-in OS user (for example, `git-credential-manager`, macOS Keychain, or a GitHub CLI credential helper). Use when each user already has read access through their own account. For `url` sources, the same credential is sent as HTTP Basic on the manifest and archive requests. |
280| `"credentialHelper"` | Runs the executable at `credentialHelper`. If it prints a bare token, the token is used as the git password for username `x-access-token` (accepted by GitHub, GitLab, and Azure DevOps) and, for `url` sources, sent as `Authorization: Bearer <token>` on the manifest and archive requests. For hosts that need a particular username, print git-credential lines `username=<user>` and `password=<token>` instead (for example `x-token-auth` for Bitbucket Data Center access tokens, or `gitlab+deploy-token-N` for a GitLab deploy token); `url` sources then use HTTP Basic. Print `authtype=Bearer` and `credential=<token>` to force a bearer header. For `url` sources, the helper can instead print a flat JSON object of HTTP headers, such as `{"Authorization": "Bearer …", "X-Tenant": "acme"}` (the form a managed MCP server's `headersHelper` prints, not an inference credential helper's `{"token": …}` object), and Claude Desktop sends every header in it on each request to that marketplace. `github` and `git` sources refuse this form. Output that opens with `{` must be a valid header object, or the fetch is refused. Username forms require Claude Desktop 1.37937.0 or later. Otherwise follows the execution model of an [inference credential helper](/docs/third-party/claude-desktop/credential-helper). |
281| `"inferenceCredential"` | `url` sources only. Sends the credentials Claude Desktop already sends to your inference gateway or to your [bootstrap server](/docs/third-party/claude-desktop/bootstrap), so a marketplace hosted on either is private to signed-in members without a separate credential. On the gateway's origin it sends the same `Authorization` bearer as inference and works for [gateway single sign-on](/docs/third-party/claude-desktop/gateway#single-sign-on-with-your-identity-provider), a [credential helper](/docs/third-party/claude-desktop/credential-helper), and bearer-scheme API keys. On the bootstrap server's origin (Claude Desktop 1.37937.0 or later) it sends the bootstrap sign-in token or your `bootstrapHeaders` and `bootstrapHeadersHelper` headers. Claude Desktop sends a credential only when the marketplace URL is on one of those two origins. When there is nothing to send yet (no sign-in held and no bootstrap headers configured, or a gateway API key sent as `x-api-key` rather than a bearer), no request is made and the entry reports why in the diagnostic report. |
282282
283283Because the fetch happens on the host, the marketplace host does not need to be on the [`coworkEgressAllowedHosts`](/docs/third-party/claude-desktop/configuration#coworkegressallowedhosts) allowlist. It does need to be reachable from end-user devices.
284284
from line 296
296296
297297### Plugin directory location
298298
299| Platform | Path |
300| -------- | -------------------------------------------------- |
301| macOS | `/Library/Application Support/Claude/org-plugins/` |
302| Windows | `C:\Program Files\Claude\org-plugins\` |
299| Platform | Path |
300| - | - |
301| macOS | `/Library/Application Support/Claude/org-plugins/` |
302| Windows | `C:\Program Files\Claude\org-plugins\` |
303303
304304On Windows, the directory is under `Program Files` (not `ProgramData`) so that only administrators can create or modify it. Claude Desktop treats the presence of this directory as an admin-provisioned source.
305305
from line 323
323323 └── SKILL.md
324324```
325325
326| File | Purpose |
327| ---------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
328| `.claude-plugin/plugin.json` | Plugin manifest (name, description, version). Required unless a top-level `SKILL.md` serves as the manifest; see the note below this table. A directory with neither is ignored. |
329| `version.json` | `{"version": "1.2.3"}`. When this string changes, Claude Desktop re-syncs the plugin on next launch. Any string change triggers re-sync (there's no semver ordering, so a downgrade is just another version string). If absent, the directory's modification time is used instead. |
330| `.mcp.json` | MCP servers bundled with this plugin. A JSON object keyed by server name: `{"mcpServers": {"<name>": {"type": "http", "url": "...", "oauth": true}}}`. A remote entry uses `type` (`http` or `sse`), not `transport`, and supports `url`, `headers`, and `oauth` only. `toolPolicy`, `headersHelper`, and `headersHelperTtlSec` are not read from this file. A local entry gives a `command` with optional `args` and `env` (`type` is `"stdio"` or omitted). Give `command` as a program name on `PATH` or an absolute path, using `${CLAUDE_PLUGIN_ROOT}` for the plugin's directory under `org-plugins/`. Claude Desktop starts these local servers itself, including when [`isLocalDevMcpEnabled`](/docs/third-party/claude-desktop/configuration#islocaldevmcpenabled) is `false`. Local entries require Claude Desktop 1.49585.0 or later. A local entry that references `${user_config.<key>}` is skipped, because per-user plugin settings are not available to organization plugins. The diagnostic report's **MCP servers** section lists each server, with the reason for any it skipped. |
331| `agents/` | Sub-agent definitions. |
332| `commands/` | Slash-command definitions. |
333| `skills/` | [Skill](/docs/skills/overview) directories. |
334| `hooks/` | Hook definitions that run on agent lifecycle events. See [Plugin hooks](#plugin-hooks) for where they run. |
326| File | Purpose |
327| - | - |
328| `.claude-plugin/plugin.json` | Plugin manifest (name, description, version). Required unless a top-level `SKILL.md` serves as the manifest; see the note below this table. A directory with neither is ignored. |
329| `version.json` | `{"version": "1.2.3"}`. When this string changes, Claude Desktop re-syncs the plugin on next launch. Any string change triggers re-sync (there's no semver ordering, so a downgrade is just another version string). If absent, the directory's modification time is used instead. |
330| `.mcp.json` | MCP servers bundled with this plugin. A JSON object keyed by server name: `{"mcpServers": {"<name>": {"type": "http", "url": "...", "oauth": true}}}`. A remote entry uses `type` (`http` or `sse`), not `transport`, and supports `url`, `headers`, and `oauth` only. `toolPolicy`, `headersHelper`, and `headersHelperTtlSec` are not read from this file. A local entry gives a `command` with optional `args` and `env` (`type` is `"stdio"` or omitted). Give `command` as a program name on `PATH` or an absolute path, using `${CLAUDE_PLUGIN_ROOT}` for the plugin's directory under `org-plugins/`. Claude Desktop starts these local servers itself, including when [`isLocalDevMcpEnabled`](/docs/third-party/claude-desktop/configuration#islocaldevmcpenabled) is `false`. Local entries require Claude Desktop 1.49585.0 or later. A local entry that references `${user_config.<key>}` is skipped, because per-user plugin settings are not available to organization plugins. The diagnostic report's **MCP servers** section lists each server, with the reason for any it skipped. |
331| `agents/` | Sub-agent definitions. |
332| `commands/` | Slash-command definitions. |
333| `skills/` | [Skill](/docs/skills/overview) directories. |
334| `hooks/` | Hook definitions that run on agent lifecycle events. See [Plugin hooks](#plugin-hooks) for where they run. |
335335
336336<Note>
337337 Each entry in `org-plugins/` must carry a valid manifest: a `.claude-plugin/plugin.json`, or a top-level `SKILL.md` whose frontmatter declares `agents` or `mcpServers` (a skill folder that also acts as a plugin). A plain skill folder does not qualify on its own. To distribute a single skill, place it under `skills/<name>/SKILL.md` in a plugin that has a `plugin.json`. A directory with no valid manifest is not loaded and never appears in the user's plugin browser. The diagnostic report's plugin section shows the rejected entry and why. To distribute an MCP connector, declare it in a plugin's `.mcp.json` or use [`managedMcpServers`](#managed-mcp-servers-admin).
from line 360
360360}
361361```
362362
363| Value | Behavior |
364| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
365| `"required"` | Installs automatically the next time the app syncs organization plugins (at launch or when a session starts). The Uninstall action is hidden. If a user's installed copy is removed, it reinstalls on the next sync. |
366| `"auto_install"` | Installs automatically on the next sync. Users can uninstall it, and it stays uninstalled for that user. |
367| `"available"` (or omitted) | Default. Users install manually from the plugin browser. |
363| Value | Behavior |
364| - | - |
365| `"required"` | Installs automatically the next time the app syncs organization plugins (at launch or when a session starts). The Uninstall action is hidden. If a user's installed copy is removed, it reinstalls on the next sync. |
366| `"auto_install"` | Installs automatically on the next sync. Users can uninstall it, and it stays uninstalled for that user. |
367| `"available"` (or omitted) | Default. Users install manually from the plugin browser. |
368368
369369This mirrors the installation preference behavior of remote-managed plugins on claude.ai. Changing a plugin's `installationPreference` takes effect at each user's next sync.
370370
from line 404
404404
405405Admins can restrict or disable each user-extension surface independently via managed configuration:
406406
407| Key | Default | Effect when `false` |
408| ------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
409| `isLocalDevMcpEnabled` | `true` | Users cannot add their own local MCP servers from **Settings → Developer**. |
410| `isDesktopExtensionEnabled` | `false` | Desktop extensions (`.mcpb`) bundled in plugins are not loaded. Set to `true` to allow them. |
411| `isDesktopExtensionSignatureRequired` | `false` | (When `true`) Unsigned `.mcpb` extensions are rejected. |
412| `skillCreationEnabled` | `true` | Users cannot create or upload skills in the app. Claude does not offer to create or update skills in conversations. |
413| `userPluginMarketplacesEnabled` | `true` | Users cannot add plugin marketplaces of their own; the add-marketplace options are hidden. Marketplaces you provision with `allowedPluginMarketplaces` are unaffected. Requires Claude Desktop 1.37937.0 or later. |
414| `userPluginUploadsEnabled` | `true` | Users cannot upload plugin files or create plugins with Claude; every in-app option for adding a plugin of their own is hidden. Plugins from your marketplaces and the organization plugins directory are unaffected. Requires Claude Desktop 1.37937.0 or later. |
407| Key | Default | Effect when `false` |
408| - | - | - |
409| `isLocalDevMcpEnabled` | `true` | Users cannot add their own local MCP servers from **Settings → Developer**. |
410| `isDesktopExtensionEnabled` | `false` | Desktop extensions (`.mcpb`) bundled in plugins are not loaded. Set to `true` to allow them. |
411| `isDesktopExtensionSignatureRequired` | `false` | (When `true`) Unsigned `.mcpb` extensions are rejected. |
412| `skillCreationEnabled` | `true` | Users cannot create or upload skills in the app. Claude does not offer to create or update skills in conversations. |
413| `userPluginMarketplacesEnabled` | `true` | Users cannot add plugin marketplaces of their own; the add-marketplace options are hidden. Marketplaces you provision with `allowedPluginMarketplaces` are unaffected. Requires Claude Desktop 1.37937.0 or later. |
414| `userPluginUploadsEnabled` | `true` | Users cannot upload plugin files or create plugins with Claude; every in-app option for adding a plugin of their own is hidden. Plugins from your marketplaces and the organization plugins directory are unaffected. Requires Claude Desktop 1.37937.0 or later. |
415415
416416Setting `isLocalDevMcpEnabled` to `false` and leaving `isDesktopExtensionEnabled` at `false` restricts MCP servers and connectors to those delivered through `managedMcpServers` and `org-plugins/`, plus any that installed plugins bundle, whether from your marketplaces or added by users. To limit plugin-bundled servers to ones you name, or to none, set [`allowedPluginMcpServers`](/docs/third-party/claude-desktop/configuration#allowedpluginmcpservers) to a list of URL patterns. An empty list admits no plugin-bundled server. Setting [`skillCreationEnabled`](/docs/third-party/claude-desktop/configuration#skillcreationenabled) to `false` turns off skill creation and upload in the app. Skills already on the device keep working, as do skills from [organization plugins](#organization-plugins-admin). Users can still install plugins from the marketplaces you provision regardless of these settings. Setting `userPluginMarketplacesEnabled` and `userPluginUploadsEnabled` to `false` removes only the options for adding marketplaces and plugins of their own, and anything a user added earlier stays in place. See the [Locked down profile](/docs/third-party/claude-desktop/configuration#recommended-security-profiles) for a complete example.
417417
No line in this hunk matches that.