SKILL.md: what it is and how to write one
Fill it in and copy it Open in the editor Opens as SKILL.md, ready to edit. Nothing is uploaded.
The shape of it — edit here, or open the full template
Result
Fill it in and take it
The whole file is below. Type into the boxes to replace the placeholders, then copy it or save it — nothing here is sent anywhere, and there is nothing to sign up for.
---
name: pdf-forms
description: Fill, flatten and extract data from PDF forms. Use when the user
mentions AcroForm fields, a fillable PDF, or wants values read out of a form.
---
<!--
SKILL.md — the file that defines an agent skill.
Two things matter more than anything else in this file:
1. The `description` is how the agent decides whether to load the skill at
all. It is read when the skill is NOT loaded, so it has to say what the
skill does *and* when to reach for it. A description that only names the
tool ("PDF tools") never gets picked.
2. Everything below the front matter is only read once the skill is chosen.
That is where the detail goes, and it is why the front matter must stay
short.
The folder is the unit, not the file:
pdf-forms/
SKILL.md this file — required
reference.md loaded on demand, not up front
scripts/fill.py run rather than read
-->
# PDF forms
Fill and read AcroForm fields in a PDF without opening one by hand.
## When to use this
- A PDF has fillable fields and values need putting into them
- Values need extracting from a form somebody already filled in
- A filled form needs flattening so the fields cannot be edited
Not for extracting text from an ordinary PDF — that is a different job and this
skill will be slower and worse at it.
## Workflow
1. **List the fields first.** Never guess field names; they are rarely what the
label on the page says.
```sh
python scripts/fields.py input.pdf
```
2. **Fill from a mapping**, so the same values can be re-applied:
```sh
python scripts/fill.py input.pdf values.json -o out.pdf
```
3. **Flatten only when asked.** Flattening is irreversible, and a form the
recipient cannot correct is usually not what was wanted.
## Conventions
- Field values are strings, including numbers — PDF has no numeric field type
- Checkboxes take the export value, not `true`; `fields.py` prints it
- A missing field is an error, not a silent skip
## Reference
Field types, the flattening caveats and the full API are in
[reference.md](reference.md). Read it only when a step above is not enough —
it is long, and loading it costs context that the task usually needs more.
SKILL.md is the entry point of an agent skill: a folder that packages a
capability an agent can pick up when a task needs it and ignore the rest of the
time.
The file is ordinary Markdown with YAML front matter. The folder is the unit:
pdf-forms/
SKILL.md the file below — required
reference.md loaded on demand, not up front
scripts/fill.py executed rather than read
The description is the whole game
---
name: pdf-forms
description: Fill, flatten and extract data from PDF forms. Use when the user
mentions AcroForm fields, a fillable PDF, or wants values read out of a form.
---
This is the one field worth agonising over, because of when it is read. The agent sees descriptions while the skills themselves are still unloaded, and picks from them. Everything else in the file is invisible at that moment.
So a description has two jobs, and most only do the first:
- What it does — “fill and read PDF form fields”
- When to reach for it — “when the user mentions AcroForm fields, a fillable PDF, or wants values read out of a form”
A description reading “PDF tools” is accurate and useless: nothing in it distinguishes the moment this skill helps from the moment it does not. Name the trigger conditions in the words a user would actually use.
Three tiers, paid for separately
The folder structure is not organisation for its own sake — each tier costs something different.
| Tier | Read when | Keep it |
|---|---|---|
description | Always, before loading | Two sentences |
SKILL.md body | The skill is chosen | A page or so |
reference.md, scripts | Only if the body is not enough | As long as it needs |
That is why the body should be a workflow rather than a manual. Anything
exhaustive — every field type, every flag, the full API — belongs in a
reference file that gets loaded on the rare occasion it is needed. A skill that
puts everything in SKILL.md makes every use of it expensive.
What the body should contain
When to use it, and when not. The “not” line is doing real work: it stops the skill being applied to an adjacent task it will handle badly.
A workflow, numbered, with the commands in it. Not prose about the domain — the steps someone would take.
The conventions that are not guessable. Checkbox values that are export strings rather than booleans, numbers that must be passed as text, a step that is irreversible. These are the lines that prevent a confidently wrong run.
A link to the reference, with a note about when to open it.
Scripts beat instructions
Where a step is deterministic, ship a script and call it. A script is executed rather than read, so it costs nothing in context, it cannot be misremembered, and it does the same thing every time. Instructions describing what a script would do are strictly worse on all three counts.
How it differs from CLAUDE.md and AGENTS.md
CLAUDE.md and AGENTS.md describe a repository and are read every session: this is where you are, these are the commands, do not touch that directory.
A skill describes a capability and is loaded only when a task calls for it.
The two are complementary — a repository file might well say which skills are
relevant to the work — and they are not substitutes. Putting a capability in
CLAUDE.md means paying for it on every task including the ones that never
touch it.
Common questions
- What is a SKILL.md file?
- The entry point of an agent skill: a Markdown file with YAML front matter that tells a coding agent what a capability does, when to use it, and how. It sits in a folder named after the skill, alongside any reference documents and scripts that go with it.
- Which part matters most?
- The description in the front matter, by a wide margin. It is read while the skill is *not* loaded, and it is what the agent uses to decide whether to load it. A description naming only the subject — "PDF tools" — never gets chosen, because nothing in it says when to reach for it.
- How long should the body be?
- Short enough that loading it is cheap. The body is read once the skill is chosen, so it competes for context with the actual task. Put the workflow and the conventions in it, and push the exhaustive detail into a reference file the skill links to and loads only when needed.
- Why a folder rather than a single file?
- Because the useful parts are different sizes. SKILL.md is loaded when the skill triggers; a reference document is loaded only if the workflow is not enough; a script is executed rather than read, and costs nothing to keep. One file would force all three to be paid for at once.
- How is it different from CLAUDE.md or AGENTS.md?
- Those describe a repository and are read every session. A skill describes a capability and is loaded only when a task needs it. One is context about where you are; the other is an ability you pick up and put down.