If you have used Claude Code for more than a few sessions, you have probably typed the same context into the opening of every window. Project conventions. Service names. The deploy pattern. The testing rule. The agent forgets between sessions, and you re-explain the same ground. A Skill is the primitive that carries that context for you.
This piece covers what a Skill actually is, what it is not, when to reach for one instead of a system prompt or an MCP server, how to build a minimal working example, and the five modes in which they go wrong.
What a Skill is
A Skill is a folder under .claude/skills/<name>/ that contains a SKILL.md file. That file holds the instructions, context, or workflow you want the agent to follow. Any supporting files, scripts, reference lists, templates, live in the same folder alongside SKILL.md.
The defining feature of Skills is automatic loading. Claude reads the description field in the frontmatter of every available Skill at session start and decides when to load one on its own, based on how well that description matches what you are currently working on. You do not have to invoke it. If you ask Claude Code to summarize what changed in your branch and you have a Skill whose description says "summarize git changes in the working copy", Claude loads it without being asked.
You can also invoke any Skill directly by typing /skill-name in Claude Code. That is the slash-invocation route, and both routes are on by default. Two frontmatter fields let you restrict them: disable-model-invocation: true turns off auto-loading and leaves only the slash command; user-invocable: false turns off the slash and leaves only auto-loading.
Personal Skills sit under ~/.claude/skills/ and are visible across all your projects on that machine. Project-level Skills sit under .claude/skills/ in your repository and travel with it for everyone on the team. Enterprise and plugin locations also exist, but personal and project are the two you will reach for first.
See the official documentation for the full frontmatter reference.
What a Skill is not
A Skill is not a system prompt. A system prompt is always present, paid on every turn, and set at agent configuration time. A Skill is loaded only when used. If you have a 2,000-word coding standard that applies to every session, the system prompt is the right place for it. If the same standard is only relevant during code review, a Skill saves those tokens on the turns where it is not needed.
A Skill is not an MCP server. MCP servers expose callable tools: functions the agent invokes to read data, take actions, or return structured results. A Skill delivers static instructions. You would build an MCP server when the agent needs to query a database or call an external API. You would write a Skill when you want to package a checklist, a convention, or a step-by-step process.
A Skill is not a subagent. A subagent is a spawned child invocation that Claude Code creates to run a sub-task in a separate context window with its own tools. A Skill runs in the main agent context by default. You can set context: fork in the frontmatter to give it a forked window, but even then it is a loaded instruction set, not an independent agent.
A Skill is not a Claude Project. Claude Projects (the claude.ai product) embed context into a persistent conversation in the browser. Skills are local files in the CLI harness. If you are working in Claude Code as your primary surface, Skills are your lever, not Projects.
The older .claude/commands/*.md format is the predecessor of Skills. A file at .claude/commands/deploy.md and a Skill at .claude/skills/deploy/SKILL.md both create /deploy and both still work. The Skills format adds the folder structure, the supporting-file capability, frontmatter for invocation control, and the automatic description-match loading that the older format did not have. If you want the deeper framing on where agent-driven flows differ from direct-invocation patterns, see what vibe coding actually is.
When to use a Skill
Three concrete triggers:
You re-type the same setup every session. If your session opening is the same block of text more than a few times in a row, it belongs in a Skill. Coding conventions, project constraints, deployment notes, review criteria: anything you would write down for a developer joining the repo for the first time.
A process has steps that must run in a specific order. Code review checklists, release procedures, debugging runbooks. A Skill carries the sequence without you reconstructing it each time, and without the sequence drifting from what you actually want.
The project uses vocabulary the agent gets wrong cold. Internal service names, proprietary data formats, third-party API quirks your team has documented. Load them on the turns where they matter, not on every turn.
What does not belong in a Skill: anything that changes between sessions. Live ticket data, current branch state, today's error logs. Static file, static context. For anything dynamic, use a tool. If you are still at the setup stage with Claude Code and want a smaller first exercise, how to start vibe coding covers the first-session loop.
A minimum viable Skill, walked through
Here is the smallest Skill that actually does something useful. This example is drawn from the Anthropic documentation.
Create the folder under your personal Skills directory:
mkdir -p ~/.claude/skills/summarize-changes
Create ~/.claude/skills/summarize-changes/SKILL.md:
---
description: Summarize git changes in the working copy
allowed-tools: Bash
---
Summarize the changes currently staged and unstaged in the working copy.
Steps:
1. Run `git status` and read which files are modified, staged, or untracked.
2. Run `git diff` for unstaged changes and `git diff --staged` for staged ones.
3. Group changes by purpose: feature additions, bug fixes, refactors, config changes.
4. Write a plain summary: what changed, why each group matters, and anything the caller should know before committing.
5. Do not invent file paths or line numbers you have not read.
Because this Skill lives under ~/.claude/skills/, it is available across all your projects on this machine without being checked into any repository.
Auto-loading route: start a Claude Code session in any repository, then say "what did I change this morning?" Claude reads the description field of every available Skill, matches "summarize git changes in the working copy" against the current task, and loads this Skill without you typing a command.
Slash route: type /summarize-changes in any session. Claude loads SKILL.md directly and runs the steps. Useful when you want it on demand regardless of what Claude inferred about the context.
The allowed-tools: Bash frontmatter line pre-approves the Bash tool for the duration of this Skill. Without it, Claude would need to request permission mid-run. You can list multiple tools: allowed-tools: Bash Read Glob.
To test: run the Skill on a real working copy with some changes and read the output. If the summary is wrong, edit SKILL.md and reinvoke. No restart, no rebuild. The file is read fresh on every invocation.
How Skills fail
Five common modes, in roughly the order you will hit them.
The name is too generic. Vague names compound quickly once you have more than a handful of Skills. "Fix bug", "review", "analyze" tell you nothing three weeks later. Name Skills for the action and the context: review-staged-diff, explain-architecture, debug-test-failure. Write the first line of SKILL.md as a sentence you can read and act on at a glance.
The Skill is too large. A 3,000-word SKILL.md costs those tokens on every invocation, on top of whatever context is already loaded. Long Skills also get read incompletely in practice: the agent satisfices near the top and misses instructions that come later. If a Skill keeps growing, split it. One Skill per distinct workflow.
Secrets end up in the file. A Skill file is plain text, usually version-controlled. An API key or connection string written into SKILL.md is in your git history from that commit forward. Store credentials in your environment or credential store. If the Skill needs to reference a secret, name the environment variable; do not write the value.
Personal Skills do not follow you between machines. Skills under ~/.claude/skills/ are on the machine where you created them. A second laptop or a remote dev environment sees none of them. Decide early whether a Skill is personal or project-shared, and if you rely on personal Skills, manage them in a dotfiles repository.
The description does not match the context you intended. Auto-loading fires on the match between the current task and the description field. A description that is too broad triggers the Skill in situations you did not want; one that is too narrow never fires when you need it. Write it as one specific sentence that names the action and the material: "summarize git changes in the working copy" matches when you ask about recent diffs and does not match when you ask about deployment. Test it across a few real sessions and check whether the Skill loads at the moments you expect.
When Skills are the wrong answer
A Skill is the right tool for static, reusable instructions you want loaded on demand. It is the wrong tool when:
The context is dynamic. If what you need depends on today's data, the current branch state, or live logs, reach for a tool. A Skill file cannot call an API or read changing state.
The instructions are specific to one job. Writing a Skill for a task you will do once adds overhead with no return. Type the instructions directly in session.
You need to share context across agents or across a pipeline. Skills are local files read by the harness on that machine. They do not cross process boundaries. For shared context in a multi-agent system, the right layers are your CLAUDE.md or the node's memory store.
You need guardrails the agent cannot override. Skills instruct; they do not enforce. A deviation from a Skill's steps is possible and will happen. Constraints that must hold go in the system prompt or in a programmatic check on tool output.
FAQ
What is the difference between a Skill and an MCP server?
An MCP server exposes callable functions: the agent invokes them at runtime to read live data, take an action, or return a structured result. A Skill is a static instruction file loaded into context, either by Claude's description-match or by your slash command. If the agent needs to query a database or call an external API, build an MCP server. If you want to package a checklist, a convention, or a workflow the agent should follow, write a Skill.
Can I share Skills across projects?
Project-level Skills under .claude/skills/ in your repository travel with the repo and are available to everyone who clones it. Personal Skills under ~/.claude/skills/ are available across all your projects on that machine but do not travel with any single repository. To use the same personal Skills on multiple machines, manage them in a dotfiles repository and sync them manually or with a setup script.
How does the agent decide which Skill to load?
Claude compares the current task against the description field in the frontmatter of every available Skill and loads the best match, automatically, without you typing anything. If a Skill has disable-model-invocation: true in its frontmatter, auto-loading is off for that Skill and only /skill-name works. The automatic description-match route is the reason Skills exist as a distinct primitive from the older .claude/commands/*.md format; that format had no description-match mechanic.
Can I put API keys or credentials in a Skill file?
No. Skill files are plain text, often checked into version control. A credential in a Skill file is a credential in your git history. Store secrets in environment variables or your credential store. If the Skill's instructions need to reference a credential, name the variable: write "use the value from GITHUB_TOKEN", not the token itself.
If you have hit the ceiling of what Claude Code's built-in features give you and need a senior engineer to help design the tooling layer for your team's workflow, that is the kind of project we take on at klim.expert.