Skills
Skills are reusable instruction modules that extend what an agent can do. Each skill is a directory containing aSKILL.md file with YAML frontmatter and markdown instructions. The agent discovers available skills at startup, advertises their descriptions to the LLM, and loads full skill content on demand via tool call.
The skill system follows the Agent Skills Open Standard, a portable specification adopted by 30+ AI tools including Claude Code, OpenAI Codex, Cursor, GitHub Copilot, and others. Skills written for this framework are compatible with those tools and vice versa.
Directory Structure
Each skill lives in its own directory under a skills root:scripts/, references/, assets/, examples/) are automatically discovered and listed in the skill’s resources property.
SKILL.md Format
Every skill needs aSKILL.md file with optional YAML frontmatter between --- markers, followed by markdown content:
Frontmatter Fields
Agent Skills Open Standard (portable)
| Field | Type | Default | Description |
|---|---|---|---|
name | string | directory name | Skill name (lowercase, hyphens, max 64 chars) |
description | string | '' | What the skill does and when to use it |
license | string | null | License (e.g. MIT, Apache-2.0) |
compatibility | string | null | Environment requirements |
metadata | map | [] | Arbitrary key-value pairs |
allowed-tools | string/list | [] | Space/comma-delimited or YAML list of allowed tools |
Cross-platform Extensions
| Field | Type | Default | Description |
|---|---|---|---|
disable-model-invocation | bool | false | Prevent the model from auto-loading this skill |
user-invocable | bool | true | Whether to show in user-facing skill listings |
argument-hint | string | null | Hint for expected arguments (e.g. [issue-number]) |
Execution Context Extensions
| Field | Type | Default | Description |
|---|---|---|---|
model | string | null | Override model when skill is active |
context | string | null | Set to fork for subagent execution |
agent | string | null | Subagent type when context: fork |
Setting Up Skills
Creating a SkillLibrary
TheSkillLibrary scans a directory for skill subdirectories:
getSkill() call and cached thereafter.
Wiring Into an Agent
TheUseSkills capability registers the load_skill tool and injects skill metadata via a hook:
- Registers
load_skilltool — the LLM can callload_skill(skill_name: "code-review")to load full skill content, orload_skill(list_skills: true)to see available skills. - Injects metadata hook —
AppendSkillMetadataHookprepends a system message listing skill names and descriptions so the LLM knows what’s available.
Argument Substitution
When loading a skill with arguments, placeholders in the body are replaced:| Placeholder | Replaced with |
|---|---|
$ARGUMENTS | Full argument string |
$ARGUMENTS[N] | Nth argument (0-based) |
$N | Shorthand for $ARGUMENTS[N] |
ARGUMENTS: <value>.
load_skill(skill_name: "fix-issue", arguments: "123"), the body becomes “Fix GitHub issue 123 following our coding standards.”
Invocation Control
Two flags control who can invoke a skill:| Configuration | Model sees it | User sees it | Use case |
|---|---|---|---|
| (default) | Yes | Yes | General-purpose skills |
disable-model-invocation: true | No | Yes | Side-effect workflows (deploy, commit) |
user-invocable: false | Yes | No | Background knowledge (legacy system context) |
Components
Skill
Immutable value object holding parsed skill data:SkillLibrary
Discovery and lazy-loading of skills from a directory:LoadSkillTool
Tool exposed to the LLM for loading skills:AppendSkillMetadataHook
Fires onBeforeStep. Before the first agent step, injects a system message listing available model-invocable skills with their descriptions and argument hints. Skips subsequent steps if already injected.
TrackActiveSkillHook
Fires onAfterToolUse. When load_skill completes successfully, updates the agent state metadata with the loaded skill’s allowed-tools list and model override. Clears these values when a skill without them is loaded.
SkillToolFilterHook
Fires onBeforeToolUse. Enforces allowed-tools restrictions when a skill with an allowed-tools field is active. If the tool being called is not in the list, blocks execution. The load_skill tool itself is never blocked, allowing the agent to switch skills.
SkillModelOverrideHook
Fires onBeforeStep. Checks agent state metadata for an active skill’s model override and applies it by creating a new LLMConfig with the specified model. This allows skills to target specific models (e.g., a coding skill that requires a more capable model).
Shell Preprocessing
Skills can embed shell commands using the!`command` syntax. When a SkillPreprocessor is configured, these patterns are executed and replaced with their output before argument substitution occurs.
!`...` patterns are replaced with live command output, giving the LLM up-to-date context.
Enabling Preprocessing
Pass aSkillPreprocessor to UseSkills:
[error: ...] markers instead of crashing the skill load.
Cross-Platform Compatibility
The portable subset that works across all Agent Skills-compatible tools:nameanddescriptionin frontmatter- Markdown instructions in the body
- Directory-per-skill layout with
SKILL.mdentry point
disable-model-invocation, context, model, etc.) are tool-specific. Unknown fields are ignored gracefully by all compliant tools, so skills with extensions remain portable — the extensions simply don’t activate in tools that don’t support them.