A skill is a directory containing SKILL.md with YAML frontmatter, optionally alongside scripts and reference files. Only the name and description sit in context; the body loads when the skill is invoked, by you with /skill-name or by the model when the description matches. Custom commands and skills are now the same mechanism, so .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both produce /deploy.
- A skill is a directory with
SKILL.mdat its root. The directory name is the command. - Only name and description stay in context. The body loads on invocation.
- That is the difference from
CLAUDE.md, which is sent at the start of every session. - Custom commands are skills now. The two directories produce the same slash command.
- The description is the routing logic, and it is capped at 1,536 characters. Key use case first.
The shape of a skill
.claude/skills/
release-notes/
SKILL.md <- required, the entrypoint
template.md <- optional reference, read on demand
scripts/
collect.sh <- optional script, executed not read
---
name: release-notes
description: Writes release notes from merged pull requests between two git tags. Use when asked to draft release notes, a changelog entry, or a summary of what shipped.
allowed-tools: Bash(git log *) Bash(gh pr list *)
---
# Release notes
## Gathering the input
Run `${CLAUDE_SKILL_DIR}/scripts/collect.sh <from-tag> <to-tag>`. It outputs one
line per merged PR with number, title, and author.
## Writing them
Follow `template.md` exactly. Rules that matter:
- Group by user-visible impact, never by component.
- One line per change, written from the user point of view. "Sessions no
longer drop on reconnect", not "fixed WebSocket handler".
- Omit anything invisible to a user: refactors, test changes, CI.
- Breaking changes go first, under their own heading, with the migration.
- Never invent a change that is not in the input.
Where a skill can live, and who gets it.
| Location | Path | Applies to |
|---|---|---|
| Enterprise | Managed settings | Everyone in the organisation |
| Personal | ~/.claude/skills/<name>/SKILL.md | All your projects |
| Project | .claude/skills/<name>/SKILL.md | This project, committed |
| Plugin | <plugin>/skills/<name>/SKILL.md | Wherever the plugin is enabled |
- On a name clash, enterprise beats personal beats project, and any of them beats a bundled skill of the same name.
- Plugin skills are namespaced
plugin-name:skill-name, so they cannot collide. - Project skills also load from every parent directory up to the repository root, so starting in a subdirectory still picks up the root ones.
- Nested
.claude/skills/below your starting directory load lazily, the first time the agent reads or edits a file in that subtree. A monorepo package can therefore ship skills that only appear when you work on it. - Skill directories are watched live: adding or editing a
SKILL.mdtakes effect in the running session with no restart.
Why progressive disclosure is the whole point
This is the property that makes skills worth using rather than a stylistic alternative to project memory.
What is in context, and when.
| Content | Always loaded? | Cost |
|---|---|---|
CLAUDE.md | Yes, at every session start | Paid on every session forever |
| Skill name and description | Yes, in the skill listing | Small, but budgeted |
| Skill body | No, only when invoked | Paid only when used |
| Bundled reference files | No, only if the agent reads one | Paid only when read |
The listing is not free, though, and it is budgeted. Claude Code allocates roughly 1 percent of the model context window to skill names and descriptions. The listing always contains every skill name; when it overflows, descriptions are dropped starting with the skills you invoke least. Each entry combining description and when_to_use is capped at 1,536 characters regardless of budget.
/doctor # estimates the listing cost and names the biggest contributors
/context # the Skills row reports the listing size after the budget is applied
The frontmatter, field by field
Every field is optional. Only description is genuinely recommended, because it is how the model decides the skill applies.
The fields worth knowing, per Claude Code documentation in August 2026.
| Field | What it does |
|---|---|
description | What the skill does and when to use it. The routing logic. Capped at 1,536 characters with when_to_use |
when_to_use | Extra trigger phrases, appended to the description in the listing |
name | Display label. For personal and project skills the directory name still sets the command |
disable-model-invocation | true means only you can run it. Use for anything with side effects |
user-invocable | false hides it from the / menu. Use for background knowledge |
allowed-tools | Pre-approves tools for the turn that invokes the skill. Clears on your next message |
disallowed-tools | Removes tools from the pool while the skill is active |
model | Model for the rest of the current turn. Not saved to settings |
effort | Effort level while this skill is active. Overrides the session level |
context: fork | Runs the skill in a subagent instead of your conversation |
paths | Globs that limit automatic activation to matching files |
argument-hint / arguments | Autocomplete hint, and named positional arguments for $name substitution |
Pre-approving tools, and the trust question
---
name: commit
description: Stage and commit the current changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---
Stage the relevant changes and commit with a message that explains why,
not what. Never use --no-verify. Never commit to main.
Skills, commands, and subagents
Custom commands were merged into skills. A file at .claude/commands/deploy.md and a directory at .claude/skills/deploy/SKILL.md both create /deploy and behave the same way. Existing command files keep working; skills add a directory for supporting files, frontmatter, and automatic invocation.
Two mechanisms that overlap and are not interchangeable.
| Skill | Subagent | |
|---|---|---|
| Invoked by | You with /name, or the model | The model, when delegating |
| Context | Yours, unless context: fork | A fresh one |
| Loaded up front | Description only | Description only |
| Own tool permissions | For the invoking turn | For its whole run |
| Own model and effort | For the invoking turn | For its whole run |
| Best for | Knowledge and procedure | Isolated work with a lot of reading |
- Use a skill when the agent should know how to do something in the conversation you are already having.
- Use a skill with
context: forkwhen the skill is a self-contained task and you want it out of your context. It runs in the background by default; setbackground: falseto wait for the result in the invoking turn. - Use a subagent when you want a reusable agent type with its own system prompt and tool set that the model delegates to on its own judgement.
Writing one that actually fires
The most common complaint about skills is that they never trigger, and the cause is nearly always the description.
| Weak description | Strong description |
|---|---|
| "Release helper" | "Writes release notes from merged PRs between two git tags. Use when asked to draft release notes, a changelog entry, or a summary of what shipped." |
| "Database stuff" | "Writes and reviews Drizzle migrations. Use when adding, altering, or dropping a table or column." |
| "Style guide" | "Applies this repository React conventions. Use when creating or editing a component under src/ui/." |
The three failures and what causes each.
| Symptom | Cause | Fix |
|---|---|---|
| Never triggers | Description names the topic, not the trigger | Rewrite as "does X. Use when Y." |
Never triggers, and /name works | Malformed YAML; the body loaded with empty metadata | Run claude --debug to see the parse error |
| Triggers on the wrong requests | Description too broad | Narrow it, or set disable-model-invocation: true |
| Stops mattering after one reply | Content is present; the model chose otherwise | Strengthen the instructions, or enforce with a hook |
| Lost after a long session | Compaction budget dropped it | Re-invoke it, and keep the top of the file load-bearing |
That last row is worth stating precisely. Once invoked, the rendered SKILL.md stays in the conversation for the rest of the session, and the file is not re-read on later turns. After a compaction, Claude Code re-attaches the most recent invocation of each skill, keeping the first 5,000 tokens of each within a 25,000 token combined budget, newest first. Invoke six skills in one long session and the earliest are simply gone.
Questions people ask
A directory containing SKILL.md with YAML frontmatter, optionally with scripts and reference files. Claude keeps the name and description in context and reads the body only when the skill is invoked, either by you with /skill-name or by the model when the description matches.
CLAUDE.md loads at the start of every session, so its length is a permanent cost. A skill body loads only when it is used. Long procedural content belongs in a skill; short project facts belong in CLAUDE.md.
Yes. A file at .claude/commands/deploy.md and a directory at .claude/skills/deploy/SKILL.md both create /deploy and work the same way. Existing command files keep working, and skills add supporting files, frontmatter, and automatic invocation.
Personal skills in ~/.claude/skills/, project skills in .claude/skills/ committed to the repo, plugin skills under a plugin, and enterprise skills through managed settings. On a name clash, enterprise beats personal beats project.
Almost always the description. Write it as "does X. Use when Y." and name the specific situations. If /skill-name works but automatic invocation never does, the YAML is probably malformed, which loads the body with empty metadata. Run claude --debug to see the parse error.
Yes. Bundle them in the skill directory, reference them from SKILL.md using ${CLAUDE_SKILL_DIR} so the path resolves anywhere, and pre-approve the command with allowed-tools if you do not want a prompt each time.
A skill when the agent should know how to do something in your current conversation. A subagent when the work should happen in a fresh context. A skill with context: fork is the middle option: your task, run in isolation.
The skill listing is budgeted at about 1 percent of the model context window, and each entry is capped at 1,536 characters. When the listing overflows, descriptions are dropped starting with the skills you invoke least. Run /doctor to see the cost and its biggest contributors.
Sources
Every figure above was read from these pages on August 2026. Vendors reprice without notice; if you find a stale number, tell us.