Skills
Extend Claude Code with reusable SKILL.md modules — the evolution of custom commands
title: "Skills" description: "Extend Claude Code with reusable SKILL.md modules — the evolution of custom commands" section: "Core" readTime: "13 min" badge: "NEW"
Skills: Extending Claude Code
Skills are reusable instruction modules that extend what Claude can do. Create a SKILL.md file and Claude adds it to its toolkit — invoking it automatically when relevant, or when you call it directly with /skill-name.
Skills follow the open AgentSkills.io standard, so they work across Claude Code and other compatible AI tools.
Custom commands have been merged into skills: .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy. Existing command files keep working, but skills add supporting files, invocation control, and subagent execution. If both exist with the same name, the skill wins.
Where Skills Live
| Scope | Location | Available to |
|---|---|---|
| Enterprise | .claude/skills/<name>/SKILL.md in the managed settings directory | All users on machines where the org deploys it |
| Personal | ~/.claude/skills/<name>/SKILL.md | All your projects on this machine |
| Project | .claude/skills/<name>/SKILL.md | This repository (commit it to share) |
| Nested | <subdir>/.claude/skills/<name>/SKILL.md | Sessions in or below <subdir> |
| Additional directory | .claude/skills/ inside a directory passed with --add-dir | That session |
| Plugin | <plugin>/skills/<name>/SKILL.md | Where plugin is enabled, as /plugin-name:skill-name |
Skill directories are watched live — adding, editing, or removing a skill in an existing skills directory takes effect without restarting the session. If you create a brand-new top-level skills directory mid-session, run /reload-skills.
Project skills load from .claude/skills/ in the start directory and every parent up to the repository root. Skills in nested .claude/skills/ directories below where you started load the first time Claude reads or edits a file in that subdirectory.
Name conflicts: enterprise beats personal, and personal beats project. Plugin skills never conflict because they are namespaced.
Anatomy of a Skill
Every skill is a directory with SKILL.md as its entry point:
my-skill/
├── SKILL.md # Required: instructions + frontmatter
├── reference.md # Optional: detailed docs loaded on demand
├── examples.md # Optional: example outputs
└── scripts/
└── helper.py # Optional: scripts Claude can run
Minimal example
---
description: Summarize uncommitted changes and flag anything risky. Use when the user asks what changed or wants a commit message.
---
## Current changes
!`git diff HEAD`
## Instructions
Summarize the changes above in 2-3 bullets, then list any risks — missing error handling, hardcoded values, tests that need updating. If the diff is empty, say there are no uncommitted changes.Save to ~/.claude/skills/summarize-changes/SKILL.md, then ask "What did I change?" — Claude invokes it automatically.
Keep SKILL.md under 500 lines. Move detailed reference material into supporting files and link to them from SKILL.md so Claude loads them only when needed.
Frontmatter Reference
All fields are optional. Only description is strongly recommended.
| Field | Purpose |
|---|---|
name | Command name shown in the / menu (defaults to directory name). Lowercase, hyphens, max 64 chars |
description | What the skill does and when to use it. Claude uses this to auto-invoke. If omitted, the first non-empty line of the body is used |
when_to_use | Additional trigger phrases (appended to description; combined text is capped at 1,536 chars in the listing) |
argument-hint | Shown in autocomplete, e.g. [issue-number] |
arguments | Named positional args for $name substitution |
disable-model-invocation | true → only you can invoke it (good for /deploy, /commit) |
user-invocable | false → only Claude can invoke it (background knowledge) |
allowed-tools | Tools Claude can use without asking during the turn that invokes the skill |
disallowed-tools | Tools removed from Claude's pool while the skill is active |
model | Override model for the rest of the current turn (or inherit) |
effort | Override effort level: low, medium, high, xhigh, max |
context | fork → runs in an isolated subagent |
agent | Which subagent type to use with context: fork (default general-purpose) |
background | With context: fork, set false to wait for the subagent's result instead of running it in the background (default true) |
hooks | Hooks registered when the skill is invoked; they stay active for the rest of the session |
paths | Glob patterns — skill auto-activates only for matching files |
shell | bash (default) or powershell for ! commands |
metadata, license, compatibility | Agent Skills spec fields — accepted but not acted on by Claude Code |
Field names must match exactly, hyphens included. Unknown fields are silently ignored.
Dynamic Context Injection
The ! syntax runs shell commands before Claude sees the skill content. The output replaces the placeholder inline:
## Git status
!`git status --short`
## Last 5 commits
!`git log -5 --oneline`Multi-line commands use a fenced block:
## Environment
```!
node --version
npm --version
git branch --show-current
```This is preprocessing — Claude only sees the final rendered result, not the commands themselves.
- The inline form is only recognized when
!is at the start of a line or right after whitespace. - A failing command aborts the whole skill invocation.
- Admins can turn this off with
"disableSkillShellExecution": truein settings; each command is then replaced with a "disabled by policy" note.
String Substitutions
| Placeholder | Value |
|---|---|
$ARGUMENTS | Everything typed after the skill name |
$ARGUMENTS[0] or $0 | First argument |
$ARGUMENTS[1] or $1 | Second argument |
$name | Named argument (declared in arguments frontmatter) |
${CLAUDE_SESSION_ID} | Current session ID |
${CLAUDE_SKILL_DIR} | Directory containing this SKILL.md |
${CLAUDE_PROJECT_DIR} | Project root directory |
${CLAUDE_EFFORT} | Current effort level |
${CLAUDE_PLUGIN_ROOT} / ${CLAUDE_PLUGIN_DATA} | Plugin install dir / persistent data dir (plugin skills only) |
If no placeholder consumes the arguments, Claude Code appends them as ARGUMENTS: <value>. Escape a literal dollar sign before a digit with a backslash, e.g. \$1.00.
---
name: fix-issue
description: Fix a GitHub issue by number
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read the issue description
2. Understand the requirements
3. Implement the fix
4. Write tests
5. Create a commitRun with: /fix-issue 347
Invocation Control
| Frontmatter | You can invoke | Claude auto-invokes |
|---|---|---|
| (default) | ✅ | ✅ |
disable-model-invocation: true | ✅ | ❌ — use for side-effect workflows |
user-invocable: false | ❌ | ✅ — use for background knowledge |
Run Skills in a Subagent
Add context: fork to run the skill in an isolated subagent. The skill content becomes the subagent's prompt, and it doesn't see your conversation history, so use this only for skills with explicit task instructions:
---
name: pr-summary
description: Summarize a pull request
context: fork
agent: Explore
allowed-tools: Bash(gh *)
---
## Pull request context
- Diff: !`gh pr diff`
- Comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Task
Summarize this pull request: what changed, why, and what risks exist.Built-in agent types: Explore, Plan, general-purpose (the default), or any custom agent from .claude/agents/. The forked subagent runs in the background unless you set background: false.
Bundled Skills
Claude Code ships with built-in skills available in every session:
| Command | What it does |
|---|---|
/simplify [target] | Four parallel review agents (reuse, simplification, efficiency, abstraction level) clean up changed code and apply fixes. Does not hunt for bugs |
/code-review [level] [--fix] [--comment] | Review the current diff, a PR, branch, or path for correctness bugs |
/debug [description] | Turn on debug logging for the session and troubleshoot by reading the debug log |
/batch <instruction> | Split a large change into 5–30 units and run one background subagent per unit in its own worktree |
/loop [interval] [prompt] | Run a prompt repeatedly while the session stays open, e.g. /loop 5m check if the deploy finished |
/run / /verify | Launch your app to see a change working / confirm a change actually does what it should |
/claude-api | Load Claude API and Managed Agents reference material for your project's language |
A skill of your own with a bundled skill's name replaces it (but not its aliases).
Pre-Approve Tools
allowed-tools grants Claude permission to use specific tools without asking when the skill runs:
---
name: commit
description: Stage and commit changes
disable-model-invocation: true
allowed-tools: Bash(git add *) Bash(git commit *) Bash(git status *)
---Control Access with Permissions
Skills run through the Skill tool, so normal permission rules apply:
# Deny all skills
Skill
# Allow or deny specific skills
Skill(commit) # exact match
Skill(review-pr *) # prefix match with any arguments
Skill(deploy *)To change visibility from settings instead of frontmatter, set skillOverrides per skill name (plugin skills are not affected):
| Value | Listed to Claude | In / menu |
|---|---|---|
"on" | Name and description | Yes |
"name-only" | Name only | Yes |
"user-invocable-only" | Hidden | Yes |
"off" | Hidden | Hidden |
Troubleshooting
Skill not triggering: Check that description includes keywords the user would naturally say. Run /skills to verify it's listed. Invoke directly with /skill-name to test. If the YAML frontmatter is malformed, the body still loads but the description is empty — run claude plugin validate .claude/skills (or start with --debug) to find the parse error.
Skill triggers too often: Add disable-model-invocation: true for manual-only workflows, or make the description more specific.
Skill descriptions cut short: The skill listing budget is 1% of the model's context window; when it overflows, descriptions of your least-used skills are dropped first. Run /doctor for an estimate and /skill-doctor to find unused skills. Raise the budget with the skillListingBudgetFraction setting (e.g. 0.02), trim description text, or set low-priority skills to "name-only" in skillOverrides.
Claude stops following a skill later on: Skill content is added once and not re-read. Move must-hold rules into a hook (optionally via the skill's hooks frontmatter). After compaction only the start of a skill may survive, so keep key instructions near the top and re-invoke the skill if needed.
Related
- Auto Memory — Claude's persistent learning system
- Hooks — Deterministic lifecycle automation
- Subagents — Parallel and isolated execution
- Plugins — Package and distribute skills