Agent skills
How to turn a workflow you repeat into a skill: a folder of instructions, scripts and reference files that an agent loads only when a task calls for it. Written for Claude Code first, where skills do the most, with the Claude apps, the Claude API, the Agent SDK and the open Agent Skills format covered after. A skill's instructions are a prompt you write once, so everything in Prompting fundamentals applies inside it.
The short version
A skill is one folder with one required file. This one is complete and works as is in Claude Code
(~/.claude/skills/ makes it available in every project):
writing-release-notes/SKILL.md---
name: writing-release-notes
description: Writes user-facing release notes from merged pull requests and commits. Use when the user asks for release notes, a changelog entry, or what changed between two versions or dates.
---
# Writing release notes
1. Get the changes: `git log --merges --oneline <from>..<to>`
(ask for the two tags or dates if the user didn't give them).
2. Group them under Breaking, Added, Changed, Fixed. Drop
chores, CI and dependency bumps unless they change behavior.
3. Write one line per change for users: what they can do now,
not which file changed.
Before answering, check: every line traces to a commit, no
internal ticket numbers, and breaking changes come first.
Output: Markdown, one heading per version, newest first.Ask "write the release notes for v2.4" and the agent picks the skill up by itself; type /writing-release-notes to
call it directly. Five things decide whether a skill works:
| Rule | Why |
|---|---|
| The description is the trigger | it's the only part the agent sees before deciding to use the skill: say what it does and when, in the words you'd type |
| One job per skill | a skill that reviews code and writes docs triggers at the wrong times and does both badly |
| Write only what the agent doesn't know | your steps, defaults, conventions and quality bar; not how to write Markdown or use git |
| Keep SKILL.md short, push detail out | long references go in files it reads on demand; exact operations go in scripts it runs |
| Test on real requests | does it trigger on three phrasings and not on a near miss, and does the output pass your checks? |
What a skill is
A skill is a directory whose SKILL.md starts with YAML frontmatter (at least name and description)
followed by Markdown instructions, optionally with scripts/, references/ and assets/. The agent loads it in
three levels, so an installed skill costs almost nothing until it's used. This is progressive disclosure:
| Level | What | Loaded | Cost |
|---|---|---|---|
| 1. Metadata | name + description | at session start, for every installed skill | about 100 tokens per skill |
| 2. Instructions | the body of SKILL.md | when a request matches the description, or you type /name | keep under about 5,000 tokens (500 lines) |
| 3. Resources | files in the folder | only when a step needs one; scripts run, and only their output enters the context | effectively unlimited |
1/4
Session starts: only each skill's name and description enter the context, about 100 tokens apiece.
The consequence for your workflows: you can install a skill for every one of them. Twenty idle skills cost about as much context as a paragraph, and only the one that fits the task gets read.
When to use a skill
A skill is one of several places to put knowledge for an agent. Pick by when the knowledge must apply:
| Mechanism | Loaded | Use it for | Not for |
|---|---|---|---|
| CLAUDE.md / AGENTS.md | every session, in full | facts every task needs: build and test commands, layout, conventions | procedures used now and then: they cost context every session |
| Skill | when relevant, or on /name | repeatable procedures and know-how: review a PR, write the weekly report, apply the house style | rules that must hold every time |
| Hook | on an event (before a tool runs, after an edit), every time | deterministic actions: format after edits, block a dangerous command, notify | anything that needs judgment |
| MCP server | its tools are always available | live access to outside systems: issue trackers, databases, APIs | how and when to use those tools (write a skill for that) |
| Subagent | in its own context window | large searches or side tasks whose details would clutter your session | short procedures (a skill with context: fork runs in a subagent) |
| Plugin | installed as a bundle | sharing skills, subagents, hooks and MCP settings together | a single personal skill |
| Plain prompt | this turn only | one-off tasks | anything you'll explain twice |
Rule of thumb: the second time you paste the same instructions into a chat, make them a skill.
Turn a workflow into a skill
Pick a workflow
Something you do at least weekly, that has a clear "done", and that you explain to the agent every time. Start with one; good first candidates are reports, reviews, release chores and anything with a checklist.
Do it once without a skill
Run the workflow with the agent in a normal session and keep notes of every correction you make and every fact you have to supply. That list, not your memory of the process, is the skill's content.
Write the description first
Name the job and the moments it applies, in the words you'd actually type. If you can't write it in two sentences, the skill does too much: split it.
Write the body
Inputs, numbered steps each with a "done when", the checks to run before answering, and the exact output format. Leave out what a capable model already knows.
Move the bulk out
Long reference material goes to
references/, exact or fragile operations toscripts/, templates toassets/. SKILL.md says when to read or run each one.Test it
Three requests that should trigger it, two near misses that shouldn't, and one real task run with and without the skill. Use a fresh session, so the agent isn't helped by the conversation where you wrote it.
Iterate, then share
Fix what you saw go wrong, one change at a time. When it works for you, commit it to the project or package it as a plugin.
| Workflow | Skill shape | How it's invoked |
|---|---|---|
| Weekly status report | template filled with live data (commits, PRs, issues) | /weekly-report, by you only |
| Code review | checklist + quality bar, references for security | automatically, when you ask for a review |
| Deploy to staging | exact commands and verification steps | by you only (disable-model-invocation: true) |
| House writing style | reference knowledge | automatically; hidden from the / menu (user-invocable: false) |
| Research a library or codebase area | instructions run in a subagent | context: fork |
| Clean and validate data files | scripts + a validator loop | automatically, when the file type comes up |
| Meeting notes to tasks | template + rules for owners and dates | automatically, when you paste notes |
Have the agent draft it
Give the agent the notes from step 2 and let it write the first version. The prompt uses the structure from Prompting fundamentals:
<materials>
[paste the transcript or your notes from doing the workflow once,
including every correction you made]
</materials>
<context>
I want a reusable Agent Skill for this workflow. It will run in
[surface: Claude Code | the Claude apps | the Claude API | another agent].
</context>
<task>
Draft the skill: SKILL.md (frontmatter and body) and any scripts/,
references/ or assets/ files it needs.
</task>
<requirements>
- name: lowercase letters, numbers and hyphens, at most 64 characters,
one job, e.g. reviewing-pull-requests
- description: third person, what it does and when to use it, with the
words I'd type; under 1,024 characters
- body under 200 lines: inputs, numbered steps with "done when", checks
before answering, output format; only what a capable model wouldn't know
- exact or fragile operations go in scripts that handle their own errors;
long reference material goes in references/
- Never invent commands, flags or file paths: write [NEEDS SOURCE]
where you're unsure.
</requirements>
<quality_bar>
Before answering, check your draft against:
- Would the description trigger on three different phrasings of the
request, and not on a near miss?
- Does every step say exactly what to do and how to know it's done?
- Is there one default for each choice, not a menu of options?
</quality_bar>
<output_format>
The folder tree, then each file in its own code block, then 3 requests
that should trigger it and 2 that shouldn't.
</output_format>
<process>
Ask me up to 3 questions first if anything missing would change the
skill. End with a list of the assumptions you made.
</process>Anatomy of a skill folder
reviewing-pull-requests/SKILL.md # required: frontmatter + bodyreferences/checklist.md # read when a step says sosecurity.mdscripts/diff_stats.sh # run; only output enters contextassets/review-template.md # copied into the output| Part | Holds | Rules |
|---|---|---|
SKILL.md | frontmatter, then instructions | required; the folder name must equal name |
references/ | documentation the agent reads when needed: schemas, policies, long examples | one level deep from SKILL.md (no reference that points to another); a table of contents at the top of files over about 100 lines |
scripts/ | code the agent runs: validators, converters, API calls | handle errors and print short, clear output; only the output costs context |
assets/ | files used in the output: templates, images, fonts | never read into context unless a step says so |
Paths inside a skill use forward slashes and are relative to the skill folder (references/checklist.md), also on
Windows. In Claude Code, ${CLAUDE_SKILL_DIR} expands to the folder's absolute path, for commands that run from
another working directory.
Frontmatter
These fields come from the open Agent Skills specification (opens in a new tab), so a skill that uses only them works wherever skills do:
| Field | Required | Rules |
|---|---|---|
name | yes | 1–64 characters; lowercase letters, digits and hyphens; no leading, trailing or double hyphen; equals the folder name |
description | yes | 1–1,024 characters; what the skill does and when to use it |
license | no | a license name, or the name of a license file in the folder |
compatibility | no | up to 500 characters on what the environment needs: tools, network, operating system |
metadata | no | a map of string keys to string values: version, owner, anything your own tooling reads |
allowed-tools | no | tools the skill may use without asking, space-separated, e.g. Bash(git:*) Read; experimental in the spec |
---
name: reviewing-pull-requests
description: Reviews a pull request for correctness, test coverage and security issues. Use when the user asks to review a PR, a diff or a branch before merging.
license: MIT
compatibility: Needs git and the GitHub CLI (gh), with network access.
metadata:
version: "1.2.0"
owner: platform-team
---| Surface | Extra rules |
|---|---|
| Claude API and Claude apps | name can't contain "anthropic" or "claude"; neither field may contain XML tags |
| Claude apps (claude.ai upload) | only the six fields above are accepted; any other field is an error, so keep Claude Code-only fields out of skills you upload there |
| Claude Code | name defaults to the folder name; frontmatter must start on line 1; unknown fields are ignored; adds the fields in Claude Code features |
Keep description on one line. The YAML spec allows multi-line values, but one line is the form every tool reads.
Writing the description
The agent decides whether to use a skill from its description alone, so a skill that never triggers almost always has a description problem.
- Third person, present tense: "Reviews pull requests…", not "I review…" or "Use this to review…".
- What, then when: the first sentence says what it does, the second when to use it ("Use when…").
- The words you'd type: nouns and verbs from real requests, file types and tool names ("PR", "diff", "code review", ".xlsx", "Grafana").
- Specific beats broad: a description that could fit ten skills triggers for none of them reliably.
- Say when not, if two skills are close: "Not for writing new tests; see writing-tests."
| Weak | Strong |
|---|---|
| "Helps with documents." | "Extracts text and tables from PDF files, fills PDF forms and merges PDFs. Use when the user mentions PDFs, forms or document extraction." |
| "Code review skill." | "Reviews a pull request for bugs, missing tests and security issues, and writes the review as inline comments. Use when asked to review a PR, a diff or a branch." |
| "Use this for reports." | "Writes the weekly engineering status report from this week's commits, merged PRs and closed issues. Use when the user asks for the weekly report or a status update." |
In Claude Code the skill list in context gets about 1% of the model's context window, and each entry
(description plus the optional when_to_use field) is cut at 1,536 characters. With many skills, long descriptions
get shortened: /doctor estimates the listing's cost and /skill-doctor reports how your skills are used.
Writing the instructions
The body is a prompt the agent reads at the moment it needs it, so the rules of a good prompt apply, plus a few that come from being read again and again:
- Concise: the agent is already capable. Explain your conventions, defaults and decisions, not general skills.
- Imperative and ordered: numbered steps, each with how to know it's done.
- Defaults, not menus: "Use pdfplumber; for scanned PDFs use OCR" beats a list of five libraries.
- One term per thing: if it's a "release" in step 1, don't call it a "version" in step 4.
- Nothing time-sensitive: no "as of this year". Put superseded behavior under an "Old patterns" heading.
- Under 500 lines: past that, split into reference files the body points to.
- Read vs run, said explicitly: "Run
scripts/validate.py report.json" (execute it) and "Seereferences/schema.md" (read it) are different instructions.
Match how tightly you specify a step to how fragile it is. These are the degrees of freedom:
| Freedom | Use when | Write |
|---|---|---|
| High | many approaches are fine and judgment matters | goals and heuristics: "Keep each commit to one change; explain why in the message." |
| Medium | there's a preferred pattern with some variation | a template or pseudocode with parameters |
| Low | the operation is fragile, exact or destructive | the exact command, and "Run exactly this; don't change the flags." |
A body that follows the same structure as a good prompt:
# Reviewing pull requests
## Inputs
- The PR number or branch. If none is given, ask for it.
## Steps
1. Get the diff: `gh pr diff <number>`. Done when you have it.
2. Run `scripts/diff_stats.sh <number>` for size and touched areas.
3. Review against references/checklist.md, file by file.
4. If auth, payments or user data are touched, also apply
references/security.md.
## Checks before answering
- Every finding names a file and line and says why it matters.
- Findings are ranked: blocking, should fix, nit.
- No finding is about style the linter already enforces.
## Output
Use assets/review-template.md. Blocking findings first.
## Edge cases
- Diff over 1,000 lines: review the riskiest files first and
say which files you skipped.Checklists and feedback loops
For long workflows, give the agent a checklist to copy into its answer and tick off, so steps don't get skipped. For anything with a validator (a schema, a linter, a test suite, a script you wrote), make the loop explicit: run it, fix what it reports, run it again, and only continue when it passes.
For risky batch work (renaming hundreds of files, bulk edits through an API), add a plan step: the agent writes the
plan to a file (changes.json), a script validates it, and only then does it execute. Mistakes surface in the plan,
where they're cheap.
Scripts and bundled files
Put a step in a script when it must be exact, when it's long or fragile, or when the agent would otherwise write the same code every time. The agent runs the script and sees only its output, so a 300-line script costs a few lines of context.
- Solve, don't defer: handle missing files, bad input and network errors in the script, and print a message that says what to do.
- No unexplained constants:
TIMEOUT = 30 # the API's limit is 30 sinstead of a bare30. - Short, structured output: a summary and the problems found, not a log. Exit non-zero on failure so the agent knows to stop.
- Declare dependencies: say what must be installed (in
compatibilityand in the step), and don't assume a package exists. - Prefer reading data over hard-coding it: a script that reads
references/rules.jsonis easier to update than one with the rules inside.
"""Check a report JSON file; exit 1 listing problems."""
import json
import sys
REQUIRED = ["title", "period", "highlights", "risks"]
def main(path: str) -> int:
try:
with open(path, encoding="utf-8") as file:
data = json.load(file)
except (OSError, json.JSONDecodeError) as err:
print(f"Cannot read {path}: {err}")
return 1
missing = [key for key in REQUIRED if not data.get(key)]
if missing:
print("Missing or empty: " + ", ".join(missing))
return 1
print(f"OK, highlights: {len(data['highlights'])}")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1]))Where a skill runs decides what its scripts can do:
| Surface | Network | Packages |
|---|---|---|
| Claude Code | your machine's network, like any program you run | whatever is installed; don't have a skill install packages globally |
| Claude apps | full, partial or none, set by you and your admin | can install from npm and PyPI when the network allows |
| Claude API | none | only what the code execution environment has preinstalled |
Claude Code features
Where skills live
| Location | Path | Applies to |
|---|---|---|
| Enterprise | set through managed settings | everyone in the organization |
| Personal | ~/.claude/skills/<name>/SKILL.md | all your projects |
| Project | .claude/skills/<name>/SKILL.md | everyone working in the repository (commit it) |
| Nested | <subdirectory>/.claude/skills/<name>/SKILL.md | loaded once the agent reads or edits a file in that subdirectory |
| Plugin | <plugin>/skills/<name>/SKILL.md | wherever the plugin is installed, as /plugin-name:skill-name |
On a name clash, enterprise beats personal, which beats project; plugin skills are namespaced, so they never clash.
Custom commands are now skills: .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create
/deploy, old command files keep working, and the skill wins if both exist.
Invoking and arguments
The agent uses a skill when a request matches its description; you call one by starting a message with /name,
followed by any arguments: /fix-issue 123. In the body:
| Placeholder | Becomes |
|---|---|
$ARGUMENTS | everything after the name (if the body has no placeholder, the arguments are appended as ARGUMENTS: …) |
$0, $1 or $ARGUMENTS[0] | one argument by position, counting from 0 |
$name | a named argument declared in arguments |
${CLAUDE_SKILL_DIR} | the skill folder's absolute path |
${CLAUDE_PROJECT_DIR} | the project root |
Controlling behavior
| Field | Effect | Typical use |
|---|---|---|
disable-model-invocation: true | only you can run it, with /name; its description leaves the context, and /loop and scheduled tasks can't run it | deploys, sends, anything with side effects |
user-invocable: false | hidden from the / menu; the agent still uses it | background knowledge: house style, domain rules |
when_to_use | extra trigger text appended to the description | longer "use when" guidance |
argument-hint | the hint shown while typing, e.g. "[issue-number]" (quote it: unquoted brackets are a YAML list) | skills you call with arguments |
arguments | names for positional arguments, used as $name | readable bodies |
allowed-tools | tools it may use without asking, for the turn that invoked it: Bash(gh *) Read | a report skill that runs git log |
disallowed-tools | tools removed while it's active | a read-only review skill |
model, effort | the model or effort level for that turn | a cheap model for a mechanical skill |
context: fork | runs in a subagent with its own context; agent picks its type (default general-purpose, or e.g. Explore), background whether it runs in the background (default true) | research whose details would clutter your session |
paths | globs (a comma-separated string or a YAML list) that limit when it loads automatically | a skill for one part of a monorepo |
hooks | hooks registered while it's active | a format-on-save rule during a refactor skill |
Live data in the instructions
A placeholder !`command` (at the start of a line or after a space) runs before the agent sees the skill and
is replaced by the command's output, so the instructions arrive with current data. Its output isn't scanned again
for placeholders. A fenced block opened with ```! runs several lines. If a command fails,
the skill doesn't run. Administrators can turn this off with the disableSkillShellExecution setting.
Managing skills
| Command | Does |
|---|---|
/skills | lists loaded skills |
/context | shows how much context the skill list uses |
/skill-doctor | reports how your skills are used and what they cost |
/reload-skills | picks up a newly created top-level skills folder (edits to existing skills load without it) |
claude plugin validate .claude/skills | checks frontmatter before you share |
Loops, goals and long runs
Some of the most useful skills aren't run once: they're run until something is true, or every few minutes while something changes. Claude Code has commands for both, and a skill is the natural thing to put inside them.
| Command | Does | With a skill |
|---|---|---|
/loop [interval] [prompt] | runs the prompt again every interval (5m, 2h; at least 1 minute); with no interval Claude picks each wait itself, 1 minute to 1 hour; with no prompt it tends the branch's PR or follows .claude/loop.md | /loop 15m /babysitting-pull-requests, or /loop /babysitting-pull-requests to let it pace itself |
/goal [condition] | after every turn a small model checks the condition against the conversation; while it isn't met, Claude starts another turn; /goal clear ends it | run a skill, then hold it to a finish line: /goal every check in the skill's report passes; or stop after 20 turns |
/schedule [description] | cloud scheduled tasks that run on Anthropic's servers, even with your machine off | a daily or weekly skill: the Monday report, a nightly dependency audit |
/batch <instruction> | splits a large change into 5–30 units and runs one background subagent per unit, each in its own worktree, each opening a PR | a migration your skill describes, applied everywhere at once |
claude --bg "<prompt>", /tasks | a session that keeps working in the background; list and manage background work | a long skill you don't want to watch |
| Stop hook | runs when Claude finishes responding and can block stopping (exit code 2) | enforce "don't stop until the validator passes" as code, not instructions |
Writing skills that repeat
- Idempotent: every step checks before it acts ("if this comment already has a reply, skip it"), so the tenth run doesn't redo the first.
- Standing instructions: Claude Code doesn't re-read SKILL.md on later turns, so write rules that apply for the whole run as rules ("never force-push"), not as one-time steps.
- One status line: end every run with a fixed line (
STATUS: checks pass · comments 0 · action none). The/goalchecker can only judge what's printed, and an unchanged line tells you nothing needs attention. - Quiet when nothing changed: print only the status line.
- State in a file: record what's been handled in a file the next run reads, because long sessions get summarized and details drop out of the conversation.
- A stop rule: "If the PR is merged or closed, say so and end the loop", or "stop once two rounds in a row find nothing new".
- Bounded: put a turn limit in every goal ("or stop after 20 turns"), and in scripts cap runs with
claude -p --max-turns 30 --max-budget-usd 5.
---
name: babysitting-pull-requests
description: Checks this branch's pull request for failing CI, new review comments and merge conflicts, and fixes what it safely can. Use when asked to watch, babysit or tend a PR, or when run by /loop.
allowed-tools: Bash(gh pr *) Bash(gh run *) Bash(git status *) Bash(git diff *) Bash(git add *) Bash(git commit *) Bash(git push)
---
# Babysitting a pull request
Safe to run again and again. Never force-push; never merge the PR.
1. Read the state: `gh pr view --json number,state,mergeable,statusCheckRollup,reviewDecision`.
If the PR is merged or closed, print "PR closed: stopping" and end the loop.
2. Read .claude/pr-babysit.md (create it if missing): the comments and runs already handled.
3. Failing checks not yet handled: read the log (`gh run view <run-id> --log-failed`), fix the cause, commit, push once.
4. Review comments not yet handled: address each in code or reply, push once, and list them in .claude/pr-babysit.md.
5. Merge conflicts: report them; don't resolve conflicts in files this PR didn't change.
## Every run ends with exactly one line
STATUS: checks <pass|fail> · new comments <n> · conflicts <yes|no> · action <what you did|none>
If nothing changed since the last run, print only that line.Run it with /loop /babysitting-pull-requests and stop it with Esc, or set a fixed interval
(/loop 15m /babysitting-pull-requests) and ask Claude to cancel it when you're done. Loops run only while Claude
Code is open and idle, and recurring ones expire after seven days.
Other places skills run
Claude apps
Turn on code execution (Settings, Capabilities), then add the skill under Customize, Skills: "+", "Create skill",
"Upload a skill". Zip the skill folder itself, so the archive's top level is that folder (house-style/SKILL.md),
not a parent folder around it, and name the folder like the skill. Only the six portable frontmatter fields are accepted. Team and Enterprise owners can provision
skills for the whole organization, and Enterprise can scan uploaded skills for malicious content. Skills you add in
the apps can sync one way into Claude Code when you sign in with the same account. Plan availability changes: check
the help center.
Claude API
Upload a skill to your workspace with POST /v1/skills (multipart files, or a zip under 30 MB). Each new version is a
complete snapshot. Attach skills to a request through the container, with the code execution tool enabled:
{
"model": "[model id]",
"max_tokens": 4096,
"container": {
"skills": [
{ "type": "anthropic", "skill_id": "xlsx",
"version": "latest" },
{ "type": "custom", "skill_id": "skill_01...",
"version": "latest" }
]
},
"tools": [
{ "type": "code_execution_20250825",
"name": "code_execution" }
],
"messages": [
{ "role": "user",
"content": "Build the Q3 budget workbook." }
]
}- Up to 20 skills per request. Anthropic's prebuilt skills are
pptx,xlsx,docxandpdf. - The container has no network access, and only preinstalled packages: bundle what the skill needs.
- Custom skills belong to the whole workspace: any API key with access can use or delete them. Use a separate workspace per customer if you serve several.
- Headers and versions change: copy them from the current skills guide (opens in a new tab).
Agent SDK
Skills are files on disk, found in the same places as in Claude Code. Load the user and project sources and enable them:
from claude_agent_sdk import ClaudeAgentOptions
options = ClaudeAgentOptions(
setting_sources=["user", "project"],
skills="all",
allowed_tools=["Read", "Grep", "Bash"],
)Setting skills adds the Skill tool automatically; if you pass an explicit tools list, include "Skill". The
session's init message lists the skills that loaded.
Other agents
Anthropic published Agent Skills as an open standard in December 2025, with the specification at
agentskills.io (opens in a new tab). The portable core is the folder layout and the six frontmatter fields;
Claude Code's extras (arguments, !`command`, invocation control, context: fork) are not part of it. For a
skill meant to work in other agents, stick to the core, check each agent's docs for where it looks for skills, and
validate with the reference tool: skills-ref validate ./my-skill.
Patterns for workflows
| Pattern | Shape | Example |
|---|---|---|
| Checklist | steps the agent copies and ticks off | onboarding a new service, a release |
| Validator loop | do, validate with a script, fix, repeat | data files, generated configs, docs that must build |
| Template fill | an asset with the exact output format | status reports, incident summaries, RFCs |
| Router | a short SKILL.md that points to one reference per case | an API with many endpoints, a style guide by document type |
| Knowledge pack | conventions and decisions, user-invocable: false | house writing style, naming rules, domain glossary |
| Tool wrapper | scripts around a CLI or API, with when-to-use rules | a reporting API, an internal deploy tool |
| Manual action | exact steps, disable-model-invocation: true | deploys, data migrations, sending email |
| Plan, validate, execute | write a plan file, check it, then act | bulk renames, mass edits, migrations |
| Forked researcher | context: fork, results summarized back | "investigate how auth works in this repo" |
| Polling loop | an idempotent skill with one status line, run by /loop | tending a PR, watching a deploy, triaging new issues |
| Goal-driven | a skill whose checks print evidence, finished with /goal | "fix until the test suite passes", "fill every section of the template" |
Example skills
Weekly report: called by you, with live data
---
name: weekly-report
description: Writes the weekly engineering status report from this week's commits, merged pull requests and closed issues. Use when the user asks for the weekly report or a status update.
disable-model-invocation: true
argument-hint: "[team name]"
allowed-tools: Bash(git log *) Bash(gh pr list *) Bash(gh issue list *)
---
# Weekly report for $ARGUMENTS
## This week's data
Commits: !`git log --since="7 days ago" --oneline --no-merges`
Merged PRs: !`gh pr list --state merged --limit 50 --json number,title,mergedAt`
Closed issues: !`gh issue list --state closed --limit 50 --json number,title,closedAt`
## Steps
1. Keep only PRs and issues closed in the last 7 days.
2. Group by theme (feature, fix, infrastructure), not by person.
3. Write 3–5 highlights in plain language: what users or the team can now do.
4. List risks and blockers only if the data or the user names them.
## Checks before answering
- Every highlight traces to a PR, issue or commit above.
- No highlight invented to fill space: fewer is fine.
## Output
Use assets/template.md exactly. End with the PR and issue numbers used.Code review: picked up automatically
---
name: reviewing-pull-requests
description: Reviews a pull request for bugs, missing tests and security issues and reports ranked findings. Use when the user asks to review a PR, a diff or a branch before merging.
---
# Reviewing pull requests
## Steps
1. Get the diff: `gh pr diff <number>` (ask for the number if missing).
2. Run `bash ${CLAUDE_SKILL_DIR}/scripts/diff_stats.sh <number>`.
3. Review each file against references/checklist.md.
4. If authentication, payments or personal data are touched, also apply
references/security.md.
## Checks before answering
- Each finding: file, line, what's wrong, why it matters, a fix.
- Ranked: blocking, should fix, nit. At most 5 nits.
- Nothing the linter or formatter already catches.
## Output
A summary line, then the findings table from assets/review-template.md.
If there are no blocking findings, say so first.House style: background knowledge
---
name: house-style
description: The company's writing style for docs, release notes, emails and UI text: voice, terminology, formatting. Use when writing or editing any user-facing text.
user-invocable: false
---
# House style
- Voice: plain and direct; second person ("you"); no exclamation marks.
- Terms: see references/glossary.md and use those exact spellings.
- Headings: sentence case. Lists: no ending periods unless full sentences.
- Numbers: digits for 10 and above, and for all units ("5 GB").
- Never: "simply", "just", "easy", or blame on the user in error messages.
For error messages and empty states, see references/ui-text.md.Deploy to staging: manual only, exact steps
---
name: deploy-staging
description: Deploys the current branch to the staging environment and verifies it. Use only when the user runs /deploy-staging.
disable-model-invocation: true
---
# Deploy to staging
Run each command exactly as written; stop at the first failure and
report its output.
1. `git status --porcelain`: must print nothing. If it does, stop
and ask the user to commit or stash.
2. `make test`: must pass.
3. `make deploy ENV=staging`
4. `curl -fsS https://staging.example.com/health`: must print "ok".
Report: the commit deployed (`git rev-parse --short HEAD`), the
health check result, and the time.Test and evaluate
Test the two things that can fail separately: triggering (does the agent pick the skill up at the right moments) and outcome (is the result good when it does).
| Test | How | Pass |
|---|---|---|
| Should trigger | three different phrasings of a real request, in a fresh session | the skill is used each time |
| Should not trigger | two near misses ("review this essay" for a code review skill) | it isn't used |
| Baseline | the same real task with the skill removed | the skill's version is clearly better; if not, the skill isn't earning its place |
| Outcome | three real tasks, checked against the skill's own checks | every check passes |
| Navigation | watch which files the agent opens | it reads what each step points to, and nothing it doesn't need |
| Models | run the outcome tests on every model you'll use | smaller models follow it too; they need more explicit steps |
Iterate with two sessions: in one you write and revise the skill with the agent ("Claude A"); a fresh one uses the skill on real tasks ("Claude B"). Bring what B got wrong back to A, change one thing, and test again. Fresh sessions matter because the authoring session already knows everything the skill fails to say.
Share and maintain
| Scope | How |
|---|---|
| Just you | ~/.claude/skills/ |
| A repository's team | commit .claude/skills/; review changes like code |
| Several repositories or teams | a plugin with a skills/ folder, published through a plugin marketplace |
| An organization in the Claude apps | an owner provisions it in the organization settings |
| An API product | upload to the workspace; pin version in requests and bump it deliberately |
- Keep a
versioninmetadataand a short changelog at the bottom of SKILL.md. - Anthropic's example skills are in the anthropics/skills (opens in a new tab) repository, which
is also a plugin marketplace:
/plugin marketplace add anthropics/skills. - Revisit a skill when its workflow changes; a stale skill is worse than none, because it's followed confidently.
Security
A skill can run code and steer an agent that has your permissions, so treat installing one like installing software.
- Install skills only from sources you trust, and read every file first: SKILL.md, scripts and anything they download.
- Be wary of skills that fetch URLs or tell the agent to send data anywhere: that's how prompt injection and data exfiltration happen.
- Never put secrets in a skill. Read them from the environment or a secrets manager at run time.
- Scope
allowed-toolsnarrowly (Bash(git log *), notBash), and usedisable-model-invocation: truefor anything with side effects. - In the API, any key in the workspace can use and delete its custom skills; separate workspaces separate tenants.
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Never triggers | the description doesn't use the words of the request, or is too broad | add the nouns and verbs you actually type; test three phrasings |
| Triggers at the wrong times | the description overlaps another skill or is generic | narrow it and add "Not for …" |
| Doesn't appear at all | frontmatter not on line 1, the folder name differs from name, or a new top-level folder | fix the file; run /reload-skills; check /skills |
| Upload rejected in the Claude apps | a Claude Code-only field, a reserved word, or the zip's root isn't the skill folder | keep only the six portable fields; re-zip from inside the parent folder |
| Follows some steps, skips others | steps without a "done when", or a body that's too long | number the steps, add a checklist, move detail to references |
| Reads every reference file | SKILL.md doesn't say which file is for which case | point to each file from the step that needs it |
| A script fails in the API | no network, or a package that isn't installed | bundle the dependency or rewrite without it |
| Description cut short in the list | too many skills for the listing budget | shorten descriptions; hide background skills from the menu |
Does nothing inside /loop | the skill has disable-model-invocation: true | make it model-invocable and guard its side effects in its steps |
| A goal never finishes | the condition isn't visible in the conversation, or has no bound | have the skill print the check's result; add "or stop after N turns" |
| Each loop run redoes earlier work | no record of what's done | keep a state file the steps read and update |
References
- Claude Code: Skills (opens in a new tab): locations, frontmatter fields, arguments, live data, troubleshooting
- Claude Code: Keep Claude working toward a goal (opens in a new tab):
/goalconditions, the checker, bounds - Claude Code: Run prompts on a schedule (opens in a new tab):
/loop, intervals, self-pacing,loop.md, limits - Agent Skills overview (opens in a new tab): progressive disclosure, surfaces, limits, security
- Skill authoring best practices (opens in a new tab): conciseness, degrees of freedom, patterns, evaluation
- Skills in the Claude API (opens in a new tab): uploading, versions, attaching skills to requests
- Agent SDK: Skills (opens in a new tab): loading and enabling skills in the SDK
- Using skills in Claude (opens in a new tab): enabling and uploading skills in the Claude apps
- Agent Skills specification (opens in a new tab): the open format and its validation tool
- anthropics/skills (opens in a new tab): example skills, a template and the plugin marketplace
- Introducing Agent Skills (opens in a new tab): the announcement and the open-standard update