NEW: Claude Code Security — research preview →

Skills

Extend Claude Code with reusable SKILL.md modules — the evolution of custom commands

NEWRead time: 13 min

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

ScopeLocationAvailable to
Enterprise.claude/skills/<name>/SKILL.md in the managed settings directoryAll users on machines where the org deploys it
Personal~/.claude/skills/<name>/SKILL.mdAll your projects on this machine
Project.claude/skills/<name>/SKILL.mdThis repository (commit it to share)
Nested<subdir>/.claude/skills/<name>/SKILL.mdSessions in or below <subdir>
Additional directory.claude/skills/ inside a directory passed with --add-dirThat session
Plugin<plugin>/skills/<name>/SKILL.mdWhere 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.

FieldPurpose
nameCommand name shown in the / menu (defaults to directory name). Lowercase, hyphens, max 64 chars
descriptionWhat 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_useAdditional trigger phrases (appended to description; combined text is capped at 1,536 chars in the listing)
argument-hintShown in autocomplete, e.g. [issue-number]
argumentsNamed positional args for $name substitution
disable-model-invocationtrue → only you can invoke it (good for /deploy, /commit)
user-invocablefalse → only Claude can invoke it (background knowledge)
allowed-toolsTools Claude can use without asking during the turn that invokes the skill
disallowed-toolsTools removed from Claude's pool while the skill is active
modelOverride model for the rest of the current turn (or inherit)
effortOverride effort level: low, medium, high, xhigh, max
contextfork → runs in an isolated subagent
agentWhich subagent type to use with context: fork (default general-purpose)
backgroundWith context: fork, set false to wait for the subagent's result instead of running it in the background (default true)
hooksHooks registered when the skill is invoked; they stay active for the rest of the session
pathsGlob patterns — skill auto-activates only for matching files
shellbash (default) or powershell for ! commands
metadata, license, compatibilityAgent 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": true in settings; each command is then replaced with a "disabled by policy" note.

String Substitutions

PlaceholderValue
$ARGUMENTSEverything typed after the skill name
$ARGUMENTS[0] or $0First argument
$ARGUMENTS[1] or $1Second argument
$nameNamed 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 commit

Run with: /fix-issue 347


Invocation Control

FrontmatterYou can invokeClaude 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:

CommandWhat 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 / /verifyLaunch your app to see a change working / confirm a change actually does what it should
/claude-apiLoad 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):

ValueListed to ClaudeIn / menu
"on"Name and descriptionYes
"name-only"Name onlyYes
"user-invocable-only"HiddenYes
"off"HiddenHidden

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.


  • Auto Memory — Claude's persistent learning system
  • Hooks — Deterministic lifecycle automation
  • Subagents — Parallel and isolated execution
  • Plugins — Package and distribute skills