An Agent Skill is a directory with a SKILL.md file in it.1 That is the whole format. The file carries two required pieces of metadata — a name and a description — followed by markdown instructions, and the directory may carry anything else the instructions need: scripts to run, reference documents to read, templates to fill.

What makes this more than a file-naming convention is when each part gets read. Anthropic’s framing is that a skill is “organized like an onboarding guide you’d create for a new team member”:2 the agent skims the table of contents on day one and opens the chapter on expense reports only when someone asks it to file one. Skills are the packaging format for the procedural knowledge an agent doesn’t already have, and progressive disclosure is the reading order that keeps that packaging from costing anything until it’s needed.

What a skill is, and what it isn’t

The three comparisons worth pinning down, because a skill is easy to confuse with each of them:

  • Not a prompt. A prompt is conversation-level and one-off. A skill is filesystem-level and reusable, so you don’t repeat the same guidance across conversations.2 The trade is that a prompt is always in context and a skill has to be discovered — which is why the description field carries so much weight.
  • Not a tool, and not MCP. MCP gives a model new capabilities — a connection down to systems it otherwise can’t reach. A skill gives it procedure: what to do with capabilities it already has, in what order, with which conventions. A skill can tell the agent to call an MCP tool, and the authoring guidance is that it should name that tool fully qualified (ServerName:tool_name) when it does.3
  • Not CLAUDE.md. In Claude Code the distinction is a budget one: CLAUDE.md content is loaded every session, a skill’s body loads only when used, “so long reference material costs almost nothing until you need it.”4 The documentation’s own trigger for creating one is telling — when a section of CLAUDE.md “has grown into a procedure rather than a fact.”4

Progressive disclosure is the whole trick

Skills load in three stages, each with a different cost:2

LevelWhen loadedToken costContent
1. MetadataAlways, at startup~100 tokens per skillname and description from the frontmatter
2. InstructionsWhen the skill triggersUnder 5k tokensThe SKILL.md body
3. ResourcesAs neededNothing until accessedBundled files — read into context, or scripts run through bash so only their output costs tokens

The architectural claim underneath is that skills exist on a filesystem the agent navigates with bash, exactly as a person would.2 Three consequences follow, and they’re the reason the format is shaped this way:

  • On-demand file access. A skill can bundle dozens of reference files; if the task needs one, that’s the one that gets read and the rest cost zero.
  • Efficient script execution. When the agent runs validate_form.py, the script’s code never enters context — only its output does. That makes a bundled script strictly cheaper, and more reliable, than having the model generate the equivalent code each time.
  • No practical limit on bundled content. Complete API documentation, large datasets, extensive examples: none of it is a context penalty until read.

This is context engineering with the filesystem as the store — the same just-in-time retrieval argument, applied to the agent’s own instructions rather than to its data. The description field is doing the work the retrieval index would do, which is why authoring guidance treats it as the single most consequential line in the file.3

The specification

The format is published as an open standard at agentskills.io, and Claude Code implements it rather than a proprietary variant.4

Directory layout

skill-name/
├── SKILL.md          # Required: metadata + instructions
├── scripts/          # Optional: executable code
├── references/       # Optional: documentation
├── assets/           # Optional: templates, resources
└── ...               # Any additional files or directories

The three optional directories are conventions, not requirements — scripts/ for code the agent runs, references/ for documents it reads on demand, assets/ for templates, images, schemas, and other static resources.1

Frontmatter

Six fields, of which two are required:1

FieldRequiredConstraints
nameYes1–64 characters, lowercase alphanumerics and hyphens only, no leading, trailing, or consecutive hyphens; must match the parent directory name
descriptionYes1–1024 characters, non-empty; says what the skill does and when to use it
licenseNoLicense name, or the name of a bundled license file
compatibilityNo≤500 characters; environment requirements — intended product, system packages, network access
metadataNoArbitrary string→string map for properties the spec doesn’t define
allowed-toolsNoSpace-separated list of pre-approved tools. Experimental; support varies by implementation

Anthropic’s platform documentation adds two constraints the spec page doesn’t spell out: name may not contain XML tags or the reserved words “anthropic” and “claude”, and neither may description.2

Most skills need only the two required fields. compatibility in particular is for the exceptions — “Requires Python 3.14+ and uv”, “Requires git, docker, jq, and access to the internet.”1

Budgets and file references

  • Keep SKILL.md under 500 lines and 5,000 tokens.1 Past that, move material into separate files.
  • Reference other files by relative path from the skill root, and keep those references one level deep from SKILL.md.1 The reason is behavioral rather than aesthetic: on a nested chain the agent tends to preview files with something like head -100 instead of reading them whole, so information at the end of the chain arrives incomplete.3
  • Validate with the reference library: skills-ref validate ./my-skill checks frontmatter and naming conventions.1 In Claude Code, claude plugin validate .claude/skills finds SKILL.md files whose frontmatter doesn’t parse.4

Skills in Claude Code

Claude Code supports custom skills only — the pre-built document skills (pptx, xlsx, docx, pdf) are API and claude.ai features — and it discovers them from the filesystem with no upload step.2 It also extends the open format with a set of fields the spec doesn’t define, which is the main thing to keep straight when authoring for more than one surface.

Where they live

LocationPathApplies to
EnterpriseManaged settings directoryAll users in the organization
Personal~/.claude/skills/<skill-name>/SKILL.mdAll your projects
Project.claude/skills/<skill-name>/SKILL.mdThis project only
Plugin<plugin>/skills/<skill-name>/SKILL.mdWherever the plugin is enabled

On a name collision, enterprise overrides personal, and personal overrides project; any of the three overrides a bundled skill of the same name (though not the bundled skill’s aliases). Plugin skills sit in a plugin-name:skill-name namespace and therefore can’t collide at all.4

Project skills load from .claude/skills/ in the starting directory and every parent up to the repository root. Skills in nested .claude/skills/ directories below the starting directory load lazily — the first time Claude reads or edits a file in that subdirectory — which is how a monorepo package supplies skills that apply only to work inside it. A nested skill that collides with a root one stays available under a directory-qualified name like apps/web:deploy.4

The command you type comes from the directory name, not the frontmatter name, for personal and project skills; name there sets only the display label. In a plugin skill, name sets the last segment of the command and the plugin prefix stays.4 This catches people out: renaming the skill in frontmatter doesn’t rename /the-command.

Who invokes it

By default both parties can: you type /skill-name, and Claude loads it automatically when the description matches. Two fields narrow that:4

FrontmatterYou can invokeClaude can invokeWhen loaded
(default)YesYesDescription always in context; body loads on invocation
disable-model-invocation: trueYesNoDescription not in context; body loads when you invoke
user-invocable: falseNoYesDescription always in context; body loads on invocation

The split is a good design prompt in itself. disable-model-invocation is for anything with side effects whose timing you want to own — /commit, /deploy, /send-slack-message; you don’t want Claude deciding to deploy because the code looks ready. user-invocable: false is for background knowledge that isn’t an action: a legacy-system-context skill Claude should consult when relevant, but which nobody would meaningfully “run.”4

The Claude Code extensions

Beyond the spec’s six fields, SKILL.md in Claude Code accepts a much larger set — all optional, with only description recommended.4 The ones that change what a skill is, rather than just labeling it:

  • when_to_use — extra trigger phrases, appended to description in the listing. The two together are capped at 1,536 characters.
  • argument-hint and arguments — autocomplete hint, and named positional arguments for $name substitution in the body.
  • allowed-tools / disallowed-tools — pre-approve tools for the invoking turn, or remove them from the pool while the skill is active. Both clear on your next message.
  • model, effort — override the model or effort level while the skill is active.
  • context: fork, agent, background — run the skill in its own subagent context, optionally as a specific agent type (Explore, Plan, general-purpose), in the background by default.
  • paths — glob patterns that limit automatic activation to work on matching files.
  • hooks — hooks registered when the skill is invoked, for the rest of the session.

The body gets extensions too. String substitutions ($ARGUMENTS, $0, $issue, ${CLAUDE_SKILL_DIR}, ${CLAUDE_PROJECT_DIR}) and dynamic context injection — !`git diff HEAD` runs before Claude reads the skill, so the instructions arrive already grounded in the current state of the repository.4

Portability is the catch. Outside Claude Code — claude.ai uploads, the Skills API, packaging with package_skill.py — only the spec’s six fields are accepted, and an extra field is a hard error rather than an ignored key: Unexpected key(s) in SKILL.md frontmatter: argument-hint.4 Body features like dynamic context injection simply don’t function there either. A skill written to the spec loads in Claude Code unchanged; a skill written to Claude Code’s full field set does not travel.

What it costs

Two budgets are worth knowing before a skill collection gets large:4

  • The listing. Every skill’s name and description sit in context so Claude knows what exists. The listing’s budget is 1% of the model’s context window (skillListingBudgetFraction), and when it overflows, descriptions are dropped starting with the skills you invoke least — which can silently strip the keywords a skill needs to trigger. Put the key use case first in the description. /doctor estimates the listing’s cost; /skill-doctor finds skills you never invoke; /context shows the post-budget size.
  • Persistence. An invoked skill’s rendered content enters the conversation as one message and stays there across later turns — Claude Code does not re-read the file. Write standing instructions, not one-time steps. Through auto-compaction, the most recent invocation of each skill is re-attached with its first 5,000 tokens, sharing a combined 25,000-token budget filled from the most recent backwards, so skills invoked early in a long session can drop out entirely.

Sharing

Project skills go in version control under .claude/skills/; broader distribution is a plugin with a skills/ directory, or organization-wide deployment through managed settings.4 Skills enabled on a claude.ai account can be synced down into ~/.claude/skills/synced/, and Cowork and cloud sessions read those rather than your local personal skills — a personal skill that exists only on your machine is “not found” when a scheduled routine tries to invoke it.4

Across surfaces

Skills work on the Claude API (with the code execution tool, referencing a skill_id in the container parameter), in Claude Code, and on claude.ai.2 Three constraints cut across them:

  • Nothing syncs. A skill uploaded to claude.ai is not available through the API; API skills aren’t on claude.ai; Claude Code’s are filesystem-based and separate from both. You manage each surface separately.2
  • Sharing scope differs. claude.ai custom skills are per-user with no admin-managed org-wide distribution; API skills are workspace-wide; Claude Code skills are personal, project, or plugin-shared.2
  • The runtime differs, and it constrains what you can write. On the API, skills run sandboxed with no network access and no runtime package installation — only pre-installed packages. In Claude Code they have the same network access as any other program on your machine, and the guidance is to install packages locally rather than globally.2

Security

The documentation’s position is blunt: use skills only from sources you trust, because a skill is instructions plus code, and a malicious one can direct the agent to invoke tools or execute code in ways that don’t match its stated purpose — data exfiltration, unauthorized access.2 Treat installing one like installing software. Skills that fetch from external URLs are the sharpest case, since fetched content can carry instructions of its own and a dependency that was safe can change.

Claude Code adds a specific trap worth naming: workspace trust does not gate allowed-tools. A project skill’s tool grants apply whenever the skill is invoked, including in a -p run inside a folder you’ve never trusted — so a skill checked into a repository can grant itself broad tool access. Read the allowed-tools of repo-provided skills before running Claude Code there.4

Where it sits

Skills are the third leg of the same problem the other two open standards on this wiki address, and the boundaries are cleaner than the marketing suggests: MCP standardizes the connection down to tools and data, A2A standardizes communication across to peer agents, and Agent Skills standardize the procedural knowledge an agent brings to either. None of the three substitutes for another.

For a single agent, a skill is the cheapest way to raise the ceiling of the single-agent pattern without adding architecture — new competence, no new components. context: fork is where it stops being that: a forked skill is a subagent with its own context window, which is the parallel pattern reached through a SKILL.md instead of an orchestration framework.

Writing one well is a separate discipline with its own literature — see Agent Skills Best Practices.

Footnotes

  1. “Specification”, agentskills.io, retrieved 2026-09-07. Local copy: references/agentskills-io-specification.md. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7

  2. “Agent Skills”, Claude Platform documentation, retrieved 2026-09-07. Local copy: references/anthropic-agent-skills-overview.md. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11

  3. “Skill authoring best practices”, Claude Platform documentation, retrieved 2026-09-07. Local copy: references/anthropic-agent-skills-best-practices.md. ↩ ↩2 ↩3

  4. “Extend Claude with skills”, Claude Code documentation, retrieved 2026-09-07. Local copy: references/claude-code-skills.md. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16


Graph View