Topic · A1
How to Write a Claude Code Skill Description That Actually Triggers
The SKILL.md description field is Claude's only trigger signal. This is the engineering discipline behind descriptions that get invoked when they should, and don't get invoked when they shouldn't.
The SKILL.md description field is the most important 200 words you will write for any Claude Code skill, and most authors get it wrong on the first try.
The mechanism: Claude Code loads every installed skill's description into the system prompt at session start. When the user (or Claude's own reasoning) generates a message, Claude evaluates which skill description matches and invokes the body of that skill. The description is the only trigger signal. If the description is vague, the skill never invokes. If it's too broad, the skill invokes when it shouldn't. The body of the skill — references/, scripts/, the rest of SKILL.md — only loads after invocation. So the description is the engineering surface area, and the rest is implementation.
This guide is the discipline behind writing descriptions that trigger reliably. It draws from Anthropic's authoring best practices, Obra's debugging post, and the patterns we've extracted from auditing hundreds of skills on the RuleSell catalog.
The shape of a description that triggers
A reliable description has four components:
- What the skill does — one clause, plain language
- When to use it — explicit trigger phrases users actually say
- What it produces — concrete output, not "helps with"
- Optionally: when NOT to use it — for skills that overlap with others
description: |
Code review for pull requests with a security and performance focus.
Use when reviewing a PR, auditing a file, or checking for security
issues, race conditions, N+1 queries, missing error handling, or
unsafe input handling. Triggered by "review this PR", "audit this
file", "check for security issues", "is this code safe". Produces
a structured review with severity-tagged findings (P0/P1/P2),
cited line numbers, and suggested fixes. Do NOT use for refactoring
or formatting — see /skill-refactor for that.
Six things this description does right:
- Names the concrete output: "structured review with severity-tagged findings, cited line numbers, suggested fixes"
- Lists 4+ trigger phrases verbatim
- Distinguishes from adjacent skills with a "do NOT use for" clause
- Mentions the specific bug categories the skill knows about (security, races, N+1)
- Imperative voice ("Use when")
- Stays well under the 1,536 character cap
description: "Helps with code review."
Four words. No trigger phrases. No output shape. Claude has nothing to match against beyond the literal string "code review" — and "code review" rarely appears verbatim in user messages. The skill sits unloaded.
The four-phrase rule
The single most effective discipline we have found: before writing the description, write down 6 ways a user might phrase the request that this skill should handle. Verbatim, in the user's voice. Then bake at least 4 of those phrases into the description.
For a skill that runs ESLint with auto-fix on the current file:
- "lint this file"
- "fix the lint errors"
- "run eslint"
- "check for code style issues"
- "format this"
- "are there any linting issues in this file"
The "pushy description" anti-pattern
Anthropic's authoring guide calls out a specific failure mode: descriptions that try too hard to trigger. Examples from their docs:
- "This is the BEST skill for code review. Always use this skill when reviewing any code."
- "Use this skill whenever the user mentions code, tests, files, or programming."
- "This skill should ALWAYS be invoked before any other skill."
The discipline is: describe what the skill does, name the trigger conditions, and trust Claude's matching. Marketing language is a tell that the author isn't confident in the actual capability.
Trigger phrases vs descriptive prose
There are two ways to convey "when to use this skill" and they have different effects.
Trigger phrases: "Triggered by 'review this PR', 'audit this file'." Descriptive prose: "Use when the user asks for a comprehensive code audit covering security, performance, and reliability dimensions."In our testing, trigger phrases dramatically outperform descriptive prose for invocation reliability. Claude pattern-matches phrases more reliably than it pattern-matches descriptions of intent. The descriptive prose version of the audit example above triggered in roughly 40% of "review this PR" messages; the phrase-list version triggered in 95%.
The implication: write trigger phrases as actual user utterances. "User asks to review code" is descriptive prose. "'review this PR', 'check this code'" is a phrase list. The phrase list wins.
Disambiguating overlapping skills
When two skills handle adjacent territory, both need explicit boundary statements. For example, a refactor skill and a lint skill overlap on "clean up this code." Without disambiguation, Claude picks one at random. With it, the right one fires.
In the refactor skill:
description: |
Refactor code for clarity and maintainability without changing behavior.
Use when the user asks to "clean this up", "simplify this", "this is messy",
"extract a function", "rename for clarity". Do NOT use for fixing lint
errors — that's /skill-lint. Do NOT use for behavior changes — that's
/skill-feature.
In the lint skill:
description: |
Run ESLint with auto-fix on the current file. Use when the user asks to
"lint this", "fix lint errors", "run eslint", "check code style". Do NOT
use for structural cleanup — that's /skill-refactor. Read-only on logic;
this skill only changes formatting and idiomatic syntax.
Each skill names its boundary against the adjacent one. Both descriptions reference the other's slash command. The user gets the right skill more often and the skills' authors avoid the silent "wrong skill invoked" failure.
The when_to_use field
Some skill ecosystems (notably Obra's Superpowers) split the trigger conditions into two YAML fields: description for what the skill does, when_to_use for trigger conditions. Anthropic's spec supports when_to_use and treats it as additional description content (counts against the 1,536-character cap).
We treat them as one combined field in practice — Claude sees the union and matches against both. If your skill plugin's tooling expects them separate, separate them; if not, put everything in description. The matching is the same.
What the rest of SKILL.md is for
Once Claude decides to invoke a skill based on the description, the rest of SKILL.md plus any references/ files load into context. This is where the implementation goes — the methodology, the checklist, the prompts, the example outputs. The first 500 lines are loaded eagerly. Below 500 lines, the rest may be loaded on demand depending on the client.
A common author mistake is to put trigger conditions in the body of SKILL.md. Wrong place. The body is for what to do after the skill triggers; the description is for whether it triggers. Body content that says "use this skill when the user asks to review a PR" is invisible — Claude doesn't read the body until after the trigger fires.
Diagnosing a skill that doesn't trigger
Eight common causes, per Obra's debug post:
- Vague description — covered above
- Skill listing budget overflow — too many installed skills, Claude truncates the listing. Set
SLASH_COMMAND_TOOL_CHAR_BUDGET=30000or trim other skills - Multi-line YAML description (Prettier reformatting) — use a single-line string or YAML block scalar, not implicit multi-line
- Wrong directory — must be
~/.claude/skills/or/SKILL.md .claude/skills//SKILL.md - Double-nested folder after unzip —
skills/my-skill/my-skill/SKILL.mdwon't load; the inner folder is wrong - Did not restart Claude Code after creating a top-level skills directory that didn't exist before
disable-model-invocation: true— only user-invokable via/skill-name- Task is simple enough that Claude solves it without invoking
/doctor in Claude Code to diagnose budget overflow specifically. The rest you find by reading the YAML.
Where this fails
Description optimization is empirical, not theoretical. The discipline above is the prior; the truth is what your specific Claude version does with your specific description. Test by installing the skill, running 10 representative user messages, and checking trigger rate. Iterate the description if it's below 80% on positive cases or above 5% on negative cases. Trigger reliability is not stable across Claude model versions. A description that triggers reliably on Opus 4.7 may behave differently on Sonnet 4.6 or future versions. Re-test on model upgrades. The "pushy description" boundary is fuzzy. A description with 6 phrase examples reads strong; a description with 20 reads pushy. Where the line falls depends on tone. Keep it under 1,200 chars and avoid superlatives ("BEST", "ALWAYS", "ONLY") and you stay safe. Auto-trigger is not the only invocation path. Users can always call a skill explicitly via/skill-name, regardless of description. If your skill is invoked primarily via slash command, description matters less for triggering but still matters for discoverability — /help and skill listings show the description.
What to read next
- /topic/skill-not-triggering — Obra's full 8-cause troubleshooting guide
- /topic/claude-code-hooks-cookbook — when to use a hook vs a skill
- /topic/skill-security-checklist — what to check before publishing a skill
- /topic/autoresearch — autoresearch ports use this pattern at scale
- /topic/best-claude-code-skills — examples of well-written descriptions in the wild
- /for/claude-code — install Claude Code itself
- /for/anthropics-skills — Anthropic's 7 reference skills with audited descriptions
Sources
- Anthropic. "Claude Code Skills documentation". Frontmatter reference, where skills live, the 1,536-character
description + when_to_usecap. - Anthropic. "Skill authoring best practices". "Pushy descriptions" anti-pattern.
- Obra (Jesse Vincent). "Why your Claude skill isn't triggering". 8 common causes.
- Obra. superpowers/skills/writing-skills/SKILL.md. Methodology behind their skill descriptions.
- HN 45607117. "Claude Skills" (simonw 'maybe a bigger deal than MCP').
- UX Planet. "7 rules for creating an effective Claude Code skill". Companion practitioner perspective.
Frequently asked
- What's the most common reason a Claude Code skill doesn't trigger?
- A vague description. The description field is the only signal Claude uses to decide whether to invoke a skill. 'Helps with code review' triggers on almost nothing. 'Use when reviewing a pull request for security issues, race conditions, or N+1 queries — auto-triggered by phrases like "review this PR" or "check for security issues"' triggers reliably. Specificity beats brevity here.
- How long should a skill description be?
- Description plus when_to_use is capped at 1,536 characters by Anthropic. Use most of it. The skills that fail to trigger are almost never too long — they're too short. Aim for 800-1,200 characters, including 3-6 phrase examples that match how users actually phrase the request.
- Should descriptions use first-person, second-person, or imperative?
- Imperative or third-person, both work. 'Use when X' (imperative) and 'Triggers when X' (third-person) both signal trigger conditions clearly. Avoid first-person ('I help with X') — it does not parse as a trigger condition and wastes characters.
- Can I include negative examples (when NOT to trigger)?
- Yes, and you should for any skill that overlaps with another. 'Use for X. Do NOT use for Y — see /skill-y for that.' is a clean pattern. Anthropic's authoring guide calls these 'pushy descriptions' when overdone, but a single negative example per skill is healthy.
- Does the description trigger on user messages or on Claude's internal reasoning?
- Both. Claude evaluates description matches against the user message and against its own internal reasoning chain. A skill described as 'Use when refactoring' will trigger when the user says 'refactor this' AND when Claude decides 'I need to refactor this code' in its planning. Write for both.
- Why does my skill trigger when I don't want it to?
- Description is too broad. 'Use when working with files' triggers on every session. Narrow the trigger to the specific task — file what, what action, in what context. The fix is the same as for under-triggering: more specificity.