wikis / Claude Code / wiki / syntheses / extension-decision-guide.md view as markdown
Extension Decision Guide: Which Mechanism for Which Job
Claude Code's extension mechanisms plug into different parts of the agentic loop. The official docs' framing: CLAUDE.md = always-on context, skills = on-demand knowledge/workflows, MCP = external connections, subagents = isolation, hooks = event automation, plugins = packaging, Agent SDK = build your own product on the same engine.
Note on slash commands: in current Claude Code, a user-invoked skill is the slash command (/deploy invokes .claude/skills/deploy/SKILL.md). "Slash command" below means a skill with disable-model-invocation: true — invocable only by you, invisible to the model, zero context cost until used. (Legacy .claude/commands/ files still load; same decision logic applies.)
Comparison
| Mechanism | What it is | Trigger | Determinism | Context cost | Reach |
|---|---|---|---|---|---|
| CLAUDE.md | Persistent instructions | Every session, automatically | Advisory — model interprets | Full content, every request | Project/user |
| Skill (model-invocable) | Markdown knowledge or workflow | /<name> or Claude matches description |
Model-interpreted | Description every request; body when used | Project/user/plugin |
Skill as slash command (disable-model-invocation: true) |
Manual workflow, often with side effects | You type /<name> [args] |
You control trigger; model executes steps | Zero until invoked | Project/user/plugin |
| Hook | Script / HTTP request / prompt / subagent bound to a lifecycle event | Events: PreToolUse, PostToolUse, Stop, SessionStart, PermissionDenied, … | Guaranteed — always fires on its event | Zero unless it returns output | Settings (user/project/managed) |
| MCP server | Protocol connection to an external service (tools + auth) | Claude calls its tools | Tool execution deterministic; invocation model-chosen | Tool names at start; schemas deferred (tool search on by default) | Local/project/user scopes |
| Subagent | Isolated worker with own context, tools, model | You ask, or main agent delegates | Model-driven | Isolated; only summary returns | Project/user/CLI/plugin |
| Plugin | Bundle of skills + hooks + subagents + MCP servers | Installed via /plugin or auto-loaded from .claude/skills (v2.1.157+) |
Inherits components' semantics | Sum of components | Distributable via marketplaces |
| Agent SDK (TS/Python) | Library to run the Claude Code engine inside your own application | Your code calls query() |
Programmatic: allowedTools, permissionMode, canUseTool, hooks |
Your app's concern | Standalone products, services, pipelines |
Analysis
- Determinism is the sharpest dividing line. "Never edit
.env" in CLAUDE.md or a skill is a request; a PreToolUse hook that blocks the edit is enforcement. Official rule: put guardrails in hooks, knowledge in skills, conventions in CLAUDE.md. - Context economics differ by mechanism. CLAUDE.md is paid on every request (keep under 200 lines; the docs warn bloated files cause rule-ignoring). Skills amortize: description-only until used. MCP is cheap-until-used thanks to deferred schemas, but CLI tools (
gh,aws) are cheaper still — no per-tool listing at all. Hooks can reduce context (e.g. a PreToolUse hook that filters test output to failures before Claude reads it). - MCP and skills are complements, not rivals. MCP provides the connection (database, Slack, browser); a skill teaches Claude how to use it well (schema, query patterns, message formats).
- Skills vs subagents = content vs container. A skill is reusable content loadable into any context; a subagent is an isolated execution context. They combine: subagents preload skills via
skills:, and a skill can run isolated viacontext: fork. - Layering/precedence: CLAUDE.md is additive across levels; skills and subagents override by name (managed > user > project for skills); MCP overrides by name (local > project > user); hooks merge — all registered hooks fire.
- The official trigger table is the best adoption heuristic — add mechanisms reactively, not up front (see Recommendations).
- Agent SDK is a different altitude. Reach for it when Claude Code is a component of your product rather than your dev tool: it exposes the permission evaluation chain programmatically (hooks → deny → ask → mode → allow →
canUseTool), per-step/per-model cost tracking, and session control. Don't use the SDK for things a skill or hook solves inside Claude Code.
Recommendations
Pick by trigger (the docs' "build your setup over time" table, extended):
- Claude gets a convention or command wrong twice → CLAUDE.md line.
- You keep typing the same starting prompt, or paste the same playbook a third time → skill.
- The workflow has side effects (deploy, release, billing) and must only run when you say so → skill with
disable-model-invocation: true(pure slash command). - Something must happen every time, with zero exceptions (lint after edit, block writes to
migrations/, Slack on session end) → hook. - You keep copying data from a browser tab Claude can't see (Jira, Figma, your DB) → MCP server — but check first whether a CLI tool covers it more cheaply.
- A side task floods your conversation with output you won't reference again, or research reads dozens of files → subagent (since 2.1.172 subagents can nest 5 levels for deep fan-out).
- A second repository needs the same setup, or you want to distribute to others → plugin (+ marketplace).
- You're building an autonomous service, CI bot, or product with its own UI/permission UX → Agent SDK.
Anti-patterns to avoid: reference manuals living in CLAUDE.md (move to skills); enforcement rules living in prompts (move to hooks); an MCP server for something gh already does; subagents for tasks whose intermediate output you actually need to see.
