CDF Plugin Marketplace

A marketplace's marketplace.json, read from .claude-plugin/marketplace.json. Models every key the Claude Code plugin manifest and marketplace references, read 2026-10-05 document: owner, metadata, renames, forceRemoveDeletedPlugins, allowCrossMarketplaceDependenciesOn and the plugins[] entries with Claude Code's seven source forms, plus two CDF extensions the README names: a local source form for a marketplace that lists plugins already on disk, and an optional per-entry cdf block carrying a declared digest and the capabilities the entry expects. Every source form is DECLARED here, including the three the harness cannot yet fetch, because a marketplace that uses one must parse and be reported rather than fail to load. A listing is not an installation, and a declared digest is a claim to be checked, never a verdict.

Schema
plugin-marketplace.schema.json, served as JSON at its $id: https://cognitive-delivery.github.io/contract/1.x/plugin-marketplace.schema.json
Dialect
http://json-schema.org/draft-07/schema#
Root
object, open (additional properties are carried)
required: name, owner, plugins
Stability
none stated at the root; every declared property carries its own
Properties
186 declared: 10 under the root, 176 in definitions

Properties

Every declared property under the root, in the schema's own order. [] is an array's items, .* the shape of every unnamed member, #name a definition. Objects carry additional properties unless a row says otherwise.

PathTypeRequiredDescriptionConstraintsStability
$schemastringstable
namestringyesThe marketplace id: letters, digits, ., _ and -, starting with a letter or digit, no .., as Claude Code accepts. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^[A-Za-z0-9][A-Za-z0-9._-]*$stable
ownerobject #owneryesWho publishes the marketplace. Required: a marketplace with no owner is an anonymous list of things to execute.stable
descriptionstringstable
versionstringstable
metadataobject #metadataMarketplace-wide defaults.stable
allowCrossMarketplaceDependenciesOnarrayMarketplace names this one permits its plugins to depend on. Absent means none.stable
allowCrossMarketplaceDependenciesOn[]stringmin length 1
renamesobjectOld plugin name to new name, or to null when the plugin is withdrawn. A rename does not carry a decision forward: the subject hash changes and the plugin is undecided again.additional properties: see renames.*stable
renames.*string | null
pluginsarrayyesThe listed plugins. Required, and may be empty: an empty marketplace is a marketplace that lists nothing, not a malformed one.stable
plugins[]object #entryOne plugin listed by the marketplace. name and source are required: a listing that names nothing cannot be addressed, and one that resolves to nothing cannot be fetched. Every other key overrides or supplements what the fetched manifest says.
forceRemoveDeletedPluginsbooleanWhen true, a plugin removed from plugins is uninstalled on users' machines. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable

Definitions

The named shapes this schema refers to as #name. A row above that links here is not expanded in place; its constraints are the definition's.

#author

PathTypeRequiredDescriptionConstraintsStability
#authorstring | objectWho publishes the plugin. An object is the documented form; a bare string is accepted because marketplaces in the wild carry one, and a reader that refused it would refuse a real plugin.any of: (1) string, min length 1; (2) object, with name, email, url, requires name
#author.name
anyOf branch 2 of 2
stringyesmin length 1stable
#author.email
anyOf branch 2 of 2
stringstable
#author.url
anyOf branch 2 of 2
stringstable

#capabilities

PathTypeRequiredDescriptionConstraintsStability
#capabilitiesobjectWhat the plugin's own code asks to be allowed when the harness runs it out of process. This is the lease manifest's allow shape, property for property, because a plugin worker's lease is generated from it and narrowed against the workspace root policy. It is deliberately NOT the store-listing interface.capabilities vocabulary a plugin may also carry: that is a shelf label, this is an authorisation request. Every list is optional here — an absent list is a plugin that asks for nothing, which is the correct default — whereas the granted manifest requires all five.
#capabilities.toolsarrayGoverned tool names the agent may call.stable
#capabilities.tools[]stringA governed tool name the plugin asks to call. At most 128 characters of letters, digits, _, ., :, / and -, so a governed cdf_ name and a <server>/<tool> pair both fit. * is refused: a lease that names every tool has not named one, and SPEC §5.2 R2 exists because a grant must say what it opens. Whitespace is refused.pattern ^[A-Za-z0-9_][A-Za-z0-9_.:/-]{0,127}$
min length 1
#capabilities.read_pathsarrayWorkspace-relative POSIX globs the agent may read. Refused here, without lookahead so any RE2-based validator can load the rule: a leading /, any .. segment, a leading ~, a drive-letter prefix and any backslash. The registry re-checks the resolved path against the workspace root.stable
#capabilities.read_paths[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
#capabilities.write_pathsarrayWorkspace-relative POSIX globs the agent may change. Refused here, without lookahead: a leading /, any .. segment, a leading ~, a drive-letter prefix and any backslash. The registry re-checks the resolved path against the workspace root, and a change outside the granted set is a scope violation that revokes the lease.stable
#capabilities.write_paths[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
#capabilities.hostsarrayHostnames the agent may reach, with an optional leading wildcard label (*.example.com). Enforced by the egress proxy once it keys off the lease.stable
#capabilities.hosts[]stringA host the plugin asks to reach. A lower-case DNS name of one or more labels, an IPv4 literal or localhost (both are DNS-name shaped), with an optional single leading *. label, or the bare *. Refused by the pattern, which uses no lookahead or backreference and compiles under RE2: a scheme, a port, a path, whitespace, upper case, a trailing dot and a wildcard anywhere but the first label. A port is not a host: the egress proxy matches hostnames, and a rule nothing enforces is a claim. IP literals are admitted because a local model provider (Ollama, LM Studio) lives at 127.0.0.1 and the root policy derives its hosts from provider URLs.pattern ^(\*|(\*\.)?[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?(\.[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?)*)$
min length 1
max length 253
#capabilities.commandsarrayExecutable names the agent may run.stable
#capabilities.commands[]stringAn executable the plugin asks to run. The basename of the executable, at most 128 characters: letters, digits, ., _, +, -. No path separator (identity is the resolved executable's basename, not where it was found), no whitespace (an argument is not part of the name) and no shell operator.pattern ^[A-Za-z0-9][A-Za-z0-9._+-]{0,127}$
min length 1
#capabilities.tool_argsobjectDECLARED argument constraints per tool a plugin asks for, as in the lease manifest it becomes (schema set 1.2, development stability): tool name to a JSON Schema the agent proposes for its own calls to that tool, after Progent's argument-schema policies. A declaration, not a grant: in 1.x an issuer MAY omit it from the granted manifest and MUST NOT treat it as granted authority, because the reference gate does not yet evaluate argument schemas and a narrowing rule without an enforcing gate is a claim the corpus cannot test. The vector tool-args-dropped shows the reference dropping it. It becomes a rule when a gate enforces it.keys must match ^[A-Za-z0-9_][A-Za-z0-9_.:/-]{0,127}$
additional properties: see #capabilities.tool_args.*
development
a declaration an issuer MAY omit from the grant (SPEC 4.4); becomes a rule when a gate enforces it
#capabilities.tool_args.*objectA JSON Schema. Not validated as one here: draft-07 cannot validate a schema as data without a meta-schema $ref, which the self-contained rule forbids.

#componentPath

PathTypeRequiredDescriptionConstraintsStability
#componentPathstring | arrayA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.any of: (1) string, min length 1; (2) array, of string, min length 1
#componentPath[]
anyOf branch 2 of 2
stringmin length 1

#entry

PathTypeRequiredDescriptionConstraintsStability
#entryobjectOne plugin listed by the marketplace. name and source are required: a listing that names nothing cannot be addressed, and one that resolves to nothing cannot be fetched. Every other key overrides or supplements what the fetched manifest says.conditional requirements (below)
#entry.namestringyespattern ^[A-Za-z0-9][A-Za-z0-9._-]*$stable
#entry.sourcestring | object #sourceyesWhere a listed plugin comes from: a relative path inside the marketplace, or one of the seven object forms. The harness fetches local, github, url and git-subdir in v1; npm, archive and command parse and are reported as an unsupported source form, because a reader that threw on them would refuse a whole marketplace over one entry it could not fetch.stable
#entry.displayNamestringstable
#entry.descriptionstringstable
#entry.versionstringstable
#entry.authorstring | object #authorWho publishes the plugin. An object is the documented form; a bare string is accepted because marketplaces in the wild carry one, and a reader that refused it would refuse a real plugin.stable
#entry.homepagestringstable
#entry.repositorystring | object #repositoryThe source repository, as a URL string or as an object carrying one.stable
#entry.licensestringstable
#entry.keywordsarraystable
#entry.keywords[]stringmin length 1
#entry.categorystringstable
#entry.tagsarraystable
#entry.tags[]stringmin length 1
#entry.defaultEnabledbooleanstable
#entry.strictbooleanwhen headersHelper is presentWhether the entry must match the fetched manifest exactly. Absent means true: the stricter reading is the default, so a marketplace relaxes it deliberately.stable
#entry.skillsstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.commandsstring | array | object #commandsFlat .md command files, directories of them, or an object map of command name to source or content. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.agentsstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.hooksobject | string | array #hooksSourceHooks declared inline as the event map, as a path to a .json file that declares them (wrapped in a top-level hooks key), or as an array mixing both. Claude Code accepts all three.stable
#entry.mcpServersobject | string | array #mcpServersSourceMCP servers declared inline keyed by name, as a path to a .json config, an .mcpb or .dxt bundle path, an https:// bundle URL, or an array mixing these. Claude Code accepts all of them.stable
#entry.lspServersstring | object | array #lspServers.json LSP config files, an inline map of server name to config, or an array of either. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.headersobjectRequest headers for an archive or url source. Never credentials: a value that needs a secret belongs in headersHelper, which the host runs and whose output the marketplace file never sees.keys must not match ^[Aa][Uu][Tt][Hh][Oo][Rr][Ii][Zz][Aa][Tt][Ii][Oo][Nn]$
An authorization header, in any case, is refused: its value would be a credential in a file everyone reads. headersHelper is the route.
additional properties: see #entry.headers.*
stable
#entry.headers.*string #credentialFreeA string that is not a credential. Refuses the seven shapes the reference evidence sanitiser refuses (a private key block, an AWS access key id, a GitHub token, an OpenAI key, a Slack token, a literal bearer token and a JWT), each a pattern without lookahead or word boundaries, which RE2 compiles. A detector, not a guarantee: it catches these shapes and nothing else, and the documented route for a secret remains the host's own environment ($VAR interpolation) or headersHelper.
#entry.headersHelperstringA path or command that produces this entry's archive-download headers at fetch time. Claude Code requires the entry to set "strict": false, and the schema enforces that with if/then. Claude Code plugin manifest and marketplace references, read 2026-10-05.min length 1stable
#entry.relevanceobject #relevanceSignals that tell Claude Code when to suggest the plugin: topic and signals. Carried, not interpreted. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.dependenciesarray #dependenciesPlugins that must be enabled for this one to work. Each entry is "name", "name@marketplace", or an object with name, marketplace and version. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.metadataobjectFree-form publisher metadata on the entry. Carried, never interpreted.stable
#entry.settingsobjectstable
#entry.userConfigobject #userConfigValues Claude Code prompts the user for when the plugin is enabled. Keys are identifiers of letters, digits and underscores not starting with a digit. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.channelsarraystable
#entry.channels[]object #channelA message channel bound to one of the plugin's MCP servers. A STRICT object in Claude Code. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#entry.outputStylesstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.workflowsstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.themesstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.experimentalobject #experimentalContainer for themes, monitors and evals, whose manifest shape Claude Code says may still change. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#entry.typesstringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
stable
#entry.cdfobject #entryCdfThe additive CDF block for one entry. Absent in a plain Claude Code marketplace.stable
#entry.strict
then: when headersHelper is present
anywhen headersHelper is presentconst falsestable

#entryCdf

PathTypeRequiredDescriptionConstraintsStability
#entryCdfobjectThe additive CDF block for one entry. Absent in a plain Claude Code marketplace.
#entryCdf.digeststringThe sha256 the fetched tree must hash to, lower-case hex. A claim the loader checks; a mismatch is a refusal with both digests named, never a warning.pattern ^[0-9a-f]{64}$stable
#entryCdf.capabilitiesobject #capabilitiesWhat the plugin's own code asks to be allowed when the harness runs it out of process. This is the lease manifest's allow shape, property for property, because a plugin worker's lease is generated from it and narrowed against the workspace root policy. It is deliberately NOT the store-listing interface.capabilities vocabulary a plugin may also carry: that is a shelf label, this is an authorisation request. Every list is optional here — an absent list is a plugin that asks for nothing, which is the correct default — whereas the granted manifest requires all five.stable

#metadata

PathTypeRequiredDescriptionConstraintsStability
#metadataobjectMarketplace-wide defaults.
#metadata.pluginRootstringThe directory relative paths in source resolve from.stable
#metadata.descriptionstringstable
#metadata.versionstringstable

#owner

PathTypeRequiredDescriptionConstraintsStability
#ownerobjectWho publishes the marketplace. Required: a marketplace with no owner is an anonymous list of things to execute.
#owner.namestringyesmin length 1stable
#owner.emailstringstable
#owner.urlstringstable

#repository

PathTypeRequiredDescriptionConstraintsStability
#repositorystring | objectThe source repository, as a URL string or as an object carrying one.any of: (1) string, min length 1; (2) object

#source

PathTypeRequiredDescriptionConstraintsStability
#sourcestring | objectWhere a listed plugin comes from: a relative path inside the marketplace, or one of the seven object forms. The harness fetches local, github, url and git-subdir in v1; npm, archive and command parse and are reported as an unsupported source form, because a reader that threw on them would refuse a whole marketplace over one entry it could not fetch.any of: (1) string, min length 1; (2) #sourceLocal; (3) #sourceGithub; (4) #sourceUrl; (5) #sourceGitSubdir; (6) #sourceNpm; (7) #sourceArchive; (8) #sourceCommand

#sourceArchive

PathTypeRequiredDescriptionConstraintsStability
#sourceArchiveobjectA downloadable archive. Declared, not fetched in v1: no archive reader exists, and hand-rolling one is where path traversal, absolute entries, symlinks and zip-slip get written wrong.
#sourceArchive.sourcestringyesone of "archive"stable
#sourceArchive.urlstringyesmin length 1stable
#sourceArchive.sha256stringThe archive digest as 64 hex characters, upper or lower case as Claude Code accepts. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^[0-9a-fA-F]{64}$stable

#sourceCommand

PathTypeRequiredDescriptionConstraintsStability
#sourceCommandobjectA command the host runs to produce the plugin. Declared, not fetched in v1: the harness does not run a marketplace-supplied command to obtain code it is about to run.
#sourceCommand.sourcestringyesone of "command"stable
#sourceCommand.commandstringyesmin length 1stable
#sourceCommand.timeoutintegerSeconds, 1 to 600; Claude Code defaults to 60. Claude Code plugin manifest and marketplace references, read 2026-10-05.min 1
max 600
stable
#sourceCommand.modestringcopy (default) copies the printed directory; link loads it in place. Claude Code plugin manifest and marketplace references, read 2026-10-05.one of "copy", "link"stable

#sourceGitSubdir

PathTypeRequiredDescriptionConstraintsStability
#sourceGitSubdirobjectOne directory of a git repository. path is repository-relative and may not escape it.
#sourceGitSubdir.sourcestringyesone of "git-subdir"stable
#sourceGitSubdir.urlstringyesmin length 1stable
#sourceGitSubdir.pathstringyesmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
stable
#sourceGitSubdir.refstringA branch, tag or other revision. A branch is not a pin.min length 1stable
#sourceGitSubdir.shastringA commit sha. The only ref that cannot move.pattern ^[0-9a-f]{7,40}$stable

#sourceGithub

PathTypeRequiredDescriptionConstraintsStability
#sourceGithubobjectA GitHub repository.
#sourceGithub.sourcestringyesone of "github"stable
#sourceGithub.repostringyesowner/repo.pattern ^[^/\s]+/[^/\s]+$stable
#sourceGithub.refstringA branch, tag or other revision. A branch is not a pin.min length 1stable
#sourceGithub.shastringA commit sha. The only ref that cannot move.pattern ^[0-9a-f]{7,40}$stable

#sourceLocal

PathTypeRequiredDescriptionConstraintsStability
#sourceLocalobjectA path already on disk. A CDF extension, not a Claude Code source form: Claude Code's only local form is the relative-path string. CDF's own marketplace lists first-party plugins that ship in the repository, and a local source is the one with nothing to fetch and nothing to pin. The README names it as such.
#sourceLocal.sourcestringyesone of "local"stable
#sourceLocal.pathstringyesmin length 1stable

#sourceNpm

PathTypeRequiredDescriptionConstraintsStability
#sourceNpmobjectAn npm package. Declared, not fetched in v1: the same missing archive reader, plus a registry the egress policy would have to permit.
#sourceNpm.sourcestringyesone of "npm"stable
#sourceNpm.packagestringyesmin length 1stable
#sourceNpm.versionstringstable
#sourceNpm.registrystringstable

#sourceUrl

PathTypeRequiredDescriptionConstraintsStability
#sourceUrlobjectA git repository at an arbitrary URL.
#sourceUrl.sourcestringyesone of "url"stable
#sourceUrl.urlstringyesmin length 1stable
#sourceUrl.refstringA branch, tag or other revision. A branch is not a pin.min length 1stable
#sourceUrl.shastringA commit sha. The only ref that cannot move.pattern ^[0-9a-f]{7,40}$stable

#dependencies

PathTypeRequiredDescriptionConstraintsStability
#dependenciesarrayPlugins that must be enabled for this one to work. Each entry is "name", "name@marketplace", or an object with name, marketplace and version. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#dependencies[]string | objectany of: (1) string, min length 1; (2) object, with name, marketplace, version, requires name
#dependencies[].name
anyOf branch 2 of 2
stringyesmin length 1stable
#dependencies[].marketplace
anyOf branch 2 of 2
stringstable
#dependencies[].version
anyOf branch 2 of 2
stringstable

#userConfigOption

PathTypeRequiredDescriptionConstraintsStability
#userConfigOptionobjectOne user-configuration option. A STRICT object in Claude Code: an unknown key stops the plugin loading, so the contract refuses it too, which is the one place the contract closes a content model to mean what Claude Code means. Claude Code plugin manifest and marketplace references, read 2026-10-05.no additional properties
#userConfigOption.typestringyesone of "string", "number", "boolean", "directory", "file"stable
#userConfigOption.titlestringyesmin length 1stable
#userConfigOption.descriptionstringyesstable
#userConfigOption.requiredbooleanstable
#userConfigOption.defaultstring | number | boolean | arrayany of: (1) string; (2) number; (3) boolean; (4) array, of stringstable
#userConfigOption.default[]
anyOf branch 4 of 4
string
#userConfigOption.optionsarraystable
#userConfigOption.options[]stringmin length 1
max length 64
#userConfigOption.multiplebooleanstable
#userConfigOption.sensitivebooleanstable
#userConfigOption.minnumberstable
#userConfigOption.maxnumberstable

#userConfig

PathTypeRequiredDescriptionConstraintsStability
#userConfigobjectValues Claude Code prompts the user for when the plugin is enabled. Keys are identifiers of letters, digits and underscores not starting with a digit. Claude Code plugin manifest and marketplace references, read 2026-10-05.keys must match ^[A-Za-z_][A-Za-z0-9_]*$
additional properties: see #userConfig.*
#userConfig.*object #userConfigOptionOne user-configuration option. A STRICT object in Claude Code: an unknown key stops the plugin loading, so the contract refuses it too, which is the one place the contract closes a content model to mean what Claude Code means. Claude Code plugin manifest and marketplace references, read 2026-10-05.

#channel

PathTypeRequiredDescriptionConstraintsStability
#channelobjectA message channel bound to one of the plugin's MCP servers. A STRICT object in Claude Code. Claude Code plugin manifest and marketplace references, read 2026-10-05.no additional properties
#channel.serverstringyesmin length 1stable
#channel.displayNamestringstable
#channel.userConfigobject #userConfigValues Claude Code prompts the user for when the plugin is enabled. Keys are identifiers of letters, digits and underscores not starting with a digit. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable

#lspServer

PathTypeRequiredDescriptionConstraintsStability
#lspServerobjectOne language server. A STRICT object in Claude Code: command and extensionToLanguage are required and an unknown key fails validation. Claude Code plugin manifest and marketplace references, read 2026-10-05.no additional properties
#lspServer.commandstringyesmin length 1stable
#lspServer.extensionToLanguageobjectyesmin properties 1
keys must match ^\.
additional properties: see #lspServer.extensionToLanguage.*
stable
#lspServer.extensionToLanguage.*stringmin length 1
#lspServer.argsarraystable
#lspServer.args[]string
#lspServer.transportstringone of "stdio", "socket"stable
#lspServer.envobjectadditional properties: see #lspServer.env.*stable
#lspServer.env.*string
#lspServer.initializationOptionsobjectstable
#lspServer.settingsobjectstable
#lspServer.workspaceFolderstringstable
#lspServer.startupTimeoutintegermin 1
max 9007199254740991
stable
#lspServer.shutdownTimeoutintegermin 1
max 9007199254740991
stable
#lspServer.requestTimeoutintegermin 1
max 9007199254740991
stable
#lspServer.restartOnCrashbooleanstable
#lspServer.maxRestartsintegermin 0
max 9007199254740991
stable
#lspServer.diagnosticsbooleanstable

#lspServers

PathTypeRequiredDescriptionConstraintsStability
#lspServersstring | object | array.json LSP config files, an inline map of server name to config, or an array of either. Claude Code plugin manifest and marketplace references, read 2026-10-05.any of: (1) string, min length 1; (2) object, additional properties #lspServer; (3) array, of string | object, any of 2 branches
#lspServers.*
anyOf branch 2 of 3
object #lspServerOne language server. A STRICT object in Claude Code: command and extensionToLanguage are required and an unknown key fails validation. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#lspServers[]
anyOf branch 3 of 3
string | objectany of: (1) string, min length 1; (2) object, additional properties #lspServer
#lspServers[].*
anyOf branch 3 of 3; anyOf branch 2 of 2
object #lspServerOne language server. A STRICT object in Claude Code: command and extensionToLanguage are required and an unknown key fails validation. Claude Code plugin manifest and marketplace references, read 2026-10-05.

#commandEntry

PathTypeRequiredDescriptionConstraintsStability
#commandEntryobjectOne command in the commands object map. Exactly one of source (a path) or content (inline Markdown) is set. Claude Code plugin manifest and marketplace references, read 2026-10-05.exactly one of: (1) requires source; (2) requires content
#commandEntry.sourcestringmin length 1stable
#commandEntry.contentstringstable
#commandEntry.descriptionstringstable
#commandEntry.argumentHintstringstable
#commandEntry.modelstringstable
#commandEntry.allowedToolsarraystable
#commandEntry.allowedTools[]stringmin length 1

#commands

PathTypeRequiredDescriptionConstraintsStability
#commandsstring | array | objectFlat .md command files, directories of them, or an object map of command name to source or content. Claude Code plugin manifest and marketplace references, read 2026-10-05.any of: (1) string, min length 1; (2) array, of string, min length 1; (3) object, additional properties #commandEntry
#commands[]
anyOf branch 2 of 3
stringmin length 1
#commands.*
anyOf branch 3 of 3
object #commandEntryOne command in the commands object map. Exactly one of source (a path) or content (inline Markdown) is set. Claude Code plugin manifest and marketplace references, read 2026-10-05.

#monitor

PathTypeRequiredDescriptionConstraintsStability
#monitorobjectOne background monitor. A STRICT object in Claude Code. Claude Code plugin manifest and marketplace references, read 2026-10-05.no additional properties
#monitor.namestringyesmin length 1stable
#monitor.commandstringyesmin length 1stable
#monitor.descriptionstringyesmin length 1stable
#monitor.whenstringstable

#experimental

PathTypeRequiredDescriptionConstraintsStability
#experimentalobjectContainer for themes, monitors and evals, whose manifest shape Claude Code says may still change. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#experimental.themesstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
#experimental.monitorsstring | arrayany of: (1) string, min length 1; (2) array, of #monitorstable
#experimental.monitors[]
anyOf branch 2 of 2
object #monitorOne background monitor. A STRICT object in Claude Code. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#experimental.evalsstring | array #componentPathA component directory or file, or a list of them. Claude Code accepts a single string or an array of strings for skills, commands, agents, outputStyles, workflows and experimental.themes, and scans the default folder when the key is absent, so an absent key is not an empty contribution. Every path starts with ./ (skills also accepts "."). Claude Code plugin manifest and marketplace references, read 2026-10-05.stable

#relevance

PathTypeRequiredDescriptionConstraintsStability
#relevanceobjectSignals that tell Claude Code when to suggest the plugin: topic and signals. Carried, not interpreted. Claude Code plugin manifest and marketplace references, read 2026-10-05.
#relevance.topicstringstable
#relevance.signalsanyRelevance signals as the marketplace reference leaves them: any value, not modelled.stable

#credentialFree

PathTypeRequiredDescriptionConstraintsStability
#credentialFreestringA string that is not a credential. Refuses the seven shapes the reference evidence sanitiser refuses (a private key block, an AWS access key id, a GitHub token, an OpenAI key, a Slack token, a literal bearer token and a JWT), each a pattern without lookahead or word boundaries, which RE2 compiles. A detector, not a guarantee: it catches these shapes and nothing else, and the documented route for a secret remains the host's own environment ($VAR interpolation) or headersHelper.must not match -----BEGIN [A-Z0-9 ]*PRIVATE KEY-----, (^|[^A-Za-z0-9])AKIA[0-9A-Z]{16}([^A-Za-z0-9]|$), (^|[^A-Za-z0-9])gh[pousr]_[A-Za-z0-9]{36,}, (^|[^A-Za-z0-9])sk-[A-Za-z0-9_-]{20,}, (^|[^A-Za-z0-9])xox[baprs]-[A-Za-z0-9-]{10,}, Bearer +[A-Za-z0-9._~+/-]{16,}, eyJ[A-Za-z0-9_-]{8,}\.eyJ[A-Za-z0-9_-]{8,}\.[A-Za-z0-9_-]{8,}

#hookHandler

PathTypeRequiredDescriptionConstraintsStability
#hookHandlerobjectOne hook, discriminated by type, after the Claude Code settings schema on SchemaStore (read 2026-10-05). The five types are closed because a handler of unknown type is one the harness cannot vet; each type's own fields stay open because Claude Code adds fields between releases and a plugin that uses one must not stop validating here.any of: (1) object, with type = "command", command, args, async, asyncRewake, shell one of "bash", "powershell", timeout, if, statusMessage, once, requires type, command, Runs a command.; (2) object, with type = "prompt", prompt, model, continueOnBlock, timeout, if, statusMessage, once, requires type, prompt, Asks the model a single-turn question.; (3) object, with type = "agent", prompt, model, timeout, if, statusMessage, once, requires type, prompt, Runs a subagent with tools.; (4) object, with type = "http", url, headers, allowedEnvVars, timeout, if, statusMessage, once, requires type, url, POSTs the hook input to a URL.; (5) object, with type = "mcp_tool", server, tool, input, timeout, if, statusMessage, once, requires type, server, tool, Calls a tool on a connected MCP server.
#hookHandler.type
anyOf branch 1 of 5: Runs a command.
stringyesone of "command"stable
#hookHandler.command
anyOf branch 1 of 5: Runs a command.
stringyesA shell command, or with args an executable run without a shell.min length 1stable
#hookHandler.args
anyOf branch 1 of 5: Runs a command.
arraystable
#hookHandler.args[]
anyOf branch 1 of 5: Runs a command.
string
#hookHandler.async
anyOf branch 1 of 5: Runs a command.
booleanstable
#hookHandler.asyncRewake
anyOf branch 1 of 5: Runs a command.
booleanstable
#hookHandler.shell
anyOf branch 1 of 5: Runs a command.
stringone of "bash", "powershell"stable
#hookHandler.timeout
anyOf branch 1 of 5: Runs a command.
numberSeconds.greater than 0stable
#hookHandler.if
anyOf branch 1 of 5: Runs a command.
stringA permission-rule filter; the hook runs only when it matches.stable
#hookHandler.statusMessage
anyOf branch 1 of 5: Runs a command.
stringstable
#hookHandler.once
anyOf branch 1 of 5: Runs a command.
booleanstable
#hookHandler.type
anyOf branch 2 of 5: Asks the model a single-turn question.
stringyesone of "prompt"stable
#hookHandler.prompt
anyOf branch 2 of 5: Asks the model a single-turn question.
stringyesmin length 1stable
#hookHandler.model
anyOf branch 2 of 5: Asks the model a single-turn question.
stringstable
#hookHandler.continueOnBlock
anyOf branch 2 of 5: Asks the model a single-turn question.
booleanstable
#hookHandler.timeout
anyOf branch 2 of 5: Asks the model a single-turn question.
numberSeconds.greater than 0stable
#hookHandler.if
anyOf branch 2 of 5: Asks the model a single-turn question.
stringA permission-rule filter; the hook runs only when it matches.stable
#hookHandler.statusMessage
anyOf branch 2 of 5: Asks the model a single-turn question.
stringstable
#hookHandler.once
anyOf branch 2 of 5: Asks the model a single-turn question.
booleanstable
#hookHandler.type
anyOf branch 3 of 5: Runs a subagent with tools.
stringyesone of "agent"stable
#hookHandler.prompt
anyOf branch 3 of 5: Runs a subagent with tools.
stringyesmin length 1stable
#hookHandler.model
anyOf branch 3 of 5: Runs a subagent with tools.
stringstable
#hookHandler.timeout
anyOf branch 3 of 5: Runs a subagent with tools.
numberSeconds.greater than 0stable
#hookHandler.if
anyOf branch 3 of 5: Runs a subagent with tools.
stringA permission-rule filter; the hook runs only when it matches.stable
#hookHandler.statusMessage
anyOf branch 3 of 5: Runs a subagent with tools.
stringstable
#hookHandler.once
anyOf branch 3 of 5: Runs a subagent with tools.
booleanstable
#hookHandler.type
anyOf branch 4 of 5: POSTs the hook input to a URL.
stringyesone of "http"stable
#hookHandler.url
anyOf branch 4 of 5: POSTs the hook input to a URL.
stringyesWhere the hook input is POSTed.min length 1stable
#hookHandler.headers
anyOf branch 4 of 5: POSTs the hook input to a URL.
objectRequest headers. Values may interpolate $VAR from allowedEnvVars; a literal credential is refused.additional properties: see #hookHandler.headers.*stable
#hookHandler.headers.*
anyOf branch 4 of 5: POSTs the hook input to a URL.
string #credentialFreeA string that is not a credential. Refuses the seven shapes the reference evidence sanitiser refuses (a private key block, an AWS access key id, a GitHub token, an OpenAI key, a Slack token, a literal bearer token and a JWT), each a pattern without lookahead or word boundaries, which RE2 compiles. A detector, not a guarantee: it catches these shapes and nothing else, and the documented route for a secret remains the host's own environment ($VAR interpolation) or headersHelper.
#hookHandler.allowedEnvVars
anyOf branch 4 of 5: POSTs the hook input to a URL.
arraystable
#hookHandler.allowedEnvVars[]
anyOf branch 4 of 5: POSTs the hook input to a URL.
string
#hookHandler.timeout
anyOf branch 4 of 5: POSTs the hook input to a URL.
numberSeconds.greater than 0stable
#hookHandler.if
anyOf branch 4 of 5: POSTs the hook input to a URL.
stringA permission-rule filter; the hook runs only when it matches.stable
#hookHandler.statusMessage
anyOf branch 4 of 5: POSTs the hook input to a URL.
stringstable
#hookHandler.once
anyOf branch 4 of 5: POSTs the hook input to a URL.
booleanstable
#hookHandler.type
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
stringyesone of "mcp_tool"stable
#hookHandler.server
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
stringyesA configured MCP server.min length 1stable
#hookHandler.tool
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
stringyesmin length 1stable
#hookHandler.input
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
objectstable
#hookHandler.timeout
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
numberSeconds.greater than 0stable
#hookHandler.if
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
stringA permission-rule filter; the hook runs only when it matches.stable
#hookHandler.statusMessage
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
stringstable
#hookHandler.once
anyOf branch 5 of 5: Calls a tool on a connected MCP server.
booleanstable

#hookMatcher

PathTypeRequiredDescriptionConstraintsStability
#hookMatcherobject
#hookMatcher.matcherstringA pattern matched against the event context; absent means every occurrence.stable
#hookMatcher.hooksarrayyesstable
#hookMatcher.hooks[]object #hookHandlerOne hook, discriminated by type, after the Claude Code settings schema on SchemaStore (read 2026-10-05). The five types are closed because a handler of unknown type is one the harness cannot vet; each type's own fields stay open because Claude Code adds fields between releases and a plugin that uses one must not stop validating here.

#hooksMap

PathTypeRequiredDescriptionConstraintsStability
#hooksMapobjectThe event map: event name to matchers. The event names are the thirty-three the Claude Code hooks reference lists (read 2026-10-05); an unknown event is refused because nothing would ever fire it.keys one of 33 values
all 33"PreToolUse", "PostToolUse", "PostToolUseFailure", "PermissionRequest", "Notification", "UserPromptSubmit", "Stop", "StopFailure", "SubagentStart", "SubagentStop", "PreCompact", "PostCompact", "Elicitation", "ElicitationResult", "TeammateIdle", "TaskCompleted", "Setup", "InstructionsLoaded", "CwdChanged", "FileChanged", "ConfigChange", "WorktreeCreate", "WorktreeRemove", "SessionStart", "SessionEnd", "PostToolBatch", "TaskCreated", "PermissionDenied", "UserPromptExpansion", "MessageDisplay", "DirectoryAdded", "PreModelSwitch", "PostModelSwitch"

additional properties: see #hooksMap.*
#hooksMap.*array
#hooksMap.*[]object #hookMatcher

#hooksSource

PathTypeRequiredDescriptionConstraintsStability
#hooksSourceobject | string | arrayHooks declared inline as the event map, as a path to a .json file that declares them (wrapped in a top-level hooks key), or as an array mixing both. Claude Code accepts all three.any of: (1) #hooksMap; (2) string, min length 1; (3) array, of object | string, any of 2 branches
#hooksSource[]
anyOf branch 3 of 3
object | stringany of: (1) #hooksMap; (2) string, min length 1

#mcpServer

PathTypeRequiredDescriptionConstraintsStability
#mcpServerobjectOne MCP server config, keyed by name in mcpServers, after the Claude Code .mcp.json reference (read 2026-10-05). stdio needs command; http, sse, ws and streamable-http need url; an entry with no type is left as the reference leaves it. env and headers values are credential-free: a literal secret in a plugin manifest ships to everyone who installs it, and ${VAR} interpolation or headersHelper is the route.conditional requirements (below)
#mcpServer.typestringone of "stdio", "http", "sse", "ws", "streamable-http"stable
#mcpServer.commandstringwhen type is "stdio"min length 1stable
#mcpServer.argsarraystable
#mcpServer.args[]string
#mcpServer.envobjectadditional properties: see #mcpServer.env.*stable
#mcpServer.env.*string #credentialFreeA string that is not a credential. Refuses the seven shapes the reference evidence sanitiser refuses (a private key block, an AWS access key id, a GitHub token, an OpenAI key, a Slack token, a literal bearer token and a JWT), each a pattern without lookahead or word boundaries, which RE2 compiles. A detector, not a guarantee: it catches these shapes and nothing else, and the documented route for a secret remains the host's own environment ($VAR interpolation) or headersHelper.
#mcpServer.urlstringwhen type is "http", "sse", "ws" or "streamable-http"min length 1stable
#mcpServer.headersobjectadditional properties: see #mcpServer.headers.*stable
#mcpServer.headers.*string #credentialFreeA string that is not a credential. Refuses the seven shapes the reference evidence sanitiser refuses (a private key block, an AWS access key id, a GitHub token, an OpenAI key, a Slack token, a literal bearer token and a JWT), each a pattern without lookahead or word boundaries, which RE2 compiles. A detector, not a guarantee: it catches these shapes and nothing else, and the documented route for a secret remains the host's own environment ($VAR interpolation) or headersHelper.
#mcpServer.headersHelperstringstable
#mcpServer.timeoutintegermin 0
max 9007199254740991
stable
#mcpServer.alwaysLoadbooleanstable
#mcpServer.oauthobjectstable

#mcpServersMap

PathTypeRequiredDescriptionConstraintsStability
#mcpServersMapobjectServer name to config.additional properties: see #mcpServersMap.*
#mcpServersMap.*object #mcpServerOne MCP server config, keyed by name in mcpServers, after the Claude Code .mcp.json reference (read 2026-10-05). stdio needs command; http, sse, ws and streamable-http need url; an entry with no type is left as the reference leaves it. env and headers values are credential-free: a literal secret in a plugin manifest ships to everyone who installs it, and ${VAR} interpolation or headersHelper is the route.

#mcpServersSource

PathTypeRequiredDescriptionConstraintsStability
#mcpServersSourceobject | string | arrayMCP servers declared inline keyed by name, as a path to a .json config, an .mcpb or .dxt bundle path, an https:// bundle URL, or an array mixing these. Claude Code accepts all of them.any of: (1) #mcpServersMap; (2) string, min length 1; (3) array, of object | string, any of 2 branches
#mcpServersSource[]
anyOf branch 3 of 3
object | stringany of: (1) #mcpServersMap; (2) string, min length 1

Conditional requirements

What an if/then clause makes required, one line per property and condition value; the same text appears in the Required column above.

PropertyRequiredWhere
strictwhen headersHelper is present#entry
strictwhen headersHelper is present, must be const false#entry
commandwhen type is "stdio"#mcpServer
urlwhen type is "http"#mcpServer
urlwhen type is "sse"#mcpServer
urlwhen type is "ws"#mcpServer
urlwhen type is "streamable-http"#mcpServer