Skip to main content
Agent Skills extend Claude with specialized capabilities that Claude invokes when relevant. Skills are packaged as SKILL.md files containing instructions, descriptions, and optional supporting resources. This page also covers commands in Agent SDK sessions. For comprehensive information about skills, including benefits, architecture, and authoring guidelines, see the Agent Skills overview.

How skills work with the Agent SDK

When using the Claude Agent SDK, skills are:
  • Defined as filesystem artifacts: you create each skill as a SKILL.md file in its own directory, such as .claude/skills/<name>/SKILL.md
  • Loaded from filesystem: the SDK loads skills from the filesystem locations governed by settingSources (TypeScript) or setting_sources (Python)
  • Automatically discovered: once filesystem settings load, the SDK discovers skill metadata at startup from user and project directories, and loads the full content when Claude invokes the skill
  • Model-invoked: Claude autonomously chooses when to use them based on context
  • User-invoked: you dispatch a skill directly by sending /<name> in a prompt. See Commands in Agent SDK sessions
  • Scoped via the skills option: discovered skills are enabled by default. Pass a list of skill names, "all", or [] to control which skills Claude can invoke
Unlike subagents, which you can define in the agents option, you create skills as files on disk. The SDK doesn’t provide a programmatic API for registering them.
Skills are discovered through the filesystem setting sources. With default query() options, the SDK loads user and project sources, so skills in ~/.claude/skills/, <cwd>/.claude/skills/, and .claude/skills/ in any parent directory of <cwd> up to the repository root are available. If you set settingSources explicitly, include 'user' or 'project' to keep skill discovery, or use the plugins option to load skills from a specific path.

Use skills with the Agent SDK

Set the skills option on query() to control which skills Claude can invoke in the session. When omitted, discovered skills are enabled and the Skill tool is available, matching CLI behavior. Pass "all" to let Claude invoke every discovered skill, a list of skill names to allow only those, or [] to let Claude invoke none. For example, to let Claude invoke only two named skills:

Set up skills in a session

When you set skills, the SDK adds the Skill tool to allowedTools automatically. If you also pass an explicit tools list, include "Skill" in that list so Claude can invoke skills. Once configured, Claude automatically discovers skills from the filesystem and invokes them when relevant to the user’s request. The following example enables every discovered skill in a session and pre-approves the tools that skills commonly need. The example sets cwd to the process’s current working directory, so run it from inside a project that has a .claude/skills/ directory in the current directory or any parent up to the repository root:

Confirm skills loaded

Near the start of the stream, the SDK yields a system message with subtype init. Check its skills array to confirm your skills loaded before Claude starts working. The array includes the user-invocable skills that you have defined, along with bundled skills included with Claude Code. The array lists user-invocable skills only. A skill with user-invocable: false in its frontmatter loads and remains available to Claude, but doesn’t appear in the array. The array reflects what the session discovered and lists the same skills whether or not they’re in your skills list.

Allow only specific skills

To let Claude invoke only specific skills, pass their names in the skills list. Names match the name field in SKILL.md or the skill’s directory name. Use plugin:skill for plugin-provided skills. The list takes exact skill names only. If an entry can’t work as an exact name, query() rejects the list before the session starts. See Invalid skill name error for the name rules and the error each SDK raises. The model doesn’t see unlisted skills and the Skill tool rejects them, while their files remain on disk and stay reachable through Read and Bash. Restricting the list doesn’t restrict dispatch by name. To let Claude invoke every discovered skill, pass skills: "all" rather than a wildcard.

Commands in Agent SDK sessions

This section is the SDK’s command documentation. A command is anything you run by sending /<name> in a prompt. Entries on the command surface differ in what backs them:
  • Built-in commands: execute logic coded into the Claude Code process the SDK runs, for example /compact
  • Bundled skills: prompt artifacts included with Claude Code, for example /code-review
  • Your skills: prompt artifacts that you author, each a directory holding a SKILL.md file. A user-invocable skill’s name joins the surface automatically, so dispatching your own /security-check and running a built-in work the same way
  • Custom command files: an older artifact form with the same behavior, flat Markdown files in .claude/commands/ whose filenames become command names. Skills are their recommended successor
By default, both you and Claude can invoke any skill. You can restrict either path through the skill’s frontmatter. For a definition of the two terms, see the glossary’s Command and Skill entries. See Commands in Claude Code for every built-in and Extend Claude with skills for the complete guide to both artifact forms.

Discover available commands

You can dispatch commands that work without an interactive terminal through the SDK. The system/init message lists the ones available in your session in its slash_commands field. Commands that need an interactive terminal, such as /theme and /terminal-setup, don’t appear in the list. Access the field when your session starts:
The printed list mixes built-in commands, bundled skills, your user-invocable skills, and .claude/commands/ files:
Your user-invocable skills appear in both this list and the skills array from Confirm skills loaded. The slash_commands list adds the rest of the commands available in your session. A skill with user-invocable: false in its frontmatter doesn’t appear in either. Sessions that configure MCP servers can also expose MCP prompts as commands.

Dispatch commands by name

Send a command by including it in your prompt string, the same way you send regular text. Dispatch doesn’t depend on the skills option. Sending /<name> runs a user-invocable skill even when your skills list omits it. Commands that act on conversation history, such as /compact, need prior messages to work with.
A command can hit the maxTurns / max_turns limit like any other prompt, ending the query with an error result instead of success. For the error-result contract, see Handle the result. If your command might hit the limit, wrap the loop in a try/catch in TypeScript or try/except in Python, as shown in Single Message Input, or set maxTurns high enough for the work to complete.

Compact history with /compact

The /compact command reduces the size of your conversation history by summarizing older messages while preserving important context. Compaction needs an existing conversation with enough prior messages to summarize. This example has a conversation first, then compacts it and reads the compact_boundary system message that reports the result:
A compact_boundary message only arrives when compaction ran. With nothing to summarize, /compact reports the reason instead of raising. The run still ends with a success result and no compact_boundary message, and the result text carries the reason, for example Not enough messages to compact. after a single short exchange. A fresh one-shot query() call starts with empty context, so use this pattern in a session with prior turns, for example in streaming input mode or when resuming a session.

Reset context with /clear

The /clear command resets the conversation to an empty context, so subsequent prompts start with no prior conversation history. The previous conversation remains on disk. You can return to that conversation by passing its session ID to the resume option. /clear is useful in streaming input mode, where you send multiple prompts over a single connection. For one-shot query() calls, each call already starts with empty context, so sending /clear has no practical effect. Start a new query() instead.

Create skills

Create each skill as a directory containing a SKILL.md file with YAML frontmatter and Markdown content. The description field determines when Claude invokes your skill. Example directory structure:

Choose a discovery level

Save skills at either of the two most common discovery levels:
  • Project skills: .claude/skills/, available only in the current project
  • Personal skills: ~/.claude/skills/, available across all your projects
If you have existing custom command files in .claude/commands/, they keep working. A command file at .claude/commands/deploy.md creates /deploy and works the same way as a skill at .claude/skills/deploy/SKILL.md would. If a command file and a skill share a name, see Where skills live for which one runs. The SDK loads .claude/commands/ and ~/.claude/commands/ files from the same two scopes as skills. See Extend Claude with skills for the complete guide to both artifact forms.

Create and dispatch your first skill

To see the full flow, create .claude/skills/security-check/SKILL.md:
Once the file exists, the skill is available through the SDK. Claude invokes it when a request matches its description, and you can dispatch it directly:
A successful run ends with a success result whose text carries the scan findings. Against a small Express app with seeded issues, the result text begins:
The skill’s name also appears in the init message’s slash_commands array.
Claude Code includes bundled code-review and verify skills. If you name a .claude/commands/ file after one of them, for example .claude/commands/code-review.md, the file’s command shadows the bundled skill and slash_commands lists the name once.

Pre-approve tools for skills

For project and personal skills, the allowed-tools frontmatter field applies only when you use the Claude Code CLI directly. In SDK sessions, manage tool approval for these skills through the allowedTools option (allowed_tools in Python) in your query configuration. Skills synced from claude.ai follow their own frontmatter rules.
Skills run with the session’s tools. The example below pre-approves Read, Grep, and Glob with allowedTools (allowed_tools in Python), so Claude can inspect files while running the security-check skill without stopping for approval:
In the stream, the skill invocation appears as a Skill tool use, followed by Read calls on the project files. The run ends with a success result whose text carries the findings. The list pre-approves the named tools rather than restricting the others. For the full permission flow, including permission modes and the canUseTool callback, see Permissions.

Troubleshooting

Skills not found

Check settingSources configuration: the SDK discovers skills through the user and project setting sources. If you set settingSources/setting_sources explicitly and omit those sources, the SDK doesn’t load skills: