How to Build a Claude Code Skill
Updated September 17, 2026
A Claude Code skill is a SKILL.md file in a folder that Claude Code watches. That much is shared with every other surface. What is specific to Claude Code is where it looks, how a skill becomes a slash command with arguments, and the frontmatter that controls who can invoke it and which tools it may use without asking. This guide covers those parts, as documented in the Claude Code skills reference.
The short answer
- Create .claude/skills/<name>/SKILL.md in the project (shared through git) or ~/.claude/skills/<name>/SKILL.md for yourself.
- Give it a name, a description, and instructions. The skill is now /name and also loads on its own when a request matches the description.
- Use $ARGUMENTS in the body to receive whatever you type after the command.
- Add disable-model-invocation: true for anything you want to trigger only by hand, such as a deploy.
- Edits are picked up live. Check with /skills.
Where Claude Code looks
Skills load from several places, and a higher row overrides a lower one when names collide:
| Location | Path | Who gets it |
|---|---|---|
| Managed | .claude/skills/ in the managed settings directory | Everyone with the deployed settings |
| Personal | ~/.claude/skills/<name>/SKILL.md | You, in every project on this machine |
| Project | .claude/skills/<name>/SKILL.md | Anyone working in this repository |
| Nested | <subdir>/.claude/skills/<name>/SKILL.md | Sessions in or below that subdirectory |
| Plugin | <plugin>/skills/<name>/SKILL.md | Wherever the plugin is enabled; invoked as /plugin:name |
| Account | Skills enabled on claude.ai, synced to ~/.claude/skills/synced/ | Sessions signed in to that account |
The personal and project folders are watched, so changes take effect within the running session. The name synced is reserved for account skills. In a monorepo, a skill in the repository root loads everywhere, and one in a package folder loads for work in that package.
Invoking a skill and passing arguments
Every skill is a slash command unless you hide it. Typing /fix-issue 123 runs the skill with $ARGUMENTS set to “123”. Indexed forms $0 and $1 pick individual words, and an arguments field in the frontmatter names them: with arguments: [component, from-lang, to-lang], the body can say “Migrate $component from $from-lang to $to-lang”. Plugin skills carry their namespace: /my-plugin:my-skill.
The skill's rendered content enters the conversation once and stays there across turns; Claude Code does not re-read the file on later turns. Invoking it again with the same arguments adds a short note rather than a second copy.
Controlling who triggers it
By default both you and Claude can invoke a skill: you by name, Claude when the description matches. Two fields change that. disable-model-invocation: true hides the skill from Claude entirely, so it loads only when you type its name, which is the right setting for deploys, releases, and anything with side effects. user-invocable: false does the opposite: it disappears from the slash menu and only Claude can load it, which suits background reference material.
A third field, paths, takes glob patterns and makes the skill auto-load only when Claude is editing files that match, so a skill about a particular package does not surface elsewhere.
Tools and permissions
allowed-tools pre-approves specific tools for the turn in which the skill is invoked, for example **Bash(git add *) Bash(git commit *) for a commit skill. It removes permission prompts; it does not add tools, and deny rules still win. The grant clears on your next message. disallowed-tools removes tools from Claude's pool while the skill is active, which is how an autonomous skill can, say, prevent Claude from stopping to ask a question. When a skill refers to an MCP tool, use the full ServerName:tool_name** form, which Anthropic recommends to avoid “tool not found” errors.
Running in a fork
context: fork runs the skill in a fresh subagent with the skill as its prompt and none of the conversation history. agent picks the subagent type, such as Explore or Plan, and background: false makes the current turn wait for the result. This keeps a long research or review task from filling the main conversation.
Skills can also pull in live context before Claude sees them: a line beginning with an exclamation mark and a backticked shell command is replaced by that command's output when the skill renders. A failing command aborts the invocation, so append || true to anything that may legitimately exit non-zero.
Test and iterate
Ask for the task in plain words and confirm the skill loaded. /skills lists every skill Claude can see with its description; /skill-doctor reports which skills are used, what they cost, and which never fire. If a skill fires too often, tighten the description; if it never fires, add the terms a request would contain. Anthropic's skill-creator plugin can run evaluation cases against a skill and compare results with and without it.
Keep one eye on portability. Every field in this guide beyond name, description, license, compatibility, metadata, and allowed-tools is Claude Code-only and stops the file uploading to claude.ai or the API. If a skill has to travel, keep the extras out, or maintain a second copy. The SKILL.md Generator flags those fields when it checks a file, and the format guide lists all of them.
Common questions
- What happened to .claude/commands?
- Custom commands still work, but skills replace them. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and behave the same. Skills add a folder for supporting files, frontmatter such as disable-model-invocation, and automatic loading from the description.
- Do I need to restart Claude Code after editing a skill?
- No. The personal and project skill folders are watched and changes are picked up in the current session. Skills inside plugins need /reload-plugins.
- How do I stop Claude from running a skill on its own?
- Add disable-model-invocation: true to the frontmatter. The skill then loads only when you type its slash command. You can also set skills to name-only or off in settings, or deny them with a permission rule.
- Can a skill run a script that ships with it?
- Yes. Reference it with a forward-slash path relative to the skill folder, and Claude runs it through Bash; the script's code never enters the context, only its output. ${CLAUDE_SKILL_DIR} expands to the skill's own directory, which is useful inside plugins.
- Will my Claude Code skill work in claude.ai?
- Only if its frontmatter uses the six specification fields. Claude Code-specific fields such as model, paths, or context cause the upload to fail. Skills also do not sync automatically between Claude Code and claude.ai; each surface gets its own copy.
Try it yourself
- SKILL.md GeneratorDescribe a repeatable task and get a SKILL.md draft for Claude, checked against the published format.
- JSON FormatterFormat, minify, and check JSON for errors.
These live under Developer tools, alongside the rest of the claude skills & skill.md guides on the guides page.