Last updated: April 2026
Skills vs MCP vs HooksWhich extension actually fits the job?
Claude Code has four ways to extend itself — Skills, MCP servers, Hooks, and Slash commands. They sound similar and the docs treat them separately, so people reach for the wrong one all the time. The short version: hooks enforce, skills package, MCP connects, slash commands trigger. Below is the decision tree and ten scenarios that map onto it.
The four layers, in one sentence each
Skills
Packaged bundles of prompts, assets, and helper code that Claude chooses to load when a session's intent matches. Think "a capability Claude can opt into."
MCP servers
External programs speaking the Model Context Protocol that expose new tools — database queries, CRM lookups, ticketing systems — for Claude to call. Think "new hands for Claude to reach out with."
Hooks
Shell commands the Claude Code runtime runs automatically at bound events. They do not ask. They fire. Think "guardrails and automation around Claude's work."
Slash commands
Named prompts stored as markdown files that you invoke by typing /name. Think "a reusable prompt with a shortcut key."
Decision tree
Answer these four questions in order. The first "yes" wins.
1. Should this run every time a specific event happens, regardless of what Claude thinks?
Yes → Hook. Format-on-save, block-dangerous-command, log-every-prompt. Deterministic, non-negotiable.
2. Does Claude need to talk to an external system it cannot safely reach via bash?
Yes → MCP server. Authenticated databases, SaaS APIs, internal services. Anything a local script would be fragile for.
3. Is this a multi-step workflow with reusable assets (checklists, prompts, scripts) you want Claude to pick up when intent matches?
Yes → Skill. Content audits, compliance reviews, vendor QA sweeps. Too heavy for one slash command, too dynamic for a hook.
4. Is it a short, reusable prompt you trigger yourself by name?
Yes → Slash command. /commit, /deploy, /release-notes. Single file, single purpose.
Most people start here: a handful of slash commands + two or three hooks. That covers most of the ergonomic wins. Reach for skills when you are repeating the same structured workflow across projects. Reach for MCP when you hit a system bash genuinely cannot handle.
Side-by-side comparison
The quick reference when you just need to confirm which layer does what.
| Dimension | Skills | MCP | Hooks | Slash cmds |
|---|---|---|---|---|
| Who decides to run it | Claude (picks based on intent) | Claude (calls the tool) | The runtime (fixed events) | You (you type /name) |
| What it extends | Claude's know-how for a task | Systems Claude can reach | Workflow around Claude | Quick reusable prompts |
| Can it block Claude? | No | Not directly | Yes (PreToolUse exit 2) | No |
| Runs automatically? | Loaded when relevant | Only when called | Yes, at bound events | No, manual |
| Where it lives | .claude/skills/ or a plugin | Own process, registered in config | settings.json | .claude/commands/ |
| Best for | Packaged multi-step workflows | Live access to external systems | Guardrails and automation | Quick, reusable single prompts |
| Overhead to set up | Medium | High (run a server) | Low (one JSON entry) | Lowest (one markdown file) |
Ten scenarios, mapped
Cover your hand over the "Answer" column, guess, then read the reasoning. If you disagree, the "why" usually makes the call obvious.
Run Prettier on every file Claude edits
Deterministic. Should never be up to Claude. PostToolUse hook on Write|Edit — one line in settings.json.
Let Claude query your internal Postgres read replica with row-level security respected
Needs live authenticated access to a system bash cannot safely expose. MCP server wraps the auth and surfaces query tools to Claude.
Type /commit and have Claude write a message + push
Single-turn reusable prompt you trigger yourself. One markdown file in .claude/commands/commit.md.
Run a 12-step vendor review that loads a checklist, runs helper scripts, writes a report file
Multi-step, packaged, reusable across projects. Claude picks it up when you describe the task, which is cleaner than stuffing 12 steps into one slash command.
Stop Claude from ever running migrations against production
A guardrail, not a capability. PreToolUse hook matching the Bash tool, checking for the prod DATABASE_URL, exit 2 if matched.
Let Claude read and comment on Jira tickets during a session
Live external system with its own auth. MCP is the canonical way to give Claude tools for third-party platforms without inventing fragile scraping.
Type /deploy to build, preview, and ship the current site
Short, reusable, triggered intentionally. A skill would be overkill for a few bash invocations.
Audit a site's content for stale posts, using a refresh-ROI scoring framework, and output a prioritised queue
Framework + scoring logic + output format that should be identical across sites. Perfect fit for a skill — Claude loads it when you say "audit the content," you do not need to remember a slash command name.
Keep a log of every prompt you send Claude, appended to a local file
UserPromptSubmit hook. Runs every turn, deterministically, no Claude involvement needed.
Pull a customer record from HubSpot mid-conversation when you mention their email
Third-party system, live lookup, needs real auth. MCP server for HubSpot exposes a lookup tool Claude can call when relevant.
The mistakes that make people overengineer
Building an MCP server for what a bash script would do
MCP servers are a real engineering commitment — you run a process, you handle auth, you version the tool surface. If the thing you want is "let Claude read a JSON file," the answer is bash. Save MCP for systems that genuinely need it.
Stuffing a 10-step workflow into a single slash command
Slash commands are single-turn prompts. When you find yourself writing a 300-line prompt file, break it up — that is a skill, or a hook-orchestrated sequence, or a sub-agent.
Using a hook where a slash command would do
If the answer to "should this happen every time" is actually "only when I say so," you want a slash command, not a hook. Hooks cost a bit of latency every session; use them only when the automatic behaviour is what you want.
Writing a skill for something you use twice
Skills are reusable capability bundles. If you would only invoke them on one specific project, you are better off with a CLAUDE.md section and a slash command.
Frequently Asked Questions
Questions I get whenever I show this decision tree to another developer.
What is the difference between Skills, MCP, and Hooks in Claude?+
Skills are packaged prompt + script bundles Claude can choose to load on demand. MCP servers are external programs that expose new tools for Claude to call. Hooks are shell commands Claude Code runs automatically at fixed events, without Claude's input. Skills extend what Claude knows how to do, MCP extends what Claude can touch, hooks enforce what happens around Claude's work.
When should I write a Skill instead of a slash command?+
Write a slash command when the thing you want is a single-turn prompt you invoke by name (like /commit or /deploy). Write a Skill when the thing you want is a broader capability with multiple steps, reusable assets, or bundled code (like a 'compliance review' skill that loads a checklist and helper scripts). Skills are heavier and are chosen by Claude based on intent; slash commands are lighter and triggered by you.
When should I build an MCP server?+
Build an MCP server when Claude needs to talk to a system it cannot reach through bash or file I/O: a proprietary API, a database with custom auth, an internal service, a CRM, a desk ticketing system. If the integration is something you would otherwise wrap in a local script, a Skill is usually enough. If it needs live authenticated access to a system, MCP is the right layer.
When should I use a Hook?+
Use a hook when you want the behaviour to happen whether or not Claude chooses it. Formatting after every edit, blocking rm -rf, running a targeted test on save, logging every prompt — these are guardrails and automations, not capabilities Claude reasons about. Hooks run deterministically at the event you bind them to.
Can a Skill include Hooks or call MCP tools?+
Skills and hooks live in different places — skills are a packaging format for prompts and assets Claude loads on demand, hooks are configured in settings.json. They do not literally contain each other, but they compose: a Skill can call bash that invokes an MCP tool, and hooks can fire around anything Claude does, including during a Skill's execution.
What about sub-agents? Where do they fit?+
Sub-agents are a different axis entirely. They are independent Claude Code agents you spawn to handle a scoped task in parallel (for example, one sub-agent per vendor during a QA sweep). You still use skills, MCP, or hooks inside a sub-agent exactly as you would in the main session. Sub-agents are about parallelism and context isolation, not about extending Claude's capabilities.
Can I start with just hooks and slash commands?+
Yes, and most people should. Hooks plus slash commands cover 80% of the value. Add Skills when you find yourself packaging the same prompt + scripts for multiple projects. Add MCP when you hit a system Claude genuinely cannot reach any other way. Skipping straight to MCP for things a bash script would handle is overengineering.
Pick the right layer, then write for it.
Once you know which extension fits, the next step is the content. The Hooks Recipes article has eight copy-paste settings.json entries. The CLAUDE.md Playbook covers the persistent context layer most people skip entirely.