Converter → SKILL.md format

SKILL.md Format: the complete field reference

Two rules fail an upload if you miss them: the skill name inside SKILL.md must be all lowercase with words separated by hyphens, and scripts cannot make requests to external websites. Everything else in this guide follows from those two constraints.

The rule that surprises people most: the name field inside SKILL.md must match the name of the folder that contains it. If they differ, the file uploads successfully and the skill appears in your list — but it never triggers when you ask for it. This is a silent failure, not an error message.

Last updated: October 5, 2026 · Verified against the public Agent Skills specification and Google Gemini help documentation

On this page

  1. Directory structure
  2. Frontmatter fields
  3. Name rules and examples
  4. Writing a description that triggers
  5. Supported file types
  6. Hard limits
  7. Progressive disclosure
  8. FAQ

Directory structure

A skill is a folder with a SKILL.md at its root. Three optional subdirectories carry supporting material.

my-skill/
├── SKILL.md          required — the instructions and metadata
├── scripts/          optional — executable code
├── references/       optional — reference docs loaded on demand
└── assets/           optional — templates, images, data files

Three subdirectories carry meaning. Anything else you create is ignored:

FolderPurposeWhen it loads
scripts/Code the skill runsWhen the skill executes
references/Background docs the model should consultOnly when the task needs them
assets/Files used in output, not read as instructionOnly when the task needs them

Frontmatter fields

The SKILL.md file is Markdown with a YAML frontmatter block at the top:

---
name: pdf-text-extractor
description: Extracts text and tables from PDF files and fills forms.
  Use when the user mentions PDFs, forms, or document extraction.
license: Apache-2.0
compatibility: Requires Python 3.10+ for the extraction scripts.
metadata:
  author: your-team
  version: "1.2"
allowed-tools: read write
---

# PDF Text Extractor

Run scripts/extract.py for each PDF...

Every field, in one table

FieldRequiredConstraints
nameYes1–64 characters. Lowercase letters, numbers and hyphens only. Must not start or end with a hyphen. No consecutive hyphens. Must match the parent folder name exactly.
descriptionYes1–1024 characters. Must state what the skill does and when to use it. The folded block scalar > is useful for long descriptions.
licenseNoA license name, or a path to a license file in the skill folder.
compatibilityNoUp to 500 characters describing the environment the skill needs.
metadataNoArbitrary key–value pairs. Values should be strings.
allowed-toolsNoSpace-separated list of tools pre-approved for this skill. Experimental.

Name rules and examples

The name field is where most upload rejections happen. Five rules, and only lowercase letters, numbers and hyphens are allowed.

✗ Wrong✓ RightWhy
PDF-Processingpdf-processingUppercase letters are rejected
-pdfpdf-extractCannot start with a hyphen
pdf-pdf-toolsCannot end with a hyphen
pdf--processingpdf-toolkitConsecutive hyphens are rejected
pdf_toolpdf-toolUnderscores are not allowed
office-wordword-processorUse folders for grouping rather than encoding hierarchy into the name
a-very-long-name-that-keeps-going-and-going-well-past-the-limitdoc-processorMaximum 64 characters

Use the folder to group, not the name. If you want office/word and office/excel, create two skills named word-processor and excel-helper. Nesting category names into the skill name produces long names that hit the 64-character limit and confuse the matching logic.

Writing a description that actually triggers

The description is the only part of your skill the model always reads at startup. It decides whether your skill gets loaded at all. Write it in third person, use the WHAT + WHEN pattern, and include the words a user would type.

DescriptionVerdictReason
Helps with documents Too vague Nothing for the model to match a request against
Extract text from PDF files Incomplete States what but not when, so the model has to guess the trigger
Extract text and tables from PDF files, fill forms, and merge documents. Use when working with PDF files, or when the user mentions PDFs, forms, document extraction, or .pdf files — even if they don't say "extract". Good WHAT and WHEN, with real trigger keywords and a near-miss clause

The near-miss clause matters more than it looks. Adding "even if they don't explicitly ask to extract" catches requests like "can you pull the numbers out of this report?" where the user never says "extract". Without it, your skill loads only when the user uses your exact vocabulary.

Supported file types

Google's rule of thumb: if you can open it in a basic text editor and read it, it is probably supported.

✓ Supported✗ Not supported
Plain text: .txt .md .rst .rtf .tex .log
Code: .py .sh .js .ts .rb .go and similar
Data and config: .json .yaml .yml .csv .toml .xml .sql
Web: .html .css .svg
Rich media: .pdf .jpg .jpeg .png .gif .webp
Word documents: .docx .doc
Spreadsheets: .xlsx .xls.pptx
Other binary formats

Convert these first — for example, export a Word file to Markdown, or a spreadsheet to CSV.

Hard limits

LimitValueWhat happens if you exceed it
Name length64 charactersUpload rejected
Description length1,024 charactersUpload rejected
Compatibility field500 charactersUpload rejected
Total size of all files100 MBUpload rejected
Skills active simultaneously100Only 100 load at once; you can keep more templates
External requests from scriptsNot allowedUpload rejected

Progressive disclosure

This is the part official documentation tends to gloss over, and it explains why long skills behave badly.

A skill loads in three stages:

  1. Metadata at startup. Roughly 100 tokens — just the name and description. This is always in context, so it is budget you cannot escape.
  2. Instructions on activation. The body of SKILL.md, budgeted under about 5,000 tokens. This loads only when the skill is triggered.
  3. Resources on demand. Files in references/ and assets/ load only when the task actually needs them.

The practical consequence: keep the main SKILL.md under 500 lines and move detail into references/. A skill that tries to carry everything in the instruction body runs into the activation budget and starts losing steps.

FAQ

What causes a SKILL.md upload to be rejected?
Two rules fail an upload if you miss them: the name must be all lowercase with words separated by hyphens, and scripts cannot make requests to external websites. Other common causes are uppercase letters, leading or trailing hyphens, consecutive hyphens, a name that does not match its folder, a description over 1024 characters, and binary files such as .docx and .xlsx.
Why does my skill load but never trigger?
Almost always the description. The name must match the parent folder name exactly, and the description must state both what the skill does and when to use it, in words a user would actually type.
Is SKILL.md the same across platforms?
Yes. SKILL.md is an open, Markdown-native standard used by Anthropic Agent Skills and adopted by Gemini. A skill written once works across platforms — something a Gemini Gem never offered, since it was locked to Google.
How long should a SKILL.md file be?
Keep the main file under 500 lines. Metadata loads at roughly 100 tokens at startup, instructions budget under 5,000 tokens on activation, and supporting resources load only as needed.
Can scripts in a skill call external APIs?
No. Scripts cannot make requests to external websites, and attempting it causes a rejection. Any data the skill needs has to be bundled in the skill folder.
Do I need the optional frontmatter fields?
No. Only name and description are required. Add license if you plan to share the skill, and compatibility if it depends on a specific runtime.