You wrote a genuinely good Skill. The instructions are tight, the scripts work, you tested them by hand. Then you give Claude the exact task it's built for — and it does the task without ever touching your Skill. The reflex is to go rewrite the body. That's the wrong file.
The short answer, up front: a Skill that never fires is almost always a description problem, not a body problem. At startup, only each Skill's name and description are pre-loaded into the system prompt — roughly 100 tokens each. Claude reads the SKILL.md body only after the description matches your request. So a flawless body behind a weak description never runs. Fix the description first.
The one non-obvious thing about how Skills fire#
Progressive disclosure is the whole design: you can install a hundred Skills and pay almost nothing, because until one triggers, only its name and description occupy context. The flip side is the trap. Claude uses the description to choose the right Skill from potentially 100+ available ones — it's a matching problem, and the description is the only thing being matched. Everything you put in the body is invisible to that decision.
So the mental model is: the description is a discovery ad, not a summary. Its job isn't to explain the Skill to a human reading the repo. Its job is to make Claude, mid-task, recognize "this is the one."
Rule 1 — Say what it does and when to use it#
The single most common failure is a description that says what the Skill does but never says when. Compare Anthropic's own PDF example:
description: Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction.
The first sentence is what. The Use when… clause is when — and it's doing the real work, because it names the concrete triggers (PDFs, forms, document extraction) that a user's actual request will contain. Two more from the docs, same shape:
description: Analyze Excel spreadsheets, create pivot tables, generate charts. Use when analyzing Excel files, spreadsheets, tabular data, or .xlsx files.
description: Generate descriptive commit messages by analyzing git diffs. Use when the user asks for help writing commit messages or reviewing staged changes.
Notice they include file extensions and literal phrases a request would use (.xlsx, "commit messages"). That's not filler — it's the match surface.
Rule 2 — Write it in third person#
This one is subtle and costs people hours. The description is injected into the system prompt, so point-of-view matters:
- ✓
Processes Excel files and generates reports - ✗
I can help you process Excel files - ✗
You can use this to process Excel files
First- and second-person phrasing causes discovery problems. A Skill that "works on my machine" but never fires for a teammate is very often written as "I can help you…". Rewrite every description as a third-person statement about the Skill.
Rule 3 — Kill the vague words#
These descriptions are real, and they never trigger reliably:
description: Helps with documents
description: Processes data
description: Does stuff with files
There's nothing for Claude to match. "Documents" doesn't distinguish your Skill from ten others, and it doesn't map to any specific request. Replace generic nouns with the actual file types, operations, and situations. Specific beats short.
Rule 4 — The name is part of the trigger#
The name is pre-loaded next to the description and feeds the same decision, so it has a spec and a craft:
- Format (hard rules): max 64 characters, lowercase letters, numbers, and hyphens only, no XML tags, and it cannot contain the reserved words
anthropicorclaude. - Style: prefer gerund form —
processing-pdfs,analyzing-spreadsheets,managing-databases,writing-documentation. Noun phrases (pdf-processing) are fine. - Avoid: vague names like
helper,utils,tools, ordata— they read as generic to Claude just like vague descriptions do.
The debugging loop#
Because triggering is a metadata problem, debug it as one:
- Reproduce the miss. Give Claude the request that should fire the Skill. If it doesn't fire, don't touch the body.
- Read your description as a matcher. Does it contain the literal words and file types the request used? If not, add a
Use when…clause that does. - Check the person. First/second person? Rewrite to third.
- Check for collisions. If two Skills have overlapping descriptions, they'll fight — differentiate the when in each and give them distinct names.
- Re-test with real requests, not paraphrases of your own description. Anthropic's guidance is explicit: iterate by observing which Skill Claude actually triggers, then refine the name and description — those two fields are "particularly critical."
Everything else in the best-practices guide — concise bodies under 500 lines, one-level-deep references, workflows with checklists — matters only after the Skill fires. Get the description right and the rest of your work finally gets to run.
One more surface note: even a perfectly-triggering Skill behaves differently depending on where it runs — the Claude API sandbox has no network and no package install, while Claude Code has full access. If your Skill fires but then fails, that's the other half of the story, and we covered it in Your Agent Skill Runs Differently on Every Surface. Still deciding whether this should be a Skill at all versus an MCP server? Start with Agent Skills vs MCP.



