← All skills

Writing Skills

Writes and revises Agent Skills so they are discovered and followed — frontmatter that validates, descriptions that match real requests, progressive disclosure, and the right degree of freedom. Use when creating a SKILL.md, editing an existing skill, packaging one for distribution, or working out why a skill never triggers.

Skill name
writing-skills
Category
meta
Price
Free
Install
~/.claude/skills/writing-skills/SKILL.md
Tags
skills, authoring, prompting, documentation, meta

Writing Skills

A skill has two jobs, and they fail independently. It has to be found — which is entirely the description's work — and then followed, which is the body's. Most broken skills are well-written bodies attached to a description nothing matches.

The contract

SKILL.md opens with YAML frontmatter. Two fields are required:

---
name: processing-invoices
description: Extracts totals, dates and line items from PDF and scanned invoices, and writes them to CSV. Use when the user mentions invoices, receipts, accounts payable, or bulk data entry from documents.
---

leading, trailing or doubled hyphens. It must match the directory name.

because the frontmatter is injected into a system prompt verbatim.

Optional and rarely needed: license, compatibility (up to 500 characters, only when the skill has real environment requirements), metadata (a flat map of strings), and allowed-tools (a single space-separated string).

The description is the whole discovery surface

Only name and description are loaded at startup, for every installed skill at once. Nothing else about the skill is visible until it triggers. So the description must carry both halves — what it does, and when to reach for it — in the third person, using the words a person would actually type.

Instead ofWrite
Helps with documentsExtracts text and tables from PDF files, fills forms, merges documents. Use when working with PDFs or when the user mentions forms or document extraction.
I can review your codeReviews changed code for correctness bugs and unclear naming. Use when the user asks for a code review or mentions a pull request.
Data toolCleans messy CSV exports: fixes headers, normalises dates, removes duplicate rows. Use when a spreadsheet or CSV will not parse cleanly.

Write the description last, then test it: list five ways someone might ask for this help, and check each phrasing against the words actually in the field.

What belongs in the body

The body loads in full every time the skill fires, so its length is a cost paid by every task that touches it. Keep it under 500 lines and roughly 5000 tokens.

Assume a capable reader. Explaining what a PDF is, or how imports work, spends context on something already known. Write the parts that are specific to this job: the conventions, the constraints, the sequence, the thing that goes wrong the first time.

Push detail outward. A skill can bundle as much as it likes, because nothing costs anything until it is read:

processing-invoices/
├── SKILL.md              loaded when the skill triggers
├── references/
│   └── field-mapping.md  read only when the mapping is needed
└── scripts/
    └── extract.py        executed; its source never enters context

Two rules make that work. Link every reference directly from SKILL.md — a file reached through another file gets partially read, so a chain quietly loses information. And give any reference over about 100 lines a contents list at the top, so a partial read still shows what is in it.

Degrees of freedom

Match how specific the instructions are to how fragile the task is.

Give direction and stop. "Check for edge cases and unclear naming" beats a twelve-point rubric that will be applied mechanically to code it does not fit.

subtly wrong. Give the exact command and say plainly not to deviate.

Both failures are common, and they look the same from the outside: the skill is ignored. Over-specified instructions get skipped because they do not fit; under- specified ones get improvised around.

Things that reliably work

describing it.

are more than about five.

again, and an explicit "only continue when it passes".

under an "Old patterns" heading.

The authoring loop

- [ ] 1. Do the task once by hand, noting what context you had to supply
- [ ] 2. Write the smallest SKILL.md that captures it
- [ ] 3. Write three test requests, phrased as a user would phrase them
- [ ] 4. Run them in a fresh session with the skill installed
- [ ] 5. Watch where it goes wrong: not triggered, wrong file read, step skipped
- [ ] 6. Fix the specific cause, not the general vibe, and run the three again

Step 5 is the one people skip, and it is the only step that produces evidence. Not triggering is a description problem. Reading the wrong file is a structure problem. Skipping a step is usually a prominence problem — the instruction was present but buried.

The full pre-publication checklist is in references/checklist.md.

Common failures

SymptomCauseFix
Never triggersDescription says what, not whenAdd the triggering situation and the user's own vocabulary
Triggers on the wrong thingsDescription too broadName the boundary explicitly
Instructions ignoredBody too long, key rule buriedCut, then promote the rule to its own section
Bundled file never readNot linked from SKILL.mdLink it directly, and say what it is for
Works for you, not for othersAssumed local contextState the assumption or remove the dependency

Distributing it

The directory is the unit. Zip it with the directory name matching the name field, and it unzips into ~/.claude/skills/ for personal use or .claude/skills/ inside a project. Treat a skill from anyone else as you would any other code you are about to run: read the scripts, and look at what any external address it contacts is for.