Skip to content
harbor
How it worksAgentsReviewMeasureDocsPricing
Get started →
How it worksAgentsReviewMeasureDocsPricingGet started →
Home/Blog

Blog

  • Claude Code and AGENTS.md
  • Claude Code skills
  • Claude Code hooks
  • claude-mem
  • Claude Code best practices
  • Karpathy CLAUDE.md
  • AGENTS.md vs CLAUDE.md
  • Cursor rules
  • copilot-instructions.md
  • Why Claude ignores it
  • CLAUDE.md length
  • Committing CLAUDE.md
  • Agent memory compared
  • CLAUDE.md vs skills vs hooks
  • Same mistake again
  • Review comments to rules
  • Slack decisions
  • Company brain
  • Context engineering, Claude 5
  • Context rot, stale rules
  • AGENTS.md research
  • ADRs for agents
  • Memory poisoning
  • MCP memory servers
  • Claude Code, Cursor, Codex
  • Growing CLAUDE.md
  • Served vs cited

Blog

Claude Code skills: how to write SKILL.md and when to use one

Published: September 23, 2026

A Claude Code skill is a folder with a SKILL.md file: a name, a description, and instructions. Claude sees every skill's description on every turn and loads the full instructions only when a task matches, or when you type /skill-name. That makes a skill the place for knowledge you need sometimes, not always.

Everything below was checked against the Claude Code skills docs on 2026-09-23 (Claude Code 2.1.280). Skills have changed more than any other part of Claude Code this year; custom slash commands were folded into them, and several fields are newer than most tutorials.

What is a skill in Claude Code?

A skill bundles instructions, and optionally supporting files and tool permissions, into something Claude can pick up on demand. It is the answer to a question every CLAUDE.md eventually raises: where does knowledge go that matters for one kind of task and is noise for the rest? CLAUDE.md is read at the start of every session. A skill costs one line of description until it is needed.

Custom slash commands are now skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy and behave the same. Old command files keep working; new work should be skills, because only skills can carry supporting files.

How do you create a skill?

Make a folder under .claude/skills/ in the repo (or ~/.claude/skills/ for yourself) and put a SKILL.md in it. The frontmatter must start on line 1.

.claude/skills/webhook-change/SKILL.md

---
name: webhook-change
description: Use when adding or changing a payment webhook handler, its retries or its idempotency key.
paths: src/payments/**
---

1. Handlers are idempotent. Key on the provider's event id.
2. Retries go through src/lib/retry.ts. Five attempts, then dead-letter.
   Why: docs/decisions/0012-webhook-retries.md
3. Add a replay test in tests/webhooks/ before opening the PR.
   See checklist.md for the full review checklist.

The folder can hold more files. SKILL.md links to them, and Claude reads them only when the task needs them; scripts in the folder are run, not read. Anthropic's guidance is to keep SKILL.md under 500 lines and move detail into those files.

SKILL.md frontmatter fields that matter

Every field is optional. These are the ones that change behaviour:

FieldWhat it does
descriptionWhat the skill does and when to use it. Claude matches your request against it to decide whether to load the skill. Combined with when_to_use, capped at 1,536 characters in the listing.
when_to_useExtra trigger context and example requests, appended to the description.
pathsGlobs that restrict when the skill auto-loads, same format as path-scoped rules.
disable-model-invocationtrue means only you can run it, with /name. Use it for anything with side effects, like a deploy.
user-invocablefalse hides it from the / menu. Only Claude can load it.
allowed-toolsTools pre-approved for the turn that invokes the skill. The grant clears on your next message.
context: forkRuns the skill in a subagent with its own context, in the background by default. Pair with agent to pick the subagent type.
modelOverrides the session model while the skill runs.

How does Claude decide to use a skill?

Progressive disclosure, in three steps. Every skill's name and description sit in context on every turn, so Claude knows what exists. When your request matches a description, or you type the command, the rendered SKILL.md enters the conversation as a message and stays there for the rest of the session. Supporting files load only if the instructions send Claude to them.

Two consequences follow. The description is the whole trigger, so write it as the task it serves (“Use when adding or changing a payment webhook handler”), not as a title (“Webhooks”). And skills are not free: fifty descriptions are fifty lines in every prompt, whether or not any of them fire.

Where do skills live, and which one wins?

LocationPathWho gets it
Enterprisemanaged settings directoryEveryone on machines with the org deployment. Highest precedence
Personal~/.claude/skills/<name>/You, in every project on this machine
Project.claude/skills/<name>/Everyone who clones the repo
Nested<subdir>/.claude/skills/Sessions working in that part of a monorepo
Plugin<plugin>/skills/<name>/Anyone with the plugin enabled, as /plugin-name:skill-name

When two share a name, enterprise beats personal beats project. Plugin skills are namespaced and never shadowed. To share a skill with the team, commit it to .claude/skills/; to share it across repos, ship it in a plugin. Which of the .claude/ files to commit is covered in should you commit CLAUDE.md.

Why isn't my Claude Code skill triggering?

From the docs, in the order worth checking:

CauseFix
disable-model-invocation: trueOnly /name works. Remove it if Claude should pick the skill itself.
The description does not match the requestRewrite it as the task, put the key use case first, add when_to_use examples.
A paths glob matches no file in playCheck the glob against the files Claude is working on.
Hidden by skillOverrides or a permission ruleRun /skills to see what is visible, and /permissions for Skill(...) rules.
Frontmatter failed to parseThe skill still loads, with no fields set. Validate the YAML and check the log.

The deeper problem is the one no field fixes. In Vercel's Next.js evals the skill was never invoked in 56% of cases, and skills left to their default behaviour passed 53%, the same as no docs at all. A compressed docs index in AGENTS.md passed 100% (Vercel, January 2026). A skill is a bet that the model will notice it needs the skill. For anything that must happen every time, use a hook; the trade-offs are in the hooks guide and CLAUDE.md vs skills vs hooks.

Skills vs CLAUDE.md: what goes where?

Anthropic's own best practices draw the line: CLAUDE.md is for what applies broadly, and “for domain knowledge or workflows that are only relevant sometimes, use skills instead.” A good test is whether a new engineer would need the line on their first day for every task. If yes, CLAUDE.md. If only when touching payments, a skill with a paths glob. If it is a procedure you run on purpose, a skill with disable-model-invocation.

Where Harbor fits

Skills pile up the way CLAUDE.md lines do. Each one is cheap to add and nobody removes them, and every description is in every prompt. harbor context, the one Harbor command that needs no account and no network, reads the machine and prints the always-on budget per turn: the skills index, skill files that are not indexed, agent definitions, MCP tools and injected context, and who put each there. It also flags skill files with no description, which are the ones Claude cannot choose on its own.

npm install -g harborloop
harbor context

A skill is still a file somebody wrote. The decisions inside it were usually made in a pull request review or a Slack thread first, and they reach Claude Code only, not Cursor or Codex. Harbor reads those places, a person approves what becomes a fact (or a policy you set approves the routine ones), and every agent is served the facts that apply to the task. It counts, per fact, how often it was served against how often an answer cited it; a cite is evidence, not proof. See served vs cited.

Start with what you already carry. Run harbor context first; the CLI reference explains each line, and the quickstart takes about ten minutes.

Questions

What is a skill in Claude Code?

A skill is a folder with a SKILL.md file holding a name, a description and instructions. Claude sees every description on every turn and loads the full instructions only when a task matches or when you type /skill-name.

Where do Claude Code skills go?

Project skills go in .claude/skills/<name>/SKILL.md and are shared through git. Personal skills go in ~/.claude/skills/. Plugins can also ship skills, which run as /plugin-name:skill-name.

What is the difference between skills and slash commands?

Custom slash commands have been merged into skills. A .claude/commands/deploy.md file and a .claude/skills/deploy/SKILL.md both create /deploy, but only skills can carry supporting files.

Why is my Claude Code skill not triggering?

Check whether disable-model-invocation is set, whether the description matches the task, whether a paths glob matches the files in play, and whether skillOverrides or a permission rule hides it. Run /skills to see what Claude can see.

Should I use a skill or CLAUDE.md?

Use CLAUDE.md for what applies to every task and a skill for knowledge or workflows that matter only sometimes. For anything that must happen every time, use a hook, because a skill depends on the model choosing to load it.

harbor

Decide once. Every agent knows. One company brain for all the agents your team runs, built from work you already do and kept only while it is still true.

Product

  • How it works
  • Review
  • Your agents
  • Guardrails
  • What it counts
  • Pricing

Developers

  • Docs
  • Blog
  • CLI
  • MCP server
  • Served and cited
  • Environments

Company

  • Get started
  • Contact
  • Privacy Policy
  • Terms of Service
  • Data Processing Agreement
  • Refund Policy
© 2026 harbor·Product names and logos are trademarks of their respective owners.