Skip to content

Upstream spec

What the published Claude Code and Agent Skills documentation describes, and how much of it claudelint reads.

Verified against Claude Code v2.1.270; documentation pages carried markers up to v2.1.269.

The claudelint column answers one question: does anything in the linter read this? A no is not a bug on its own — it means no rule needs the field yet, and the reason says which rule or phase would change that. A — means claudelint has no opinion about the section at all.

This page is generated from internal/upstream/digest.json and internal/upstream/acknowledged.json. A weekly job re-extracts the digest from upstream, so a row here is what the documentation said the last time anyone looked.

The built-in tools a skill, command, or agent may name in allowed-tools, disallowed-tools, or tools.

ToolclaudelintReason
Agentyes—
Artifactyes—
AskUserQuestionyes—
Bashyes—
CronCreateyes—
CronDeleteyes—
CronListyes—
Edityes—
EndConversationyes—
EnterPlanModeyes—
EnterWorktreeyes—
ExitPlanModeyes—
ExitWorktreeyes—
Globyes—
Grepyes—
LSPyes—
ListAgentsyes—
ListMcpResourcesToolyes—
Monitoryes—
NotebookEdityes—
PowerShellyes—
PushNotificationyes—
Readyes—
ReadMcpResourceToolyes—
RemoteTriggeryes—
ReportFindingsyes—
ScheduleWakeupyes—
SendFeedbackyes—
SendMessageyes—
SendUserFileyes—
ShareOnboardingGuideyes—
Skillyes—
TaskCreateyes—
TaskGetyes—
TaskListyes—
TaskOutputyes—
TaskStopyes—
TaskUpdateyes—
TodoWriteyes—
ToolSearchyes—
WaitForMcpServersyes—
WebFetchyes—
WebSearchyes—
Workflowyes—
Writeyes—

Tools that upstream renamed or removed are no longer in the table above. claudelint still recognizes them, and reports them with their replacement rather than as typos — see Deprecated and removed tools.

Hook events, handler types, and the fields a handler entry may carry.

EventclaudelintReason
ConfigChangeyes—
CwdChangedyes—
DirectoryAddedyes—
Elicitationyes—
ElicitationResultyes—
FileChangedyes—
InstructionsLoadedyes—
MessageDisplayyes—
Notificationyes—
PermissionDeniedyes—
PermissionRequestyes—
PostCompactyes—
PostModelSwitchyes—
PostToolBatchyes—
PostToolUseyes—
PostToolUseFailureyes—
PreCompactyes—
PreModelSwitchyes—
PreToolUseyes—
SessionEndyes—
SessionStartyes—
Setupyes—
Stopyes—
StopFailureyes—
SubagentStartyes—
SubagentStopyes—
TaskCompletedyes—
TaskCreatedyes—
TeammateIdleyes—
UserPromptExpansionyes—
UserPromptSubmityes—
WorktreeCreateyes—
WorktreeRemoveyes—
TypeclaudelintReason
agentyes—
commandyes—
httpyes—
mcp_toolyes—
promptyes—

Grouped as the documentation groups them: common fields apply to every handler, the rest to one type.

agent:

FieldRequiredTypeclaudelintReason
modelno—noprompt and agent handler field; agents/model-policy covers agent frontmatter, not hook handlers (OQ4).
promptyes—yes—

command:

FieldRequiredTypeclaudelintReason
argsno—yes—
asyncno—yes—
asyncRewakeno—nocommand handler field paired with async; hooks/async-rewake has no rule yet (OQ4).
commandyes—yes—
shellno—yes—

common:

FieldRequiredTypeclaudelintReason
ifno—nocommon conditional field; no rule evaluates hook conditions (OQ4).
onceno—nocommon field; no rule reads it (OQ4).
statusMessageno—nocommon presentation field; no rule reads it (OQ4).
timeoutno—yes—
typeyes—yes—

http:

FieldRequiredTypeclaudelintReason
allowedEnvVarsno—nohttp handler field; no rule reads it. A hooks/http-env-allowlist rule would, and gets its own IMPL (OQ4).
headersno—nohttp handler field; the secret-in-header check that would read it is security rule territory, not yet written (OQ4).
urlyes—yes—

mcp_tool:

FieldRequiredTypeclaudelintReason
inputno—nomcp_tool handler field; no rule validates the tool input shape (OQ4).
serveryes—yes—
toolyes—yes—

prompt:

FieldRequiredTypeclaudelintReason
modelno—noprompt and agent handler field; agents/model-policy covers agent frontmatter, not hook handlers (OQ4).
promptyes—yes—

Seconds applied when a handler declares no timeout.

By typeSeconds
agent60
command600
http600
mcp_tool600
prompt30
By eventSeconds
MessageDisplay10
PostModelSwitch30
PreModelSwitch30
UserPromptSubmit30

Skills and commands share one documented frontmatter table. claudelint splits it across two parsers, so a field is marked read when either reads it.

FieldRequiredTypeclaudelintReason
agentno—yes—
allowed-toolsno—yes—
argument-hintno—yes—
argumentsno—nonot parsed; no rule consumes it. A skills/arguments-valid rule would, and gets its own IMPL (OQ4).
backgroundno—nonot parsed; no rule consumes it (OQ4).
compatibilityno—nonot parsed; portable.limits records its 500-character cap for a future skills/portable-fields rule (OQ4).
contextno—yes—
descriptionrecommended—yes—
disable-model-invocationno—yes—
disallowed-toolsno—yes—
effortno—nonot parsed on skills; agents/field-enums covers the agent spelling. Parse it when a skill rule needs it (OQ4).
hooksno—nonot parsed on skills; hook contents are the hook rule package’s job (DESIGN-0005 non-goal).
licenseno—nonot parsed; portable.allowed_fields records it for a future skills/portable-fields rule (OQ4).
metadatano—nofree-form metadata; nothing to validate (OQ4).
modelno—yes—
nameno—yes—
pathsno—nonot parsed; no rule consumes it (IMPL-0004 out of scope, OQ4).
shellno—nonot parsed; no rule consumes it (OQ4).
user-invocableno—yes—
when_to_useno—yes—

Documented string substitutions: $ARGUMENTS, $ARGUMENTS[N], $N, $name, ${CLAUDE_EFFORT}, ${CLAUDE_PLUGIN_DATA}, ${CLAUDE_PLUGIN_ROOT}, ${CLAUDE_PROJECT_DIR}, ${CLAUDE_SESSION_ID}, ${CLAUDE_SKILL_DIR}.

Usable outside Claude Code: allowed-tools, compatibility, description, license, metadata, name.

Subagent frontmatter and the values its enum fields accept.

FieldRequiredTypeclaudelintReason
backgroundno—yes—
colorno—yes—
descriptionyes—yes—
disallowedToolsno—yes—
effortno—yes—
experimentalno—nodocumented as experimental; DESIGN-0006 records field names only for experimental surfaces. Parse it when a rule needs it (IMPL-0005 OQ4).
hooksno—yes—
initialPromptno—yes—
isolationno—yes—
maxTurnsno—yes—
mcpServersno—yes—
memoryno—yes—
modelno—yes—
nameyes—yes—
permissionModeno—yes—
skillsno—yes—
toolsno—yes—

color:

ValueclaudelintReason
blueyes—
cyanyes—
greenyes—
orangeyes—
pinkyes—
purpleyes—
redyes—
yellowyes—

effort:

ValueclaudelintReason
highyes—
lowyes—
maxyes—
mediumyes—
xhighyes—

isolation:

ValueclaudelintReason
HEADnonot a value: the docs describe worktree isolation in prose that mentions the HEAD commit, and the extractor takes every code span in the cell. agents/field-enums checks isolation directly against “worktree”.
worktreeyes—

memory:

ValueclaudelintReason
localyes—
projectyes—
useryes—

model:

ValueclaudelintReason
claude-opus-5noan example full model ID in the description cell, not an alias. artifact.IsValidModelRef already accepts any claude-* ID, so agents/field-enums passes it.
fableyes—
haikuyes—
inherityes—
opusyes—
sonnetyes—

permissionMode:

ValueclaudelintReason
acceptEditsyes—
autoyes—
bypassPermissionsyes—
defaultyes—
dontAskyes—
manualyes—
planyes—

The plugin manifest and where a plugin’s components live.

FieldRequiredTypeclaudelintReason
$schemanostringnoeditor metadata, not a plugin property; plugin/manifest-fields has nothing to check on it.
agentsnostring|arrayyes—
authornoobjectnometadata field; no rule consumes it (OQ4). plugin/manifest-fields would parse it when one does.
channelsnoarraynoexperimental surface; field name recorded only, per DESIGN-0006 non-goals.
commandsnostring|arrayyes—
defaultEnablednobooleannometadata field; no rule consumes it (OQ4).
dependenciesnoarraynocomponent field; a plugin/dependencies-resolvable rule would read it and gets its own IMPL (OQ4).
descriptionnostringyes—
displayNamenostringnometadata field; no rule consumes it (OQ4).
experimental.evalsnostring|arraynoexperimental surface; field name recorded only, per DESIGN-0006 non-goals.
experimental.monitorsnostring|arraynoexperimental surface; field name recorded only, per DESIGN-0006 non-goals.
experimental.themesnostring|arraynoexperimental surface; field name recorded only, per DESIGN-0006 non-goals.
homepagenostringnometadata field; no rule consumes it (OQ4).
hooksnostring|array|objectnocomponent path field; the hook rules lint hooks/hooks.json directly, so the manifest pointer needs no parse (OQ4).
keywordsnoarraynometadata field; no rule consumes it (OQ4).
licensenostringnometadata field; no rule consumes it (OQ4).
lspServersnostring|array|objectnoexperimental surface; field name recorded only, per DESIGN-0006 non-goals.
mcpServersnostring|array|objectnocomponent path field; the mcp rules lint .mcp.json and plugin-embedded servers directly (OQ4).
metadatanoobjectnofree-form metadata; nothing to validate (OQ4).
nameyesstringyes—
outputStylesnostring|arraynocomponent path field; no rule consumes it (OQ4).
repositorynostringnometadata field; no rule consumes it (OQ4).
skillsnostring|arrayyes—
userConfignoobjectnocomponent field; a plugin/user-config-valid rule would read it and gets its own IMPL (OQ4).
versionnostringyes—
workflowsnostring|arraynocomponent path field; no rule consumes it (OQ4).
ComponentPath
agentsagents/
commandscommands/
executablesbin/
hookshooks/hooks.json
lsp servers.lsp.json
manifest.claude-plugin/plugin.json
mcp servers.mcp.json
monitorsmonitors/monitors.json
output stylesoutput-styles/
settingssettings.json
skillsskills/
themesthemes/
workflowsworkflows/

The marketplace manifest, its plugin entries, and the source shapes a plugin entry may declare.

FieldRequiredTypeclaudelintReason
$schemanostring——
allowCrossMarketplaceDependenciesOnnoarray——
descriptionnostring——
metadata.pluginRootnostring——
nameyesstring——
owneryesobject——
pluginsyesarray——
renamesnoobject——
versionnostring——
FieldRequiredTypeclaudelintReason
emailnostring——
nameyesstring——
urlnostring——
FieldRequiredTypeclaudelintReason
authornoobject——
categorynostring——
defaultEnablednoboolean——
descriptionnostring——
displayNamenostring——
homepagenostring——
keywordsnoarray——
licensenostring——
metadatanoobject——
nameyesstring——
relevancenoobject——
repositorynostring——
sourceyesstring|object——
strictnoboolean——
tagsnoarray——
versionnostring——
KindRequiredOptionalclaudelint
archiveurlsha256yes
commandcommandmode, timeoutyes
git-subdirpath, urlref, shayes
githubreporef, shayes
npmpackageregistry, versionyes
urlurlref, shayes

Reserved for official Anthropic use. A manifest shipping one stops loading for every user.

NameclaudelintReason
agent-skillsyes—
anthropic-agent-skillsyes—
anthropic-marketplaceyes—
anthropic-pluginsyes—
claude-code-marketplaceyes—
claude-code-pluginsyes—
claude-communityyes—
claude-for-financial-servicesyes—
claude-for-legalyes—
claude-plugins-communityyes—
claude-plugins-officialyes—
claude-tag-pluginsyes—
financial-services-pluginsyes—
first-party-pluginsyes—
healthcareyes—
knowledge-work-pluginsyes—
life-sciencesyes—

The shape of one entry in .mcp.json or a plugin’s mcp.servers.

FieldRequiredTypeclaudelintReason
args————
authServerMetadataUrl————
callbackPort————
clientId————
command————
env————
headers————
headersHelper————
oauth————
scopes————
type————
url————
xaa————
TransportclaudelintReason
httpyes—
sseyes—
stdioyes—
wsyes—

The Agent Skills specification, which is narrower than the Claude Code superset above. claudelint does not enforce it yet; it is recorded so a future portability rule has something to read.

Name pattern: ^[a-z0-9-]+$

Allowed fields: allowed-tools, compatibility, description, license, metadata, name

Allowed by Anthropic’s own validator: allowed-tools, compatibility, description, license, metadata, name

LimitsSeconds
compatibility500
description1024
name64

Where the published documentation and the SchemaStore JSON schemas describe different things. The documentation wins: these are recorded, not enforced.

TopicSourceDocumented onlySource only
hooks.eventsschemastore.pluginDirectoryAdded, MessageDisplay, PostModelSwitch, PreModelSwitch—
hooks.eventsschemastore.settingsPostModelSwitch, PreModelSwitch—
marketplace.sourcesschemastore.marketplacearchive, command—
plugins.manifest_fieldsschemastore.plugindefaultEnabled, displayName, experimental.evals, experimental.monitors, experimental.themes, metadata, workflowsmonitors, settings, themes