a01 CLAUDE CODE · JAN 2026

Claude Code Extensibility Guide

A visual guide to Plugins, Subagents, and Skills -- the three mechanisms for extending Claude Code's capabilities.

01 / 07How the Three Mechanisms Relate

Claude Code offers three complementary systems for extending its capabilities. Plugins bundle multiple extensions into shareable packages, subagents provide specialized AI assistants with isolated context, and skills inject task-specific instructions on demand.

// Architecture overview
CLAUDE CODE CORE
System Prompt + Tools
PLUGINS
Bundles
  • Commands
  • Agents
  • Skills
  • Hooks
  • MCP servers
SUBAGENTS
Delegates
  • Own context
  • Own tools
  • Specialized expertise
  • Resumable sessions
SKILLS
Expands
  • Prompt injection
  • Scripts
  • References
  • Tool scoping
// Relationship summary
  • Plugins contain subagents, skills, hooks, commands, and MCP servers
  • Subagents can load skills via the "skills:" frontmatter field
  • Skills expand prompts with context-specific instructions
  • All three can be used independently or together

02 / 07Directory Structure

All extensions live under the .claude/ directory at your project root, with optional user-level extensions in ~/.claude/.

// Project directory layout
project-root/
├── .claude/
│ ├── agents/project subagents
│ │ ├── code-reviewer.md
│ │ ├── test-runner.md
│ │ └── debugger.md
│ │
│ ├── skills/project skills
│ │ ├── pdf/
│ │ │ ├── SKILL.mdrequired: skill definition
│ │ │ ├── scripts/
│ │ │ └── references/
│ │ └── commit-messages/
│ │ └── SKILL.md
│ │
│ ├── commands/slash commands
│ │ ├── deploy.md
│ │ └── lint.md
│ │
│ └── settings.json
├── .claude-plugin/plugin marker (if this IS a plugin)
│ └── plugin.jsonplugin manifest
└── .mcp.jsonMCP server configs
// User-level locations (~/.claude/)
~/.claude/applies to all projects
├── agents/user subagents
├── skills/user skills
├── commands/user slash commands
└── settings.json

03 / 07Subagents: Specialized AI Assistants

Subagents are pre-configured AI personalities that Claude delegates tasks to. Each subagent operates in its own context window with specific tools and expertise.

What problem they solve

ProblemHow Subagents Help
Context pollutionEach runs in isolated context window
Repetitive instructionsDefine expertise once, reuse everywhere
Tool sprawlLimit each subagent to relevant tools only
Team consistencyShare via version control

File format

.claude/agents/code-reviewer.md markdown
---
name: code-reviewer              # REQUIRED: lowercase-with-hyphens
description: >                   # REQUIRED: When to invoke this agent
  Expert code reviewer. Use PROACTIVELY after any code changes
  to check quality and security.
tools: Read, Grep, Glob, Bash    # OPTIONAL: Limits available tools
model: inherit                   # OPTIONAL: sonnet|opus|haiku|inherit
permissionMode: default          # OPTIONAL: How to handle permissions
skills: project-conventions      # OPTIONAL: Skills to auto-load
---

<!-- BODY: The subagent's system prompt -->

You are a senior code reviewer ensuring high standards.

## When Invoked
1. Run `git diff` to see recent changes
2. Focus on modified files only
3. Begin review immediately

## Review Checklist
- [ ] Code is simple and readable
- [ ] No duplicated logic
- [ ] Proper error handling
- [ ] No exposed secrets or API keys
- [ ] Input validation implemented

## Output Format
Organize feedback by priority:
- Critical (must fix before merge)
- Warning (should address)
- Suggestion (nice to have)

Invocation flow

// Subagent invocation flow
1User Request or Automatic Match
User: "Review my code changes" → Claude matches task to agent description
2Discovery
Scans .claude/agents/ for matching agent configs
3Spawn Subagent
  • Create new context window (isolated)
  • Load system prompt from markdown body
  • Restrict tools to: Read, Grep, Glob, Bash
  • Auto-load skill: project-conventions
  • Assign agentId for resume capability
4Execute
Subagent runs git diff, reads files, applies checklist, formats findings
5Return Results
Review findings injected into main conversation; agentId saved for potential resume

Real-world examples

Test runner subagent

.claude/agents/test-runner.mdmarkdown
---
name: test-runner
description: Run tests and fix failures. Use PROACTIVELY after code changes.
tools: Read, Edit, Bash, Glob
---

You are a test automation expert.

## Process
1. Detect test framework: `package.json` → Jest/Vitest, `pytest.ini` → pytest
2. Run appropriate command: `npm test` or `pytest -v`
3. If failures occur:
   - Analyze stack traces
   - Identify root cause
   - Fix while preserving test intent
4. Re-run to confirm fix

## Key Principle
Never modify tests to make them pass. Fix the code they're testing.

Documentation generator subagent

.claude/agents/doc-generator.mdmarkdown
---
name: doc-generator
description: Generate API docs and README files. Use when creating documentation.
tools: Read, Write, Grep, Glob
model: opus
---

You are a technical writer specializing in developer documentation.

## When Generating API Docs
1. Scan for exported functions/classes
2. Extract JSDoc/docstrings
3. Generate OpenAPI spec or markdown tables
4. Include code examples for each endpoint

## README Structure
- Quick start (under 5 minutes)
- Installation options
- Configuration reference
- Common use cases with examples

04 / 07Skills: On-Demand Prompt Expansion

Skills are markdown files that teach Claude specific tasks. Unlike subagents, skills expand the current context rather than spawning new assistants. They use progressive disclosure to load only what's needed.

The three-level architecture

// Skill progressive disclosure
Level 1Metadata (~100 tokens per skill)
Loaded at startup into system prompt
<available_skills> <skill> <n>pdf</n> <description>Extract and analyze PDFs</description> </skill> <skill> <n>commit-messages</n> <description>Generate git commit messages</description> </skill> </available_skills>
User: "Read this PDF" → Claude matches → invokes Skill tool
Level 2Instructions (loaded on-demand)
Full SKILL.md body injected into context
Base Path: /Users/dev/.claude/skills/pdf/ # PDF Processing Skill Use the extract_text.py script: python3 {baseDir}/scripts/extract_text.py <input> After extraction, summarize key points...
Claude needs more info → Reads reference file
Level 3Resources (loaded as-needed)
Claude uses Read/Bash to access bundled files
> Bash: python3 /path/to/scripts/extract_text.py report.pdf > Read: /path/to/references/forms.md Script OUTPUT enters context (not source code)

File format

.claude/skills/code-review/SKILL.mdmarkdown
---
name: code-review                          # REQUIRED: max 64 chars
description: >                             # REQUIRED: max 1024 chars
  Reviews code for quality, security, and best practices.
  Use when reviewing PRs or analyzing code changes.
allowed-tools: "Bash(git:*),Read,Grep"     # OPTIONAL: Tool permissions
model: "claude-opus-4-20250514"            # OPTIONAL: Model override
version: "1.0.0"                           # OPTIONAL: Tracking
disable-model-invocation: false           # OPTIONAL: Manual-only if true
user-invocable: true                       # OPTIONAL: Show in menu
---

# Code Review Skill

## Prerequisites
- Git repository with staged or committed changes
- Access to source files

## Process

### Step 1: Gather Changes
Run the analyzer script to collect diff information:
```bash
python {baseDir}/scripts/analyzer.py --path . --output /tmp/review.json
```

### Step 2: Review Checklist
For each changed file, verify:
- [ ] Functions under 50 lines
- [ ] Clear variable names
- [ ] Error handling present
- [ ] No hardcoded secrets

## Resources
For advanced patterns, see [{baseDir}/references/patterns.md]

Invocation flow

// Skill invocation flow
1User Request
User: "Review my PR" → Claude scans <available_skills> in system prompt
2Tool Call
{ "name": "Skill", "input": { "command": "code-review" } }
3Skill Activation
  • Show user: "The 'code-review' skill is loading"
  • Read full SKILL.md from .claude/skills/code-review/
  • Inject into context with {baseDir} resolved
  • Apply tool restrictions: Bash(git:*),Read,Grep
  • Switch model if specified
4Execute in Current Context
Claude follows injected instructions—runs scripts, reads references. Script OUTPUT enters context, not source code (efficient!)
5Response
Results in same conversation (no new context window)

Real-world examples

Commit message generator

.claude/skills/commit-messages/SKILL.mdmarkdown
---
name: commit-messages
description: Generates conventional commit messages. Use when committing code.
allowed-tools: "Bash(git diff:*),Bash(git status:*)"
---

# Commit Message Generator

## Format
```
<type>(<scope>): <subject>

<body>

<footer>
```

## Types
- feat: New feature
- fix: Bug fix
- refactor: Code restructure
- docs: Documentation
- test: Adding tests

## Process
1. Run `git diff --staged --stat` for overview
2. Run `git diff --staged` for details
3. Identify primary change type
4. Generate message following format

API scaffolding skill

.claude/skills/api-scaffold/SKILL.mdmarkdown
---
name: api-scaffold
description: Scaffold REST API endpoints with validation and tests.
allowed-tools: "Read,Write,Bash(npm:*)"
---

# API Endpoint Scaffolding

## Process
1. Get endpoint details: method, path, request/response schema
2. Generate files:
   - `routes/<resource>.ts` - Route handler
   - `validators/<resource>.ts` - Zod schemas
   - `tests/<resource>.test.ts` - Integration tests

## Template
```typescript
import { Router } from 'express';
import { validate } from '../middleware/validate';
import { {Resource}Schema } from '../validators/{resource}';

const router = Router();

router.post('/', validate({Resource}Schema), async (req, res) => {
  // Implementation
});

export default router;
```

05 / 07Plugins: Bundled Extensibility Packages

Plugins are shareable packages that bundle multiple extensions (commands, subagents, skills, hooks, MCP servers) into installable units.

Plugin structure

// Plugin directory layout
my-plugin/
├── .claude-plugin/REQUIRED: plugin marker
│ └── plugin.jsonREQUIRED: manifest file
├── commands/DEFAULT: slash commands
│ ├── review.md→ /my-plugin:review
│ └── deploy.md→ /my-plugin:deploy
├── agents/DEFAULT: subagents
│ ├── security-reviewer.md
│ └── performance-tester.md
├── skills/DEFAULT: skills
│ └── code-patterns/
│ ├── SKILL.md
│ └── references/
├── hooks/hook configurations
│ └── hooks.json
├── scripts/utility scripts
├── .mcp.jsonMCP server definitions
└── README.md
// Critical
  • commands/, agents/, skills/, hooks/ go at ROOT level
  • NOT inside .claude-plugin/ (common mistake!)

Plugin manifest

.claude-plugin/plugin.jsonjson
{
  // ─────────────────────────────────────────
  // REQUIRED FIELD
  // ─────────────────────────────────────────
  "name": "code-quality-suite",        // Unique, kebab-case identifier

  // ─────────────────────────────────────────
  // METADATA (optional but recommended)
  // ─────────────────────────────────────────
  "version": "1.2.0",                  // Semantic version
  "description": "Code review, testing, and documentation tools",
  "author": {
    "name": "Dev Team",
    "email": "dev@example.com"
  },
  "license": "MIT",

  // ─────────────────────────────────────────
  // COMPONENT PATHS (optional)
  // ─────────────────────────────────────────
  "commands": "./extra-commands/",     // String or array
  "agents": [                          // Multiple paths supported
    "./agents/",
    "./advanced-agents/"
  ],
  "mcpServers": {                      // Inline MCP config
    "plugin-db": {
      "command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
      "args": ["--port", "5432"]
    }
  }
}

Plugin loading flow

// Plugin installation & loading
1Install Command
claude plugin install formatter@marketplace
2Discovery Phase
  • Locate .claude-plugin/plugin.json
  • Validate manifest schema
  • Check for name conflicts
3Installation Phase
  • Copy plugin directory to cache
  • Resolve ${CLAUDE_PLUGIN_ROOT}
  • Register with scope: user | project | local
4Component Registration
  • Commands: commands/review.md → /code-quality-suite:review
  • Agents: agents/security-reviewer.md → Available for delegation
  • Skills: skills/code-patterns/SKILL.md → Added to <available_skills>
  • Hooks: hooks/hooks.json → Event handlers registered
  • MCP: .mcp.json → Servers started automatically
5Ready to Use
Plugin components available in Claude Code

06 / 07Comparison: When to Use Each

Decision flowchart

// Choosing the right mechanism
Do you need to bundle multiple extensions for sharing?
YES →
PLUGIN
Does it need isolated context + task delegation?
YES →
SUBAGENT
Need to inject instructions into current context?
YES →
SKILL
Simple prompt expansion?
Slash Command or CLAUDE.md

Feature comparison

FeatureSubagentsSkillsPlugins
Primary purposeDelegate to specialistsExpand promptsBundle & share
ContextOwn isolated windowSame conversationContainer for others
Location.claude/agents/*.md.claude/skills/*/SKILL.md*/.claude-plugin/
InvocationAuto or explicitAuto via Skill toolContains other types
Tool accessConfigurable per agentScoped via allowed-toolsInherited by contents
Model override Yes YesVia contained agents
Resumable Yes (agentId) NoN/A
ShareabilityCopy .md fileCopy skill folderInstall from marketplace

Use case mapping

ScenarioBest ChoiceWhy
Code review automationSubagentNeeds isolated context, specialized tools
Test generationSubagentComplex multi-step process, tool access
Documentation generationSkill or SubagentSkill for templates, subagent for full docs
Linting/formattingPlugin with hooksTriggers automatically after edits
API scaffoldingSkillInject templates into current context
Project conventionsSkillExpand prompts with team standards
Team tooling bundlePluginDistribute multiple extensions together

07 / 07Best Practices & Gotchas

// Subagents
Do
  • Use action-oriented descriptions: "Use PROACTIVELY after code changes"
  • Keep agents focused on single responsibilities
  • Version control project agents for team sharing
  • Use skills: field to auto-load relevant skills
Don't
  • Give vague descriptions like "helps with code"
  • Grant unnecessary tools — least privilege
  • Expect agents to spawn other agents (not allowed)
  • Forget agents start with clean context (latency)
// Skills
Do
  • Write specific descriptions with keywords users would say
  • Use {baseDir} for portable script paths
  • Leverage progressive disclosure: keep SKILL.md under 5k tokens
  • Put heavy logic in scripts/ (output enters context, not code)
Don't
  • Put SKILL.md directly in skills/ (needs subdirectory)
  • Use tabs in YAML frontmatter (spaces only)
  • Hardcode absolute paths
  • Forget chmod +x on scripts
// Plugins
Do
  • Put only plugin.json inside .claude-plugin/
  • Use ${CLAUDE_PLUGIN_ROOT} for all internal paths
  • Test with claude --debug to see loading errors
  • Keep plugin self-contained (no ../ paths)
Don't
  • Put commands/, agents/, skills/ inside .claude-plugin/
  • Use reserved marketplace names
  • Reference files outside plugin directory
  • Forget to namespace commands (/plugin-name:command)

Common errors & fixes

ErrorCauseFix
Subagent not appearingFile not in agents/Move to .claude/agents/
Skill not loadingSKILL.md in wrong locationMust be .claude/skills/<n>/SKILL.md
Plugin commands missingWrong directory structureEnsure commands/ at plugin root
Hook not firingScript not executablechmod +x script.sh
Path errors after installAbsolute paths usedUse ${CLAUDE_PLUGIN_ROOT} or {baseDir}
YAML parse errorTabs or missing ---Use spaces, ensure frontmatter starts line 1

//Conclusion

Claude Code's extensibility architecture follows a composition pattern: skills provide atomic capabilities, subagents combine skills with isolated context for complex tasks, and plugins bundle everything into distributable packages.

The key insight is that each mechanism operates at a different level of abstraction -- skills expand prompts, subagents delegate execution, and plugins organize distribution.

For most coding workflows: start with skills for reusable instructions, add subagents when you need specialized delegation with isolated context, and wrap everything in a plugin when you need to share across teams or projects.

Working on production AI?

I'm Sathya — I help teams ship RAG pipelines, MCP servers, and agentic products from Ghent, Belgium.

Visit happysathya.com →