Skill Builder — the principles behind a skill that triggers and stays focused
For interactive scaffolding, evaluation and benchmarking of a skill, use Anthropic's official Skill Creator (claude.com/plugins/skill-creator). This skill is the complementary judgment layer: the opinionated principles that make a skill trigger reliably and stay focused, plus a review checklist and the packaging path. Use it to design, review, or debug a skill, not to generate boilerplate.
The root virtue: predictability
A skill exists to pull determinism out of a stochastic system. What you make repeatable is the process, not the output — the agent should take the same approach every run, even when the result differs. Design the procedure; don't script the answer. Two tests fall out of this:
- Completion criteria the agent can check. The skill must give it a way to tell done from not-done — otherwise it stops early and calls it finished.
- One leading word. Anchor the skill on a single concept the model already knows well (e.g. tracer bullet, receipt, lesson, seam) and repeat it in the name, the description and the body. A word the model thinks with anchors both triggering and execution — far more than a phrase it has to decode.
First: is a skill even the right tool?
Claude Code has five extension primitives. Pick the one that fits before writing anything.
- Skill — a reusable workflow or body of knowledge, pulled in when its description matches the request. For "how to do X well" that recurs across projects. (This is what you're building here.)
- CLAUDE.md — always-on project context (conventions, commands, layout). For facts every session in THIS repo needs. Not triggered; always loaded.
- Subagent — a delegated task run in its own context window. For fan-out, isolation, or a specialized role.
- Hook — deterministic automation on an event (PostToolUse, Stop…). For "always run X when Y", enforced by the harness, not the model.
- MCP server — external tools/data over a protocol. For reaching a system the model otherwise can't.
If the answer is "knowledge or a procedure the model should apply when the situation arises", it's a skill. Otherwise stop and use the right primitive.
The description is everything (the #1 lever)
A skill only helps if it triggers at the right moment. The description in the frontmatter decides that almost entirely. Spend most of your effort here — and know the real failure mode: Claude UNDER-triggers skills far more than it over-triggers (it only consults a skill when it can't trivially handle the task itself). So lean inclusive and a little "pushy".
A strong description:
- "Use when…" + real trigger phrases someone would actually type, and be pushy: "use this whenever the user mentions X, Y or Z, even if they don't say '' explicitly". Anthropic's own docx/xlsx skills phrase it exactly that way.
- What it does, in one breath — enough for the model to know it's the right tool.
- "NOT for…" — only if a sibling skill competes. Anthropic's official skills mostly OMIT this, because their domains are distinct (pdf ≠ xlsx, no confusion possible). Add it when you have adjacent skills that could both match (a "review changes" skill vs a "ship a feature" skill) — there it disambiguates. Don't add it just to look careful: an over-restrictive description makes the skill under-trigger, which is the worse problem.
---
name: my-skill
description: Use when <situations>, e.g. "<real phrase>", "<real phrase>" — be a little pushy
("whenever the user mentions …, even if they don't say '<skill>'"). <what it does in one line>.
[NOT for <adjacent case> — add only if a sibling skill competes.]
---
Name: lowercase, hyphens, a verb-or-noun that reads as a command (book-distill, senior-review). Add argument-hint if the skill takes arguments.
Model-invoked vs user-invoked. By default a skill is model-invoked: its description sits in context and other skills can reach it — right for reusable knowledge that should fire on its own. Set disable-model-invocation: true to make it user-invoked (/skill only): the description leaves the model's reach, saving context. Reserve it for skills nobody else needs to auto-trigger — heavy, domain-specific, run-on-demand (a tax-dossier writer, a one-off migration).
Keep the body skimmable (progressive disclosure)
Three loading levels: metadata (name + description, always in context) → SKILL.md body (loaded when the skill fires) → bundled resources (loaded or executed on demand). Keep the body lean so it doesn't crowd the context.
- < 500 lines is the target, not a law. Anthropic's own docx skill is 590. Go longer when the domain warrants it, but past ~500 add a layer of hierarchy and clear pointers ("for X, read references/x.md").
- Externalize the heavy stuff — when it pays. Two thirds of Anthropic's official skills are a single SKILL.md; split only when it earns it. When you do,
scripts/ (executable, deterministic ops) earns its place far more often than references/ (docs) — the document skills (pdf, xlsx, docx) are mostly scripts. Use references/<variant>.md for multi-framework domains; a reference over ~300 lines gets a table of contents.
- Imperative and concrete. "Do X. Never Y." Minimal example over paragraphs of theory.
- A checklist at the end beats a wall of prose.
Folder shape
my-skill/
└── SKILL.md # required: frontmatter (name, description) + body
(optional alongside:)
scripts/* # executable code for deterministic ops (earns its place most often)
references/*.md # detail loaded on demand (multi-framework, heavy domains)
assets/* # templates, fonts, icons used in the output
Personal skills live in ~/.claude/skills/<name>/ (or a project's .claude/skills/). To SHARE one, wrap it in a plugin.
Package for distribution (plugin + marketplace)
To make a skill installable by others:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # { "name", "description", "version", "author" }
└── skills/
└── my-skill/
└── SKILL.md
A marketplace is a repo with .claude-plugin/marketplace.json listing plugins (each source a relative path like ./plugins/my-plugin). Users add and install with:
/plugin marketplace add owner/repo
/plugin install my-plugin@marketplace-name
Validate before publishing: claude plugin validate <path>. Pin a version (omit it and every commit becomes a new auto-updating version). Keep all files inside the plugin root (no ../shared).
The loop to author one
- Decide it's a skill (see the five primitives).
- Write the description first — Use-when + real trigger phrases, leaning pushy; add NOT-for only if a sibling competes. This is the product.
- Write the lean body — core principle, the steps/loop, a minimal example, a checklist.
- Externalize the heavy stuff to
reference/.
- Test triggering: does it fire on the real phrases? Does it stay silent on the adjacent cases? Tune the description, not the body.
- Package + validate if sharing (plugin.json, marketplace.json,
claude plugin validate).
Anti-patterns
- Vague description ("helps with code") — it never triggers. The most common failure, and worse than over-triggering.
- Over-restrictive description — too many caveats and the skill under-triggers (the bigger risk). Lean pushy; reserve "NOT for" for genuine sibling competition.
- Monster SKILL.md — only a problem if the bulk is detail that belongs in scripts/ or references/; size alone isn't the sin (docx is 590 lines).
- Hardcoding one project's specifics in a skill meant to be reused — keep it stack-agnostic, discover specifics live.
- Renaming the concept mid-body — one term, used consistently (the model anchors on it).
- Wrong primitive — an always-on rule should be CLAUDE.md or a hook, not a skill.
- Sediment — stale instructions left from past versions that no longer match the skill; prune them on every edit instead of layering on top.
- No-op line — a sentence the agent would follow anyway; delete the whole sentence, don't trim its words.
Checklist
1---2name: skill-builder3description: Use when the user is designing, reviewing or debugging a Claude Code skill and needs the judgment behind a good SKILL.md — should this even be a skill (vs CLAUDE.md / subagent / hook / MCP), why a description does or doesn't trigger, how to keep the body skimmable, how to package it. Carries the opinionated principles plus a review checklist. Trigger on "review my SKILL.md", "why doesn't my skill trigger", "principles of a good skill", "should this be a skill or a hook", "is my skill description good", even when the word "skill" is only implied. NOT for interactive scaffolding from scratch (use Anthropic's Skill Creator), nor for general coding.4---56# Skill Builder — the principles behind a skill that triggers and stays focused78> For interactive scaffolding, evaluation and benchmarking of a skill, use Anthropic's official **Skill Creator** (claude.com/plugins/skill-creator). This skill is the complementary **judgment layer**: the opinionated principles that make a skill trigger reliably and stay focused, plus a review checklist and the packaging path. Use it to design, review, or debug a skill, not to generate boilerplate.910## The root virtue: predictability1112A skill exists to pull determinism out of a stochastic system. What you make repeatable is the **process**, not the output — the agent should take the same approach every run, even when the result differs. Design the procedure; don't script the answer. Two tests fall out of this:1314- **Completion criteria the agent can check.** The skill must give it a way to tell *done* from *not-done* — otherwise it stops early and calls it finished.15- **One leading word.** Anchor the skill on a single concept the model already knows well (e.g. *tracer bullet*, *receipt*, *lesson*, *seam*) and repeat it in the name, the description and the body. A word the model thinks with anchors both *triggering* and *execution* — far more than a phrase it has to decode.1617## First: is a skill even the right tool?1819Claude Code has five extension primitives. Pick the one that fits before writing anything.2021- **Skill** — a reusable workflow or body of knowledge, pulled in **when its description matches the request**. For "how to do X well" that recurs across projects. (This is what you're building here.)22- **CLAUDE.md** — always-on project context (conventions, commands, layout). For facts every session in THIS repo needs. Not triggered; always loaded.23- **Subagent** — a delegated task run in its own context window. For fan-out, isolation, or a specialized role.24- **Hook** — deterministic automation on an event (PostToolUse, Stop…). For "always run X when Y", enforced by the harness, not the model.25- **MCP server** — external tools/data over a protocol. For reaching a system the model otherwise can't.2627If the answer is "knowledge or a procedure the model should apply when the situation arises", it's a skill. Otherwise stop and use the right primitive.2829## The description is everything (the #1 lever)3031A skill only helps if it triggers at the right moment. The `description` in the frontmatter decides that almost entirely. Spend most of your effort here — and know the real failure mode: **Claude UNDER-triggers skills** far more than it over-triggers (it only consults a skill when it can't trivially handle the task itself). So lean inclusive and a little "pushy".3233A strong description:34351. **"Use when…" + real trigger phrases** someone would actually type, and be pushy: "use this whenever the user mentions X, Y or Z, **even if they don't say** '<skill>' explicitly". Anthropic's own docx/xlsx skills phrase it exactly that way.362. **What it does**, in one breath — enough for the model to know it's the right tool.373. **"NOT for…" — only if a sibling skill competes.** Anthropic's official skills mostly OMIT this, because their domains are distinct (pdf ≠ xlsx, no confusion possible). Add it when you have adjacent skills that could both match (a "review changes" skill vs a "ship a feature" skill) — there it disambiguates. Don't add it just to look careful: an over-restrictive description makes the skill under-trigger, which is the worse problem.3839```40---41name: my-skill42description: Use when <situations>, e.g. "<real phrase>", "<real phrase>" — be a little pushy43 ("whenever the user mentions …, even if they don't say '<skill>'"). <what it does in one line>.44 [NOT for <adjacent case> — add only if a sibling skill competes.]45---46```4748Name: lowercase, hyphens, a verb-or-noun that reads as a command (`book-distill`, `senior-review`). Add `argument-hint` if the skill takes arguments.4950**Model-invoked vs user-invoked.** By default a skill is model-invoked: its description sits in context and other skills can reach it — right for reusable knowledge that should fire on its own. Set `disable-model-invocation: true` to make it user-invoked (`/skill` only): the description leaves the model's reach, saving context. Reserve it for skills nobody else needs to auto-trigger — heavy, domain-specific, run-on-demand (a tax-dossier writer, a one-off migration).5152## Keep the body skimmable (progressive disclosure)5354Three loading levels: **metadata** (name + description, always in context) → **SKILL.md body** (loaded when the skill fires) → **bundled resources** (loaded or executed on demand). Keep the body lean so it doesn't crowd the context.5556- **< 500 lines is the target, not a law.** Anthropic's own docx skill is 590. Go longer when the domain warrants it, but past ~500 add a layer of hierarchy and clear pointers ("for X, read references/x.md").57- **Externalize the heavy stuff — when it pays.** Two thirds of Anthropic's official skills are a single SKILL.md; split only when it earns it. When you do, **`scripts/` (executable, deterministic ops) earns its place far more often than `references/` (docs)** — the document skills (pdf, xlsx, docx) are mostly scripts. Use `references/<variant>.md` for multi-framework domains; a reference over ~300 lines gets a table of contents.58- **Imperative and concrete.** "Do X. Never Y." Minimal example over paragraphs of theory.59- A checklist at the end beats a wall of prose.6061## Folder shape6263```64my-skill/65└── SKILL.md # required: frontmatter (name, description) + body66 (optional alongside:)67 scripts/* # executable code for deterministic ops (earns its place most often)68 references/*.md # detail loaded on demand (multi-framework, heavy domains)69 assets/* # templates, fonts, icons used in the output70```7172Personal skills live in `~/.claude/skills/<name>/` (or a project's `.claude/skills/`). To SHARE one, wrap it in a plugin.7374## Package for distribution (plugin + marketplace)7576To make a skill installable by others:7778```79my-plugin/80├── .claude-plugin/81│ └── plugin.json # { "name", "description", "version", "author" }82└── skills/83 └── my-skill/84 └── SKILL.md85```8687A **marketplace** is a repo with `.claude-plugin/marketplace.json` listing plugins (each `source` a relative path like `./plugins/my-plugin`). Users add and install with:8889```bash90/plugin marketplace add owner/repo91/plugin install my-plugin@marketplace-name92```9394Validate before publishing: `claude plugin validate <path>`. Pin a `version` (omit it and every commit becomes a new auto-updating version). Keep all files inside the plugin root (no `../shared`).9596## The loop to author one97981. **Decide it's a skill** (see the five primitives).992. **Write the description first** — Use-when + real trigger phrases, leaning pushy; add NOT-for only if a sibling competes. This is the product.1003. **Write the lean body** — core principle, the steps/loop, a minimal example, a checklist.1014. **Externalize the heavy stuff** to `reference/`.1025. **Test triggering**: does it fire on the real phrases? Does it stay silent on the adjacent cases? Tune the description, not the body.1036. **Package + validate** if sharing (plugin.json, marketplace.json, `claude plugin validate`).104105## Anti-patterns106107- **Vague description** ("helps with code") — it never triggers. The most common failure, and worse than over-triggering.108- **Over-restrictive description** — too many caveats and the skill under-triggers (the bigger risk). Lean pushy; reserve "NOT for" for genuine sibling competition.109- **Monster SKILL.md** — only a problem if the bulk is detail that belongs in scripts/ or references/; size alone isn't the sin (docx is 590 lines).110- **Hardcoding one project's specifics** in a skill meant to be reused — keep it stack-agnostic, discover specifics live.111- **Renaming the concept mid-body** — one term, used consistently (the model anchors on it).112- **Wrong primitive** — an always-on rule should be CLAUDE.md or a hook, not a skill.113- **Sediment** — stale instructions left from past versions that no longer match the skill; prune them on every edit instead of layering on top.114- **No-op line** — a sentence the agent would follow anyway; delete the whole sentence, don't trim its words.115116## Checklist117118- [ ] A skill is the right primitive (not CLAUDE.md / subagent / hook / MCP)119- [ ] `description` has Use-when + real trigger phrases, leans pushy (under-triggering is the bigger risk); NOT-for only if a sibling competes120- [ ] Name is lowercase-hyphen, reads like a command121- [ ] Body is skimmable; heavy detail lives in reference/122- [ ] One leading word the model already knows, repeated in name + description + body; imperative, minimal examples123- [ ] The skill gives the agent a checkable "done" signal (completion criteria)124- [ ] Triggers on the intended phrases, silent on adjacent cases125- [ ] If shared: plugin.json + marketplace.json, version pinned, `claude plugin validate` passes