Skip to main content
Skills are defined as SKILL.md files inside a named directory. This page covers everything you need to know to write effective skills.

File Structure

Place skills in the appropriate directory depending on scope:
The directory name is the skill’s identifier (used for /my-skill invocation). The SKILL.md file contains optional YAML frontmatter and the skill’s prompt content.
On Windows, %APPDATA% typically resolves to C:\Users\<YourUser>\AppData\Roaming.

Frontmatter Reference

All Frontmatter Fields


Model Override

Use the model field to run a skill with a different model than the one active in the current session. This is useful for using a faster model for simple tasks or a more capable model for complex ones:
The model name uses the same values as the --model CLI flag (e.g., opus, sonnet, swe, codex). See Models for the full list.

Running Skills as Subagents

Running skills as subagents is experimental. The subagent and agent frontmatter fields may change in future releases.
By default, a skill’s prompt is injected into the current conversation — the agent processes it inline. You can instead run a skill as a subagent, which spawns an independent worker with its own context window. This is useful for skills that perform focused, self-contained tasks where you don’t want the output to clutter the main conversation. There are two ways to run a skill as a subagent:

subagent: true

Set subagent: true to run the skill as a subagent using the default subagent_general profile:
When invoked, this skill spawns a foreground subagent that runs the skill’s prompt as its task. The parent agent waits for the subagent to complete, then reads and summarizes the results.
When a skill runs as a subagent, its allowed-tools and permissions frontmatter are not applied. The subagent runs with the tool set of its profile — subagent_general has access to all tools. To limit which tools a subagent skill can use, define a custom subagent profile with allowed-tools and reference it with agent: instead of subagent: true.

agent: <profile>

Use the agent field to run the skill as a subagent with a specific custom subagent profile:
The agent value must match the name of a registered subagent profile (either built-in like subagent_explore / subagent_general, or a custom profile you’ve defined). The subagent inherits the profile’s system prompt, tool restrictions, and model — while the skill’s content becomes the task. A custom profile’s allowed-tools is a true restriction (unlisted tools are unavailable to the subagent), so this is the way to run a skill with a limited tool set.
If both agent and subagent are set, agent takes precedence. The model field on the skill overrides the subagent profile’s model when both are specified.
Skills running as subagents do not spawn nested subagents — if the skill is already executing inside a subagent, it runs inline instead to prevent infinite recursion.

Orchestrating Subagents Using Skills

Because skills can run as subagents, you can use them to orchestrate multi-step work. Define a set of subagent skills that each handle a focused task, then write a regular skill that invokes them. The outer skill becomes the orchestrator — it calls each subagent, collects the results, and decides what to do next. For example, here are two subagent skills and an orchestrator that coordinates them:
Invoking /health-check runs the orchestrator in the main agent. It calls /research-changes, which spawns a subagent to explore the repo. Once that finishes, it calls /validate-tests, which spawns another subagent to run the tests. The orchestrator then synthesizes both results into a final summary. A subagent skill will never use a subagent when calling other skills, even if those skills have subagent: true — they run inline instead. This means you don’t need to worry about unbounded nesting. The orchestration pattern is always one level deep: the orchestrator spawns subagents, and those subagents execute everything else inline.

Prompt Content

The body of the SKILL.md file (after the frontmatter) is the prompt that gets injected when the skill is invoked.

Permissions

Skills can define their own permission scope using the same syntax as the main permissions config:
How skill permissions work:
  • allow — These scopes are auto-approved during skill execution
  • deny — These scopes are blocked during skill execution
  • ask — These scopes always prompt the user
deny is the way to hard-block a tool for an inline skill. Tool-name entries such as exec or edit block the entire tool, and mcp__server__tool patterns block MCP tools — see Tool-Based Permissions.
Skill permissions are additive to (not replacing) the session’s base permissions. A skill cannot grant permissions that are denied at a higher level (project or organization config).
Skill permissions apply only when the skill runs inline. They are not applied when the skill runs as a subagent (subagent: true or agent:).

Auto-Approved Tools

allowed-tools lists tools that are auto-approved while the skill runs, so the agent can use them without a permission prompt:
Each entry is equivalent to a permissions.allow entry for that tool name. Available tool names: read, edit, grep, glob, exec You can also auto-approve MCP tools:
allowed-tools is not a restriction. Tools that are not listed remain available to the skill and go through the normal permission checks (prompting the user, or running without a prompt if the session’s permissions already allow them). Omitting allowed-tools changes nothing about which tools the skill can use — it only means no tool is pre-approved.To actually prevent a skill from using a tool:
  • For inline skills, add the tool name to permissions.deny (see Permissions).
  • For subagent skills, define a custom subagent profile with allowed-tools and run the skill with agent: <profile>. On a subagent profile, allowed-tools restricts the tool set; on a skill, it does not.

Examples

Code Review Skill

Component Generator

Deployment Checklist

Search Expert


Tips

Keep prompts focused

A skill should do one thing well. Create multiple skills rather than one mega-skill.

Include examples

Show the agent what good output looks like in your prompt.

Deny what a skill must not do

Use permissions.deny (or a custom subagent profile) to block tools. allowed-tools only skips prompts.

Test with /skill-name

Invoke your skill and iterate on the prompt until the output is what you want.