Skip to main content

ToolkitSkills · Mental Model

Mental Model

Skills follow a three-stage progressive disclosure model that controls when and how instructions enter Claude's . Understanding this model is the difference between skills that activate reliably and skills that sit dormant.

What a Skill Actually Is

A skill is a directory containing a SKILL.md file. The file has two parts: YAML frontmatter (metadata Claude uses to decide relevance) and a markdown body (instructions Claude follows when invoked). That's it. No runtime, no compilation, no API.

.claude/skills/deploy/
├── SKILL.md              # Required. Frontmatter + instructions.
├── references/           # Optional. Large reference docs, API specs.
│   └── api-spec.md
├── scripts/              # Optional. Executable code Claude can run.
│   └── validate.sh
└── assets/               # Optional. Templates, config samples.
    └── config.template

The path must be <root>/skills/<name>/SKILL.md. Nesting deeper (e.g., skills/a/b/SKILL.md) does not work.

Skill Scopes

ScopePathUse Case
Project.claude/skills/<name>/SKILL.mdTeam standards, repo-specific workflows
Personal~/.claude/skills/<name>/SKILL.mdYour global workflows across all repos
EnterpriseDeployed via managed-settings.jsonOrg-wide enforcement
Pluginskills/ directory inside a published pluginDistributed skill packages
Legacy.claude/commands/<name>.mdStill works, but prefer .claude/skills/

The Three-Stage Lifecycle

Stage 1: Metadata Loading

At session start, Claude Code reads the name and description fields from every discoverable skill's frontmatter. These are injected into the system as a skill registry. The full SKILL.md content is NOT loaded yet.

What the system prompt registry looks like internally:

Available skills:
- deploying-to-staging: Deployment expert for staging environments. ALWAYS invoke when...
- reviewing-code: Structured code review process. Invoke when reviewing PRs...
- fixing-issues: Fix a GitHub issue by number. ALWAYS invoke when the user says...

Cost: ~100 tokens per skill. Twenty skills = ~2,000 tokens always present in every turn. This is the overhead you pay just for having skills available.

Stage 2: Invocation Decision

Claude decides whether to invoke a skill. Two paths exist:

Manual invocation: User types /skill-name [args]. Always works. Bypasses description matching entirely. This is the guaranteed path.

Auto-invocation: Claude reads the skill descriptions in its system prompt, reasons about relevance to the current task, and calls the Skill tool. This is a language model decision, not algorithmic matching. The description is the only input Claude uses to decide.

Stage 3: Content Injection

Once invoked, the rendered SKILL.md content enters the conversation as a single message. It stays there for the rest of the session. Claude does NOT re-read the skill file on later turns.

Supporting files in the skill directory are NOT auto-loaded. Claude must explicitly read them using Read or Bash tools. A skill that references its own assets:

# API Scaffolding
 
## Step 1: Load the route template
Read the template file:
`cat ${CLAUDE_SKILL_DIR}/assets/route.template.ts`
 
## Step 2: Check the API spec
Read the OpenAPI spec for endpoint definitions:
`cat ${CLAUDE_SKILL_DIR}/references/openapi.yaml`
 
## Step 3: Generate the endpoint
Use the template and spec to create the new route handler.

This is intentional — it keeps the initial injection lean.

Skill Resolution Order

When naming conflicts occur, precedence from highest to lowest:

  1. Enterprise skills (managed-settings.json) — override everything
  2. Personal skills (~/.claude/skills/) — your global preferences
  3. Project skills (.claude/skills/) — team/repo standards
  4. Plugin skills (plugin skills/ directory) — lowest priority

If a skill and a legacy command share the same name, the skill takes precedence.

Known issue (April 2026): When a project has .claude/skills/, skills from ~/.claude/skills/ may not load. This contradicts documented behavior where both should be discovered.

Context Window Implications

Understanding the budget is non-negotiable for skill design:

ContentWhen LoadedToken Budget
CLAUDE.mdEvery turn~2,000 tokens recommended max
Skill descriptions (name + description)Session start, every turn~100 tokens each
Invoked skill bodyOn invocation, stays until compactionNo hard limit, but 500 lines recommended max
Re-attached skill (after compaction)After auto-compaction5,000 tokens per skill, 25,000 combined max
tool schemasSession start, every turn5,000-10,000 tokens per server

The Compaction Cycle

When the context window fills up, Claude Code triggers auto-compaction. During compaction:

  1. Conversation history is summarized
  2. The most recent invocation of each skill is re-attached
  3. Each re-attached skill gets up to 5,000 tokens (first 5,000 of the original)
  4. Re-attached skills share a combined budget of 25,000 tokens
  5. The budget fills starting from the most recently invoked skill

This means long skills lose their tail content after compaction. Front-load the critical instructions in the first 5,000 tokens of your SKILL.md.

SKILL.md Frontmatter Reference

All fields are optional, but description is strongly recommended.

---
# Identity
name: deploying-to-staging      # Max 64 chars. Lowercase, numbers, hyphens.
                                 # No reserved words ("anthropic", "claude").
                                 # If omitted, uses directory name.
                                 # Gerund form recommended (verb + -ing).
 
# Trigger
description: |                   # Max 1,024 chars. What + when.
  Deployment expert for staging environments.
  ALWAYS invoke this skill when the user asks about deploying,
  releasing, or pushing to staging.
 
# Execution control
context: fork                    # Runs in isolated subagent. No conversation history.
agent: Explore                   # Which agent type executes.
model: claude-sonnet-4-6         # Override model for this skill.
 
# Security
allowed-tools: Read,Grep,Glob   # Only listed tools permitted.
                                 # Supports Bash scoping: Bash(git:*), Bash(npm:*)
disable-model-invocation: true   # Only manual /slash-command. Hidden from auto-invocation.
 
# Metadata (Agent Skills Standard)
license: MIT
compatibility: "node>=18"       # Max 500 chars.
metadata:
  version: "1.2.0"
  author: "dakota"
---

How Skills Differ from Everything Else

MechanismLoadedPurposeNature
CLAUDE.mdEvery turnGlobal project instructionsAdvisory, always in context
SkillsOn-demand (description always; body when invoked)Task-specific workflowsAdvisory, loaded when relevant
HooksAutomatically at lifecycle eventsEnforce constraints deterministicallyDeterministic, runs regardless of Claude's judgment
Legacy commandsOn explicit /command invocationSaved promptsSame as skills but single-file, no auto-invocation
MCP serversTool schemas at startupExternal tool connectivityInfrastructure, provides tools not instructions

The most common mistake: treating skills as "CLAUDE.md sections that load on demand." Skills are interactive workflows with parameterization, forking, tool restrictions, and model overrides. If your skill is just a paragraph of instructions, it probably belongs in CLAUDE.md.

Argument Interpolation

Skills support parameter passing through shell-style variables:

VariableExpands To
$ARGUMENTSEverything typed after the slash command
$0, $1, $2Positional args (shell-style quoting)
${CLAUDE_SKILL_DIR}Absolute path to the skill's directory

A SKILL.md using all three interpolation types:

---
name: migrate-database
description: |
  Database migration runner. ALWAYS invoke when the user asks
  to create or run a migration. Do not run migration commands directly.
---
 
# Database Migration
 
## Target
Run migration: $ARGUMENTS
 
## Steps
1. Identify migration type from first arg: `$0` (create | run | rollback)
2. Target environment from second arg: `$1` (dev | staging | production)
3. Load the environment config template:
   `cat ${CLAUDE_SKILL_DIR}/assets/env-config.template`
4. Execute the migration using the reference script:
   `bash ${CLAUDE_SKILL_DIR}/scripts/migrate.sh $0 $1`
5. Verify the result against the expected schema in:
   `${CLAUDE_SKILL_DIR}/references/schema-spec.md`

Invocation: /migrate-database create staging makes $0 = "create", $1 = "staging", and $ARGUMENTS = "create staging".

If a skill does not reference $ARGUMENTS, Claude Code automatically appends ARGUMENTS: <input> so Claude still sees the input.

Multi-word arguments use shell-style quoting: /my-skill "hello world" second makes $0 = "hello world", $1 = "second".

Watch out: Multi-line input passed to $ARGUMENTS can break across 16+ commands. Keep arguments to single-line values when possible.