Skills
Teach Claude a routine once.
A SKILL.md with steps, scripts, and reference files. Runs when you call it, or when Claude decides it's relevant.
Reach for it when You've typed the same instructions three times.
/deploy stagingThe commands you'll use every day, plus the five ways to extend Claude Code and when to reach for each. Every claim links to the official docs.
Checked against the official Claude Code docs on October 18, 2026.
Five ways to extend Claude Code, and the exact moment in a session where each one kicks in.
Where each one plugs in
Teach Claude a routine once.
A SKILL.md with steps, scripts, and reference files. Runs when you call it, or when Claude decides it's relevant.
Reach for it when You've typed the same instructions three times.
/deploy stagingHand off the messy side quest.
A helper with its own context window, tools, and model. It does the digging and hands back a summary.
Reach for it when A task would bury your conversation in logs or search results.
@test-runner run the suite, tell me what brokeRules that run every single time.
Your script fires on a lifecycle event: before a tool call, after an edit, when Claude stops. Exit code 2 blocks.
Reach for it when It has to happen whether or not Claude remembers.
PreToolUse β block git push --forcePlug Claude into everything else.
Servers that add new tools: GitHub, Sentry, Notion, your database, a real browser.
Reach for it when Claude needs to reach a system outside your repo.
claude mcp add --transport http sentry https://mcp.sentry.dev/mcpShip the whole setup as one install.
Skills, agents, hooks, and MCP servers bundled together, versioned, and installable from a marketplace.
Reach for it when You want your team's setup in every repo, or someone else's in yours.
/plugin install commit-commands@claude-plugins-officialLooking for custom slash commands? They've been merged into skills. Old .claude/commands/ files still work. docs β
Pick what you're trying to do. The wizard tells you which mechanism to reach for.
Reach for
Skills
Create .claude/skills/<name>/SKILL.md and commit it. Everyone on the repo gets /name.
Reach for
Subagents
Define one in .claude/agents/. It works in its own context window and hands back only a summary.
Reach for
Hooks
Add a PreToolUse hook in .claude/settings.json. Exit code 2 blocks the call and tells Claude why.
Reach for
MCP Servers
Run claude mcp add, or commit a .mcp.json at the project root so the whole team gets it.
Reach for
Hooks, not CLAUDE.md
The docs put it plainly: an instruction in CLAUDE.md or a skill is a request, a PreToolUse hook that blocks the action is enforcement.
Reach for
Skills + CLAUDE.md
Put always-on conventions in CLAUDE.md, and longer playbooks in skills that only load when relevant.
Reach for
Plugins
Install one from a marketplace. Anthropic's official marketplace is added the first time you start Claude Code.
Reach for
Plugins
Package your skills, agents, hooks, and MCP config as a plugin and publish it through your own marketplace.
Most of your time in Claude Code isn't spent writing skills or hooks. It's spent steering a session. These are the commands and keys that do the most work, grouped by what you're trying to do.
Manage context
/contextSee what's filling the window, as a colored grid/compact [focus]Summarize so far to free up room/clearStart fresh. The old chat stays in /resume/btw <question>Side question that doesn't join the chatUndo and go back
/rewindRoll back the chat, the code, or both/resumePick up a previous sessionSet up
/initGenerate a starter CLAUDE.md/memoryEdit CLAUDE.md, toggle auto memory/permissionsAllow, ask, and deny rules/modelSwitch model. Arrows change effortCheck your work
/reviewReview the diff, a branch, or a PR/doctorDiagnose and fix your setup/usageCost and plan limitsSee what loaded
/skillsSkills, with token cost per skill/hooksHooks that are actually configured/mcpServer status and OAuth/pluginInstalled plugins and marketplacesSources Commands reference β Interactive mode and shortcuts β Checkpointing β
Plain markdown that Claude reads at the start of every session. Conventions, build commands, and 'never do this' notes live here. It isn't an extension mechanism, but every other mechanism on this page works better when this file is good.
~/.claude/CLAUDE.md
π€ Just you
You, in every projectyour-repo/CLAUDE.md
π₯ Team
The team, through gitCLAUDE.local.md
π€ Just you
You, in this repo. Add it to .gitignore.claude/rules/api.md
π₯ Team
The team, only when matching files are openAll locations, including managed policy β
Under 200 lines: what the docs recommend
Longer: more context per turn, and Claude follows it less reliably
Writing effective instructions β
---
paths:
- "src/api/**/*.ts"
---
# API conventions
- Every endpoint validates input with zod before touching the database
- Return errors as { error: { code, message } }, never a bare string
- Every query on a tenant table filters by tenant_id
Sources Memory and CLAUDE.md docs β Path-specific rules β
A skill is a folder with a SKILL.md file. You run it with /skill-name, and Claude can also load it on its own when the description matches what you're doing.
Config.claude/skills/<name>/SKILL.md (project) Β· ~/.claude/skills/<name>/SKILL.md (personal)
Custom commands have been merged into skills. A file at .claude/commands/deploy.md and a skill at .claude/skills/deploy/SKILL.md both create /deploy. Old command files keep working, but write new ones as skills so you get supporting files and invocation control. docs β
namedescriptionallowed-toolsdisable-model-invocationuser-invocableargument-hintcontextBoth of you
(default)Description sits in context every turn
Use for Most skills
Only you
disable-model-invocation: trueDescription stays out of context
Use for /deploy, /commit, anything with side effects
Only Claude
user-invocable: falseDescription sits in context every turn
Use for Background knowledge, like how a legacy system works
---
name: deploy
description: Deploy the current branch to staging or production
argument-hint: [staging|production]
disable-model-invocation: true
allowed-tools: Bash(npm run *) Bash(npm test) Read
---
Current branch: !`git branch --show-current`
Deploy the app to $ARGUMENTS (default: staging):
1. Run tests: `npm test`
2. Build: `npm run build`
3. Deploy: `npm run deploy -- --env $ARGUMENTS`
4. Verify the deployment health check passes
5. Report the deployed URL back to me
Sources Skills docs β Frontmatter reference β anthropics/skills examples β
Specialized assistants that do a side task in their own context window and return only a summary. Define one when you keep spawning the same kind of worker with the same instructions.
Config.claude/agents/*.md (project) Β· ~/.claude/agents/*.md (personal)
namedescriptiontoolsdisallowedToolsmodelpermissionModeDo it yourself
Your conversation
92% full of stuff you'll never look at again
Delegate to a subagent
Your conversation
35% full. Just the answer came back
test-runner (its own window)
Thrown away when it finishes
Illustrative. The point is the shape, not the exact numbers. docs β
Three layers below you by default. At the limit the Agent tool is withheld, so the last one does the work itself. Change it with CLAUDE_CODE_MAX_SUBAGENT_SPAWN_DEPTH. docs β
---
name: test-runner
description: Run the test suite and report failures with suggested fixes. Use after code changes.
tools: Bash, Read, Grep, Glob
model: sonnet
---
You are a test-running specialist. When invoked:
1. Identify the test framework in use (check package.json, pytest.ini, etc.)
2. Run the full test suite
3. For any failures, read the failing test and the source code
4. Report: which tests failed, why, and a suggested fix
5. Never modify source code. Only report findings.
Handlers that fire automatically on lifecycle events. Use them for guardrails, formatting, logging, and notifications. A hook can be a shell command, an HTTP call, an MCP tool, or a prompt for a model to evaluate.
Config.claude/settings.json β hooks (also ~/.claude/settings.json, .claude/settings.local.json, plugins)
exit 0
Go
Success. The action runs. JSON on stdout can still steer it.
exit 2
Blocked
The action is stopped, and your stderr goes to Claude as the reason.
exit 1, 3, β¦
Error, but it runs anyway
Logged as a hook error and the action still happens. A hook that exits 1 to block does nothing.
Claude Code has over 30 hook events. These are the ones you'll reach for first.
| Event | When it fires | Blocking |
|---|---|---|
SessionStart | Session starts or resumes. Stdout is added to Claude's context, so it's good for injecting state. | π Watch only |
UserPromptSubmit | Fires when you submit a prompt, before Claude sees it. | π Can block |
PreToolUse | Fires before a tool runs. Exit 2 blocks the call. | π Can block |
PermissionRequest | Fires when a permission prompt would appear. Return a decision to allow or deny it. | π Decides allow/deny |
PostToolUse | Fires after a tool succeeds. Gets tool_input and tool_response on stdin. | π Watch only |
Notification | Fires when Claude needs your attention (waiting on input or a permission prompt). | π Watch only |
SubagentStop | Fires when a subagent finishes. | π Can block |
Stop | Fires when Claude finishes responding. Blocking it makes Claude keep working. | π Can block |
PreCompact | Fires before context compaction. | π Can block |
SessionEnd | Fires when the session ends. Good for cleanup and logging. | π Watch only |
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.command' | grep -qE 'git (push.*(-f|--force)|reset --hard|clean -f)' && { echo 'Blocked: destructive git command' >&2; exit 2; } || exit 0"
}
]
}
]
}
}
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "jq -r '.tool_input.file_path' | xargs npx prettier --write"
}
]
}
]
}
}
{
"hooks": {
"Notification": [
{
"matcher": "",
"hooks": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code needs your attention\" with title \"Claude Code\"'"
}
]
}
]
}
}
Model Context Protocol servers expose external tools to Claude. Add one with claude mcp add and its tools are available in your session. Remote servers use HTTP, local ones run as a process over stdio.
Config.mcp.json (project, committed) Β· ~/.claude.json (local and user scopes)
GitHub
Review PRs, create issues, search repos
claude mcp add --transport http github https://api.githubcopilot.com/mcp/
Sentry
Pull errors and stack traces into the chat
claude mcp add --transport http sentry https://mcp.sentry.dev/mcp
Notion
Read and update docs, specs, and databases
claude mcp add --transport http notion https://mcp.notion.com/mcp
Postgres (DBHub)
Query and inspect schemas. Use a read-only user
claude mcp add db -- npx -y @bytebase/dbhub --dsn "postgresql://..."
Playwright
Drive a real browser: click, fill, screenshot
claude mcp add playwright -- npx @playwright/mcp@latest
~/.claude.json
You, this project.mcp.json
The team, through git~/.claude.json
You, every projecta plugin's .mcp.json
Wherever the plugin is onyour claude.ai account
You, everywhereThe winning entry is used whole. Fields don't merge across scopes. docs β
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_PAT}"
}
},
"db": {
"command": "npx",
"args": ["-y", "@bytebase/dbhub", "--dsn", "${DATABASE_URL}"]
}
}
}
Sources MCP docs β MCP quickstart β Playwright MCP β DBHub β
A plugin is a directory of skills, agents, hooks, and MCP servers that Claude Code installs and loads as one unit. It's the distribution layer on top of the four mechanisms above.
Config.claude-plugin/plugin.json (manifest) Β· managed with /plugin
A manifest at .claude-plugin/plugin.json, plus any of skills/, agents/, hooks/hooks.json, and .mcp.json. Plugin skills are namespaced, so a review skill in my-plugin runs as /my-plugin:review and two plugins can't collide.
A marketplace is a repo with a .claude-plugin/marketplace.json listing plugins and where to fetch them. Claude Code adds Anthropic's official one (claude-plugins-official) the first time you start an interactive session.
Install one to get a setup someone else maintains. Build one to give your team's setup to every repo with versioned updates. While you're developing, skip the marketplace and load it straight from the folder with --plugin-dir.
my-plugin
.claude-plugin/plugin.jsonSkills
skills/review/SKILL.mdβ runs as /my-plugin:review
Agents
agents/reviewer.mdβ a subagent Claude can delegate to
Hooks
hooks/hooks.jsonβ run on lifecycle events
MCP
.mcp.jsonβ tools from a server
claude-plugins-officialAnthropic's own. Added the first time you start Claude Code.
claude-communityAnthropic-hosted community names, only from github.com/anthropics/.
your-company/pluginsEverything else, including your own company's marketplace.
How marketplace tiers work β
| Command | What It Does |
|---|---|
/plugin | Open the plugin manager (Discover, Installed, Marketplaces tabs) |
/plugin marketplace add <source> | Add a marketplace from a GitHub repo, URL, or local path |
/plugin install <name>@<marketplace> | Install a plugin, e.g. commit-commands@claude-plugins-official |
/reload-plugins | Apply plugin edits without restarting the session |
claude --plugin-dir ./my-plugin | Load a plugin from disk for one session (for development) |
claude plugin disable <name> | Turn a plugin off without uninstalling it |
Sources Plugins overview β Create a plugin β Plugin commands β Browse plugins β
The case for investing in Claude Code customization.
When 20 developers prompt Claude differently, you get 20 different patterns. Skills and agents encode your team's best practices into reusable templates, so every engineer gets the senior architect's approach by default.
An instruction in CLAUDE.md is a request. A PreToolUse hook is enforcement. Block force-pushes, protect .env, auto-format every edit, all without relying on anyone remembering the process. docs β
New developers run /setup and get a working environment. They run /deploy and it works. The knowledge that used to live in a senior engineer's head becomes something you can execute.
Every organization has unwritten rules: 'always use the v2 API for payments,' 'never query the users table without a tenant filter.' CLAUDE.md and skills write them down, and hooks enforce the ones that can't be broken. Both survive employee turnover.
A /review skill that takes an hour to write and saves 10 minutes per PR pays for itself after six PRs. Across 50 PRs a week and 48 working weeks, that's 400 hours a year. Plug in your own numbers below.
Your numbers, not a benchmark. Time a few PRs with and without the skill before you trust the minutes.
Hours per year = PRs per week Γ minutes saved Γ 48 working weeks Γ· 60. Payback = build time Γ· minutes saved per PR.
This cheat sheet covers the mechanics. Know someone who isn't an engineer and wants to start? The guide walks them through a first build, one prompt at a time.
Read the Full Guide