Issue 00 · Autumn 2026日本語 · RSS
AgentKoji

How to Create Claude Code Skills (SKILL.md)

A skill's description is cut at 1,536 characters in the skill listing. Where SKILL.md goes, which frontmatter keys exist, and how to write and invoke a skill.

TL;DR

  • A skill is a runbook whose body loads only when invoked, unlike CLAUDE.md, which is read every session.
  • Custom slash commands are merged into skills: .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy; use the directory form for new work.
  • When names collide, enterprise beats personal and personal beats project, and a skill beats a .claude/commands/ file with the same name.

A skill is a runbook that Claude loads only when it needs it. CLAUDE.md is read at the start of every session; a skill’s body is read only when the skill is invoked. This guide covers where skills live, a minimal SKILL.md, how to write the description, how to invoke a skill, and when to use CLAUDE.md, skills or hooks instead. In our test environment (macOS, Claude Code 2.1.304, on 2026-10-20), we put a skill into a dummy todo app and validated its format. We did not run a session that calls the model.

What a skill is

The docs suggest creating a skill when you keep pasting the same instructions, checklist or multi-step procedure into chat, or when part of CLAUDE.md has turned from a fact into a procedure. A skill’s body loads only when it’s used, so long reference material costs almost nothing until then.

Custom slash commands have been merged into skills. .claude/commands/deploy.md and .claude/skills/deploy/SKILL.md both create /deploy and work the same way. Existing .claude/commands/ files keep working. For new work, use the directory form, which can also hold supporting files.

Source: https://code.claude.com/docs/en/skills (checked 2026-10-20)

Where skills live

LocationPathLoads in
Personal~/.claude/skills/<name>/SKILL.mdAll your projects on this machine
Project.claude/skills/<name>/SKILL.mdSessions in this repository; commit it to share with your team
Plugin<plugin>/skills/<name>/SKILL.mdWherever the plugin is enabled, as /plugin-name:skill-name
Enterprise.claude/skills/ in the managed settings directoryEvery user on machines your organization deploys it to

When two skills share a name, enterprise wins over personal, and personal wins over project. With deploy in both ~/.claude/skills/ and the project, /deploy runs the personal one. If a skill and a .claude/commands/ file share a name, the skill wins.

Source: https://code.claude.com/docs/en/skills (checked 2026-10-20)

A minimal SKILL.md

Here is a release runbook for a dummy todo app, saved as .claude/skills/release/SKILL.md:

---
name: release
description: Cut a release of the todo app. Use when the user asks to release, tag a version, or publish the changelog. Do not use for hotfix deploys or database migrations.
argument-hint: "[version]"
disable-model-invocation: true
allowed-tools: Bash(npm test) Bash(npm run build) Bash(git tag *)
---

Release version $ARGUMENTS of the todo app.

1. Run `npm test`. Stop and report if any test fails.
2. Run `npm run build`.
3. Add a `## $ARGUMENTS` section to CHANGELOG.md from the commits since the last tag.
4. Create the tag with `git tag v$ARGUMENTS`. Do not push.
5. Report the tag name and the changelog section.

The main frontmatter keys are below. None is required; the docs recommend at least description.

KeyWhat it does
nameName shown in the / menu. Defaults to the directory name
descriptionWhat the skill does and when to use it. Claude reads it to decide whether to load the skill
when_to_useExtra trigger context, appended to description
argument-hintHint shown during autocomplete, such as [version]
argumentsNamed arguments for $name placeholders
disable-model-invocationtrue stops Claude from loading the skill on its own; you run it with /name
user-invocablefalse hides it from the / menu so only Claude uses it
allowed-toolsTools Claude can use without asking during the turn that invokes the skill
disallowed-toolsTools removed while the skill is active

Source: https://code.claude.com/docs/en/skills (checked 2026-10-20)

Set disable-model-invocation: true on anything with side effects, like a release, so Claude doesn’t start it unprompted. allowed-tools does not restrict which tools exist. It only skips the permission prompt for that turn, and the grant clears when you send your next message.

Validate the format

claude plugin validate checks a skills directory without starting a session (v2.1.233 or later). The example above passed:

$ claude plugin validate .claude/skills
Validating components in: <project>/.claude/skills

✔ Validation passed

We added a skill with an unclosed quote in its frontmatter:

✘ Found 1 error:

  ❯ frontmatter: YAML frontmatter failed to parse: YAML Parse error: Unexpected character. At runtime this skill loads with empty metadata (all frontmatter fields silently dropped).

The validator did not catch a misspelled key. A skill with disable-model-invokation: true returned Validation passed, even with --strict. The docs say unknown keys are ignored without an error, so copy key names from the table.

Writing the description

Describe when to use the skill, not what it is. Claude reads the description to decide whether to load the skill, and the docs recommend including the words users would naturally say.

We follow two rules when we write one. First, name the cases where the skill should not be used. In the example, that’s “hotfix deploys or database migrations”. Second, describe when each tool is used, not just which tools exist.

In the skill listing, description and when_to_use together are cut at 1,536 characters, so put the main use first. For trimming what loads into every session, see Trim Your CLAUDE.md.

Source: https://code.claude.com/docs/en/skills (checked 2026-10-20)

Invoking a skill

By default, both you and Claude can invoke a skill.

With disable-model-invocation: true, the description stays out of context, and the body loads only when you invoke it. If Claude doesn’t use a skill, the docs suggest asking What skills are available? to check that it’s listed.

Source: https://code.claude.com/docs/en/skills (checked 2026-10-20)

We did not test automatic loading or /release in a live session (not run).

CLAUDE.md, skills or hooks

ContentWhereWhy
Facts needed every session (build commands, what each directory is for)CLAUDE.mdAlways read at session start
Multi-step procedures (releases, migrations)SkillThe body loads only when used
Rules that must always hold (never read secret files)HooksRun every time, whether or not Claude follows the skill

The docs also say that when Claude stops following a rule from a skill partway through, a rule that must hold every time belongs in a hook. See Claude Code Hooks in Practice.

Summary