How to Create a Claude Skill: SKILL.md Template and Five Rules

Build one skill end to end: the folder, the SKILL.md frontmatter, a description that makes it trigger, bundled scripts, testing that it fires when it should and not when it should not, and sharing it in Claude Code and the Claude apps.

7 min read

To create a Claude skill, make a folder named after the job, put a SKILL.md file in it with a short YAML header (a name and a description that says what the skill does and when to use it), write the steps underneath in plain Markdown, and add any scripts or reference files the job needs beside it. In Claude Code the folder goes in ~/.claude/skills/ for you or .claude/skills/ in a repository for your team; in the Claude apps you zip it and upload it. Then test it twice: once with a request that should trigger it, once with one that should not. This article builds one skill from an empty folder to a shared one. For finished project-management skills to copy, see Claude skills for project management; if you are still deciding whether you need a skill or an MCP server, read MCP vs Claude skills first.

Pick one job

A good first skill is something you have typed into a chat three times: the same checklist, the same format, the same “and remember to…”. The example here writes a changelog entry for the staged changes in a repository, in the team’s house style. It is small, it runs often, and it is easy to tell whether the result is right. Anything that is a fact Claude needs in every session belongs in CLAUDE.md instead; a skill is for a procedure, or reference material Claude needs only sometimes.

Make the folder

One skill, laid out
.claude/skills/changelog-entry/
  SKILL.md            # required: frontmatter + instructions
  style.md            # house style and past examples, read when needed
  scripts/
    check_entry.py    # run by Claude; only its output enters the context

Where the folder lives decides who gets it. The Claude Code skills documentation (opens in a new tab) lists the places a skill can load from:

  • Personal: ~/.claude/skills/<name>/SKILL.md, in every project on your machine.
  • Project: .claude/skills/<name>/SKILL.md, in sessions in that repository. Commit it and your team has it too.
  • Nested: a .claude/skills/ folder inside a subdirectory, for one package of a monorepo. It loads once Claude works on files there.
  • Plugin: <plugin>/skills/<name>/SKILL.md, wherever the plugin is enabled, run as /plugin-name:skill-name.
  • Enterprise: deployed by your organisation through managed settings, on every machine it reaches.

An older single-file command in .claude/commands/ still works and creates the same /name, but a skill folder can carry supporting files, so use one for anything new.

The SKILL.md template

.claude/skills/changelog-entry/SKILL.md
---
name: changelog-entry
description: Writes a CHANGELOG.md entry for the staged changes in the team's house
  style. Use when the user asks for a changelog entry, a release note line, or what
  to put in the changelog for a commit.
---

# Changelog entry

1. Run `git diff --cached --stat`, then read the diff of any file whose
   behaviour changed. Ignore formatting-only changes.
2. Choose one section: Added, Changed, Fixed or Removed.
3. Write one line in the present tense, under 100 characters, describing what a
   user notices, not which file changed.
4. Run `python ${CLAUDE_SKILL_DIR}/scripts/check_entry.py "<line>"` and fix
   anything it reports.
5. Show the line and its section. Do not edit CHANGELOG.md unless asked.

For tone and past examples, read [style.md](style.md).

The frontmatter must open on the file’s first line, between --- markers. Claude Code treats every field as optional and recommends description; without a name the folder name becomes the command, so this skill runs as /changelog-entry. The Claude apps and the API are stricter: name and description are both required, the name is at most 64 characters of lowercase letters, numbers and hyphens, and it may not contain “claude” or “anthropic”. Write to the stricter rules and the same folder works everywhere.

The same goes for extra fields. Claude Code accepts many, such as disable-model-invocation, allowed-tools, paths and context, but an upload to the Claude apps accepts only the fields in the Agent Skills specification (opens in a new tab) (name, description, license, compatibility, metadata and allowed-tools) and fails with an “unexpected key” error on anything else. ${CLAUDE_SKILL_DIR} in the body is a Claude Code substitution for the skill’s own folder, so the script is found whatever directory the session started in.

Write a description that makes it trigger

Until a skill is used, its name and description are all Claude sees of it. Claude matches your request against that text to decide whether to load the rest, so the description does two jobs: what the skill does, and when to use it, in the words people actually type. Anthropic’s skill authoring best practices (opens in a new tab) add a third rule: write it in the third person (“Writes a changelog entry…”), never “I can help you…”, because the description is placed in the system prompt.

  • Put the main use case first. In Claude Code, the description plus any when_to_use text is cut at 1,536 characters in the skill listing, and with many skills installed some descriptions are dropped to fit a budget.
  • For a skill you will upload to the Claude apps, keep it short: the help article on creating custom skills gives 200 characters as the maximum there.
  • Avoid “helps with documents”. Name the file types, the commands, the phrases: “changelog”, “release note”, “what changed”.

Bundle scripts and reference files

Anything deterministic, such as validating a format, counting, or converting a file, is better done by a script than by the model. Put it in the skill folder and tell Claude when to run it; only the script’s output enters the conversation, not its code. Reference material works the same way: link style.md from SKILL.md and say what is in it, and Claude reads it only when the task needs it. Keep SKILL.md itself under 500 lines, and keep references one level deep so Claude does not have to follow a chain of files to find the rule it needs.

In Claude Code, running the script will normally ask for permission. If you want it to run without a prompt, add allowed-tools: Bash(python ${CLAUDE_SKILL_DIR}/scripts/check_entry.py *) to the frontmatter. The grant applies only for the turn that invoked the skill, and it does not restrict other tools.

Test that it triggers, and that it does not

  1. Start a fresh session, so nothing from writing the skill is still in context. Ask “What skills are available?” and check it is listed.
  2. Ask something it should catch without naming it: “what should go in the changelog for this?”.
  3. Ask something close that it should ignore: “what is a changelog?”. If it fires, narrow the description.
  4. Run it directly with /changelog-entry to test the steps on their own.
  5. If it never triggers, add the words people use to the description. If /changelog-entry works but automatic loading does not, the YAML probably failed to parse: Claude Code then loads the body with no metadata. Start with claude --debug to see the error, or run claude plugin validate .claude/skills on recent versions.

Claude Code picks up edits to SKILL.md in ~/.claude/skills/ and the project’s .claude/skills/ during the session, without a restart. To measure a skill rather than eyeball it, the skill-creator plugin runs your test prompts with and without the skill and compares the results.

In Claude Code
/plugin install skill-creator@claude-plugins-official

Share it

  • In a repository: commit .claude/skills/changelog-entry/. Everyone who opens the repository has it, and changes to it are reviewed like code.
  • Across repositories: put it in a plugin, which is the packaging layer for skills, subagents and hooks. Plugins, skills and subagents compared covers when that is worth it.
  • In the Claude apps: zip the folder so the folder itself is the root of the zip, then go to Customize, Skills, the plus button, Create skill, Upload a skill. Anthropic’s guide to using skills in Claude (opens in a new tab) notes that skills need code execution turned on, and that on Team and Enterprise plans you can share a skill with named colleagues or publish it to the organisation.

The two worlds meet in one direction. When you sign in to Claude Code with a claude.ai account on a recent version, the skills enabled for that account are downloaded into ~/.claude/skills/synced/ and load in your terminal sessions. A skill that lives only in your local ~/.claude/skills/ does not travel the other way; upload it if you want it in the apps.

Five rules

  1. One job per skill. A skill that writes changelogs and also bumps versions and tags releases will trigger at the wrong moments and be hard to test.
  2. The description is the trigger. What it does, when to use it, third person, the words people say, main use first.
  3. Anything with side effects gets disable-model-invocation: true. A deploy or a publish should start when you type /deploy, not when Claude decides the code looks ready.
  4. Short body, detail in files, scripts for the exact parts. Once loaded, the body stays in the conversation, so every line of it costs something on every later turn.
  5. Read a skill before you install it. A skill can tell Claude to run code, and in Claude Code a project skill’s allowed-tools applies even in a folder you have never trusted. Check every bundled file.

What a skill should not hold

A skill is how a job is done. It is the wrong place for what is still to do: a list of tasks written into a skill or a markdown file is stale the day after, and nobody else can see what was ticked or by whom. Keep the list on a board and let the skill use it. With fenbs connected over MCP, a skill’s steps can call fenbs_search, fenbs_create_item and fenbs_comment by name, and the board still decides what the connection may do and records each change under the assistant’s name. The everyday rhythm is in a task-tracking workflow for Claude Code.

Related

Connect a board for your skills to use: Claude Code integration or Claude. Where skills sit in a repository alongside settings and subagents: Claude Code project structure. What the board shares with every assistant: AI context.

Questions people ask.

What is the minimum a Claude skill needs?

A folder containing a SKILL.md file with YAML frontmatter and instructions. Claude Code only recommends a description, but the Claude apps and the API require both name and description, so include both and the same folder works everywhere.

Where do I put a skill in Claude Code?

In ~/.claude/skills/<name>/SKILL.md for every project on your machine, or in .claude/skills/<name>/SKILL.md inside a repository so everyone who works there gets it. Plugins and managed settings can also deliver skills.

Why does my skill not trigger?

Usually the description does not contain the words you used. Add the phrases people type, put the main use first, and check the frontmatter parses: if it does not, the skill still runs as /name but Claude cannot match it automatically.

Can I use the same skill in Claude Code and the Claude app?

Yes, if the frontmatter uses only the fields the Agent Skills specification allows. Zip the folder and upload it in the app. If you sign in to Claude Code with the same claude.ai account on a recent version, the skills enabled there also load in your terminal sessions.

Start with one thing.

There is nothing to set up first. Write one line and you’ve started.