Plugin Structure for Claude Code
Overview
Claude Code plugins follow a standardized directory structure with automatic component discovery. Understanding this structure enables creating well-organized, maintainable plugins that integrate seamlessly with Claude Code.
Key concepts:
- Conventional directory layout for automatic discovery
- Manifest-driven configuration in
.claude-plugin/plugin.json
- Component-based organization (commands, agents, skills, hooks)
- Portable path references using
${CLAUDE_PLUGIN_ROOT}
- Explicit vs. auto-discovered component loading
Directory Structure
Every Claude Code plugin follows this organizational pattern:
plugin-name/
βββ .claude-plugin/
β βββ plugin.json # Required: Plugin manifest
βββ commands/ # Slash commands (.md files)
βββ agents/ # Subagent definitions (.md files)
βββ skills/ # Agent skills (subdirectories)
β βββ skill-name/
β βββ SKILL.md # Required for each skill
βββ hooks/
β βββ hooks.json # Event handler configuration
βββ .mcp.json # MCP server definitions
βββ scripts/ # Helper scripts and utilities
Critical rules:
- Manifest location: The
plugin.json manifest MUST be in .claude-plugin/ directory
- Component locations: All component directories (commands, agents, skills, hooks) MUST be at plugin root level, NOT nested inside
.claude-plugin/
- Optional components: Only create directories for components the plugin actually uses
- Naming convention: Use kebab-case for all directory and file names
Plugin Manifest (plugin.json)
The manifest defines plugin metadata and configuration. Located at .claude-plugin/plugin.json:
Required Fields
{
"name": "plugin-name"
}
Name requirements:
- Use kebab-case format (lowercase with hyphens)
- Must be unique across installed plugins
- No spaces or special characters
- Example:
code-review-assistant, test-runner, api-docs
Recommended Metadata
{
"name": "plugin-name",
"version": "1.0.0",
"description": "Brief explanation of plugin purpose",
"author": {
"name": "Author Name",
"email": "[email protected]",
"url": "https://example.com"
},
"homepage": "https://docs.example.com",
"repository": "https://github.com/user/plugin-name",
"license": "MIT",
"keywords": ["testing", "automation", "ci-cd"]
}
Version format: Follow semantic versioning (MAJOR.MINOR.PATCH)
Keywords: Use for plugin discovery and categorization
Component Path Configuration
Specify custom paths for components (supplements default directories):
{
"name": "plugin-name",
"commands": "./custom-commands",
"agents": ["./agents", "./specialized-agents"],
"hooks": "./config/hooks.json",
"mcpServers": "./.mcp.json"
}
Important: Custom paths supplement defaultsβthey don't replace them. Components in both default directories and custom paths will load.
Path rules:
- Must be relative to plugin root
- Must start with
./
- Cannot use absolute paths
- Support arrays for multiple locations
Component Organization
Commands
Location: commands/ directory
Format: Markdown files with YAML frontmatter
Auto-discovery: All .md files in commands/ load automatically
Example structure:
commands/
βββ review.md # /review command
βββ test.md # /test command
βββ deploy.md # /deploy command
File format:
---
name: command-name
description: Command description
---
Command implementation instructions...
Usage: Commands integrate as native slash commands in Claude Code
Agents
Location: agents/ directory
Format: Markdown files with YAML frontmatter
Auto-discovery: All .md files in agents/ load automatically
Example structure:
agents/
βββ code-reviewer.md
βββ test-generator.md
βββ refactorer.md
File format:
---
description: Agent role and expertise
capabilities:
- Specific task 1
- Specific task 2
---
Detailed agent instructions and knowledge...
Usage: Users can invoke agents manually, or Claude Code selects them automatically based on task context
Skills
Location: skills/ directory with subdirectories per skill
Format: Each skill in its own directory with SKILL.md file
Auto-discovery: All SKILL.md files in skill subdirectories load automatically
Example structure:
skills/
βββ api-testing/
β βββ SKILL.md
β βββ scripts/
β β βββ test-runner.py
β βββ references/
β βββ api-spec.md
βββ database-migrations/
βββ SKILL.md
βββ examples/
βββ migration-template.sql
SKILL.md format:
---
name: Skill Name
description: When to use this skill
version: 1.0.0
---
Skill instructions and guidance...
Supporting files: Skills can include scripts, references, examples, or assets in subdirectories
Usage: Claude Code autonomously activates skills based on task context matching the description
Hooks
Location: hooks/hooks.json or inline in plugin.json
Format: JSON configuration defining event handlers
Registration: Hooks register automatically when plugin enables
Example structure:
hooks/
βββ hooks.json # Hook configuration
βββ scripts/
βββ validate.sh # Hook script
βββ check-style.sh # Hook script
Configuration format:
{
"PreToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "bash ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh",
"timeout": 30
}]
}]
}
Available events: PreToolUse, PostToolUse, Stop, SubagentStop, SessionStart, SessionEnd, UserPromptSubmit, PreCompact, Notification
Usage: Hooks execute automatically in response to Claude Code events
MCP Servers
Location: .mcp.json at plugin root or inline in plugin.json
Format: JSON configuration for MCP server definitions
Auto-start: Servers start automatically when plugin enables
Example format:
{
"mcpServers": {
"server-name": {
"command": "node",
"args": ["${CLAUDE_PLUGIN_ROOT}/servers/server.js"],
"env": {
"API_KEY": "${API_KEY}"
}
}
}
}
Usage: MCP servers integrate seamlessly with Claude Code's tool system
Portable Path References
${CLAUDE_PLUGIN_ROOT}
Use ${CLAUDE_PLUGIN_ROOT} environment variable for all intra-plugin path references:
{
"command": "bash ${CLAUDE_PLUGIN_ROOT}/scripts/run.sh"
}
Why it matters: Plugins install in different locations depending on:
- User installation method (marketplace, local, npm)
- Operating system conventions
- User preferences
Where to use it:
- Hook command paths
- MCP server command arguments
- Script execution references
- Resource file paths
Never use:
- Hardcoded absolute paths (
/Users/name/plugins/...)
- Relative paths from working directory (
./scripts/... in commands)
- Home directory shortcuts (
~/plugins/...)
Path Resolution Rules
In manifest JSON fields (hooks, MCP servers):
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/tool.sh"
In component files (commands, agents, skills):
Reference scripts at: ${CLAUDE_PLUGIN_ROOT}/scripts/helper.py
In executed scripts:
#!/bin/bash
source "${CLAUDE_PLUGIN_ROOT}/lib/common.sh"
File Naming Conventions
Component Files
Commands: Use kebab-case .md files
code-review.md β /code-review
run-tests.md β /run-tests
api-docs.md β /api-docs
Agents: Use kebab-case .md files describing role
test-generator.md
code-reviewer.md
performance-analyzer.md
Skills: Use kebab-case directory names
api-testing/
database-migrations/
error-handling/
Supporting Files
Scripts: Use descriptive kebab-case names with appropriate extensions
validate-input.sh
generate-report.py
process-data.js
Documentation: Use kebab-case markdown files
api-reference.md
migration-guide.md
best-practices.md
Configuration: Use standard names
hooks.json
.mcp.json
plugin.json
Auto-Discovery Mechanism
Claude Code automatically discovers and loads components:
- Plugin manifest: Reads
.claude-plugin/plugin.json when plugin enables
- Commands: Scans
commands/ directory for .md files
- Agents: Scans
agents/ directory for .md files
- Skills: Scans
skills/ for subdirectories containing SKILL.md
- Hooks: Loads configuration from
hooks/hooks.json or manifest
- MCP servers: Loads configuration from
.mcp.json or manifest
Discovery timing:
- Plugin installation: Components register with Claude Code
- Plugin enable: Components become available for use
- No restart required: Changes take effect on next Claude Code session
Override behavior: Custom paths in plugin.json supplement (not replace) default directories
Best Practices
Organization
-
Logical grouping: Group related components together