Skip to content

Skill Engine

Tools give Claude new capabilities. Skills give Claude new knowledge. A tool executes an action. A skill changes how Claude thinks about a problem.

Skills vs Tools

ToolSkill
FormRegistered function with schemaMarkdown template
EffectChanges what the agent CAN doChanges what the agent KNOWS
ExecutionRuns code, returns resultInjected as text into conversation
ExampleBash runs a shell command/verify injects: “Your job is not to confirm — it’s to try to break it.”
PersistenceStateless per callActive for duration of invocation scope

The /verify skill doesn’t run any verification code. It injects a structured prompt that reframes the agent’s role. Claude then uses its existing tools (Bash, FileRead, etc.) with entirely different instructions. Same tools, different behavior.

5 Sources

SourceLocationScopePriority
BundledCompiled into CLIAll sessionsLowest
User~/.claude/skills/All projectsLow
Project.claude/skills/Current projectMedium
MCPRemote MCP serversSessionHigh
ManagedEnterprise policy pathOrganizationHighest

When the same skill name appears in multiple sources, the higher-priority source wins. Project skills override user skills. Enterprise policy overrides everything.

16 bundled skills ship with the CLI: 11 always-on, 5 feature-gated (enabled via config or flags).

3 Discovery Modes

flowchart TD START([Session starts]) --> STATIC STATIC["Static Discovery\n─────────────────\nScan all source directories in parallel\nMemoize results\nDeduplicate by resolved path\nOne-time load, cached for session"] STATIC --> READY([Skills ready]) READY --> ACTION{Agent touches\na file?} ACTION -->|Yes| DYNAMIC ACTION -->|No| READY DYNAMIC["Dynamic Discovery\n─────────────────\nWalk UP directory tree from touched file\nCheck each ancestor for .claude/skills/\nDeeper directory = higher priority\nMonorepo pattern: package-local skills"] DYNAMIC --> COND["Conditional Activation\n─────────────────\nSkills with 'paths' frontmatter\nMatch against touched file path\nGitignore-style patterns\nOnly active when pattern matches"] COND --> INJECT([Inject matching skills\ninto conversation]) INJECT --> READY

Monorepo pattern: A skill at packages/auth/.claude/skills/auth-specialist.md only loads when the agent opens files inside packages/auth/. A skill at packages/payments/.claude/skills/ stays hidden until you work in that package. Each package carries its own expertise without polluting the global context.

SKILL.md Anatomy

---
name: migration-reviewer
description: >
Reviews database migrations for safety, reversibility,
and naming convention compliance.
when_to_use: >
When the agent opens or creates files matching **/migrations/**
paths:
- "**/migrations/**"
- "**/db/migrate/**"
allowed-tools:
- FileRead
- Grep
- Bash
arguments:
- name: dialect
description: "SQL dialect: postgres | mysql | sqlite"
default: postgres
context: inline # inline | fork
hooks:
PostToolUse: "npm run lint:migrations"
---
You are a database migration specialist reviewing for the ${dialect} dialect.
Current branch: `!git branch --show-current`
Pending migrations: `!ls migrations/ | grep -v _applied`
Before reviewing any migration:
1. Check filename follows pattern: YYYYMMDD_HHMMSS_description.sql
2. Verify every destructive operation has a corresponding rollback
3. Confirm indexes are created CONCURRENTLY to avoid table locks

Key frontmatter fields:

FieldPurpose
pathsGitignore-style patterns for conditional activation
allowed-toolsRestrict which tools are available during this skill
argumentsTemplate variables substituted into the markdown body
context: inlineInject into current conversation
context: forkSpawn a subagent with this skill as its system prompt
hooksPer-skill lifecycle events (e.g. auto-lint after every write)

Shell-in-Prompt

Skills can embed inline shell commands using backtick syntax in the markdown body. Before injection, the system executes them and substitutes the output:

In SKILL.md:
Current branch: `!git branch --show-current`
Pending migrations: `!ls migrations/ | grep "\.sql$"`
Injected into conversation:
Current branch: main
Pending migrations:
20240301_120000_add_users.sql
20240315_093000_add_sessions.sql

The agent receives live context without having to run commands itself — dynamic, zero-cost context injection at skill load time.

Security Boundaries

MCP skills cannot execute shell commands. The !command syntax is blocked for any skill sourced from a remote MCP server. Remote/untrusted code cannot reach the local shell — only bundled, user, and project skills can use shell-in-prompt.

Gitignore protection. Before loading any skill directory, the system calls isPathGitignored(). Skills inside node_modules/ or any .gitignore-d path are silently skipped. This prevents supply-chain injection: an npm package cannot ship malicious .claude/skills/ that auto-load into your session.

Protected: node_modules/**/.claude/skills/ ← gitignored, skipped
Protected: .git/**/.claude/skills/ ← gitignored, skipped
Allowed: packages/auth/.claude/skills/ ← not gitignored, loaded
Allowed: ~/.claude/skills/ ← user-owned, loaded

Magic Docs

Claude Code includes an auto-documentation system: files marked with # MAGIC DOC: are automatically updated by a background agent as your code evolves. The agent is sandboxed to file editing only — no shell, no network access.

Full details → Hidden Features

Why This Matters to You

  • How to write better SKILL.md → use paths for targeted activation so skills only appear when relevant; use allowed-tools to sandbox what the skill can do
  • How monorepo skills work → directory walk discovers .claude/skills/ in ancestor directories; deeper = higher priority; each package defines its own expertise
  • Why MCP skills can’t run shell commands → remote untrusted code has no shell access; only local skills (bundled, user, project) can use !command syntax
  • How shell-in-prompt works → backtick commands execute at skill load time, output substituted before injection; agent gets live context for free
  • How to prevent unwanted skill loading → add the directory to .gitignore; the system respects it automatically

See also: Plugin EngineMulti-Agent SystemTool Orchestration