मुख्य कंटेंट तक स्किप करें

SKILL.md: The Cross-Agent Open Standard

मध्यम

For a few years every coding agent had its own file: .cursorrules, CLAUDE.md, Codex system prompts, Gemini instructions, a dozen more. Then Anthropic quietly turned their internal Skills format into an open spec — and within 48 hours the biggest agents in the world were reading each other's files. Today one directory called code-reviewer/ with a SKILL.md inside runs unchanged in Claude Code, Codex CLI, ChatGPT, Gemini CLI, Junie, Kiro, Goose and Cursor. This is the closest the agent world has come to a shared plug.

This page is the practical field guide: what the standard actually is at the byte level, the one clever trick (progressive disclosure) that makes 100-skill installs cheap, exactly which fields break portability the moment you touch them, the honest security picture, and a copy-pasteable portable skill you can ship today.

What you'll learn
  • Understand what SKILL.md is at the file-format level — required fields, optional fields, directory layout
  • Understand progressive disclosure: why 100 skills cost ~10K tokens at startup, not 100× the body
  • Know the exact vendor extensions that silently break portability across agents
  • Write a skill that runs unchanged in Claude Code, Codex CLI and Gemini CLI
  • Weigh the security trade-off honestly before installing skills from any marketplace

What the standard actually is

Strip away the marketing and the Agent Skills open standard is small enough to hold in your head:

  • A directory whose name is the skill's name
  • A required SKILL.md file inside it — YAML frontmatter, then Markdown body
  • Optional siblings: scripts/ (executables the skill can run), references/ (docs the skill can pull in on demand), assets/ (templates, images, prompt files), and — added later — agents/ for opt-in vendor-specific config

That's the whole surface area. Two required frontmatter fields do most of the work:

  • name — up to 64 characters, lowercase-with-hyphens, must match the parent directory
  • description — up to 1,024 characters, the sentence the agent uses to decide whether to load this skill for the current task

Everything else — license, compatibility, metadata, and the still-experimental allowed-tools — is optional and safely ignored by tools that don't understand it. Bodies are Markdown; the community convention is to keep them under ~5,000 tokens, and real-world skills mostly do: median skill size on the largest marketplace is about 1,414 tokens with 90% under 3,935 tokens.

The one clever trick: progressive disclosure

The reason SKILL.md works at scale isn't the file format — it's how agents load it. All conformant agents implement three tiers:

Guided walkthrough1 of 3
  1. The agent walks the skills directory and reads only the frontmatter of every SKILL.md. That's roughly 100 tokens per skill. Install 100 skills and you've spent ~10K tokens of context before your first prompt — cheaper than a single long system message.

This is why the spec caps description so tightly and treats it as a first-class field: it's the only text the model sees when choosing whether to activate the skill. A vague description is the single most common reason a skill that "should work" never fires.

:::tip Write the description last, and rewrite it Once the body of a skill is solid, go back and treat the description as your ad copy. It has one job: help the model recognize the shape of a task that this skill should own. "Reviews pull requests" is bad. "Reviews a PR diff for logic bugs, missing tests, and violated project conventions; use whenever the user asks for a review, code review, or 'look at this PR'" is good. :::

The universal directory

Every conformant agent expects the same layout. This one works everywhere:

code-reviewer/
├── SKILL.md # required — the instructions the agent reads
├── scripts/ # optional — executables the skill can invoke
│ └── run-linters.sh
├── references/ # optional — long docs the skill pulls on demand
│ └── style-guide.md
├── assets/ # optional — templates, prompt files, snippets
│ └── pr-comment-template.md
└── agents/ # optional — VENDOR-SPECIFIC, opt-in only
└── openai.yaml # ignored by every non-Codex agent

The agents/ subdirectory is the safety valve for the standard: it lets vendors ship extensions without contaminating the portable core. A file at agents/openai.yaml is Codex-specific and every other agent will simply ignore it. Use it when you need extra power; know it costs you portability.

What actually travels vs what silently doesn't

The whole spec was designed for portability, but real skills in the wild have three failure modes.

What you usePortable?Why
name, description, Markdown body✅ YesCore spec. Every conformant agent reads these identically.
scripts/, references/, assets/ referenced from the body✅ YesDirectory layout is part of the spec; agents will read them when the body says to.
license, metadata✅ Yes (safe to ignore)Optional fields — non-supporting agents skip without erroring.
allowed-tools frontmatter⚠️ PartialMarked experimental in the spec; syntax across agents is not standardized. Claude Code honors one form, Codex CLI another, most others ignore it entirely.
Claude Code's when_to_use list❌ Claude-onlySilently ignored by Codex, Gemini CLI and everyone else.
Claude Code's context: fork subagent flag❌ Claude-onlyNon-portable subagent execution semantics — model behavior differs everywhere else.
agents/openai.yaml extensions❌ Codex-onlyExplicitly vendor-scoped by design. Portable because other agents ignore it.

The lesson is blunt: stick to name + description + Markdown body + the three optional subdirectories and your skill runs everywhere. Reach into any frontmatter field beyond the core two and you're building for one agent. That's a legitimate choice — some skills genuinely need it — but do it deliberately, not because you copy-pasted a template.

How activation actually works (per agent)

The spec standardizes the file, not the decision. Each agent still runs its own activation logic on the descriptions it read at startup:

  • Claude Code matches the model's read of the current turn against description and (if present) the Claude-specific when_to_use list; activation is a model decision, not a keyword rule.
  • Codex CLI uses the same description-driven activation, with optional overrides in agents/openai.yaml.
  • Gemini CLI likewise loads descriptions at startup and lets Gemini choose; behavior tracks Gemini's own tool-selection heuristics.
  • Cursor, Junie, Kiro, Goose all implement description-driven activation with light variations in weighting.

Practical consequence: a skill that never fires on one agent but works on another almost always has a description problem, not a body problem. Rewrite the description to describe the user request shape, not the skill's internals, and the fire rate goes up on every agent at once.

A portable SKILL.md you can copy

Here is a minimal, actually-portable code-review skill. Drop it in ~/.agents/skills/code-reviewer/SKILL.md and it will run in Claude Code, Codex CLI, ChatGPT and Gemini CLI without modification.

code-reviewer/SKILL.md

---
name: code-reviewer
description: Reviews a diff or pull request for logic bugs, security issues, missing tests, and violations of project conventions. Use whenever the user asks for a review, code review, PR review, or "look at this diff / patch / change".
license: MIT
---

# Code Reviewer

You review code changes with the discipline of a staff engineer who cares
about the codebase surviving contact with reality. You are opinionated but
short. You never restate what the diff does — the user can read it.

## What to look at

1. **Logic bugs** — off-by-one, wrong operator, swapped arguments, unhandled
 error path, race, silent catch.
2. **Missing tests** — any changed behavior without a test is a finding.
3. **Security** — injection, secrets, missing auth checks, unsafe deserialization,
 unbounded input.
4. **Project conventions** — if a CLAUDE.md, AGENTS.md, .cursorrules, or README
 exists in the repo root, load it and enforce what it says.
5. **Complexity that will hurt future readers** — call it out, propose the
 simpler shape.

## What NOT to do

- Do not comment on formatting the linter will catch.
- Do not praise. No "great work" / "nice refactor".
- Do not summarize the diff. Assume the reader read it.

## Output format

For each finding, one line:

`path:line — <severity>: <problem>. <concrete fix>.`

Severities: 🔴 blocker, 🟠 important, 🟡 nit.

End with a one-line verdict: "ship", "ship with fixes", or "rework".

Every line of that skill runs on every conformant agent. Nothing in the frontmatter is vendor-scoped. The body uses plain Markdown headings that any agent parses.

Now compare to a non-portable variant — subtly, it's Claude-only:

Claude-only variant (do not use if you want portability)

---
name: code-reviewer
description: Reviews a diff or pull request.
when_to_use:
- user asks for a review
- user pastes a diff
context: fork
allowed-tools: [Bash, Read, Grep]
---

Three things break portability at once: when_to_use (Claude Code only), context: fork (Claude Code subagent semantics), and allowed-tools (experimental, not honored consistently). Codex will read the description as "Reviews a diff or pull request" — which is so vague it will barely ever activate — and ignore the rest.

The security picture (be honest with yourself)

The uncomfortable truth about installing skills from any marketplace: a skill is arbitrary instructions to a highly capable agent that runs in your environment with your permissions. The standard specifies no code signing, no sandboxing, no mandatory review, and no runtime permission model. It is by design a text-file spec, not a security spec.

The concrete numbers, from independent analyses of large public skill catalogs (verify at source before quoting):

  • Roughly one in three publicly-shared skills contains at least one security-relevant flaw — over-broad shell instructions, hardcoded secrets, calls to untrusted URLs, or curl | sh-style bootstrap steps.
  • A smaller but non-zero set of skills has been flagged as outright malicious — attempting exfiltration, credential harvesting, or destructive operations.
  • Skills inherit whatever the agent inherits. If your agent can read ~/.ssh/, so can any skill you install.

Practical defenses that actually work:

Guided walkthrough1 of 4
  1. It is Markdown. It takes a minute. If the description says 'formats prose' and the body contains `curl` to a URL you don't recognize, that is the moment you stop.

For a deeper dive on how skills get compromised and what to check, see Vetting Agent Skills and Coding Agents Under Attack.

When to write a skill vs when to just prompt

New maintainers of a skill catalog often over-produce them. A useful rule:

  • Prompt for a one-off task or a shape you'll use in one project. Skills carry startup cost — even if it's small — and clutter your description budget.
  • Write a skill when the same instructions apply across many chats or projects (code review, commit-message writing, changelog generation, invoice extraction) and the description would be unambiguous. If you can't write a crisp description, the skill won't fire reliably anyway.
  • Reach for a subagent instead when the task needs its own tool set, its own model choice, or genuine parallelism. Skills instruct the main model; subagents run separately. See Subagents.

Check your grip

Check yourself

0/4
  1. You install 100 skills. Roughly how many tokens do their descriptions cost your agent at startup?
  2. Which of these frontmatter fields will silently break your skill on Codex CLI and Gemini CLI even though it works in Claude Code?
  3. A skill you wrote fires reliably on Claude Code but almost never on Codex CLI. What's the highest-leverage thing to fix first?
  4. Why is the security posture of Agent Skills fundamentally weaker than, say, npm packages with lockfiles and audit tooling?

Sources & further reading