Custom Skills

Creating custom skills to extend agent capabilities.

Overview

Skills are reusable prompt fragments that agents can invoke during their sessions. Each skill is a Markdown file with optional YAML frontmatter that controls how the skill behaves — who can invoke it, what tools it can use, and how arguments are substituted.

Skill File Format

A skill file has two parts: frontmatter (optional) and body (required).

---
name: my-skill
description: A brief description of what this skill does
user-invocable: true
argument-hint: "<required-arg> [optional-arg]"
---

You are now executing the "my-skill" skill.

The user asked: $ARGUMENTS

Perform the requested action and report results.

Step 1: Choose a Location

Skills are discovered from three paths, in priority order:

PriorityPathStyle
1 (highest)<project>/.claude/skills/<name>/SKILL.mdDirectory
2<project>/.skills/<name>.mdFlat file
3 (lowest)~/.claude/skills/<name>/SKILL.mdGlobal directory

Directory style is preferred — each skill gets its own directory, which can contain supporting files:

.claude/skills/
  commit/
    SKILL.md
  review/
    SKILL.md
    checklist.md

Flat file style is available for backward compatibility:

.skills/
  commit.md
  review.md

If a skill with the same name exists at multiple paths, the highest-priority path wins. First match is used; duplicates at lower priorities are ignored.

Step 2: Write the Frontmatter

The YAML frontmatter block is delimited by --- lines at the top of the file. All fields are optional:

FieldTypeDefaultDescription
nameStringFilename/directory nameSkill identifier (overrides the inferred name)
descriptionStringNoneOne-line description shown in skill discovery
user-invocableboolfalseIf true, appears in the / slash-command menu
disable-model-invocationboolfalseIf true, only the user can invoke this skill (not the model)
allowed-toolsString[]NoneRestrict which tools the skill can access
modelStringNoneOverride the model for this skill's execution
contextStringNoneSet to "fork" for subagent execution
agentStringNoneSubagent type when context: fork
argument-hintStringNoneUsage hint displayed to the user
hooksHooksConfigNoneLifecycle hooks specific to this skill
unsafeboolNoneReserved for future WASM sandbox flag

Invocation Control

SettingEffect
user-invocable: trueAppears in / menu; user and model can invoke
user-invocable: falseHidden from menu; model-only unless model invocation also disabled
disable-model-invocation: trueOnly the user can invoke via /skill-name

Example Frontmatter

---
name: commit
description: Create a conventional commit
user-invocable: true
disable-model-invocation: false
allowed-tools:
  - Bash
  - Read
  - Grep
argument-hint: "[commit message]"
model: claude-sonnet-4-5-20250929
---

Step 3: Write the Body

The body is everything after the closing ---. It's injected into the agent's prompt when the skill is invoked. Use argument placeholders to make the skill dynamic:

Argument Substitution

PlaceholderReplaced With
$ARGUMENTSThe full argument string passed by the invoker
$ARGUMENTS[0] through $ARGUMENTS[9]Positional argument (space-split)
$0 through $9Shorthand for $ARGUMENTS[N]

Substitution is single-pass (left-to-right) — output from one replacement is never re-processed. Missing positional arguments are replaced with an empty string. Only indices 0–9 are supported.

Example Body

---
name: test-file
description: Run tests for a specific file
user-invocable: true
argument-hint: "<file-path>"
---

Run the tests for the file at `$0`.

Steps:
1. Read the file to understand what it does
2. Find the corresponding test file
3. Run the tests with `cargo test`
4. If tests fail, analyze the failures and suggest fixes
5. Report results

Full context from user: $ARGUMENTS

When invoked as /test-file src/main.rs, the placeholders expand to:

  • $0src/main.rs
  • $ARGUMENTSsrc/main.rs

When invoked as /test-file src/main.rs --verbose, the placeholders expand to:

  • $0src/main.rs
  • $1--verbose
  • $ARGUMENTSsrc/main.rs --verbose

Step 4: Add Skill-Level Hooks (Optional)

Skills can define their own hooks that fire during skill execution:

---
name: deploy
description: Deploy to staging
user-invocable: true
hooks:
  pre_tool_use:
    - matcher: Bash
      hooks:
        - type: command
          command: ./scripts/validate-deploy.sh
          timeout: 10
---

Hook configuration follows the same format as project-level hooks. See Hooks for details.

Step 5: Test Your Skill

Verify Discovery

Skills are discovered automatically when agents build their prompts. To verify your skill is found, check that:

  1. The file exists at one of the three resolution paths
  2. The filename or name field matches what you expect
  3. If user-invocable: true, it should appear in the agent's available slash commands

Test Resolution

The resolution order is deterministic:

  1. Swarm checks <project>/.claude/skills/<name>/SKILL.md
  2. If not found, checks <project>/.skills/<name>.md
  3. If not found, checks ~/.claude/skills/<name>/SKILL.md
  4. If not found at any path, the skill is not available

Validate the Name

Skill names must contain only [a-zA-Z0-9_:-]. Names with other characters (including /, .., spaces) are rejected to prevent path traversal.

Examples

Simple Commit Skill

---
name: commit
description: Create a git commit with conventional format
user-invocable: true
allowed-tools:
  - Bash
  - Read
  - Grep
argument-hint: "[commit message]"
---

Create a git commit following the conventional commits format.

If no message was provided, analyze the staged changes and generate an appropriate message.

User input: $ARGUMENTS

Steps:
1. Run `git diff --cached` to see staged changes
2. Generate or use the provided commit message
3. Ensure the message follows conventional commits (feat:, fix:, chore:, etc.)
4. Create the commit

Code Review Skill

---
name: review
description: Review code changes in the current branch
user-invocable: true
disable-model-invocation: true
argument-hint: "[focus area]"
---

Review the code changes in the current branch compared to main.

Focus area: $ARGUMENTS

Steps:
1. Run `git diff main...HEAD` to see all changes
2. For each changed file, analyze:
   - Correctness: Are there bugs or logic errors?
   - Security: Any vulnerabilities introduced?
   - Performance: Any obvious performance issues?
   - Style: Does the code follow project conventions?
3. Provide a summary of findings

Subagent Skill

---
name: research
description: Research a topic using a subagent
user-invocable: true
context: fork
agent: researcher
argument-hint: "<topic>"
---

Research the following topic thoroughly: $ARGUMENTS

Provide a detailed summary with references.
  • Skills Concept — How the skill system works internally
  • Hooks — Lifecycle hooks for skills and agents
  • Permissions — How allowed-tools interacts with permissions