Skill Bundle Format
SKILL.md frontmatter, scripts/references/assets layout, agentskills.io compatibility
Skill Bundle Format
A skill is a reusable knowledge-bundle that teaches an agent how to do a
specific task. Skills are imported into the platform as .zip archives or
created in-place via the Studio UI. This document specifies the exact file
layout, frontmatter fields, and size limits for the .zip import path.
Upstream compatibility
The platform's skill format is a superset of agentskills.io
(the open spec Anthropic published with Claude Agent Skills and which OpenAI
Codex, VS Code, Cursor, Gemini CLI, and 20+ other clients implement). Any skill
authored to the agentskills.io spec — including the flagship Anthropic bundles
at github.com/anthropics/skills
(pdf, xlsx, pptx, docx, skill-creator) — imports here without
modification. The sections below call out our extensions explicitly.
References:
- Spec: https://agentskills.io/specification
- Anthropic announcement: https://www.anthropic.com/news/skills
- Reference implementations: https://github.com/anthropics/skills
Quick reference
- Entry point:
SKILL.mdat the archive root (or one level deep — see Nested layouts) - Required frontmatter field:
name - Max archive size: 100 MB
- Max per-file size: 10 MB
- File types:
script,reference,asset(inferred from directory name, see Files)
Minimum valid bundle
my-skill.zip
└── SKILL.md
SKILL.md:
---
name: my-skill
description: One-sentence summary shown in the agent builder.
---
# My Skill
When the user asks to do X, follow these steps:
1. First step
2. Second step
Full layout
my-skill.zip
├── SKILL.md # Required — frontmatter + Markdown instructions
├── scripts/ # Executable helpers (auto-typed as `script`)
│ ├── render.py
│ └── check.sh
├── references/ # Supporting docs (auto-typed as `reference`)
│ ├── style-guide.md
│ └── glossary.md
└── assets/ # Binary / opaque data (auto-typed as `asset`)
├── template.docx
└── logo.png
Nested layouts
The importer also accepts a single top-level directory wrapping the bundle:
my-skill.zip
└── my-skill/
├── SKILL.md
├── scripts/
└── references/
This matches what most archive tools produce when zipping a folder. The
top-level directory name is stripped; the contained SKILL.md is treated
as the root.
Frontmatter
YAML between --- fences at the top of SKILL.md. All fields are optional
except name.
| Field | Type | Default | Notes |
|---|---|---|---|
name | string | — | Required. Must match ^[a-z0-9-]+$. Used as the skill id. |
description | string | "" | One-sentence summary. Shown in the skill picker + agent builder. |
category | string | general | One of the platform-defined categories (see skills page filter). |
tags | string[] | [] | Free-form labels for search + filtering. |
allowed-tools | string[] | [] | Informational — list tool ids the skill's instructions reference. |
required-tool-sets | string[] | [] | Advisory — tool-set ids the agent should have granted before loading this skill. |
license | string | — | SPDX identifier (e.g. MIT, Apache-2.0) or custom string. |
compatibility | string | — | Free-form compatibility note (e.g. platform>=2025.04). |
disable-model-invocation | boolean | false | When true, the skill is not offered via load_skill_instructions. |
user-invocable | boolean | true | When false, only agents can load the skill, not users directly. |
content-hash | string | — | Optional SHA-256 of the canonicalised bundle. Verified on import. |
Body
Everything after the closing --- is the Markdown body — this is what
the platform injects into the agent's context when the skill loads. Write
it as imperative, step-by-step instructions; avoid narrative prose.
Size guidance (from agentskills.io): keep SKILL.md under ~500 lines /
5 000 tokens. Longer content belongs in references/ — the
load_skill_instructions tool returns the body verbatim and long bodies
blow the LLM's context budget. Put runnable code in scripts/ so only
the output enters context, not the source.
Our extensions vs. agentskills.io
Fields marked below are NOT in the upstream spec but are honoured by our importer when present:
| Field | In agentskills.io? | Our behaviour |
|---|---|---|
category | No | Used for Studio filtering; defaults to general. |
tags | No | Free-form labels for search. |
required-tool-sets | No | Advisory prerequisite tool-set ids. |
disable-model-invocation | No | When true, suppresses the skill from load_skill_instructions discovery. |
user-invocable | No | When false, agents can load but users can't invoke directly. |
content-hash | No | SHA-256 of canonicalised bundle for tamper detection. |
Upstream skills omit these fields; they simply default (category=general, tags=[], user-invocable=true, etc.). Your agentskills.io-compliant bundle imports cleanly with zero edits.
Files
Any file under the archive root (other than SKILL.md) is attached to the
skill as a typed file. The platform infers the file type from the top-level
directory:
| Directory prefix | Inferred fileType | Typical use |
|---|---|---|
scripts/ | script | Runnable code loaded via the virtual run_skill_script tool. |
references/ | reference | Supporting docs the instructions can link to. |
assets/ | asset | Binary / opaque data (images, templates, PDFs). |
| (anywhere else) | inferred by extension | .py/.sh/.js/.ts → script; .md/.txt → reference; else asset. |
All files are stored UTF-8 — binary files must be kept under the 10 MB per-file cap. Files larger than 10 MB are rejected with HTTP 413.
Size limits
| Limit | Value | Enforcement point |
|---|---|---|
| Per-file | 10 MB | POST /api/skills/:id/files |
| Total archive | 100 MB | POST /api/skills/import |
| Frontmatter | ~1 KB | Parser-level (dictated by YAML practical use) |
How the platform uses a skill at runtime
- Discovery. An agent's skill grants make the skill visible to
load_skill_instructions. The LLM seesname + description + categoryin its tool list. - Load. When the LLM calls
load_skill_instructions(skill_id), the platform returns theSKILL.mdbody. - Scripts. If the skill carries
scripts/files, the LLM can callrun_skill_script(skill_id, file_id)to execute them in the code sandbox. Only stdout/stderr enters LLM context — the source never does. - References / assets. Delivered on demand; not auto-injected.
Import ways
- UI: Studio → Skills → Import button → pick
.zipor.json. - API:
POST /api/skills/importwithmultipart/form-data(field name:file). - Studio inline: Create a skill, save, reopen with Edit → Upload file to attach scripts/references/assets one at a time.
Export
GET /api/skills/:id/export returns the bundle as a .zip in the
canonical layout above. Round-tripping (export → import) reproduces the
bundle byte-identical when content-hash is preserved.
Troubleshooting
| Symptom | Cause |
|---|---|
| HTTP 413 | Archive > 100 MB or a single file > 10 MB. |
| "SKILL.md not found" | Either the archive has no SKILL.md, or it's more than one level deep. |
| "Frontmatter missing required field: name" | name: omitted or not lowercase-kebab-case. |
| "Invalid fileType for path ..." | A file outside scripts/ references/ assets/ with an unknown extension. |
| Silent drop of file | File size 0 bytes — the importer skips empty files. |