# SKILL.md frontmatter fields an open source agent skill needs

> A broken SKILL.md frontmatter is fixable: check the two required fields against their limits, then the four optional ones. Kortix is the open-source CompanyOS: your agents, their skills, your company memory, and every connector in one git repo you own, with the agents working on real cloud computers.

URL: https://agentskillsguide.dev/skill-md-frontmatter

## The frontmatter a canonical example actually needs

`SKILL.md`

```
---
name: pdf-processing
description: Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction.
---
```

Source: https://platform.claude.com/docs/en/agents-and-tools/agent-skills/overview

Two required fields and none of the four optional ones. The description names the work and the requests that should reach it.

## All six fields, then one description twice

A frontmatter that passes every limit, and the same line before and after it was written as a trigger. The first panel uses all six fields, and only `name` and `description` are required between the fences. The second panel's first line is 40 characters, short enough to draw the action's "very short description" warning; the second line clears it and names three moments a request can arrive in.

### SKILL.md

`skills/release-checklist/SKILL.md`

```
---
name: release-checklist
description: Use this skill when a release is cut, a version is tagged, or someone asks whether a release is ready. It runs the release checklist, checks each gate in order, and records the gate that failed.
license: LICENSE
compatibility: Requires network access to the issue tracker and the package registry.
metadata:
  owner: platform-team
  version: "1.0"
allowed-tools: Bash Read Grep
---
# Release checklist

Run the gates in order. Stop at the first gate that fails and name it in the report.
```

### description, before and after

`SKILL.md`

```
# before: a topic sentence
description: Release checklist for the platform team.

# after: an instruction with the moments to load it
description: Use this skill when a release is cut, a version is tagged, or someone asks whether a release is ready. It runs the release checklist, checks each gate in order, and records the gate that failed.
```

## Two fields carry the rules, four fill in the rest

A SKILL.md frontmatter fails in three ways. The file does not parse, a required field is missing, or every field is legal and the skill still never runs. The format asks for six fields and requires two: `name` and `description`. `license`, `compatibility`, `metadata` and `allowed-tools` are permitted, and a skill with only the first two is complete.

Everything sits between the opening and closing `---` as YAML, and the fences are part of the requirement. The [Validate Skill action](https://github.com/marketplace/actions/validate-skill) reports each field's shape as an error and four softer problems as warnings: a description under 50 characters, an empty body, a body over 500 lines, and an unknown field. That warning earns its place. A key typed `discriptions:` passes YAML, then vanishes from the metadata an agent reads, so the file looks correct in the editor and never loads.

## `name`: 64 characters, spelled like the folder

The field "Must be 1-64 characters" and may only use lowercase a-z, digits and hyphens. It "Must not start or end with a hyphen (-)", "Must not contain consecutive hyphens (--)" and "Must match the parent directory name". Five rules explain most failing files: `Refund_Policy` carries an uppercase letter and an underscore, `refund--policy` has a double hyphen, `refund-policy-` ends in one, and a skill copied out of a bundle keeps its old name while the folder is renamed around it.

The folder rule is the one a validator cannot forgive. In a Kortix project the `skills` table maps a skill name to its folder, the folder's last segment is the name, and `kortix validate` treats a skill folder with no `SKILL.md`, or a `SKILL.md` whose frontmatter `name:` is not the skill name, as an error, exiting 1 ([kortix.yaml reference](https://kortix.com/docs/developers#kortixyaml-reference)). The fix is a rename in two places, the directory and the field.

## `description`: 1,024 characters that decide the load

This is the field an agent matches a request against. It "Must be 1-1024 characters" and "Should describe both what the skill does and when to use it". Kortix's guide says the same thing in plainer words: "The agent reads each skill's description and decides when to load it. Write the description as 'when to use this', not only 'what this is'." The guide to [optimizing descriptions](https://agentskills.io/skill-creation/optimizing-descriptions) turns that into a rule you can apply to a file on your desk: "Use imperative phrasing. Frame the description as an instruction to the agent: 'Use this skill when...' rather than 'This skill does...'", and "Err on the side of being pushy".

Four shapes account for the descriptions that fail. A title ("PDF processing"). A summary of the body, which says what happens after loading and nothing about why loading should start. A scope sentence with no situation in it ("Helps with documents"). A stub under 50 characters, which passes the required check and trips the action's warning. Rewrite all four the same way: keep the work in the first clause, then name the requests and moments that should reach it. The limit leaves room: "The specification enforces a hard limit of 1024 characters", enough for a paragraph.

## `license`: one short line, for a folder that travels

The optional field "Specifies the license applied to the skill", and the recommendation is to keep it short, "either the name of a license or the name of a bundled license file". A skill that stays inside one repository can leave it empty. A skill published, vendored into another project or handed to a partner should carry the name, or point at the file beside it with `license: LICENSE`. The `license:` line in the first panel takes the second route.

## `compatibility`: 500 characters, and usually none

"Must be 1-500 characters if provided", and it "Should only be included if your skill has specific environment requirements". The specification is direct about frequency: "Most skills do not need the compatibility field." What belongs here is the environment: the intended product, required system packages, network access. What does not belong is the skill's own version, which is bookkeeping and lives in `metadata`. Every requirement written here is a promise a reader will test on their own machine.

## `metadata`: string keys, string values

"A map from string keys to string values" that "Clients can use this to store additional properties not defined by the Agent Skills spec". The recommendation is to make key names unique so two tools do not collide. An owner and a version are the two values worth typing:

```
metadata:
  owner: platform-team
  version: "1.0"
```

The quotes matter. An unquoted `1.0` is a YAML float, and a validator asking for string values rejects it. Nested maps and lists sit outside the field as the specification defines it, so a list of regions or tags goes into the body or becomes one key per value.

## `allowed-tools`: a note of intent, and no more

"A space-separated string of tools that are pre-approved to run". The next line is the one to read twice: "Experimental. Support for this field may vary between agent implementations". The validator's only check on it is "allowed-tools: Must be a space-delimited string". A comma-separated list is the error a pipeline catches. Nothing in that check says whether a client honours the line.

Two things follow. Write the field as a note of what the steps need, space-separated and short. Then set permission where the runtime enforces it. In Kortix, a registered skill reaches an agent only when the agent's `skills` line enables it, so the effective limit on a skill is written in `kortix.yaml` rather than in the skill's own frontmatter.

## The order to fix a failing file

Start at the fences and work down. Confirm the frontmatter opens and closes with `---` and parses as YAML, because every later error is noise until it does. Compare `name` with the folder and rename both. Read the description aloud and ask whether it names a situation; if it names a topic, rewrite it from the panel's second version. Leave the optional fields empty unless one has a real answer, then quote any version number.

Two checks close the loop. `skills-ref validate ./my-skill` covers the frontmatter and the naming conventions, and [the validation comparison](/validate-a-skill-md) shows what other checkers add. The limits themselves, quoted one by one, are on [the specification page](/agent-skills-specification). When the file is legal and still does not trigger, the remaining work is written in [how to write a SKILL.md](/how-to-write-a-skill-md), because a passing check says nothing about whether a description triggers.

## The four questions behind a file that will not load

Required fields, the tools line, the folder rule and nested metadata, answered from the sources.

### Which fields are required in SKILL.md frontmatter?

`name` and `description`. A file with both passes the required check, and `license`, `compatibility`, `metadata` and `allowed-tools` are optional. A misspelled key shows up as an unknown-field warning, so read the warnings before you believe the file is done.

### Does allowed-tools restrict what a skill can run?

Not on its own. The specification calls the field "Experimental. Support for this field may vary between agent implementations", and the validator only checks that it is a space-delimited string. Treat it as a note of intent and set the permission where the runtime grants tools.

### Does the folder name have to match the name field?

Yes. `name` "Must match the parent directory name", so `skills/release-checklist/` holds `name: release-checklist`. Kortix treats a skill folder with no `SKILL.md`, or a `name:` that is not the skill name, as an error, and `kortix validate` exits 1.

### Can metadata hold nested values?

No. It is "A map from string keys to string values", so a nested map or a list is outside the field. Quote a version number, because an unquoted `1.0` reads as a float, and use the body for anything structured.

## Fix the file with the validator, then write the description for the agent.

Run it on Kortix Cloud, in your VPC, or on your own on-prem network. Self-host is free.

[Try Kortix](https://kortix.com) · [Read the docs](https://kortix.com/docs/guide#skills)

Session work reaches main through a change request · Merge is default-deny for agents
