CDF Plugin Manifest

A plugin's plugin.json, read from .claude-plugin/plugin.json. Models every key the Claude Code plugin manifest and marketplace references, read 2026-10-05 document, with the same meaning, so a Claude Code plugin validates here; unknown top-level keys pass through, as Claude Code strips them with a warning. Two keys are CDF's own: the optional cdf block, which declares what the harness alone understands, and plugin-level category, which Claude Code documents only on a marketplace entry — what the plugin contributes, what its own code asks to be allowed, and who vouches for the declaration. name is the only required key, which is Claude Code's rule and not a relaxation of ours: a manifest that named nothing could not be addressed, and everything else has a defensible default. A declaration is not an installation: reading this file tells the loader what a plugin says about itself, never that it may run.

Schema
plugin-manifest.schema.json, served as JSON at its $id: https://cognitive-delivery.github.io/contract/1.x/plugin-manifest.schema.json
Dialect
http://json-schema.org/draft-07/schema#
Root
object, open (additional properties are carried)
required: name
Stability
none stated at the root; every declared property carries its own
Properties
168 declared: 34 under the root, 134 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
namestringyesThe plugin id: letters, digits, ., _ and -, starting with a letter or digit, as Claude Code accepts (it recommends kebab-case and warns otherwise). The only required key, and the one a decision record is keyed to. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^[A-Za-z0-9][A-Za-z0-9._-]*$stable
descriptionstringstable
versionstringThe plugin's own version. An open string: a plugin is free to version itself however it likes, and a marketplace may pin a different one.stable
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
displayNamestringA human label for a listing. name remains the identity.stable
homepagestringstable
repositorystring | object #repositoryThe source repository, as a URL string or as an object carrying one.stable
licensestringstable
keywordsarraystable
keywords[]stringmin length 1
categorystringFree-form category. A CDF extension on the manifest: Claude Code documents category on a marketplace entry only, and strips it from plugin.json with a warning. Kept because CDF's decision records key on it; the README names it as not a Claude Code key. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
metadataobjectFree-form publisher metadata. Carried, never interpreted.stable
defaultEnabledbooleanWhether a host that installs this plugin enables it by default. A hint to the host, never an approval: presence is not approval, and neither is this.stable
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
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
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
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
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
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
$schemastringJSON Schema URL for editor autocomplete. Ignored at load time.stable
iconstringPath of an image inside the plugin for its listing in Anthropic's directory. Claude Code plugin manifest and marketplace references, read 2026-10-05.min length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
stable
documentationUrlstringRead by Anthropic's directory from plugin.json only; Claude Code ignores it at load time and warns when it appears in a marketplace entry. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^https://stable
supportUrlstringRead by Anthropic's directory from plugin.json only; Claude Code ignores it at load time and warns when it appears in a marketplace entry. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^https://stable
privacyPolicyUrlstringRead by Anthropic's directory from plugin.json only; Claude Code ignores it at load time and warns when it appears in a marketplace entry. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^https://stable
termsOfServiceUrlstringRead by Anthropic's directory from plugin.json only; Claude Code ignores it at load time and warns when it appears in a marketplace entry. Claude Code plugin manifest and marketplace references, read 2026-10-05.pattern ^https://stable
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
settingsobjectSettings applied while the plugin is enabled; Claude Code honours agent and subagentStatusLine and drops the rest. Claude Code plugin manifest and marketplace references, read 2026-10-05.stable
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
typesstringA .d.ts file declaring a mod's $.state values and $ nouns. Claude Code plugin manifest and marketplace references, read 2026-10-05.min length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
stable
channelsarraystable
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.
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
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
themesstring | arrayTheme files or directories at the top level. Claude Code still loads this key but warns; experimental.themes is the documented place. Claude Code plugin manifest and marketplace references, read 2026-10-05.any of: (1) string, min length 1; (2) array, of string, min length 1stable
themes[]
anyOf branch 2 of 2
stringmin length 1
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
cdfobject #cdfThe additive CDF block. Absent in a plain Claude Code plugin, and its absence is not a defect: such a plugin contributes its skills, commands, agents, hooks and MCP servers and declares nothing further.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.

#attestation

PathTypeRequiredDescriptionConstraintsStability
#attestationobjectWho vouches for the declaration. Optional: a plugin published without a key has nothing to sign with, and the harness records that honestly rather than claiming a signature it does not have. The issuer vocabulary is the lease manifest's, so one reader understands both.
#attestation.issuerstringyesWhich party produced the declaration.one of "agent", "bridge", "harness", "plugin"stable
#attestation.signaturestringLower-case hex signature over the canonical bytes of the manifest, when the issuer can sign.pattern ^[0-9a-f]+$stable
#attestation.key_fingerprintstringFingerprint of the key that produced signature. Never the key.min length 1stable

#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.

#cdf

PathTypeRequiredDescriptionConstraintsStability
#cdfobjectThe additive CDF block. Absent in a plain Claude Code plugin, and its absence is not a defect: such a plugin contributes its skills, commands, agents, hooks and MCP servers and declares nothing further.
#cdf.schemaVersionstringyesContract version this block was written against.one of "1.0"stable
#cdf.contributesobject #contributesWhat the plugin adds to the harness as DATA the kernel reads. Every list is optional. Nothing here is code the kernel executes: a contributed check names a worker the harness spawns, and a contributed provider names a host the egress policy must already permit.stable
#cdf.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
#cdf.attestationobject #attestationWho vouches for the declaration. Optional: a plugin published without a key has nothing to sign with, and the harness records that honestly rather than claiming a signature it does not have. The issuer vocabulary is the lease manifest's, so one reader understands both.stable

#check

PathTypeRequiredDescriptionConstraintsStability
#checkobjectA data or delivery check the plugin implements. worker is a path inside the plugin; the harness runs it out of process, never in the kernel.
#check.idstringyesmin length 1stable
#check.workerstringyesmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
stable

#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

#contributes

PathTypeRequiredDescriptionConstraintsStability
#contributesobjectWhat the plugin adds to the harness as DATA the kernel reads. Every list is optional. Nothing here is code the kernel executes: a contributed check names a worker the harness spawns, and a contributed provider names a host the egress policy must already permit.
#contributes.providersarrayModel providers the plugin adds to the registry.stable
#contributes.providers[]object #providerA model provider the plugin contributes. kind is the closed set of wire protocols the harness speaks; a provider whose protocol is neither is not a provider the harness can drive.
#contributes.trackersarrayTracker strategies the plugin adds to the mirror.stable
#contributes.trackers[]object #trackerA tracker strategy the plugin contributes. The action ids name integration actions; an id the host does not know is reported, never invented.
#contributes.docPacksarrayPaths inside the plugin to document packs it contributes.stable
#contributes.docPacks[]stringmin length 1
must not match ^/, (^|/)\.\.(/|$), ^~, ^[A-Za-z]:, \\
#contributes.checksarrayChecks the plugin implements.stable
#contributes.checks[]object #checkA data or delivery check the plugin implements. worker is a path inside the plugin; the harness runs it out of process, never in the kernel.

#prices

PathTypeRequiredDescriptionConstraintsStability
#pricesobjectDeclared unit prices, for budget accounting. Advisory: the harness records what it spent, not what it was told it would cost.
#prices.input_per_millionnumbermin 0stable
#prices.output_per_millionnumbermin 0stable

#provider

PathTypeRequiredDescriptionConstraintsStability
#providerobjectA model provider the plugin contributes. kind is the closed set of wire protocols the harness speaks; a provider whose protocol is neither is not a provider the harness can drive.
#provider.idstringyesmin length 1stable
#provider.kindstringyesThe wire protocol. Closed: the harness has exactly these two clients.one of "openai-compatible", "anthropic"stable
#provider.baseUrlstringWhere the provider is reached: https://, or http:// to loopback only (127.0.0.1, localhost, [::1]), because a local model provider such as Ollama or LM Studio lives there and a plain-http remote provider would carry a key in the clear.min length 1
any of: (1) pattern ^https://; (2) pattern ^http://(127\.0\.0\.1|localhost|\[::1\])(:[0-9]{1,5})?(/|$)
stable
#provider.modelstringmin length 1stable
#provider.pricesobject #pricesDeclared unit prices, for budget accounting. Advisory: the harness records what it spent, not what it was told it would cost.stable
#provider.extraHostsarrayHostnames beyond the base URL's own that this provider reaches. They must still be permitted by the lease.stable
#provider.extraHosts[]stringmin length 1

#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

#tracker

PathTypeRequiredDescriptionConstraintsStability
#trackerobjectA tracker strategy the plugin contributes. The action ids name integration actions; an id the host does not know is reported, never invented.
#tracker.idstringyesmin length 1stable
#tracker.labelstringyesmin length 1stable
#tracker.readActionstringyesmin length 1stable
#tracker.commentActionstringmin length 1stable
#tracker.transitionActionstringmin length 1stable
#tracker.createActionstringmin length 1stable
#tracker.externalIdLabelstringmin length 1stable
#tracker.externalIdPlaceholderstringmin length 1stable

#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

#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
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