Claude Code Skills: How to Build and Use Them

Claude Code skills are on-demand instruction folders that teach Claude Code how to do a specific task, each defined by a SKILL.md file whose name and description the model reads to decide when to use it. You drop a skill into ~/.claude/skills/ or your project's .claude/skills/, and from then on Claude Code loads it only when the work matches, so the instructions stay out of your context window until they are actually needed.
Most explanations treat Claude Code skills as "custom prompts," which undersells them and confuses them with slash commands. A skill is closer to a lazily loaded playbook the model chooses on its own, based on what you asked.
What are Claude Code skills?
They are packaged know-how the agent pulls in when relevant, not text you paste every time.
Each skill is a directory containing a SKILL.md. That file has YAML frontmatter with a name and a description, followed by the instructions themselves. The description is the part that does the work: Claude scans available skill descriptions, and when your request matches one, it reads the full body and follows it.
This is progressive disclosure in practice. The full instructions only enter context when the skill fires, which is why you can keep dozens of skills installed without bloating every conversation. A skill for writing migration files sits dormant until you actually ask about a migration.
Skills can bundle more than text. A skill folder can carry helper scripts, reference documents, and templates the instructions point to. So a "deploy checklist" skill might include the exact shell commands, and a "brand voice" skill might include a style reference the model reads before writing.
The mental model that clicks: a skill is a colleague's runbook the agent decides to open. You are not calling it; the model is choosing it from a shelf based on your intent and the skill's description.
How do you create a Claude Code skill?
Make a folder, write a SKILL.md, and Claude picks it up.
The smallest useful skill is one file. Create the directory and the manifest:
mkdir -p ~/.claude/skills/changelog
---
name: changelog
description: Use when the user asks to update the CHANGELOG or summarize
merged changes into release notes. Formats entries under Added, Fixed,
and Changed headings following Keep a Changelog.
---
# Changelog updates
When asked to update the changelog:
1. Read the recent git log since the last version tag.
2. Group commits into Added, Changed, Fixed, Removed.
3. Write entries in past tense, one line each, newest version on top.
4. Never invent a version number; ask if the bump is unclear.
That is a complete skill. Personal skills live in ~/.claude/skills/, project skills in .claude/skills/ so they travel with the repo, and plugins can ship skills to a whole team. If you are still setting up the tool itself, the how to use Claude Code walkthrough covers the basics first.
The frontmatter takes one more optional key worth knowing: allowed-tools. It restricts which tools the skill may use while it is active, so a documentation skill can be barred from running shell commands even if the rest of your session allows them. Leave it out and the skill inherits your session's permissions; add it when a skill should be sandboxed to a narrow job.
As a skill grows, split its body from its assets. Keep the procedure in SKILL.md and move long reference material into sibling files the instructions point to, such as reference.md or a scripts/ folder. Claude reads those extra files only when the skill body tells it to, so a large skill still costs nothing until it fires.
You invoke a skill in two ways. Usually you do nothing and let the model trigger it from the description. When you want to force it, type /changelog as a slash command.
Keep the body of a skill short and imperative. Long, hedged instructions get followed loosely. A numbered procedure with a hard rule or two gets followed exactly.
Skills vs MCP vs hooks: which do you reach for?
Different problems, different tools. Reaching for the wrong one is the most common mistake.
| Claude Code skills | MCP servers | Hooks | Slash commands | |
|---|---|---|---|---|
| What it adds | Know-how and procedures | External tools and data | Deterministic automation | A saved prompt you invoke |
| Who triggers it | The model, from the description | The model, when it needs the tool | The harness, on an event | You, by typing it |
| Runs code | Only bundled scripts you call | Yes, the server does | Yes, shell commands | No |
| Best for | "Do this task this way" | "Reach this database or API" | "Always run X after Y" | "Run this exact prompt" |
| Lives in | .claude/skills/ | config + a running server | settings.json | .claude/commands/ |
The line that matters: a skill teaches the model how, while an MCP server gives the model something new to do. If you need Claude to query Postgres, that is MCP. If you need Claude to follow your team's PR-review procedure, that is a skill.
Hooks are the third axis and the one people skip. A hook runs a shell command on an event, such as formatting code after every edit or blocking a commit that fails lint. Hooks are not the model's choice; they always fire, which is exactly why you use them for guarantees rather than judgment calls.
How do you write a skill Claude actually triggers?
Write the description for the model's decision, not for a human reader.
The single biggest failure mode is a vague description. "Helps with testing" tells the model almost nothing about when to fire. The model matches your request against these descriptions, so the description has to name the trigger conditions in the user's own language.
A strong description does three things:
- States the trigger explicitly ("Use when the user asks to..." or "Trigger on requests to...").
- Names the concrete nouns and verbs a user would say ("write a migration," "add a column," "rollback").
- Draws the boundary against neighbors ("Not for seeding data; use the seed skill for that").
Test it the way the model sees it. Ask for the task in a few phrasings and watch whether the skill fires. If it does not, the description is too abstract, not the body. The description is the trigger; the body is the behavior.
Two skills with overlapping descriptions will fight, and the model may pick the wrong one. Keep each skill's scope tight and make the boundaries in the descriptions mutually exclusive.
Can a skill react to what is on your screen?
Yes, if the skill is paired with a source of screen context. A skill on its own only knows what you type.
This is where skills, MCP, and a capture tool combine well. A skill can say "when the user points at the screen and says 'this' or 'that,' read the capture and act on the named element." But the skill still needs something to supply that named element, because Claude Code in a terminal cannot see your display.
PinVari fills that role. It ships a Claude Code skill that triggers when you point at the screen and use deictic language, and it exposes the resolved capture over a local MCP server. You hold ⌥⌘A, circle a broken button, and say "this label is wrong, it should read Save." PinVari resolves the exact accessibility element on-device, then the skill tells Claude how to read it through pinvari_next_instruction.
The reason this matters is accuracy. Without a resolved element, an agent maps "this button" to the wrong component and edits the wrong thing. With a named element carrying a role, label, and frame, the skill acts on the control you actually meant. The plumbing is in the local MCP server for screen context post.
PinVari runs on-device with no API keys of its own, distributed as a notarized DMG, and it is a one-time $39 launch license rather than a subscription, priced here.
FAQ
Where do Claude Code skills live?
Personal skills go in ~/.claude/skills/, project skills in .claude/skills/ inside the repo so they are shared through git, and teams can distribute skills through plugins. Each skill is its own subfolder containing a SKILL.md.
How is a skill different from a slash command?
A slash command is a saved prompt you invoke by typing it. A skill is chosen by the model from its description when your request matches, and it can bundle scripts and reference files. You can still force a skill with a slash-style invocation when you want to.
Do Claude Code skills use extra tokens?
Only when they fire. Because of progressive disclosure, the full instructions enter the context window solely when the skill triggers, so installing many skills does not tax every conversation the way a bloated system prompt would.
Can I share skills across a team?
Yes. Put project skills in .claude/skills/ so they travel with the repository, or package them into a plugin to distribute a whole set. Everyone who checks out the repo or installs the plugin gets the same skills.
Why does my skill never trigger?
Almost always the description is too vague. The model decides from the description alone, so it must name the trigger conditions in the words a user would actually type. Rewrite it to state "use when..." plus the concrete nouns and verbs, and test a few phrasings.
Hand your agent the exact element
PinVari resolves what you point at into a named, executable instruction — on-device, no keys, your own agent. If you run Claude Code, it is one command.
claude mcp add pinvariGet PinVari — $39 →


