
Writing a Claude Code skill that actually fires
Most skills are correct files with descriptions that never match real language. The frontmatter fields that change behaviour, and the three skills a website repository should carry.
If you keep pasting the same three paragraphs of instruction into a new session, you have already written a skill and are just storing it badly. A skill is that text in a file the agent can load on its own, at the moment it is relevant, instead of when you remember to supply it. The mechanics are simple enough to learn in an afternoon, and the part that decides whether it works is not the mechanics.
Where the file goes decides who gets it
A skill is a folder with a markdown file called SKILL.md inside it, and the folder's location is the whole access-control story. Put it under your home directory and it loads in every project on your machine. Put it in the repository and it loads for everyone who works there, once committed. The skills documentation has the full table, including the nested case for monorepos and the plugin case for distributing one across a team.
For client work the repository location is almost always right, because a skill that encodes how this site is built should travel with the site. The home-directory location is for your own habits: how you like commits written, which checks you always want run.
The description is written for the dispatcher
This is where most skills fail, and it is not obvious from reading one. The description field is not a summary for a human browsing a list. It is the text the agent reads to decide whether this skill applies to what you just asked, and nothing else about the skill is loaded until that decision is made. A description that says what the skill is will not fire. A description that says when to use it will.
Two details follow from that. Put the key use case first, because the combined description text is truncated in the listing at 1,536 characters to keep context cost down. And include the phrases you actually type, not the formal name of the task: if you say check the crawl, the description should contain check the crawl.
The frontmatter fields that change behaviour
| Field | What it does | The mistake |
|---|---|---|
| description | Decides when the skill fires | Describing the skill instead of the trigger |
| when_to_use | Extra trigger phrases, appended to the description | Repeating the description instead of adding phrasings |
| disable-model-invocation | Stops the agent loading it on its own | Leaving it off on anything destructive |
| allowed-tools | Pre-approves tools for that turn only | Granting more than the task needs |
| argument-hint | Shows expected arguments in autocomplete | Omitting it on a skill that takes input |
One of those deserves emphasis. Anything that deploys, deletes, publishes or sends should carry disable-model-invocation, so it runs only when you type its name. We gate every skill we install this way as a standing rule, because the cost of a deploy skill firing on its own judgement is not symmetrical with the cost of typing six characters.
Keep the body short, because it stays in context
Once a skill loads, its content stays in context across turns, so every line is a recurring cost for the rest of the session. The docs say to state what to do rather than narrating how or why, and that is the right instinct. A skill that explains its own reasoning for four hundred words is charging you for that reasoning on every subsequent request.
The move that makes this bearable is supporting files. Keep SKILL.md to the decision rules and put the long reference material in a separate file alongside it, mentioned by name. The agent reads it when it needs it and not before. Anything deterministic belongs in a script rather than in prose: a check with a pass or fail answer should be a command, not a paragraph asking the agent to look carefully.
Test it by trying to make it fire
The only test that matters is whether the skill loads when it should. Open a fresh session, phrase the request the way you would naturally phrase it, and see whether the skill comes in. Then phrase it three other ways. Most broken skills are correct files with descriptions that never match real language, and you will not discover that by reading your own description, because you already know what it means.
Three worth writing for a website repository
Start with the verification skill: the exact sequence of commands that proves a change works on this site, since that sequence is different for every project and nobody remembers it. Then the content skill: the rules your copy follows, which for us includes never using an em dash and which pages stay in English only. Then the release skill, gated to manual invocation, holding the pre-deploy checklist from the production piece.
That is the full set for a marketing site, and it is deliberately small. The companion piece on the skills worth having covers the ones you can install rather than write, and the CLAUDE.md piece covers what belongs in instructions instead. A skill answers how we do this particular job; instructions answer what is always true here. Confusing the two is how both files get too long.
Naming, and the two ways a skill gets invoked
A skill can arrive two ways, and the distinction decides how you name it. The agent can load it on its own, matching your request against the description, or you can type its name as a command. The name defaults to the folder name, and because the same text appears in the slash menu, a skill called release reads correctly when typed and badly when matched. The slash command reference covers the older command-file format, which still works and shares most of the same frontmatter.
The practical rule is to name for the typed case and write the description for the matched case, because the two audiences genuinely differ. A verb and a noun works for both: check-crawl, write-post, run-release. Avoid names that collide with a command you already use, since resolution between skills sharing a name is a rule you then have to remember.
The rest of the configuration surface is covered in the companion pieces: the skills worth installing rather than writing, the MCP servers that solve the access problem a skill cannot, and the hooks that enforce what a skill only requests.

