Anatomy of a SKILL.md
A SKILL.md is two required fields, a body of procedural instructions, and optional files loaded only when the agent actually needs them.
A SKILL.md file has exactly two required fields — name and description — plus a markdown body of instructions, and both format and required fields come from Anthropic's own documentation, not convention (Agent Skills overview).
The frontmatter: what triggers it
---
name: review-endpoint
description: Review a REST endpoint for auth, validation, and error handling. Use when reviewing or writing an API route.
---
name must be lowercase letters, numbers, and hyphens, max 64 characters, and can't contain "anthropic" or "claude". description must be non-empty, max 1024 characters, and — this is the field that matters most — it's what the agent matches your request against to decide whether to load the skill at all. Write it as "what this does" plus "when to use it," not just a label. In Claude Code specifically, description is the only other recommended field: every other frontmatter key, like allowed-tools or disable-model-invocation, is optional (Use Skills in Claude Code).
The body: instructions, not narration
The body is markdown the agent reads only after the description matches. This is where progressive disclosure earns its keep: metadata costs roughly 100 tokens per skill and is loaded for every skill at startup, but the instruction body — recommended to stay under 5,000 tokens — loads only when triggered, and any bundled reference files load only if the instructions point to them (Agent Skills overview). Anthropic's own framing: a skill is "a well-organized manual that starts with a table of contents, then specific chapters, and finally a detailed appendix" (Equipping agents for the real world with Agent Skills). Write the body as a checklist or numbered procedure, not a story — every line stays in context for the rest of the session once loaded, so treat it like CLAUDE.md content: state what to do, not why.
Inputs and examples
A skill can bundle supporting files that stay at zero token cost until referenced:
review-endpoint/
├── SKILL.md
├── examples.md # a sample review, referenced by link
└── checklist.md # the full OWASP-style checklist
Link to them from the body (see [checklist.md](checklist.md)) so the agent knows they exist and when to read them. Anthropic recommends keeping SKILL.md itself under 500 lines and moving detail into these separate files.
A worked example
---
name: review-endpoint
description: Review a REST endpoint for auth, validation, and error handling. Use when reviewing or writing an API route.
---
## Checklist
- Auth check runs before any database read
- Input validated against a schema, not just type-checked
- Errors return one consistent JSON shape, no raw stack traces
- Rate limiting applied on write paths
## Done when
Every item above is confirmed against the actual code, with a file:line reference for each finding.
That "Done when" line matters more than it looks: without a stop condition, the agent can call the review finished after checking one item.
Try it today
- Pick one task you keep prompting from scratch and name it clearly, e.g.
review-endpoint. - Write
descriptionas one sentence covering both what it does and when to trigger it. - Turn your usual prompt into a checklist with an explicit "done when" line.
- Save it to
.claude/skills/review-endpoint/SKILL.mdin your project. - Ask a question that should match the description and confirm the agent loads it instead of improvising.
Where this breaks
A vague description means the agent either never triggers the skill or triggers it for the wrong task — specificity in that one field does most of the work. A body over a few thousand tokens defeats progressive disclosure, since it all lands in context the moment it's triggered. And a skill only helps the agent decide what to check; it doesn't enforce that the check ran, which is why some of these belong in a hook instead.
Next: prompt, skill, hook, or MCP server — a decision table.