Skip to content

AI Agent Skill Format Specification

An AI agent skill is a self-contained directory that teaches an AI coding assistant how to use a specific tool, API, or workflow. The assistant discovers installed skills at startup and loads their instructions alongside its built-in knowledge.

This document specifies the portable skill format used by Claude Code, Codex CLI, Gemini CLI, OpenClaw, and any agent platform that adopts this convention.


Overview

Skills bridge the gap between what an AI assistant knows by default and what it needs to know to operate your specific tool. A skill for a CLI tool might teach the agent which commands exist, which flags are required, and how to chain commands together for common workflows. A skill for an API might explain authentication, rate limits, and error handling patterns.

Skills are plain text — a directory of Markdown files — so they are portable, diff-friendly, and trivial to distribute alongside a binary or publish to a package registry.

Ecosystem Support

The following platforms read skills from skills/ subdirectories within their config directories:

Platform Config Directory
Claude Code ~/.claude/
Codex CLI ~/.codex/
Gemini CLI ~/.gemini/
OpenClaw ~/.openclaw/
Cross-tool standard ~/.agents/

File Structure

my-skill/
  SKILL.md           # Required: frontmatter metadata + instructions
  references/        # Optional: topic-specific deep dives
  scripts/           # Optional: executable helper scripts
  assets/            # Optional: templates, data files, schemas

The only required file is SKILL.md. Everything else is optional and referenced from the main file as needed.

The directory name is the skill name. A skill installed at ~/.claude/skills/bullpen-cli/ has name bullpen-cli.


SKILL.md Format

SKILL.md is a Markdown file with YAML frontmatter. The frontmatter provides metadata for discovery and version management. The Markdown body contains the instructions the agent reads.

Frontmatter

The file must begin with a YAML frontmatter block delimited by ---:

---
name: my-skill
description: "When and why to use this skill."
version: "1.0.0"
license: MIT
metadata:
  author: Your Name or Organization
  tags: [tag1, tag2, tag3]
  docs-url: docs.example.com
allowed-tools: [Bash, Read]
---

Required Fields

Field Type Description
name string Unique identifier. Should match the directory name. The directory name is the authoritative identifier; this field is used for display and verification.
description string One or two sentences describing when the agent should activate this skill. This is the primary signal the agent uses to decide whether to consult the skill for a given user request.

Optional Fields

Field Type Description
version string (semver) Skill version for update tracking. Use "0.0.0" as a placeholder that the installer stamps at install time.
license string (SPDX) License identifier, e.g. MIT, Apache-2.0.
metadata.author string Human-readable author or organization name.
metadata.tags string[] Discovery tags for search and categorization.
metadata.docs-url string URL to full documentation (without https:// prefix is fine).
allowed-tools string[] Platform-specific tool allowlist (Claude Code). Restricts which tools the agent may invoke when operating under this skill. Omit to allow all tools.

Writing a Good description

The description field is critical — it is what the agent reads to decide whether a skill is relevant to the current task. Write it as an explicit activation condition:

# Good: specific, scannable activation conditions
description: "Use the Bullpen CLI to trade Polymarket prediction markets,
  discover events, manage portfolios, and automate trading workflows.
  Use when the user asks about prediction markets, Polymarket, buying/selling
  shares, checking positions, market discovery, orderbooks, or scripting
  prediction market operations."

# Poor: vague, no activation signal
description: "Bullpen CLI skill for trading."

Markdown Body

The body after the frontmatter --- is free-form Markdown. The sections below are recommended but not required.

1. Instructions / Decision Tree

A routing section that tells the agent where to go for each type of user intent. For simple skills, this can be a short paragraph. For complex tools with many commands, use a table or decision tree:

## Instructions

Route to the right reference based on the user's intent:

| User Intent | Reference |
|-------------|-----------|
| Install or authenticate | `references/getting-started.md` |
| Execute a trade | `references/trading.md` |
| Check portfolio | `references/portfolio-and-orders.md` |

2. Quick Command Map

An intent-to-command table for common operations the agent can use without loading full references:

## Quick Command Map

| Intent | Command |
|--------|---------|
| Log in | `mytool login` |
| Check status | `mytool status` |
| List items | `mytool list` |

3. Examples

Multi-step workflows showing how commands chain together. Examples are especially useful for non-obvious sequences:

## Examples

### Research and Trade

User says: "Buy Yes shares on the Bitcoin market"

1. Search: `bullpen polymarket search "bitcoin"`
2. Check price: `bullpen polymarket price <SLUG>`
3. Buy: `bullpen polymarket buy <SLUG> Yes 10 --yes`
4. Verify: `bullpen polymarket positions`

4. Troubleshooting

An error-to-fix table for the most common failure modes:

## Troubleshooting

| Error | Fix |
|-------|-----|
| "Not authenticated" | Run `mytool login` |
| "Rate limited" | Wait 30 seconds; reduce request frequency in scripts |
| Command not found | Run `mytool upgrade` to get the latest version |

5. Resources

Links to documentation, issue tracker, and support channels.


Install Locations

Skills are installed as subdirectories under a skills/ folder within a platform's config directory. Each platform looks in its own directory, and most platforms also support a cross-tool standard path under ~/.agents/.

Personal Skills (User-Scoped)

Personal skills apply to all projects for that user.

Platform Path
Claude Code ~/.claude/skills/{name}/
Codex CLI ~/.codex/skills/{name}/
Gemini CLI ~/.gemini/skills/{name}/
OpenClaw ~/.openclaw/skills/{name}/
Cross-tool standard ~/.agents/skills/{name}/

The cross-tool path (~/.agents/skills/) is a platform-neutral location that non-Claude platforms read in addition to their own directories. Installing to this path makes a skill available across all tools without platform-specific installs.

Sibling skills: When a skill is distributed with companion skills, the installer may write sibling directories automatically. For example, bullpen skill install writes both bullpen-cli/ and bullpen-bracket/ under the same skills directory in a single command.

Project Skills (Repository-Scoped)

Project skills are checked in to a repository and apply only when the agent is working within that project.

Platform Path
Claude Code .claude/skills/{name}/ (in repo root)
Other platforms .agents/skills/{name}/ (in repo root)

Both project and personal skills are loaded. If both exist for the same name, behavior depends on the platform. The directory name is the authoritative identifier.

Discovery Algorithm

At startup, each platform scans its skills/ directories for subdirectories containing SKILL.md:

for each skills_dir in [personal_dir, project_dir, cross_tool_dir]:
    for each entry in skills_dir:
        if entry is a directory and entry/SKILL.md exists:
            load skill with name = entry.directory_name

The directory name is the authoritative skill name — not the name field in the frontmatter — because the directory name is what the file system enforces as unique. The name field in frontmatter should match the directory name and is used for display and version reporting.


Parsing Contract

Platforms parse the SKILL.md frontmatter without a full YAML library, using simple line-by-line extraction. This keeps the parser dependency-free and guarantees that all platforms parse identically.

Algorithm

state = BEFORE_FRONTMATTER
for each line in file:
    if line.trim() == "---":
        if state == BEFORE_FRONTMATTER:
            state = IN_FRONTMATTER
        elif state == IN_FRONTMATTER:
            state = AFTER_FRONTMATTER (stop parsing)
        continue
    if state == IN_FRONTMATTER:
        # Split on first colon
        if line contains ":":
            key, value = line.split(":", maxsplit=1)
            key = key.trim()
            value = value.trim().strip_quotes()
            store key -> value

Rules

  • Only top-level keys are extracted by default. Nested keys (e.g. metadata.author) require additional logic to track nesting depth.
  • Values are stripped of surrounding double quotes.
  • Array values (e.g. tags: [a, b, c]) are parsed by stripping [ and ] and splitting on ,.
  • Lines that do not contain : are ignored.
  • The frontmatter ends at the second --- line.

Example (Rust)

fn parse_frontmatter_field(content: &str, field: &str) -> Option<String> {
    let mut in_frontmatter = false;
    for line in content.lines() {
        if line.trim() == "---" {
            if in_frontmatter { break; }
            in_frontmatter = true;
            continue;
        }
        if in_frontmatter {
            let trimmed = line.trim();
            if let Some(rest) = trimmed.strip_prefix(field) {
                if let Some(value) = rest.strip_prefix(':') {
                    return Some(value.trim().trim_matches('"').to_string());
                }
            }
        }
    }
    None
}

This approach is intentionally minimal. For skills that need richer metadata, place additional structured data in a separate file under assets/ and parse it independently.


Version Management

Skills use semantic versioning (major.minor.patch). The version field enables tools that install skills to detect when an installed skill is outdated relative to the version shipped with the latest binary.

Version Placement

The version field can appear in two locations within the frontmatter:

  • Top-level (preferred for new skills):
    version: "1.0.0"
    
  • Under metadata (legacy, supported by Bullpen CLI):
    metadata:
      version: "1.0.0"
    

Both placements are supported. Bullpen's stamp_version() implementation searches for version: at any indentation level within the frontmatter, so it handles both top-level and nested metadata.version fields. New skills should prefer the top-level placement for consistency with the rest of the spec.

Placeholder Stamping

Skills distributed with a CLI tool should use "0.0.0" as a placeholder version in the source file:

version: "0.0.0"

At install time, the CLI replaces this placeholder with the actual binary version:

fn stamp_version(content: &str, version: &str) -> String {
    // Replace `version: "0.0.0"` with `version: "1.2.3"` in frontmatter
    // Searches for `version:` at any indentation level
    // ...
}

This ensures the installed skill version always matches the CLI version without requiring the skill file to be manually updated on every release.

Checking for Updates

When listing installed skills, a tool can compare the installed version field against the current binary version to report outdated skills:

bullpen skill list
  bullpen-cli v0.1.10 (outdated, latest: 0.1.17) [Claude Code personal]
  bullpen-bracket v0.1.17 (up to date) [Claude Code personal]

Examples

Minimal Skill

The smallest valid skill — only the two required fields:

---
name: my-tool
description: "Use my-tool CLI to manage widgets and automations. Use when the user asks about widgets, querying the widget catalog, or running widget automations."
---

# My Tool

Run `my-tool --help` to see available commands.

A skill using all available fields and the recommended section structure:

---
name: bullpen-cli
description: "Use the Bullpen CLI to trade Polymarket prediction markets, discover events, manage portfolios, and automate trading workflows. Use when the user asks about prediction markets, Polymarket, buying/selling shares, checking positions, market discovery, orderbooks, tracking traders, or scripting prediction market operations."
version: "0.0.0"
license: MIT
metadata:
  author: BullpenFi
  tags: [prediction-markets, polymarket, trading, cli, portfolio]
  docs-url: cli.bullpen.fi
allowed-tools: [Bash, Read]
---

# Bullpen CLI Skill

## Instructions

Route to the right reference based on the user's intent:

| User Intent | Reference |
|-------------|-----------|
| Install or authenticate | `references/getting-started.md` |
| Discover and research markets | `references/discovery-and-research.md` |
| Execute trades | `references/trading.md` |
| Manage portfolio and orders | `references/portfolio-and-orders.md` |

## Quick Command Map

| Intent | Command |
|--------|---------|
| Log in | `bullpen login` |
| Check status | `bullpen status` |
| Discover markets | `bullpen polymarket discover` |
| Buy shares | `bullpen polymarket buy <SLUG> <OUTCOME> <USD>` |

## Troubleshooting

| Error | Fix |
|-------|-----|
| "Not authenticated" | Run `bullpen login` |
| "Market not found" | Use `bullpen polymarket search` to find the correct slug |

## Resources

- Docs: [cli.bullpen.fi](https://cli.bullpen.fi)
- Issues: [github.com/BullpenFi/bullpen-cli-releases/issues](https://github.com/BullpenFi/bullpen-cli-releases/issues)

Skill with References Directory

For large tools with many commands, split the instructions across topic-specific reference files and load them on demand:

bullpen-cli/
  SKILL.md                              # Router: identifies user intent and points to references
  references/
    getting-started.md                  # Install, auth, first-time setup
    trading.md                          # Buy, sell, limit orders, CTF split/merge
    portfolio-and-orders.md             # Positions, open orders, watchlist
    discovery-and-research.md           # Discover, search, event details, price history
    scripting-and-automation.md         # JSON output, jq pipelines, batch workflows

The main SKILL.md acts as a router. It reads the user intent and directs the agent to load the appropriate reference file before acting:

## Instructions

### Step 1: Identify the user's intent

**Trading** (buy, sell, limit orders):
- Read `references/trading.md`

**Discovery** (find markets, prices, events):
- Read `references/discovery-and-research.md`

**Portfolio** (positions, orders, watchlist):
- Read `references/portfolio-and-orders.md`

This pattern keeps the main file concise while making deep documentation available on demand without loading everything upfront.


Platform Compatibility Matrix

Not all platforms support all frontmatter fields. The table below shows which fields each platform reads as of the current specification version.

Field Claude Code Codex CLI Gemini CLI OpenClaw
name Yes Yes Yes Yes
description Yes Yes Yes Yes
version Yes Yes Yes Yes
license display only display only display only display only
metadata.author display only display only display only display only
metadata.tags display only display only display only display only
metadata.docs-url display only display only display only display only
allowed-tools Yes No No No

"Yes" means the platform uses the field to affect agent behavior. "display only" means the field is read and shown in skill listings but does not change how the agent operates. "No" means the field is ignored.

The allowed-tools field is Claude Code-specific. On other platforms, the agent uses its default tool allowlist regardless of what this field contains.

Note: This matrix describes Bullpen CLI's implementation of the skill format. Support for other platforms reflects the intended behavior of the emerging standard. Verify specific platform documentation for authoritative compatibility information.


Distributing Skills with a CLI Tool

The recommended pattern for CLI tools is to embed skill files directly in the binary and write them to disk via an install command:

# Install skills to all detected AI agent platforms
mytool skill install

# Install to a specific platform
mytool skill install --claude
mytool skill install --codex

# Install to a specific path
mytool skill install --path /custom/path/

# Uninstall
mytool skill uninstall

Embedding skill files in the binary (using include_str!() in Rust or equivalent) means the skill is always in sync with the binary version, works offline, and requires no network access at install time.

When the binary is upgraded, the skills should be re-written automatically so the installed skill version tracks the binary version.


See Also