claudeBenutzer09
5

Agent Skills

Capture a procedure you keep needing as a skill — Claude reaches for it on its own as soon as it fits the task.

Intermediate 1 hour

A skill packs a procedure you would otherwise keep pasting into chat into a single file. Compared with a prompt snippet you gain three things: the body costs context only once the skill actually runs; it can bring live data in from the shell; and you decide whether you invoke it, Claude does, or both. This module walks through the pieces in order — loading behaviour, then the frontmatter, then the skills that are already on board.

What Claude sees of a skill, and when

What Claude sees first is only the short form: every skill’s name and description sit in a listing that travels along on every turn. Only on invocation does the rendered content of SKILL.md enter the conversation, as one single message, and it stays there for the rest of the session. Further files in the skill directory get read one at a time, when Claude needs them.

That is why a large collection of skills costs little: what sits in context permanently is the listing, not the content. Two consequences are worth remembering. From the moment of invocation, every line of the body is a recurring cost — keep it short, and state what to do instead of narrating why. And Claude does not re-read the file on later turns: anything that should hold for the whole task belongs in there as a standing instruction, not as a one-time step.

Where the file lives decides who has the skill. ~/.claude/skills/<name>/SKILL.md applies across all your projects, .claude/skills/<name>/SKILL.md only to this one and travels with git; on top of those come the managed-settings level for a whole organisation and skills from plugins. When two skills share a name, the organisation level beats the personal one and the personal one beats the project — and a skill at any of these levels also replaces a bundled skill of the same name. Plugin skills sit under plugin-name:skill-name and therefore cannot collide at all.

Below your working directory Claude also looks in nested .claude/skills/ folders: if it edits a file in packages/frontend/, the skills from packages/frontend/.claude/skills/ are available too. The folders above your starting directory are read the same way, up to the repository root, so starting in a subfolder does not lose the root’s skills. If a nested name collides, both variants stay reachable — the nested one under its directory-qualified name, such as apps/web:deploy.

.claude/skills/code-review/
├── SKILL.md              # Instructions (required)
├── templates/
│   └── review-checklist.md
└── scripts/
    └── analyze-metrics.py

The description decides whether a skill fires

The description is the field everything hangs on: Claude decides purely from it whether a skill fits the request. A sentence like “helps with programming” carries no signal and will never fire. It becomes usable as soon as the action, the subject and the occasion appear in it:

---
name: security-review
description: Scan code for security vulnerabilities including injection flaws, authentication issues, and data exposure. Use when reviewing code changes, preparing a PR, or when the user mentions security, vulnerabilities, or audit.
---

So name the action (“review”, “generate”, “analyse”), the subject area, and the phrasings that should make the skill catch. For the occasion there is a field of its own: when_to_use gets appended to the description in the listing. Claude Code cuts the two together off at 1,536 characters per entry — adjustable via skillListingMaxDescChars — so the main case belongs up front and the remaining trigger phrasings go into when_to_use:

---
name: security-review
description: Scan code for security vulnerabilities including injection flaws, authentication issues, and data exposure.
when_to_use: When reviewing code changes, preparing a PR, or when the user mentions security, vulnerabilities, or audit.
---

For the listing as a whole, Claude Code reserves 1% of the context window by default. You can raise that via skillListingBudgetFraction (say 0.02 for 2%) or via SLASH_COMMAND_TOOL_CHAR_BUDGET as a fixed character count. When the budget runs short, the descriptions of the least-used skills fall away and only their names remain: Claude can still invoke them, but can no longer see what they are for. /doctor estimates what the listing costs against the budget and names the biggest contributors.

Bulky material goes into files of its own next to the skill, referenced from SKILL.md with relative paths. That keeps the body lean, and the long remainder is read only when it is needed:

For the full review checklist, see [templates/review-checklist.md](templates/review-checklist.md).

So that Claude can judge which file is worth opening when, write down for each reference what it contains. As a rule of thumb SKILL.md stays under 500 lines; detailed reference belongs in neighbouring files, executable helpers in a scripts/ subdirectory.

Feeding in live context, steering invocation

!command is how you pull live data into a skill: Claude Code runs the command before the content is sent off at all and puts the output where the placeholder was. So Claude gets to see data, not the command. For multi-line calls there is the block form, opened with ```!. Substitution runs exactly once over the original file — output that itself looks like a placeholder is not evaluated a second time:

---
name: pr-summary
description: Summarize pull request changes. Use when asked to review or summarize a PR.
context: fork
agent: Explore
---

## PR context
- Diff: !`gh pr diff`
- Comments: !`gh pr view --comments`
- Changed files: !`gh pr diff --name-only`

Summarize the intent and key changes in this pull request.

Which shell does the work is controlled by shell: bash is the default, powershell the alternative. It takes effect when the PowerShell tool is active — on Windows without Git Bash by itself, otherwise via CLAUDE_CODE_USE_POWERSHELL_TOOL=1, which on Linux and macOS additionally requires pwsh on your PATH:

---
name: windows-helper
description: Manage Windows services and configurations
shell: powershell
---

Two fields govern who may start a skill. disable-model-invocation: true takes the automatic choice away from Claude: the skill stays reachable through /skill-name, and in exchange its description drops out of context. That is the right call for anything with outward effects — deploys, pushes, messages sent. Conversely user-invocable: false hides the skill in the / menu but still lets Claude load it on its own; meant for background knowledge that makes no sense as a command.

paths: takes a list of globs and thereby limits when a skill loads automatically: only when Claude is working with files that match one of the patterns. That keeps project-specific skills out of sessions where they do not belong:

---
name: api-generator
description: Generate REST API endpoints from schema definitions.
paths: ["src/**/*.ts", "tests/**"]
---

effort sets the reasoning depth for as long as the skill is active, overriding the session’s level for that time. Possible values are low, medium, high, xhigh and max; which levels actually exist depends on the model, and max applies to the running session only. Without an entry the skill inherits the session level:

---
name: security-review
description: Scan code for security vulnerabilities.
effort: high
---

context: fork sends the skill into a subagent of its own: the body becomes the task there, the conversation history stays outside, your main context stays free. Which agent type takes over is what agent says — Explore for reading only, Plan for drafting, general-purpose for anything that needs the full toolbox; without an entry, general-purpose is used. The fork runs in the background and reports its result once it finishes; with background: false the invoking turn waits for it instead. Without a concrete task in the body a fork is pointless — a pure collection of conventions returns nothing from there.

model picks a different model for the rest of the running turn without anchoring it in your settings; on your next prompt the session’s model applies again. The permitted values are the same as for /model, plus inherit for “change nothing”:

---
name: deep-analysis
description: Thoroughly analyze the codebase for a specific pattern or issue
context: fork
agent: Explore
model: opus
disable-model-invocation: true
---

Analyze $ARGUMENTS across the entire codebase:
1. Use Glob and Grep to find all occurrences
2. Read each file and understand context
3. Summarize patterns, inconsistencies, and recommendations

Passing arguments, pre-approving tools

Arguments reach a skill three ways. $ARGUMENTS stands for everything that follows the name. $ARGUMENTS[0] and its short form $0 pick out individual positions, with multi-word values held together by quotes. And if you want speaking names, declare them in the arguments frontmatter field; they map onto the positions in order. All of it is substituted before the prompt reaches Claude. argument-hint shows in the slash menu what the skill expects:

---
name: review-pr
description: Review a GitHub PR by number
argument-hint: "<pr-number> <priority>"
allowed-tools: Bash(gh *), Read, Grep, Glob
---

Review PR #$0 with priority $1. Focus on security and performance.

Reference our standards in [standards/code-review.md](standards/code-review.md).

Invoked as /review-pr 456 high: $0 becomes 456, $1 becomes high. A position with no argument — $2, say, when only two values were passed — stays in the text unchanged; a named placeholder with no value expands to an empty string.

allowed-tools permits the listed tools without asking, and it does so for exactly the turn that invokes the skill. Your next message lets the grant lapse, even though the skill content stays in context; invoking it again re-applies it. Nothing is restricted in the process — every other tool stays available and keeps following your permission settings. To take tools away instead, list them under disallowed-tools. For skills that live in the project, both take effect only once you have trusted the folder: read them first.

Alongside the positions, Claude Code knows a set of fixed placeholders: ${CLAUDE_SESSION_ID} for the running session, ${CLAUDE_EFFORT} for the active effort level, ${CLAUDE_SKILL_DIR} for the directory holding the SKILL.md, and ${CLAUDE_PROJECT_DIR} for the project root. The last two are substituted in the Bash rules of allowed-tools as well — the same placeholder in both places lets a bundled script run without a prompt.

Older command files under .claude/commands/*.md keep working unchanged and understand the same frontmatter. Skills are still the recommendation, because only they bring a directory of accompanying files. If both exist under the same name, the skill wins.

Setting visibility from your settings

Some skills you want to tame without touching their file — ones that sit in the project repo and belong to everybody, for instance. That is what skillOverrides in your settings is for: one entry per skill name, setting visibility from the outside. It does not cover plugin skills; you manage those through /plugin. You need not write the entries yourself — in the /skills menu you highlight a skill, cycle the states with Space, and save with Enter to .claude/settings.local.json:

{
  "skillOverrides": {
    "legacy-context": "name-only",
    "deploy": "off"
  }
}

Four values are possible. "on" is the normal case and lists name plus description. "name-only" leaves just the name — the skill stays invocable, but Claude can no longer see what it is for; that is the frugal way to free up budget. "user-invocable-only" takes it out of Claude’s listing entirely and keeps it open to you in the / menu, labelled user-only there. "off" hides it everywhere. A skill with no entry counts as "on".

What already ships with it

One set of skills is already on board and needs no installation, among them /doctor, /code-review, /batch, /debug, /loop and /claude-api. They are prompt-based: they hand Claude a detailed set of instructions and let it do the work with its own tools — unlike most built-in commands, which execute fixed logic. Three of them work together and need v2.1.145 at minimum: /run, /verify and /run-skill-generator launch your app and confirm a change on the running program rather than on tests alone.

Invocation What it is for
/code-review Goes through the current diff for correctness bugs and cleanup opportunities; --fix applies the findings, --comment posts them on the pull request
/batch Breaks a large change into 5 to 30 independent units and puts one background subagent per unit to work in a worktree of its own
/debug Turns on debug logging for the running session and traces the problem through that log
/loop Repeats a prompt for as long as the session stays open — on a fixed interval or at a pace it picks itself
/claude-api Pulls in the Claude API reference for your project’s language, migration to a newer model included
/run Starts your app and drives it so you actually see a change running
/verify Builds and starts the app to confirm a change on the running program instead of on tests or type checks
/run-skill-generator Records how your project builds and launches from a clean environment and files that recipe for /run and /verify

With no preparation, /run and /verify derive the launch from the project type — CLI, server, TUI, browser-driven — and from package.json, Makefile or your README. As soon as more than a standard launch is involved, a database say, an env file, a graphical session or a multi-step build, that derivation gets unreliable. Then you run /run-skill-generator once: it gets the app running from a clean environment, records the install commands, environment variables and launch script, and commits the result as a per-project skill at .claude/skills/run-<name>/. After that, /run, /verify and any other agent in the repo follow that recipe. If the build or launch path changes, repeat the step.

/fewer-permission-prompts goes through your transcripts, collects the read-only Bash and MCP calls that come up often, and proposes a prioritised allowlist for .claude/settings.json from them. Run it only after a few sessions — then the list describes your actual workflow:

/fewer-permission-prompts