What are Skills?
Skills extend Claude Code with custom commands. Add a SKILL.md file to .claude/skills/ and Claude automatically learns to use it when relevant, or you invoke it directly with /skill-name.
Skills follow the open Agent Skills standard with extensions: invocation control (who can call skills), subagent execution, and dynamic context injection.
SKILL.md Frontmatter — All Fields
Every skill begins with YAML frontmatter between --- markers:
| Field | Type | Default | Description | Example |
|---|---|---|---|---|
name |
String | (dir name) | Unique identifier, kebab-case, max 64 chars. Becomes the /slash-command. |
explain-code |
description |
String | (recommended) | What the skill does and when Claude should use it. Used for auto-invocation. Include trigger keywords. | Explains code with visual diagrams |
argument-hint |
String | (optional) | Hint shown during autocomplete. | [url] [--option] |
disable-model-invocation |
Boolean | false |
If true: only you can invoke, Claude cannot. Use for side-effect workflows (deploy, commit). | true |
user-invocable |
Boolean | true |
If false: hidden from menu, only Claude can invoke. For background knowledge. | false |
allowed-tools |
String | (all) | Comma-separated tools Claude can use without permission prompts. | Read, Grep, Glob |
model |
String | (inherit) | AI model: haiku, sonnet, opus, or full model ID. | sonnet |
effort |
String | (inherit) | Effort level: low, medium, high, max (Opus 4.6 only). | high |
context |
String | (inline) | If fork: runs in isolated subagent context, preserves main conversation. | fork |
agent |
String | general-purpose |
Which subagent for context: fork. Options: Explore, Plan, general-purpose. | Explore |
hooks |
Object | (optional) | Lifecycle hooks: PreToolUse, PostToolUse, Stop. | See hooks section below |
Frontmatter Example
---
name: deep-research
description: Thoroughly researches a topic with codebase search
context: fork
agent: Explore
allowed-tools: "Read, Grep, Glob"
model: sonnet
---
String Substitutions — Dynamic Values
Skills support string substitution for dynamic values:
| Variable | Description | Example |
|---|---|---|
$ARGUMENTS |
All arguments passed as string. Auto-appended with ARGUMENTS: <value> if not present. |
/fix-issue 123 urgent |
$ARGUMENTS[N] |
Access specific argument by 0-based index. | $ARGUMENTS[0], $ARGUMENTS[1] |
$N |
Shorthand for $ARGUMENTS[N]. |
$0, $1, $2 |
${CLAUDE_SESSION_ID} |
Current session ID for logging. | logs/${CLAUDE_SESSION_ID}.log |
${CLAUDE_SKILL_DIR} |
Absolute path to skill directory. ALWAYS use instead of hardcoded paths! | ${CLAUDE_SKILL_DIR}/scripts/helper.py |
Substitution Examples
With indexed arguments:
---
name: migrate-component
description: Migrate component between frameworks
---
Migrate $0 from $1 to $2. Keep all behavior and tests.
Invocation: /migrate-component SearchBar React Vue
→ $0=SearchBar, $1=React, $2=Vue
With session logging:
---
name: session-logger
description: Logs session activity
---
Write the following to `logs/${CLAUDE_SESSION_ID}.log`:
$ARGUMENTS
Using skill directory:
---
name: codebase-visualizer
allowed-tools: "Bash(python *)"
---
python ${CLAUDE_SKILL_DIR}/scripts/visualize.py .
CRITICAL: Use ${CLAUDE_SKILL_DIR} instead of hardcoded paths!
Dynamic Context Injection — Live Data
The !`<command>` syntax executes shell commands BEFORE the skill is sent to Claude. Output replaces the placeholder:
---
name: pr-summary
description: Summarize pull request changes
context: fork
agent: Explore
allowed-tools: "Bash(gh *)"
---
## Pull Request Context
- PR diff: !`gh pr diff`
- PR comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`
## Your Task
Summarize this pull request...
Flow:
- Each
!`<command>`executes immediately - Output replaces the placeholder
- Claude receives fully-rendered prompt with real data
This is preprocessing, not something Claude executes!
Bundled Skills — Built-in
Claude Code includes integrated skills available in every session:
| Skill | Purpose | Example |
|---|---|---|
/batch <instruction> |
Orchestrate large-scale changes in parallel. Researches codebase, decomposes into 5-30 units, spawns agents in git worktrees, each creates PR. | /batch migrate src/ from Solid to React |
/claude-api |
Load Claude API reference material. Python, TypeScript, Java, Go, Ruby, C#, PHP, cURL + Agent SDK. | Auto-activates on anthropic import |
/debug [description] |
Troubleshoot current session. Reads debug log. | /debug why files not reading? |
/loop [interval] <prompt> |
Run prompt repeatedly on interval. For polling, PR monitoring, deployment checks. | /loop 5m check deploy |
/simplify [focus] |
Review changed files for quality. Spawns 3 review agents in parallel. | /simplify focus on efficiency |
These skills are prompt-based — they can spawn agents in parallel and adapt to your codebase.
Skill Locations — Scope and Priority
Where you store a skill determines scope and priority:
| Location | Path | Applies to | Priority |
|---|---|---|---|
| Enterprise | (Managed Settings) | All org users | 1 (highest) |
| Personal | ~/.claude/skills/<name>/SKILL.md |
All your projects | 2 |
| Project | .claude/skills/<name>/SKILL.md |
This project only | 3 |
| Plugin | <plugin>/skills/<name>/SKILL.md |
Where plugin enabled | 4 (lowest) |
Priority rule: Enterprise > Personal > Project > Plugin. Conflict resolution: higher priority wins.
Automatic nested discovery: Claude Code finds skills in nested .claude/skills/ directories. In monorepos: packages/frontend/.claude/skills/.
Skill Directory Structure
my-skill/
├── SKILL.md # Main instructions (required)
├── template.md # Template for Claude
├── examples/
│ └── sample.md # Example output
└── scripts/
├── main.py # One job per script!
└── helpers.py # Support code
SKILL.md is required. Reference supporting files so Claude knows when to load them:
## Detailed documentation
- API details: [reference.md](reference.md)
- Usage examples: [examples.md](examples.md)
Tip: Keep SKILL.md under 500 lines.
Who Can Invoke Skills?
disable-model-invocation: true — User Only
Prevents Claude from auto-invoking. Use for side-effect workflows:
---
name: deploy
description: Deploy app to production
disable-model-invocation: true
---
Effect:
- You can invoke
/deploy✅ - Claude auto-invokes ❌
- In Claude's context ❌
user-invocable: false — Claude Only
Skill is hidden. Only Claude can invoke. For background knowledge:
---
name: legacy-system-context
description: Explains how the old system works
user-invocable: false
---
Effect:
- You can invoke ❌
- Claude auto-invokes ✅
- In Claude's context ✅
Invocation Matrix
| Frontmatter | You | Claude | Context |
|---|---|---|---|
| (default) | ✅ | ✅ | Description always |
disable-model-invocation: true |
✅ | ❌ | Description NOT in context |
user-invocable: false |
❌ | ✅ | Description always |
Restrict Tool Access — allowed-tools
Limit which tools Claude can use without permission:
---
name: safe-reader
description: Read files without making changes
allowed-tools: "Read, Grep, Glob"
---
Claude can ONLY use Read, Grep, Glob with this skill.
Best practice: Principle of Least Privilege:
- Read-only:
Read, Grep, Glob - Content creation:
Read, Grep, Glob, Write, Edit - Deployment:
Read, Grep, Glob, Bash
Skills in Subagents — context: fork
With context: fork, skill runs in isolated subagent context:
---
name: deep-research
description: Thoroughly research a topic
context: fork
agent: Explore
---
Research $ARGUMENTS thoroughly:
1. Find relevant files
2. Read and analyze code
3. Summarize findings
Flow:
- New isolated context created
- Subagent receives skill content as prompt
agentfield determines execution environment- Results returned to main session
Subagent types:
Explore: Codebase search, read-only tools, HaikuPlan: Research, architecture, read-only, Sonnetgeneral-purpose: Full tool access, complex tasks
Hooks in Skills — Lifecycle Automation
Skills can define hooks that run on specific events:
---
name: code-reviewer
description: Review code with automatic linting
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-command.sh"
PostToolUse:
- matcher: "Edit|Write"
hooks:
- type: command
command: "./scripts/run-linter.sh"
---
Hook events:
PreToolUse: Before Claude uses a tool (validation, logging)PostToolUse: After a tool is used (cleanup, linting)Stop: When skill completes
Hook scripts receive input via stdin. Exit with 0 (OK) or 2 (block).
Pass Arguments to Skills
Both you and Claude can pass arguments. Available via $ARGUMENTS:
---
name: fix-issue
description: Fix a GitHub issue
disable-model-invocation: true
---
Fix GitHub issue $ARGUMENTS following our coding standards.
1. Read issue description
2. Understand requirements
3. Implement fix
4. Write tests
5. Create commit
Invocation: /fix-issue 123 → Claude gets "Fix GitHub issue 123..."
With multiple arguments:
---
name: migrate-component
---
Migrate $0 from $1 to $2. Keep behavior and tests.
Invocation: /migrate-component Button React Vue
If skill doesn't include $ARGUMENTS, they're auto-appended.
Skill Discovery — When Claude Uses Skills
Claude knows your skills through their description. Better descriptions = better auto-invocation:
- Good: "Explains code with diagrams. Use when explaining how code works."
- Poor: "Code tool" (too vague)
Claude's skill context has a budget (2% of context window, min 16KB). /context shows if descriptions are excluded. Set SLASH_COMMAND_TOOL_CHAR_BUDGET to override.
Skill Naming and Prefixes — Conventions
Standard prefixes help organize:
| Prefix | Domain | Example |
|---|---|---|
deploy-* |
Deployment | deploy-prod, deploy-docker |
n8n-* |
n8n | n8n-import, n8n-validate |
content-* |
Content | content-blog, content-social |
market-* |
Marketing | market-email, market-campaign |
test-* |
Testing | test-coverage, test-integration |
dr-* |
Disaster Recovery | dr-backup, dr-restore |
Use kebab-case, max 64 chars, unique across all repos.
Troubleshooting
Skill doesn't trigger
- Check if description includes keywords users would say
- Verify it appears in "What skills are available?"
- Try rephrasing request to match description
- Invoke directly:
/skill-name
Skill triggers too often
- Make description more specific
- Add
disable-model-invocation: truefor manual-only
Claude doesn't see all skills
Skill description budget (~16KB). With many skills, some may be excluded. Solution: set SLASH_COMMAND_TOOL_CHAR_BUDGET.
Related Features
- Sub-Agents: Delegate tasks to specialized agents
- Plugins: Package and distribute skills
- Memory (CLAUDE.md): Persistent context management
- Hooks: Automate workflows around tool events
- Permissions: Control tool and skill access
Created: 2026-03-21 | Source: code.claude.com/docs/en/skills
