SKILL.md format reference for Codex
The SKILL.md file format for Codex skills (not skills.md): frontmatter fields, naming rules, triggering descriptions, body structure, scripts, openai.yaml.
The minimal file
A skill is a folder whose name matches the skill, containing a SKILL.md file. Name it exactly that: uppercase SKILL, singular. A skills.md file is not a skill file at all, and a lowercase skill.md only works by accident on case-insensitive filesystems, then breaks on Linux and in CI. The file starts with YAML frontmatter between two --- lines, followed by Markdown:
---
name: changelog-entry
description: Writes a Keep a Changelog entry for the current branch from its commits and diff. Use when the user asks to update CHANGELOG.md, add a changelog entry, or describe a change for release notes.
---
# Changelog entry
1. Read `CHANGELOG.md` and find the `## [Unreleased]` section.
2. Summarize the branch with `git log --oneline main..HEAD` and `git diff --stat main...HEAD`.
3. Add one line per user-visible change under Added, Changed, Fixed or Removed.
4. Do not mention refactors, tests or CI changes unless users can observe them.
Put the frontmatter first: the opening --- belongs on line 1, and the YAML between the markers has to parse. If a description contains a colon followed by a space, wrap the value in quotes.
Frontmatter fields
Codex skills follow the open Agent Skills specification. The spec defines these fields:
| Field | Required | Constraints | Notes for Codex |
|---|---|---|---|
name | Yes | 1 to 64 characters; lowercase letters, numbers, hyphens | Shown in /skills and used for $name mentions |
description | Yes | 1 to 1,024 characters | The only text Codex uses to decide implicit invocation |
license | No | License name or a bundled license file | Informational |
compatibility | No | Up to 500 characters | Environment requirements, such as “Requires Python 3.12 and uv” |
metadata | No | Map of string keys to string values | Free-form, for example author and version |
allowed-tools | No | Space-separated tool list | Experimental in the spec; support varies by agent |
Codex’s own documentation requires only name and description. Keep optional fields only when they help a human reader, and leave out allowed-tools unless you have confirmed what a given agent does with it.
---
name: pdf-forms
description: Fills, reads and flattens fillable PDF forms with pypdf. Use when the user wants to populate a PDF form from data or batch-fill forms from a CSV.
license: MIT
compatibility: Requires Python 3.10+ with pypdf installed
metadata:
version: "1.2"
---
Naming rules
From the specification:
- 1 to 64 characters.
- Lowercase
a-z, digits0-9and hyphens only. - No leading or trailing hyphen, and no
--. - Must match the parent directory name.
| Name | Valid? | Why |
|---|---|---|
release-notes | Yes | |
pdf2docx | Yes | Digits are fine |
Release-Notes | No | Uppercase |
-release | No | Leading hyphen |
release--notes | No | Consecutive hyphens |
Two Codex-specific points. First, Codex does not merge skills that share a name: if ~/.agents/skills/review and repo/.agents/skills/review both exist, both appear and you have to guess which one you are getting. Use distinct, descriptive names. Second, the name is what people type after $, so prefer names that read like the task (db-migration) over internal codenames.
Writing the description
The description is the only part of a skill that Codex sees before deciding to load it. It sits in a catalog with every other installed skill, and when the catalog exceeds its budget (2% of the context window by default) Codex shortens descriptions. Write accordingly:
- Lead with the job. The first clause should say what the skill produces. If the description gets cut, the front survives.
- Then say when to use it. Include the phrases users actually type: error messages, file types, tool names, verbs like “review”, “migrate”, “fill”.
- Draw a boundary when a neighbor exists. “Not for end-to-end browser tests; use playwright-e2e” stops two skills fighting over the same request.
- Stay concrete. Name formats, frameworks and commands. Adjectives do not match anything.
Weak:
description: Helps with database stuff and best practices.
Strong:
description: Writes zero-downtime PostgreSQL schema migrations using expand and contract steps, concurrent index builds and batched backfills. Use when adding or renaming columns, changing types, adding NOT NULL or foreign keys on large tables, or when a migration locked a table in production.
The description tuning skill and the troubleshooting guide go further.
The body
There are no required sections. What reliably works:
- A one-paragraph definition of done at the top, so Codex knows when to stop.
- Numbered, imperative steps with explicit inputs and outputs. “Run
pnpm test” beats “make sure tests pass”. - Real commands and code for the parts that are easy to get wrong.
- Hard rules for things that must never happen (force-pushing, editing generated files, skipping hooks).
- Gotchas that a capable engineer would still trip over.
- An output contract: the exact shape of the final report or file.
Size matters because Codex loads the entire body once the skill is selected. The specification recommends staying under 500 lines and about 5,000 tokens. If a section is only needed in some cases, move it to references/ and say when to read it.
Optional folders
pdf-forms/
├── SKILL.md
├── references/
│ ├── field-types.md
│ └── xfa.md
├── scripts/
│ └── list_fields.py
├── assets/
│ └── sample-mapping.csv
└── agents/
└── openai.yaml
references/ holds documentation Codex reads on demand. Link each file from SKILL.md with a relative path and a condition: “If the form contains XFA, read references/xfa.md first.” Keep references one level deep; a reference that points to another reference is easy to miss. Smaller, focused files cost less context than one large one.
scripts/ holds code Codex can run. Use a script when the operation must be deterministic or would take many error-prone steps to describe. Scripts should document their dependencies, print clear errors and exit non-zero on failure. They run as ordinary commands under your sandbox and approval policy, so a script that needs the network will hit the same approval prompt as any other networked command. Codex’s guidance is to prefer instructions over scripts unless you need determinism or external tooling.
assets/ holds templates, schemas, example files and images that the skill copies or fills in.
agents/openai.yaml
This optional file configures how Codex and the ChatGPT desktop app present and use the skill. It does not replace the frontmatter.
interface:
display_name: "PDF forms"
short_description: "Fill and flatten fillable PDFs"
icon_small: "./assets/icon.svg"
icon_large: "./assets/icon.png"
brand_color: "#3B82F6"
default_prompt: "Fill this PDF form from the attached data"
policy:
allow_implicit_invocation: true
dependencies:
tools:
- type: "mcp"
value: "openaiDeveloperDocs"
description: "OpenAI Docs MCP server"
transport: "streamable_http"
url: "https://developers.openai.com/mcp"
| Key | Purpose |
|---|---|
interface.display_name, short_description | Human-friendly name and blurb in the UI |
interface.icon_small, icon_large, brand_color | Visual identity in the desktop app |
interface.default_prompt | A starter prompt offered with the skill |
policy.allow_implicit_invocation | Defaults to true. Set false so Codex loads the skill only on an explicit $name mention |
dependencies.tools | Tools the skill needs, such as an MCP server with its transport and URL |
When a skill declares an MCP dependency, Codex can prompt to install the missing server; that behavior is on by default and controlled by the skill_mcp_dependency_install feature flag. Every skill downloaded from this site includes a generated agents/openai.yaml with a display name, short description and default prompt.
Validate before you ship
The Agent Skills project publishes a reference validator:
skills-ref validate ./pdf-forms
It checks frontmatter and naming. Then test behavior in Codex: run /skills to confirm the skill is listed, invoke it with $pdf-forms, and try three or four natural requests without the mention to confirm it triggers implicitly. The first skill tutorial walks through that loop, and the annotated examples show complete skills.
Frequently asked questions
What fields does SKILL.md need?
Only two are required: name and description. The Agent Skills specification also defines optional license, compatibility, metadata and allowed-tools fields, but Codex needs just the two required ones.
What are the naming rules for a skill?
Up to 64 characters of lowercase letters, numbers and hyphens, not starting or ending with a hyphen and without consecutive hyphens. The name should match the skill's folder name and be unique, because Codex does not merge two skills that share a name.
How long can a SKILL.md file be?
The Agent Skills specification recommends keeping the body under 500 lines and roughly 5,000 tokens. Codex reads the whole file when it selects the skill, so longer material belongs in references/ files that are read only when needed.
What is agents/openai.yaml?
An optional file inside the skill folder that Codex and the ChatGPT desktop app read for UI metadata (display name, short description, icons, brand color, default prompt), invocation policy such as allow_implicit_invocation, and tool dependencies like an MCP server.