Skip to main content

Claude Code extension primitives

The terms blur together because they all "extend Claude Code" but they sit at different layers. The fastest way to keep them straight is to ask two questions about each one: when does it load, and who triggers it.

The mental model in one sentence: some files are always in front of Claude (CLAUDE.md), some are invoked on demand (Skills, Subagents, MCP), some fire automatically on events (Hooks), and some bundle everything together for sharing (Plugins).

The five layers

Each card below shows: the primitive, where it lives, and what it does in one line.

Always loadedSits in context every turn. You write it.
CLAUDE.md
project root or ~/.claude/

Project conventions, your role, tool preferences. Loaded every conversation.

CLAUDE.local.md
project root (git-ignored)

Personal overrides that shouldn't be shared with the team.

Memory
~/.claude/projects/<slug>/memory/

Claude-written notes that persist across conversations. You don't edit these by hand.

On-demandClaude reads the description, then invokes when relevant.
Skills
.claude/skills/<name>/SKILL.md

Reusable workflows. Only the frontmatter description sits in context. Full body loads when Claude picks it.

Subagents
.claude/agents/<name>.md

Specialized workers with their own context window. Claude delegates via the Agent tool.

MCP servers
.mcp.json or settings.json

External tool providers. Show up as extra tools (e.g. an n8n MCP exposes workflow tools).

Event-drivenThe harness fires these automatically. Claude can't skip them.
Hooks
.claude/settings.json

Shell commands triggered by events: PreToolUse, PostToolUse, UserPromptSubmit, Stop, SessionStart.

settings.json
.claude/settings.json or ~/.claude/

The harness config. Hooks, permissions, env vars, model selection, statusline, skillOverrides.

User-triggeredYou type the name. Claude expands the prompt.
Slash commands
.claude/commands/<name>.md

Type /name in chat to expand. Newer projects use user-invocable Skills instead -- same effect, more features.

DistributionOne install brings everything above with it.
Plugins
.claude-plugin/plugin.json

A packaging format. Bundles skills, hooks, slash commands, subagents, and MCP servers into one shareable unit.

Quick reference

PrimitiveLocationWho triggersWhen loaded
CLAUDE.mdproject root(automatic)Every turn
Skills.claude/skills/<name>/Claude (picks it)On invocation
Subagents.claude/agents/<name>.mdClaude (delegates)On invocation, separate context
Hookssettings.jsonHarness (on event)Deterministic, every matching event
Slash commands.claude/commands/<name>.mdYou type /nameWhen typed
MCP servers.mcp.jsonConfigured, then Claude calls toolsTools listed every turn, invoked on demand
settings.json.claude/settings.jsonHarness (reads at start)Session start
Memory~/.claude/projects/.../memory/Claude (writes it)Across conversations
Plugins.claude-plugin/plugin.jsonInstallerBundles all of the above

Each one in detail

CLAUDE.md and CLAUDE.local.md

Static text files. CLAUDE.md sits at the project root (or in subdirs for scoped instructions, or in ~/.claude/ for user-wide). It is loaded into context every conversation. Use it for project conventions, your role, tool preferences.

CLAUDE.local.md is the git-ignored variant for personal overrides.

Trade-off: always-on means it eats context. Keep it tight. Heavy reference material belongs in linked files or skills, not inline.

Skills

A skill is a folder: .claude/skills/<name>/SKILL.md, plus any helper scripts or references in the same folder.

The SKILL.md file has YAML frontmatter (at minimum name and description). Only the description is loaded into context up front. Claude reads descriptions of all available skills, then reads the full SKILL.md when it decides the skill is relevant.

Skills are auto-discovered from .claude/skills/ in your current directory, walking up to the repo root, plus ~/.claude/skills/ for user-wide skills.

Use when: you have a recurring workflow you want Claude to pick up on autonomously.

Subagents

A subagent is a markdown file at .claude/agents/<name>.md with YAML frontmatter (name, description, tools, optional model, permissionMode, etc.).

Each subagent runs with its own context window. Claude delegates work to them via the Agent tool. Useful for parallel work, scoped tool access, or protecting the main context from large search results.

Use when: you want isolated research or specialised work that shouldn't pollute the main conversation.

Hooks

Shell commands the harness runs automatically on events. Configured in settings.json:

  • PreToolUse / PostToolUse -- before or after a tool call
  • UserPromptSubmit -- when you press enter
  • Stop -- when Claude finishes its turn
  • SessionStart -- new session

Claude doesn't choose to fire hooks. The harness does. That's the key distinction from skills.

Use when: you want deterministic automation -- auto-format after edits, block dangerous commands, log activity, inject context.

Plugins

A packaging format. A plugin bundles skills, hooks, slash commands, subagents, and MCP servers into one installable unit, defined by a .claude-plugin/plugin.json manifest.

Installed from a marketplace or local path. Think of plugins as the "npm package" of Claude Code extensions.

Use when: you want to share a coherent set of extensions with others, or reuse them across machines.

Slash commands

Custom prompts in .claude/commands/<name>.md. Type /name in chat to expand. Different from skills because you trigger them explicitly.

Newer Claude Code projects merge slash commands into skills (a user-invocable skill produces /name as well, with extra features). Both .claude/commands/ and user-invocable skills work today; skills are the path forward.

MCP servers

External tool providers via the Model Context Protocol. Configured in .mcp.json or in settings.json. They expose extra tools to Claude (e.g. an n8n MCP exposes workflow management tools).

MCP is how you give Claude access to systems outside its built-in toolset.

settings.json

The harness config. Lives at .claude/settings.json (project) or ~/.claude/settings.json (user). Controls hooks, permissions, env vars, model selection, statusline, and skill overrides.

settings.local.json is the git-ignored variant for personal config.

Memory

Files Claude writes itself, persisted across conversations. Stored under ~/.claude/projects/<slug>/memory/, indexed by a MEMORY.md file.

Memory is for stable facts about you, your project, and your preferences. Not for in-progress task state.

Bundled skills (built-ins)

Claude Code ships with built-in skills you can call directly without writing your own: /loop, /run, /verify, /security-review, /review, /init, /claude-api, and more. They behave the same as project skills but live inside the binary.

Decision guide

I want to...Use
Tell Claude how this project worksCLAUDE.md
Add a personal override that isn't shared with the teamCLAUDE.local.md
Build a reusable workflow Claude picks up on its ownSkill
Delegate research without polluting contextSubagent
Run a script every time Claude edits a fileHook (PostToolUse)
Block dangerous commands before they runHook (PreToolUse)
Type /foo to expand a promptSlash command (or user-invocable skill)
Give Claude access to an external systemMCP server
Share a set of extensions with othersPlugin
Have Claude remember something across sessionsMemory (Claude writes it itself)
Change permissions, model, or envsettings.json

A few terms that confuse people

"agents.md" -- there is no single agents.md file in Claude Code. Each subagent gets its own file in .claude/agents/. The single-file AGENTS.md exists in Codex, not Claude Code -- a common source of confusion if you've worked with both.

"Skills vs slash commands" -- a user-invocable skill produces a slash command. The mechanisms overlap. Prefer skills going forward; they have more features and are where the platform is heading.

"Skills vs subagents" -- skills run in the main conversation context. Subagents run in their own context window. Use a subagent when you want isolation (parallel work, large search results, scoped tools).