Every team that uses an AI agent for real work ends up writing the same paragraph again and again: "Our reports use this template. Always filter out test accounts. Run the linter before you commit. Here is how our deploy works." That paragraph lives in a chat history, a wiki page, or a system prompt that keeps growing until nobody dares to edit it.
On October 16, 2025 Anthropic launched Agent Skills, a deliberately simple answer to that problem: put the know-how in a folder, with a Markdown file that says what it is for, plus whatever scripts and reference files it needs. The agent sees a one-line description of every installed skill, and opens the folder only when a task calls for it. Simon Willison's reaction the same day was that skills might be "a bigger deal than MCP", mostly because they are so simple.
Two months in, skills work across the Claude apps, Claude Code and the API, Anthropic has published a set of example and document skills, and the format is documented in a short specification. This cheatsheet collects what you need to write, ship and review them.
1. Definitions
| Term | Meaning |
|---|---|
| Skill | A folder of instructions, scripts and resources that an agent can discover and load dynamically to do a specific task better |
| SKILL.md | The required entry point: YAML frontmatter (name, description) followed by Markdown instructions |
| Frontmatter | The metadata block at the top of SKILL.md. Loaded into the system prompt at startup |
| Progressive disclosure | Loading information in stages: metadata always, instructions when triggered, extra files only when needed |
| Bundled resources | Additional files in the skill folder: reference docs, templates, data, scripts |
| Pre-built skills | Anthropic-provided skills for Word (docx), Excel (xlsx), PowerPoint (pptx) and PDF (pdf) |
| Custom skills | Skills you write and install yourself |
Anthropic's engineering post puts it this way: "Building a skill for an agent is like putting together an onboarding guide for a new hire." That analogy is the best mental model: a skill is not code that the agent calls, it is documentation (and tools) that the agent reads and uses.
2. Anatomy of a skill
A minimal skill is one file:
weekly-report/
SKILL.md
A larger one bundles more:
pdf-processing/
SKILL.md # overview and instructions (loaded when triggered)
FORMS.md # form-filling guide (loaded only if needed)
REFERENCE.md # detailed API reference (loaded only if needed)
scripts/
fill_form.py # executed, not loaded into context
validate.py
And the SKILL.md itself:
---
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.
---
# PDF Processing
## Quick start
Use pdfplumber to extract text. See REFERENCE.md for advanced options.
## Filling forms
Read FORMS.md and follow it exactly. Always run scripts/validate.py before saving.
Frontmatter fields
| Field | Required | Rules (per Anthropic docs and the spec) |
|---|---|---|
name |
Yes | Lowercase letters, numbers and hyphens; max 64 characters; no XML tags; must not contain the reserved words "anthropic" or "claude"; the spec says it should match the folder name |
description |
Yes | Non-empty, max 1,024 characters, no XML tags. Must say what the skill does and when to use it |
license |
No | Short license name or a reference to a bundled license file |
allowed-tools |
No | Tools pre-approved to run while the skill is active. The spec notes it is currently supported only in Claude Code |
metadata |
No | String-to-string map for client-specific properties |
The Markdown body has no required structure. Typical sections: quick start, step-by-step workflow, rules, examples, and pointers to bundled files.
3. Progressive disclosure: why skills scale
This is the core design idea, and the reason you can install dozens of skills without filling the context window.
| Level | What loads | When | Approximate cost (Anthropic docs) |
|---|---|---|---|
| 1. Metadata | name and description of every installed skill |
At startup, in the system prompt | About 100 tokens per skill |
| 2. Instructions | The full SKILL.md body | When the agent decides the skill is relevant | Under 5k tokens recommended |
| 3. Resources | Referenced files, read on demand; scripts executed via bash | Only when the instructions point to them and the task needs them | Nothing until used; for scripts, only their output |
From the engineering post: "The metadata is the first level of progressive disclosure: it provides just enough information for Claude to know when each skill should be used without loading all of it into context." The agent then reads SKILL.md with a normal file read, and opens other files the same way.
Two consequences:
- The description is the trigger. If the description is vague, the skill never loads, however good the body is.
- Bundled content is close to free until used. A skill can ship a large schema reference or a long style guide. It costs context only on the tasks that need it.
4. Scripts and resources
Skills can include code "for Claude to execute as tools at its discretion" (engineering post). This is what separates skills from a folder of prompts.
| Content type | Good for | Example |
|---|---|---|
| Instructions (Markdown) | Flexible guidance, judgment calls, workflows | "Review structure first, then naming, then tests" |
| Code (scripts) | Deterministic, fragile or repeated operations | validate_form.py, build_report.py, a migration checker |
| Resources (data, templates) | Facts to look up and formats to copy | Database schemas, brand templates, API references |
Why scripts matter:
- Reliability. Sorting a list, parsing a PDF form or validating a JSON file is better done by tested code than by tokens generated on the fly.
- Efficiency. When the agent runs a script, the code never enters the context, only its output does.
- Consistency. Every run uses the same logic, so results are comparable.
Be explicit about intent in SKILL.md: "Run scripts/validate.py" (execute) is different from "See scripts/validate.py for the algorithm" (read as reference).
5. Where skills run
| Surface | Pre-built skills | Custom skills | How to install | Notes |
|---|---|---|---|---|
| Claude apps (claude.ai, desktop) | Yes | Yes, on paid plans with code execution enabled | Upload a zip in settings | Network access depends on user and admin settings |
| Claude Code | Via plugins | Yes | Folders in ~/.claude/skills/ (personal) or .claude/skills/ (project), or plugins |
Full access of your local machine, so treat skills like any local code |
| Claude API | Yes (pptx, xlsx, docx, pdf) |
Yes, via the /v1/skills endpoints |
Upload, then reference by skill_id in the container parameter |
Runs in the code execution container: no network access, no runtime package installs |
Practical notes:
- Custom skills do not sync across surfaces. A skill uploaded to claude.ai is not available in the API, and Claude Code reads its own folders. Keep the source in a repository and publish it to each surface.
- On the API, skills require the code execution tool and, during the beta, beta headers (
code-execution-2025-08-25,skills-2025-10-02, plusfiles-api-2025-04-14if you download generated files). - Claude Code plugins can distribute skills. Anthropic's
anthropics/skillsrepository can be added as a plugin marketplace with/plugin marketplace add anthropics/skills.
API example (beta, as documented in Anthropic's cookbook)
import anthropic
client = anthropic.Anthropic() # anthropic>=0.71.0
response = client.beta.messages.create(
model="claude-sonnet-4-5-20250929",
max_tokens=4096,
betas=["code-execution-2025-08-25", "skills-2025-10-02"],
container={
"skills": [
{"type": "anthropic", "skill_id": "xlsx", "version": "latest"},
]
},
tools=[{"type": "code_execution_20250825", "name": "code_execution"}],
messages=[{"role": "user", "content": "Create a monthly budget spreadsheet with a summary chart."}],
)
# Uploading a custom skill from a local folder:
from anthropic.lib import files_from_dir
skill = client.beta.skills.create(
display_title="Weekly report",
files=files_from_dir("skills/weekly-report"),
)
print(skill.id)
6. Skills vs. MCP vs. system prompts vs. subagents
These are complementary, not competing. Each solves a different problem.
| Skills | MCP servers | System prompt / project instructions | Subagents | |
|---|---|---|---|---|
| What it provides | Know-how: procedures, conventions, scripts, references | Access: tools and data from external systems | Always-on rules and context | A separate agent with its own context window and instructions |
| When loaded | On demand, by description match | Tool definitions usually loaded up front | Every call | When delegated a task |
| Context cost when unused | A description line | Full tool schemas (can be large) | Full text, always | None in the main thread |
| Format | Folder with SKILL.md | A server speaking a protocol | Text | Agent definition (e.g. a Markdown file in Claude Code) |
| Best for | "How we do X here" | "Let the agent talk to Jira, a database, a SaaS API" | A few rules that apply to every task | Parallel or isolated work: research, review, large searches |
Rules of thumb:
- If it is about access, use MCP (or a plain tool). A skill cannot give the agent credentials or an API it does not have.
- If it is about method, use a skill. "How to write our incident report", "how to use our internal CLI", "how to query the sales schema".
- Combine them. A skill can teach the agent how to use an MCP server well: which tools to call, in what order, with which filters. Anthropic's best practices recommend fully qualified MCP tool names in skills (
ServerName:tool_name). - Keep the system prompt short. Move anything task-specific out of it and into skills, so it loads only when relevant.
- Subagents and skills compose. A subagent can use skills inside its own context; skills do not isolate context by themselves.
7. Authoring tips
Condensed from Anthropic's "Skill authoring best practices" and the example skills:
- Start from real failures. Run the agent on representative tasks without a skill, note what it gets wrong or keeps asking, and write only what fixes that. The docs suggest building at least three evaluation scenarios before writing extensive instructions.
- Write the description first, in third person. "Processes Excel files and generates reports. Use when..." rather than "I can help you...". Include the words a user would actually type.
- Be concise. Assume the model is already capable; do not explain what a PDF is. Every token in SKILL.md competes with the conversation once loaded.
- Keep SKILL.md under about 500 lines. Split the rest into separate files and link them from SKILL.md.
- Keep references one level deep. Link every reference file directly from SKILL.md. Chains of "see A, which says see B" lead to partial reads.
- Match freedom to fragility. Open-ended tasks get high-level guidance. Fragile operations (migrations, form filling) get an exact script and "do not modify the command".
- Add feedback loops. "Run the validator, fix errors, repeat until it passes" improves quality more than any wording change.
- Scripts should solve, not punt. Handle errors in the script with clear messages, document constants, and list dependencies.
- Name descriptively.
processing-pdfsorpdf-processing, nothelperorutils. Use forward slashes in paths. - Avoid time-sensitive instructions like "before August use the old API". Put legacy notes in a clearly marked "old patterns" section.
- Test with every model you plan to use. What is enough for a large model may be too little for a small one.
- Watch how the agent navigates. If it never opens a file, the file is unnecessary or badly signposted. If it opens the same file every time, that content belongs in SKILL.md.
A tiny frontmatter validator
Catch the basic errors before uploading. Standard library only, intentionally simple (it handles single-line values, which is what most skills use):
import re
import sys
from pathlib import Path
NAME_RE = re.compile(r"^[a-z0-9]+(-[a-z0-9]+)*$")
RESERVED = ("anthropic", "claude")
def parse_frontmatter(text: str) -> dict[str, str]:
if not text.startswith("---\n"):
raise ValueError("SKILL.md must start with '---' frontmatter")
block = text[4:].split("\n---", 1)[0]
fields = {}
for line in block.splitlines():
if ":" in line and not line.startswith(" "):
key, value = line.split(":", 1)
fields[key.strip()] = value.strip().strip('"')
return fields
def validate(skill_dir: Path) -> list[str]:
skill_md = skill_dir / "SKILL.md"
if not skill_md.exists():
return ["missing SKILL.md"]
text = skill_md.read_text(encoding="utf-8")
fm = parse_frontmatter(text)
errors = []
name, desc = fm.get("name", ""), fm.get("description", "")
if not NAME_RE.match(name) or len(name) > 64:
errors.append(f"name {name!r}: lowercase letters, digits, hyphens, max 64")
if any(word in name for word in RESERVED):
errors.append(f"name {name!r} contains a reserved word")
if name != skill_dir.name:
errors.append(f"name {name!r} does not match folder {skill_dir.name!r}")
if not desc or len(desc) > 1024:
errors.append("description must be 1-1024 characters")
if "<" in name + desc:
errors.append("no XML tags in name or description")
if "when" not in desc.lower():
errors.append("warning: description should say when to use the skill")
body_lines = text.count("\n")
if body_lines > 500:
errors.append(f"warning: SKILL.md has {body_lines} lines; split into files")
return errors
if __name__ == "__main__":
for path in sys.argv[1:]:
problems = validate(Path(path))
print(f"{path}: {'OK' if not problems else '; '.join(problems)}")
Run it in CI over your skills/ folder, next to whatever evaluation tasks you keep for each skill.
8. Security: treat skills like software
A skill is instructions plus code that the agent will follow and run. Anthropic's guidance is direct: "We recommend installing skills only from trusted sources. When installing a skill from a less-trusted source, thoroughly audit it before use." The launch post adds that the feature "gives Claude access to execute code", so be "mindful about which skills you use".
Threats to keep in mind:
| Risk | What it looks like | Mitigation |
|---|---|---|
| Malicious instructions | SKILL.md tells the agent to read secrets or send data somewhere | Read every Markdown file in the skill, not just SKILL.md |
| Malicious code | A bundled script does more than its name says | Review scripts like any dependency; pin versions |
| External fetches | A skill downloads instructions or data at run time, which can change later | Prefer self-contained skills; flag any network call in review |
| Excessive permissions | allowed-tools pre-approves broad shell access in Claude Code |
Grant the minimum; review it like a permissions change |
| Supply chain drift | A trusted skill repository changes after you installed it | Vendor skills into your own repo; review diffs on update |
Simon Willison's launch-day note applies to all of this: skills depend on a code execution environment, and "the word safe there is doing a lot of work". Run agents with skills in a sandbox or container when they touch anything sensitive.
9. Checklist
- [ ] Does the description say what the skill does and when to use it, in third person?
- [ ] Is
namelowercase-hyphenated, under 64 characters, and equal to the folder name? - [ ] Is SKILL.md under about 500 lines, with details split into linked files?
- [ ] Are all reference files linked directly from SKILL.md?
- [ ] Do fragile steps use scripts with clear error messages?
- [ ] Is there a validation loop for quality-critical output?
- [ ] Are there at least a few evaluation tasks, run with and without the skill?
- [ ] Has every file (Markdown and code) been reviewed by a human?
- [ ] Is the skill versioned in a repository and published to each surface that needs it?
Why this matters
- Know-how becomes a reviewable artifact. Conventions that lived in people's heads or in long prompts become files you can diff, test and share.
- Progressive disclosure keeps context lean. Many skills can be installed while only the relevant one is loaded.
- Scripts make agents more deterministic. The agent decides what to do; tested code does the fragile parts.
- One format, several surfaces. The same folder works in the Claude apps, Claude Code and the API, even if you have to publish it to each.
- Skills are code. The same supply chain discipline you apply to dependencies applies here.
Final Thoughts
Agent Skills are almost boring: a folder, a Markdown file, a bit of YAML. That is the point. They move the effort from clever prompting to writing good internal documentation and small reliable scripts, which teams already know how to review and maintain.
Start with one workflow your team explains to the agent every week. Write the description carefully, keep the body short, put the fragile parts in a script, add a validation step, and test it on real tasks. Then review it like code, because that is what it is.
Sources
- Anthropic, Introducing Agent Skills (October 16, 2025): launch, availability across Claude apps, Claude Code and API, pre-built document skills, skill-creator, code execution caution.
- Anthropic Engineering, Equipping agents for the real world with Agent Skills (October 16, 2025): progressive disclosure levels, required frontmatter, bundled code, onboarding guide analogy, trusted sources guidance.
- Anthropic docs, Agent Skills overview: frontmatter rules, token costs per level, surfaces, Claude Code skill folders, no cross-surface sync, API runtime constraints, security considerations.
- Anthropic docs, Skill authoring best practices: conciseness, third-person descriptions, 500-line guidance, one-level references, degrees of freedom, evaluations first, MCP tool naming.
- Anthropic, anthropics/skills on GitHub: example and document skills, template, plugin marketplace instructions, and the Agent Skills spec (version 1.0 of October 16, 2025; 1.1 of December 16, 2025) with optional
license,allowed-toolsandmetadatafields. - Anthropic, Claude Cookbooks: skills: beta headers,
client.beta.messages.createwithcontainer,client.beta.skills.createwithfiles_from_dir. - Simon Willison, Claude Skills are awesome, maybe a bigger deal than MCP (October 16, 2025): token efficiency vs. MCP, simplicity, dependence on a safe code execution environment.