# SKILL.md, Explained

> The anatomy of the one required file in an agent skill: every frontmatter field, why description decides whether your skill ever loads, how long the body should be — annotated with a real, shipping SKILL.md.

By Michał Jaskólski · Published 2026-08-17 · Updated 2026-08-17 · 8 min read
Canonical: https://skills.wondel.ai/learn/skill-md-explained/
Skills used: clean-code, refactoring-patterns, clean-architecture

**TL;DR:** A SKILL.md is a markdown file with YAML frontmatter. Two fields are required — name and description — and the description is the load-bearing one, because it is the only part most agents read before deciding whether to open the rest. The body holds the instructions; anything long belongs in referenced files that load on demand.

- Two frontmatter fields are required: name (max 64 chars, matching the directory) and description (max 1024 chars).
- The description is the trigger — write what the skill does and the exact situations that should activate it, in that order.
- Progressive disclosure means the body is a budget: keep SKILL.md under about 500 lines and push detail into references/.
- Write directions, not a summary — if the file reads like an article about the topic, it will not change what your agent does.

Every agent skill is a folder, and every skill folder has exactly one required file: `SKILL.md`. Everything else — scripts, reference documents, templates — is optional. If you understand one thing about the format, understand this file.

It is markdown with YAML frontmatter at the top. That is the whole specification. The subtlety is not in the syntax; it is in knowing which parts the agent reads, when it reads them, and what that means for where you put your words. Get that wrong and you end up with a technically valid skill that never fires — or one that fires constantly and floods the context with detail nobody needed.

This page walks the file top to bottom, annotated with one of our own shipping skills. For the higher-level framing first, see [what is an AI agent skill](https://skills.wondel.ai/learn/what-is-an-ai-agent-skill/).

## What's actually inside a SKILL.md file?

Two parts, in order. A YAML frontmatter block delimited by `---`, and a markdown body. Here is the top of [Clean Code](https://skills.wondel.ai/skills/clean-code/), one of the 50 skills in our library, unedited:

```yaml
---
name: clean-code
description: 'Write readable, maintainable code through disciplined naming, small functions, and clean error handling. Use when the user mentions "clean up this code", "this function is too long", "code smells", "naming conventions", "boy scout rule", "single responsibility", or "unit test quality". Also trigger when reviewing a pull request for readability, untangling a messy function, debating comment styles, or improving error-handling patterns. Covers SRP, comment discipline, formatting, and unit testing. For refactoring techniques, see refactoring-patterns. For architecture and dependency rules, see clean-architecture.'
license: MIT
metadata:
  author: wondelai
  version: "1.4.0"
---
```

Four fields, of which two are required. Then the body opens with an H1 and a one-paragraph statement of when to apply the skill:

```markdown
# Clean Code Framework

A disciplined approach to writing code that communicates intent, minimizes
surprises, and welcomes change. Apply these principles when writing new code,
reviewing pull requests, refactoring legacy systems, or advising on code quality.

## Core Principle

**Code is read far more often than it is written — optimize for the reader.**
```

Note what that opening does. It is not introducing a topic; it restates the activation conditions in the agent's working context, then hands it one principle to reason from. Every paragraph in a good `SKILL.md` is trying to change a decision the agent is about to make.

## What does each frontmatter field do?

The [specification](https://agentskills.io/specification) defines six fields. Most skills use two or three.

**`name`** (required). Maximum 64 characters, lowercase letters, numbers and hyphens only, no leading, trailing or consecutive hyphens — and it must match the parent directory name. `clean-code` lives in `clean-code/`. This is what users type to invoke the skill explicitly, so make it the obvious noun phrase rather than something clever.

**`description`** (required). Maximum 1024 characters, non-empty. It should describe both what the skill does and when to use it. This is the field that decides whether your skill is ever loaded, and it gets its own section below.

**`license`** (optional). A license name, or a pointer to a bundled license file. Ours say `MIT`. Worth setting on anything you publish.

**`compatibility`** (optional, max 500 characters). Environment requirements: an intended product, required system packages, network access. The spec is blunt that most skills do not need it — use it when your skill genuinely will not work without `docker` and `jq` on the path.

**`metadata`** (optional). An arbitrary map of string keys to string values, for anything the spec does not define. We use it for `author` and `version`, which is what makes a library reviewable — you can see whether a teammate is running the version that fixed the bad advice.

**`allowed-tools`** (optional, experimental). A space-separated list of pre-approved tools the skill may use, like `Bash(git:*) Read`. The specification marks it experimental and warns support varies between agents — treat it as a convenience where it works, not a security boundary you rely on.

That is the complete list. If you find yourself wanting a seventh field, it belongs in `metadata`.

## Why is `description` the single most important line?

Because for most of a session it is the only part of your skill the agent has seen.

Agents load skills through progressive disclosure. At discovery, the agent reads just the `name` and `description` of every installed skill — around a hundred tokens each — and only opens the full `SKILL.md` when a task matches. Your instructions can be immaculate; if the description does not match the way a real request is phrased, none of them will ever be read.

> Everything else in the file is an argument for what to do. The description is the argument for whether the agent bothers to look.

So write it as two halves, in this order: **what the skill does**, then **when to use it**. The second half is where most descriptions fail, because it requires predicting the user's words rather than describing your own topic. Three habits make the difference:

- **Name the symptoms, not the subject.** People do not ask for "code quality". They say a function is too long. Put the phrasing they actually use into the description — note that Clean Code's trigger half is almost entirely quoted user speech.
- **Include the situations, not just the words.** Keyword matching is fragile alone; a clause like "also trigger when reviewing a pull request for readability" gives the agent a scenario to recognise when the vocabulary differs.
- **Disambiguate against your neighbours.** The last two sentences of the Clean Code description exist purely to route: "For refactoring techniques, see refactoring-patterns. For architecture and dependency rules, see clean-architecture." In a library of 50 skills, the failure mode is not that nothing loads — it is that the *adjacent* skill loads.

You have 1024 characters. Using 200 of them is usually a mistake; using all 1024 on prose that never names a trigger is worse.

## What belongs in the body — and what doesn't?

The body is where the agent gets its directions, and the operative constraint is that it loads **all at once** — the moment the skill activates, the entire file enters context. That makes the body a budget, not a canvas.

The specification recommends keeping the instruction layer under roughly 5,000 tokens and the main `SKILL.md` under 500 lines, with detailed material moved into separate files. Our Clean Code skill lands at 222 lines, with six reference files beside it — `naming-conventions.md`, `functions-and-methods.md`, `error-handling.md`, `code-smells.md`, `comments-formatting.md`, `testing-principles.md`.

The way it hands off is worth copying. Inside the section on naming, after the principles and a compact table of patterns, sits a single line:

```markdown
See [references/naming-conventions.md](references/naming-conventions.md) when
renaming or reviewing names — per-language conventions, pronounceable/searchable
tables, and before/after examples.
```

Two things make that pointer work. It uses a relative path from the skill root, as the spec calls for. And it says *when* to open the file and *what is in it*, so the agent can decide without reading it. A bare link with no conditions is one the agent either always follows or never does.

What stays in the body: principles to reason from, the procedure, decision criteria, compact tables. What moves out: exhaustive enumerations, per-language variations, long worked examples — anything that is reference material rather than instruction. Keep reference chains one level deep.

## When should a skill bundle scripts?

When the work is deterministic and you would rather it not be re-derived every time.

The convention is a `scripts/` directory holding executable code the agent runs — Python, Bash and JavaScript are common, though what actually runs depends on the agent. The rule of thumb: if the steps never vary and correctness matters more than judgment, write the script and have `SKILL.md` say when to run it and how to read the output. That beats asking the model to regenerate the same logic every invocation, because generated code varies and a committed script does not.

Scripts should be self-contained or document their dependencies, fail with messages an agent can act on, and handle the obvious edge cases. An `assets/` directory covers the rest — templates, schemas, lookup tables, anything static the skill hands over rather than describes.

Many good skills have neither. Clean Code has none: it is pure judgment, and judgment does not compile.

## What are the most common SKILL.md mistakes?

Four, in descending order of how often we see them.

**A vague description.** "Helps with code quality." "Assists with documentation." These are topics, not triggers, and skills carrying them sit unloaded forever while their authors conclude the format does not work. The spec's own example of a poor description is `Helps with PDFs.` If you fix one thing here, fix this.

**Dumping the whole book into the body.** A 2,000-line `SKILL.md` defeats progressive disclosure: every activation now costs a large fraction of the context window, most of it irrelevant. The fix is not to delete material — move it into `references/` and add a conditional pointer.

**Writing a summary instead of directions.** The subtle one. A file that explains a methodology reads well to a human and changes nothing about the agent's behaviour. Directions are imperative and testable: *flag any function over twenty lines*, *extract handlers rather than inlining try-catch*. Our test — if the text would work unchanged as a blog post, it is not yet a skill.

**No boundary against neighbouring skills.** Two skills whose descriptions both plausibly match "improve this code" will fight, and the winner is arbitrary. Name the adjacent skills and state which owns which case.

> **Prompt** — Use the `clean-code` skill to review my most important service class and flag any function over twenty lines or doing more than one thing, every name that does not reveal intent, and any swallowed exceptions — then give it a score out of ten and the top five fixes in priority order
> (https://skills.wondel.ai/skills/clean-code/)

## Frequently asked questions

### What are the required fields in a SKILL.md?

Exactly two: name and description. The name must be 1 to 64 characters, lowercase letters, numbers and hyphens only, with no leading, trailing or consecutive hyphens, and it must match the folder the file sits in. The description must be non-empty and at most 1024 characters. Everything else is optional.

### How long should a SKILL.md be?

Short enough that loading it is cheap, since the whole body enters context the moment the skill activates. The specification recommends keeping the instruction layer under about 5,000 tokens and the main file under 500 lines. Our Clean Code skill sits at 222 lines with six reference files beside it — principles and procedure in the main file, exhaustive detail one level away and loaded only when a task needs it.

### Why isn't my skill loading?

Almost always the description. Agents match against it before reading anything else, so a description naming your topic rather than the user's symptoms will never fire. Rewrite it with the phrases people actually type and the situations that should trigger it, and check it does not overlap ambiguously with a neighbouring skill. As a diagnostic, name the skill explicitly in your prompt — if it works when invoked by name but never fires on its own, the description is the problem.

### Can I use any markdown in the body?

Yes. The spec places no format restrictions on the body — headings, tables, code blocks, checklists, whatever communicates the procedure most compactly. Tables earn their space because they encode a lot of decision criteria in few tokens. What matters is not the markup but the mode: write directions the agent can act on, not exposition it can only agree with.

### Where do I put files the skill needs?

By convention, executable code goes in scripts/, deeper documentation in references/, and static resources like templates and lookup tables in assets/. None are required, but the conventional names help agents and humans navigate an unfamiliar skill. Reference them with relative paths from the skill root, one level deep rather than nesting pointers inside pointers.

### Does the version field do anything?

Not to the agent — version lives inside metadata, which the specification defines as an arbitrary map clients may use for their own purposes. Its value is to your team. A version plus an author makes a library reviewable: you can tell which revision a colleague is running, roll back advice that turned out wrong, and treat a change to a skill the way you treat a change to code.

## Where to go next

About to write your first one? [How to write an agent skill](https://skills.wondel.ai/learn/how-to-write-an-agent-skill/) turns this anatomy into a procedure. Still deciding whether a skill is the right container at all — as opposed to an MCP server or a subagent — start with [what is an AI agent skill](https://skills.wondel.ai/learn/what-is-an-ai-agent-skill/).

The fastest way to internalise the shape is to read a few real ones. All 50 of ours are MIT-licensed:

```
npx skills add wondelai/skills --all --global
```

Open any `SKILL.md` in the folder it installs to, and you will see the same anatomy: a description built out of the user's own words, a body that fits in one screen of scrolling, and the depth kept one level away until something asks for it.
