
Claude Skills: Turn Claude Into a Specialist for Your Work With a Single Folder
Skills is a new Claude feature that lets developers package a workflow, reference, and scripts into a bundle that Claude invokes on its own when needed, cutting context bloat, reusable across every project, and distributable as a plugin.
Anyone who has used Claude Code for a while notices the same pattern: you paste the same prompt (for example, "write a PR description in our company's format", "run a migration following this 8-step checklist") into every session, until CLAUDE.md grows to 600 lines and eats half your context.
Since Oct 2025, Anthropic shipped Agent Skills, which package your knowledge into a bundle that Claude picks up on its own only when it needs it, without consuming context when it doesn't, and that you can distribute across your team.
This article is a primer for developers who want to start writing their own skill today.
What a Skill is (in one sentence)
A Skill is a folder on the filesystem that contains a SKILL.md file (with YAML frontmatter) plus other supporting files (markdown reference, script, asset) that Claude loads when needed, based on whether the task matches that skill's description.
The unit of a skill is a plain folder, not a binary or a special DSL:
my-skill/
├── SKILL.md # entrypoint (required, has YAML frontmatter)
├── reference.md # loaded when needed
└── scripts/
└── helper.py # Claude can run it via bash, the code never enters context
How is it different from a prompt / CLAUDE.md / MCP server?
| Where it lives | Loaded when | Gives Claude... | |
|---|---|---|---|
| Prompt | current turn | every turn | a one-shot instruction |
| CLAUDE.md | repo root / ~/.claude/ | always in the system prompt | static facts/rules |
| MCP server | a running process | tools list is in context at all times | new tools (functions over a protocol) |
| Skill | a folder on disk | metadata only, body loads on trigger | know-how + bundled scripts |
The key point: a Skill is not a new tool. It is a "knowledge wrapper" that tells Claude "a task like this should follow these steps, and here is a helper script too". Claude still uses its own existing tools (Bash, Read, Edit, ...), but now with a clear playbook.
Why Skills exist: the design problem they solve
ref: Best practices
Three problems the docs state plainly:
- Context bloat: if you paste an 800-line "how to write a PR" guide into every session, context disappears and the guide easily goes stale. A Skill loads only metadata (~100 tokens) at startup, and the body loads only when the task matches.
- Repeated instructions: a team pastes the same checklist into chat, everyone individually. Roll it into a skill and it lives committed in the repo, done.
- CLAUDE.md growing too large: if your project's CLAUDE.md has a section that has turned into an 8-step "procedure" rather than a "fact", that is exactly what should be split out into a skill.
A fourth problem (from the announcement):
"Skills can include executable code for tasks where traditional programming is more reliable than token generation."
Example: if you ask Claude to validate a JSON schema by "thinking", it can slip up, but if the skill has a validate.py and you tell Claude to "run this script", the result is deterministic.
Before / After: how it differs from the old way
Compare two scenarios Thai teams hit often:
Scenario A: a PR description in the team standard
Before: everyone pastes the same prompt:
Help me write a PR description in our team's format
It has 3 sections: Why, What, Test plan
In Why, include context + ticket link
In What, a bullet list of the changed files
Test plan is a markdown checkbox list
No emoji, no " Generated with..."
... (another 20 lines)
Pasted every turn, some people remember it and some forget, the format is inconsistent across the team.
After: you have .claude/skills/pr-description/SKILL.md:
---
name: pr-description
description: Write a PR description in our team's standard 3-section format (Why, What, Test plan). Use when the user asks to write or update a PR description, or after committing.
---
## Format
- ## Why, context + ticket link
- ## What, bullet of changed files
- ## Test plan, markdown checkbox list
## Rules
- No emoji
- No "Generated with..." trailer
- ...You commit it into the repo, the whole team uses the same thing, the prompt shrinks to "help me write a PR description", and Claude triggers the skill on its own.
Scenario B: deploying to the company's ECS
Before: every dev on the team memorizes the steps and slips up often:
"Forgot to update the task definition before aws ecs update-service"
"What was the secret ARN for this service again"
"The Jenkinsfile pattern the team uses is deployEcsService, right"
After: .claude/skills/uplift-deploy/SKILL.md + a reference.md with all the secret ARNs + scripts/check-task-def.py (deterministic verification):
.claude/skills/uplift-deploy/
├── SKILL.md # the main steps
├── reference.md # secret ARNs of 12 services
├── jenkinsfile.md # pattern + warnings
└── scripts/
└── check-task-def.py
Claude reads SKILL.md (5k tokens) and points to reference.md only if it needs to check a secret. The check-task-def.py script runs directly, so Claude doesn't guess. Every dev on the team uses the same pattern, and every deploy is reproducible.
The difference in outcome
| Before (prompt-only) | After (skill) | |
|---|---|---|
| Context consumed | 800+ tokens every turn | 100 tokens (metadata) + 5k on trigger |
| Consistency across the team | everyone remembers their own version | identical (in the repo) |
| Deterministic ops | "Claude guesses" | a real script |
| Onboarding new people | "read the wiki + ask your pair" | clone the repo, done |
| Auditable? | scroll chat history | git log |
The parts of a skill

The smallest possible 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.
---
# PDF Processing
## Quick start
Use pdfplumber for text extraction:
```python
import pdfplumber
with pdfplumber.open("file.pdf") as pdf:
text = pdf.pages[0].extract_text()
```Frontmatter, the common fields
| field | required? | notes |
|---|---|---|
name | yes | [a-z0-9-] only, max 64 chars, must not contain the words claude / anthropic |
description | yes | the most important one. Claude uses this field to decide which skill to trigger. Always write it in the third person ("Processes PDFs...", not "I help with...") |
allowed-tools | no | (Claude Code) pre-approve tools while the skill is active, e.g. Bash(git add *) Bash(git commit *) |
disable-model-invocation | no | (Claude Code) true = the user must type /skill-name, Claude cannot trigger it on its own |
model | no | override the model for that turn |
Supporting files of a real skill (Anthropic's pdf)
ref: github.com/anthropics/skills
pdf/
├── SKILL.md # high-level guide (loaded on trigger)
├── FORMS.md # form-filling guide (loaded only if you do forms)
├── reference.md # API reference (loaded only when needed)
├── examples.md
└── scripts/
├── analyze_form.py # bash exec, the code never enters context
├── fill_form.py
└── validate.py
This is the canonical pattern: SKILL.md is a "table of contents" that points to reference.md and scripts/ when needed.
Progressive Disclosure: the mental model you need to understand
ref: Overview
This is the reason a skill won't break your context:
| Level | Loaded when | Token cost | Contents |
|---|---|---|---|
| L1: Metadata | startup (every skill) | ~100 tokens/skill | name + description |
| L2: Instructions | skill is triggered | <5k tokens | SKILL.md body |
| L3: Resources | on demand, per file | unlimited (as needed) | reference.md, schema, scripts |
Which means:
- Installing 100 skills consumes only ~10k tokens of context at startup, very cheap
- A script bundled in a skill costs 0 tokens, because Claude runs
bash:python scripts/validate.pyand gets the output back, the script's source code never enters context at all - A skill can ship a 50-page reference, and if the task doesn't need it, it costs nothing
Where a skill can live
ref: Claude Code skills
| Location | path | scope |
|---|---|---|
| Personal | ~/.claude/skills/<name>/SKILL.md | all of your projects |
| Project | .claude/skills/<name>/SKILL.md | this project only (can be committed to git) |
| Plugin | <plugin>/skills/<name>/SKILL.md | wherever the plugin is enabled |
| Enterprise | managed settings | every user in the organization |
Precedence: enterprise → personal → project (higher overrides lower). Plugins use the namespace plugin-name:skill-name to avoid collisions.
Writing a good skill: 3 key rules
ref: Best practices
1. The description is everything for triggering
The docs say it plainly: it is "critical for skill selection". Claude has 100+ skills to choose from and uses each one's description to decide.
Good:
description: Generate descriptive commit messages by analyzing git diffs. Use when the user asks for help writing commit messages or reviewing staged changes.Bad:
description: Helps with documentsFirst person (breaks triggering):
description: I can help you with X2. Separate SKILL.md from the reference
- SKILL.md body < 500 lines: the main instructions + quick-start
reference.md/examples.md: API detail, edge cases, long code examples, which Claude reads only when neededscripts/: the deterministic stuff (validation, migration). The code never enters context, only its output comes back
3. Don't teach Claude what it already knows
"Default assumption: Claude is already very smart. Only add context Claude doesn't already have."
Don't waste space explaining what a PDF is or what HTTP is, cut it.
Skill vs MCP server: which to use

| Aspect | Skill | MCP server |
|---|---|---|
| What it adds | procedural knowledge + bundled scripts | new tools (functions over the MCP protocol) |
| Distribution | a folder + plugin | a running process |
| Loading | metadata only until triggered | tool list is always in context |
| State | stateless (files on disk) | can hold a connection, a session |
| Good for | "do task X this way, here" | "talk to system Y" (an API, DB, external service) |
| Cost when unused | ~100 tokens | its tool schema is always in there |
Rule of thumb: if what you want to add describes as "here are the steps to do this + read this doc" → write a skill. If it is "call a live system to fetch or modify data" → use MCP.
Distribution: how to hand it out
Four main ways:
- Commit the folder directly into the project's
.claude/skills/, and distribute it through git as usual. The simplest option, auditable via PR, and the team sees a normal diff. - The Anthropic plugin marketplace, the
anthropics/skillsrepo:
/plugin marketplace add anthropics/skills
/plugin install document-skills@anthropic-agent-skills
- skills.sh, a cross-tool marketplace (Open Agent Skills Ecosystem). Install one skill and use it across Claude Code, Cursor, Codex, GitHub Copilot, Windsurf, Gemini, Cline, and more:
npx skills add <owner>/<repo>Good if your team uses several tools and doesn't want to lock into Claude alone. 4. A private third-party marketplace, any GitHub repo with the right structure can be used as a marketplace (Notion made their own, Notion Skills)
On the Claude API side: upload a skill via POST /v1/skills and reference it with a skill_id when you call the Messages API.
References to look at before writing your first skill
anthropics/skills, the source of thepdf,xlsx,docx,pptxskills that power Claude.ai itself. Reading each one'sSKILL.mdis the best reference there is- skills.sh, community-curated, searchable by tool name
- Claude Code skills docs, the complete frontmatter field reference
- Best practices guide, naming, description, degree of freedom, important if you want Claude to trigger correctly
Important gotchas for Thai developers
ref: Overview > Security
namecannot be in Thai,[a-z0-9-]only. Thai in the body / description is fine, but do include an English trigger keyword in the description in case Claude is thinking in English- Quote paths with spaces: if a script in the skill references
$CLAUDE_SKILL_DIRand the path is/Volumes/My SSD/..., forgetting to quote it breaks the script:bash -c "cd \"$CLAUDE_SKILL_DIR\" && ..." - Security: a skill can run code. The docs warn plainly: "Use Skills only from trusted sources... a malicious Skill can direct Claude to invoke tools or execute code in ways that don't match the Skill's stated purpose.", so audit
scripts/before installing - Secret leak: don't hardcode a token in SKILL.md or
!`cat .env`in the body. The body is injected into the conversation context and will get logged - Lifecycle in Claude Code: once a skill is invoked, its body stays in the session the whole time. Editing the file mid-session won't refresh it until it triggers again or you start a new session
- Don't use the words
claude/anthropicinname, it is rejected immediately - Cross-surface doesn't sync yet: uploading to claude.ai does not make the API or Claude Code see it. These 3 surfaces are separate
Summary
A Skill is the tool that turns "the knowledge in your head" into "an asset your team can reuse", in three phrases:
- Stop pasting the same prompt → build the skill once, reuse it every session
- Stop breaking context → progressive disclosure loads only what's needed
- Stop relying on the LLM to guess deterministic things → bundle a script and Claude will run it
If you have a checklist or workflow you repeat in your head, try mkdir -p ~/.claude/skills/my-first-skill && touch SKILL.md and write the frontmatter plus 10 lines of instructions first. Claude will trigger it when you work on something that matches the description.
Take a look at real examples at anthropics/skills, open the SKILL.md of pdf or xlsx and reverse-engineer how the frontmatter / structure / scripts/ are organized. Or search for skills other people have already written at skills.sh, sometimes the thing you were about to write is already done, install with npx skills add <repo> and you're finished.
In 30 minutes you'll have your own first skill, ready to commit into your project's .claude/skills/.

