Skills (slash commands) let you package reusable prompts that standardize how AI agents approach recurring tasks. Instead of retyping the same detailed instructions every time, you define them once and invoke them with a command.
Figure: ... I know Kung Fu š„
A skill is a markdown file containing a prompt that gets injected into the AI agent's context when invoked. Think of skills like reusable prompt templates - they guide the agent's behavior for a specific task without needing access to external systems (unlike MCP servers).
---name: security-reviewdescription: Review code for security, performance, and standards compliance---Review the code changes in the current diff for:- Security vulnerabilities (injection, auth issues, data exposure)- Performance problems (N+1 queries, unnecessary allocations)- Adherence to our team's coding standardsFor each issue found:1. Reference the specific file and line number2. Explain why it's a problem3. Suggest a concrete fix
ā Figure: Good example - A SKILL.md file with YAML frontmatter (between --- markers) and markdown instructions
To invoke this skill, type /security-review in Claude Code, @security-review in GitHub Copilot, or simply ask a question that matches the skill's description and the agent will load it automatically.
For connecting to external systems like databases or APIs, use MCP servers instead.
You don't always need to write skills from scratch. Trusted providers like Anthropic publish pre-built skills you can install. For example, Anthropic's official skills repository includes document skills, creative design skills, and development utilities.
The best way to discover and install skills is skills.sh - Vercel's open agent skills ecosystem. It's a registry of community and official skills plus a CLI that installs a skill into the right location for whichever agent you use (Claude Code, GitHub Copilot, Cursor, Codex, and 70+ others) - no per-agent setup required:
npx skills add anthropics/skills --skill frontend-design
If you're using Claude Code only, you can alternatively install via the plugin system:
/plugin marketplace add anthropics/skills/plugin install document-skills@anthropic-agent-skills
Consider creating a skill when you are:
User: Review this code for security vulnerabilities, performance issues, adherence to our team's coding standards, and test coverage gaps. Provide actionable feedback with specific line references.
Agent: ā Code review complete.
(1 day later)
User: Review this code for security vulnerabilities, performance issues, adherence to our team's coding standards, and test coverage gaps. Provide actionable feedback with specific line references.
Agent: ā Code review complete.
ā Figure: Bad example - Repeating the same detailed review prompt every time is tedious and error-prone
User: /security-review
Agent: ā Code review complete.
ā Figure: Good example - A skill encapsulates the review instructions - one command, consistent results every time
You should create a repository which acts as the source of truth for all general-purpose skills. Doing so allows developers to store and share skills safely and securely. Skills that are updated/introduced should go through a review process to ensure that no safety issues are being introduced.
Project-specific skills should be stored within their project repositories.
Project-level skills (committed to the repo) are one of the most effective ways to standardize workflows across a team:
/code-review for a code review" or "Use /deploy to deploy to staging")Skills are prompt injections by design - they instruct the AI to behave in a specific way. A malicious skill could instruct the agent to run destructive commands, exfiltrate data, or bypass safety checks.
To share skills beyond your team, publish them to skills.sh. There's no submission process - push a public GitHub repository containing your SKILL.md files and anyone can install them with one command, regardless of which agent they use:
npx skills add your-org/your-skills-repo
This beats maintaining separate install instructions for Claude Code, Copilot, Cursor, and every other agent - the skills CLI puts the skill in the right place for each one.
If you installed a skill via npx skills add, the CLI already placed it correctly for your agent - the locations below are for writing your own skills manually.
Create a SKILL.md file inside a named directory under .claude/skills/:
.claude/āāā skills/āāā security-review/ā āāā SKILL.md ā invoked with /security-reviewāāā commit/ā āāā SKILL.md ā invoked with /commitāāā plan/āāā SKILL.md ā invoked with /plan
You can also create personal skills at ~/.claude/skills/ that are available across all projects.
Create markdown files in your project's .github/copilot/ directory to define custom agents:
.github/āāā copilot/āāā review.md ā invoked with @security-reviewāāā plan.md ā invoked with @plan
Create a SKILL.md file inside a named directory under .opencode/skills/ (OpenCode also discovers skills from .claude/skills/):
.opencode/āāā skills/āāā security-review/ā āāā SKILL.md ā invoked as a slash command or loaded by the agentāāā plan/āāā SKILL.md
You can also create personal skills at ~/.config/opencode/skills/ that are available across all projects.
A good skill is specific about what the agent should do, how it should structure its output, and what it should avoid.
Review the code and give feedback.
ā Figure: Bad example - Too vague - the agent has no guidance on what to check or how to structure its response
---name: code-reviewdescription: Review code for security, performance, standards, and test coverageallowed-tools: Read, Grep, Glob---Review the code changes in the current diff for:- Security vulnerabilities (injection, auth issues, data exposure)- Performance problems (N+1 queries, unnecessary allocations, missing indexes)- Adherence to our team's coding standards (which can be found in STANDARDS.md)- Test coverage gapsFor each issue found:1. Reference the specific file and line number2. Explain why it's a problem3. Suggest a concrete fixIf no issues are found in a category, skip it ā do notlist categories with "no issues found."
ā Figure: Good example - Specific checks, clear output format, and explicit instructions on what to skip
The description is not documentation. It is the text the agent reads to decide whether to load the skill at all. A skill that is installed but never fires is wasted, and a skill that fires on the wrong request is worse.
Matching is semantic, not a string comparison, so the agent will recognise paraphrases. It still needs to know the intent. Write the description in three parts: what the skill does, examples of what a user says when they want it, and any scope guard. Then test it with a few different phrasings and adjust.
description: Helps with sprint reviews
ā Figure: Bad example - Too broad to separate this skill from a retro summary, a sprint report, or a planning session
description: Prepare draft emails for a Sprint Review, Retro, and Planning meeting.Trigger when the user says "prepare sprint review", "draft sprint emails","sprint review prep", or asks to get ready for the sprint ceremony.Accepts an optional sprint number and auto-detects the board from the repo.Drafts only - never sends email.
ā Figure: Good example - What it does, example phrases, what it accepts, and what it will never do
Some skills should only run when a person asks for them by name, for example anything that pushes, sends, bills, or deletes. Say so in the description, and in Claude Code set disable-model-invocation: true so the agent cannot load the skill on its own. Other tools ignore that field. OpenCode, for example, reads only its own frontmatter fields, so there the guard has to come from the agent's tool permissions rather than the skill file.
A skill that runs to 600 lines is loaded into the context window in full every time it triggers. Keep the SKILL.md to the workflow, roughly 100 lines, and put the long material beside it:
skills/āāā timesheets/āāā SKILL.md ā the workflow, read every timeāāā references/ā āāā source-gathering.md ā read only when the step needs itā āāā gotchas.mdāāā scripts/āāā scan_activity.py ā run, not read
Tell the agent in SKILL.md which reference to open at which step. The agent pays for the detail only when it needs it.
Tips for writing skills:
$ARGUMENTS or similar placeholders so users can pass context when invoking the skillHere are some common properties to include, you can view the full spec here: https://agentskills.io/specification#frontmatter-required.
| Property | Description |
name | Display name for the skill (defaults to the directory name) |
description | What the skill does - the agent uses this to decide when to load the skill automatically |
allowed-tools | Restricts which tools the agent can use (e.g. Read, Grep, Glob for a read-only skill) |
disable-model-invocation | Set to true to prevent the agent from loading the skill automatically (manual-only) |
user-invocable | Set to false to hide from the / menu (agent-only background knowledge) |
context | Set to fork to run the skill in an isolated subagent |
argument-hint | Hint shown during autocomplete (e.g. [issue-number]) |
Where you store a skill determines who can use it:
| Scope | Location | Applies to |
| Personal | ~/.claude/skills/ or ~/.config/opencode/skills/ | Across all projects, only your machine |
| Project | .claude/skills/ committed to the repository | Project-scoped, everyone with access to the repository |
Personal skills are great for your own preferences and workflows (e.g. your preferred commit message format). Project skills are committed to version control so the whole team benefits. When a personal and project skill share the same name, project-level skills take precedence.