How to set up Claude skills_
A working step-by-step for installing Claude skills in Claude Code — where files go, what the frontmatter needs, how invocation works, and the half-dozen things that quietly stop a skill from loading. Includes two complete example skills you can copy and adapt.
What this guide assumes
You have Claude Code installed and working. You have used it at least once. You know what a markdown file is and you are comfortable editing one in a terminal or editor. If you do not know what a Claude skill is yet, read skills vs MCPs first — the rest of this page assumes you already understand that a skill is packaged instructions loaded into the model's context, not code that runs.
Two facts you need before going further. First: skill format and discovery is Claude Code-specific. The patterns here will not drop into Cursor or Cline unchanged. Second: skills are plain text. They cannot read files, hit APIs, or run code on their own. If you want any of that, you also need an MCP server — the skill can tell the model to use one, but cannot be one.
Pick where the skill lives
Two options. Decide before you create the file.
Global skill — available in every project. Lives here:
~/.claude/skills/<skill-name>/SKILL.md Project skill — scoped to one project, shared with the team via git. Lives here:
<project-root>/.claude/skills/<skill-name>/SKILL.md Rule of thumb: personal preferences and cross-project habits go global. Team conventions, project context, and codebase-specific rules go in the project. Commit project skills to git so every teammate gets them on clone.
Create the skill directory and file
Each skill is a folder with a SKILL.md file inside. The folder name is the skill's identifier; the SKILL.md is the actual content. From your project root, for example:
mkdir -p .claude/skills/writing-prs
touch .claude/skills/writing-prs/SKILL.md
Two file-naming gotchas worth flagging now. The filename is SKILL.md, uppercase, exact. Lowercase skill.md will not be picked up. The directory name should match the skill identifier you put in the frontmatter — convention is kebab-case. Inconsistency between directory name and frontmatter name is the most common reason a skill silently fails to load.
Write the frontmatter
Every SKILL.md starts with a YAML frontmatter block — that is how Claude Code knows what the skill is called and when to consider invoking it. The minimum looks like this:
---
name: writing-prs
description: Use when drafting pull request descriptions, summaries, or commit messages — encodes team voice and required sections.
--- Two fields, both required, both load-bearing.
name — the identifier. Match it to the directory name. Kebab-case, no spaces.
description — the trigger text. This is what Claude reads to decide whether your skill is relevant to the current task. Write it as you would describe the skill to a coworker: "Use when…" or "Triggers on…" patterns work well. Specific descriptions trigger more reliably than vague ones — "drafting PRs and commit messages" beats "code stuff."
Watch the YAML syntax. The opening and closing --- must each be on their own line. No leading whitespace. No tab characters inside the block. If the frontmatter is malformed, the whole skill is ignored without warning.
Write the skill body
Below the frontmatter, write the actual instructions in plain markdown. There is no required structure — but skills that work well share a shape:
- One-paragraph summary of what the skill is for.
- Concrete rules — what to do, what not to do, what format to use.
- Examples — at least one good output, ideally one bad-then-good pair.
- Edge cases — when the rules do not apply.
Skills that ramble or read like blog posts get partially ignored. Skills that read like a coworker handing you a tight playbook get followed. Aim for the second.
Keep skills short — 50 to 300 lines is the sweet spot for most. If yours is getting longer, that is usually a sign it should be two skills instead of one.
Copy these, adapt to your team
Example 1: writing-prs
File: .claude/skills/writing-prs/SKILL.md
---
name: writing-prs
description: Use when drafting pull request descriptions, commit messages, or PR summaries. Encodes team voice and required structure.
---
# Writing pull requests
Use this skill whenever the user asks for a PR description, commit message,
or summary of changes.
## Required structure
Every PR description has three sections, in this order:
1. **What changed** — one or two sentences, plain English.
2. **Why** — the problem this solves or the reason for the change.
3. **Test plan** — checklist of what to verify before merging.
## Voice rules
- Second person ("your team"), not first person ("we").
- Active voice.
- No filler words: "simply," "just," "basically."
- No emoji.
- No marketing language: "robust," "powerful," "seamless."
## Example
Bad:
> This PR refactors the auth module to be more robust and improves
> performance significantly.
Good:
> **What changed**
> Replaced the session lookup in `getCurrentUser()` with a single
> indexed query. Removed the in-memory cache that was no longer needed.
>
> **Why**
> The cache was a 2024 workaround for a slow query. The slow query is
> now fixed (issue #482), so the cache adds complexity without value.
>
> **Test plan**
> - [ ] Run integration tests
> - [ ] Verify session works for fresh login
> - [ ] Verify session works after server restart Example 2: querying-customers-db
File: .claude/skills/querying-customers-db/SKILL.md — pairs with a Postgres MCP server.
---
name: querying-customers-db
description: Use when querying the customers database via the Postgres MCP server. Encodes table conventions, safe query patterns, and PII rules.
---
# Querying the customers database
Use this skill any time you query the customers Postgres database
through the connected MCP server.
## Tables you should know
- `customers` — primary, partitioned by `region`. Always filter by
`region` to avoid full scans.
- `customer_pii` — contains raw email and phone. Read-only. Only query
when the user explicitly asks for PII fields.
- `subscriptions` — joined to customers via `customer_id`.
## Always
- Filter by `created_at` when scanning recent data — never `SELECT *`
without a date filter.
- Use `LIMIT` on exploratory queries; the customers table is large.
- Quote identifiers if they contain capitals or underscores.
## Never
- Run `UPDATE` or `DELETE` against this database. It is read-only.
- Join `customer_pii` to `customers` and return raw email in a CSV
export — log the request and ask the user to confirm.
## Pagination pattern
For paginated reads, use keyset pagination on `id`:
```sql
SELECT id, name, created_at
FROM customers
WHERE region = 'us-east'
AND id > $last_id
ORDER BY id
LIMIT 100;
```
Avoid OFFSET on this table — it gets slow past page 5. The five things that quietly break skills
1. Malformed frontmatter
Missing closing ---, tab characters inside the YAML, smart quotes instead of regular quotes, a colon in the description without quoting the value. Any of these and the skill disappears silently. Open the file, paste the frontmatter into a YAML validator, fix whatever is wrong.
2. Wrong filename or directory
The file must be SKILL.md — uppercase, exact. The directory must match the name field in the frontmatter. writing_prs in the directory and writing-prs in the frontmatter? Will not load. Pick one convention and stick to it.
3. Description too vague to trigger
If your description reads "general code stuff" or "helps with coding," it will never auto-trigger reliably because every task is "code stuff." Be specific about the trigger conditions: "Use when drafting PRs," "Triggers on database queries to the customers table," "Use whenever writing TypeScript types for API responses."
4. Two skills with overlapping descriptions
If you have a "writing-prs" skill and a "writing-commits" skill with overlapping descriptions, Claude may pick the wrong one or load both inconsistently. Either merge them or make the descriptions sharply distinct.
5. Forgetting to restart Claude Code
Skills are discovered at session start. If you add a new skill mid-session, Claude Code will not see it until the next session. Restart and try again.
Common questions about skills setup
My skill is not loading. What did I miss?
+
The usual suspect is the frontmatter — Claude Code reads the YAML block at the top of SKILL.md to decide when to auto-invoke a skill. If the frontmatter is malformed (missing closing ---, wrong field names, broken YAML), the skill will be silently ignored. Open the file, check that --- is on its own line at the very top and bottom of the frontmatter block, and validate the YAML. Second most common: the file is named skill.md instead of SKILL.md, or the directory does not match the skill name in the frontmatter. Restart Claude Code after fixing.
Where do skills actually live on disk?
+
Two places. Global skills (available across every project) live in ~/.claude/skills/<skill-name>/SKILL.md. Project-scoped skills live in .claude/skills/<skill-name>/SKILL.md inside your project directory. Project skills only load when you run Claude Code from that project. Most teams put shareable team skills in the project (so they get committed to git) and personal preferences in the global directory.
How does Claude decide when to use a skill?
+
Two paths. Auto-discovery: Claude reads the description field in each skill's frontmatter at session start. When you ask something that semantically matches a description, Claude considers invoking that skill. Manual: you can invoke a skill explicitly with the Skill tool — useful if you want guaranteed behavior. For skills that should always be active (project conventions, voice rules), write the description to be broad enough that any task triggers it.
What is the difference between a skill and an agent or subagent?
+
A skill is instructions loaded into the model's context. An agent (or subagent) is a separate invocation of the model with its own context, typically for a contained sub-task. Skills modify how the current model thinks. Subagents spawn fresh model calls. You can have a skill that instructs the model to delegate certain work to subagents — but the skill itself is just text, while the subagent is a real model call.
Can I share skills between team members?
+
Yes — put them in .claude/skills/ inside your project repo and commit them to git. Every team member who clones the repo gets the skills automatically when they open Claude Code there. This is the recommended pattern for anything team-specific (conventions, codebase knowledge, workflow rules). Keep global skills (~/.claude/skills/) for personal preferences that should not be shared.
Will skills work in Cursor, Cline, or other tools?
+
Not directly. Claude skills as defined here are a Claude Code concept — the file format, the discovery mechanism, the auto-invocation are all specific to that harness. Other tools have similar concepts: Cursor has cursorrules, Cline has custom instructions, Zed has its own format. The principle (packaged instructions for the model) transfers; the file format does not. If you maintain skills, expect to also maintain parallel configs for any other AI tool your team uses — unless and until a cross-tool standard emerges.
How long should a skill be?
+
Short. The good skills I have seen and written are usually 50–300 lines of markdown. Long skills tend to drift — half of them are useful, half are noise the model ignores. If a skill is getting long, split it: one skill for the workflow, one for the conventions, one for the gotchas. Smaller, more focused skills also auto-trigger more reliably because the description field can be specific.
Want this dialed in by someone who has set up dozens?
Setting up one skill is straightforward. Setting up the right twenty for your team's codebase, conventions, and workflow — and making sure they all trigger when they should and stay out of the way when they should not — is the work. Tell the duck what your team does today. You will leave with a plan, not another tab to read.