Claude Code Extensibility Guide

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

How 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

Directory 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.md← Required: 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.json← Plugin manifest
└── .mcp.json← MCP server configs
User-Level Locations (~/.claude/)
~/.claude/← Applies to all projects
├── agents/← User subagents
├── skills/← User skills
├── commands/← User slash commands
└── settings.json

Subagents: 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

Problem How Subagents Help
Context pollution Each runs in isolated context window
Repetitive instructions Define expertise once, reuse everywhere
Tool sprawl Limit each subagent to relevant tools only
Team consistency Share 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
1 User Request or Automatic Match
User: "Review my code changes" → Claude matches task to agent description
2 Discovery
Scans .claude/agents/ for matching agent configs
3 Spawn 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
4 Execute
Subagent runs git diff, reads files, applies checklist, formats findings
5 Return Results
Review findings injected into main conversation; agentId saved for potential resume

Real-World Examples

Test Runner Subagent

.claude/agents/test-runner.md markdown
---
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.md markdown
---
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

Skills: 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 1 Metadata (~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 2 Instructions (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 3 Resources (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.md markdown
---
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
1 User Request
User: "Review my PR" → Claude scans <available_skills> in system prompt
2 Tool Call
{ "name": "Skill", "input": { "command": "code-review" } }
3 Skill 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
4 Execute in Current Context
Claude follows injected instructions—runs scripts, reads references. Script OUTPUT enters context, not source code (efficient!)
5 Response
Results in same conversation (no new context window)

Real-World Examples

Commit Message Generator

.claude/skills/commit-messages/SKILL.md markdown
---
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.md markdown
---
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;
```

Plugins: 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 directory
│ └── plugin.json← REQUIRED: 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.json← MCP server definitions
└── README.md
⚠️ Critical
  • commands/, agents/, skills/, hooks/ go at ROOT level
  • NOT inside .claude-plugin/ (common mistake!)

Plugin Manifest

.claude-plugin/plugin.json json
{
  // ═══════════════════════════════════════════════════════════
  // 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 - supplements default locations)
  // ═══════════════════════════════════════════════════════════
  "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
1 Install Command
claude plugin install formatter@marketplace
2 Discovery Phase
  • Locate .claude-plugin/plugin.json
  • Validate manifest schema
  • Check for name conflicts
3 Installation Phase
  • Copy plugin directory to cache
  • Resolve ${CLAUDE_PLUGIN_ROOT}
  • Register with scope: user | project | local
4 Component 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
5 Ready to Use
Plugin components available in Claude Code

Comparison: 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

Feature Subagents Skills Plugins
Primary purpose Delegate to specialists Expand prompts Bundle & share
Context Own isolated window Same conversation Container for others
Location .claude/agents/*.md .claude/skills/*/SKILL.md */.claude-plugin/
Invocation Auto or explicit Auto via Skill tool Contains other types
Tool access Configurable per agent Scoped via allowed-tools Inherited by contents
Model override Yes Yes Via contained agents
Resumable Yes (agentId) No N/A
Shareability Copy .md file Copy skill folder Install from marketplace

Use Case Mapping

Scenario Best Choice Why
Code review automation Subagent Needs isolated context, specialized tools
Test generation Subagent Complex multi-step process, tool access
Documentation generation Skill or Subagent Skill for templates, subagent for full docs
Linting/formatting Plugin with hooks Triggers automatically after edits
API scaffolding Skill Inject templates into current context
Project conventions Skill Expand prompts with team standards
Team tooling bundle Plugin Distribute multiple extensions together

Best 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

Error Cause Fix
Subagent not appearing File not in agents/ Move to .claude/agents/
Skill not loading SKILL.md in wrong location Must be .claude/skills/<n>/SKILL.md
Plugin commands missing Wrong directory structure Ensure commands/ at plugin root
Hook not firing Script not executable chmod +x script.sh
Path errors after install Absolute paths used Use ${CLAUDE_PLUGIN_ROOT} or {baseDir}
YAML parse error Tabs 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.