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.mdfile 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) orsetting_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
skillsoption: discovered skills are enabled by default. Pass a list of skill names,"all", or[]to control which skills Claude can invoke
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 theskills 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 setskills, 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 subtypeinit. 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 theskills 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.mdfile. A user-invocable skill’s name joins the surface automatically, so dispatching your own/security-checkand 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
Discover available commands
You can dispatch commands that work without an interactive terminal through the SDK. Thesystem/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:
.claude/commands/ files:
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 theskills 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 aSKILL.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
.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:
success result whose text carries the scan findings. Against a small Express app with seeded issues, the result text begins:
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.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:
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 theuser and project setting sources. If you set settingSources/setting_sources explicitly and omit those sources, the SDK doesn’t load skills: