Claude Code plugin.json Schema Reference
Complete reference for Claude Code plugin manifest files.
Minimal Valid plugin.json
For plugins using standard directory structures, this is all you need:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Brief description of the plugin"
}
Auto-discovery will automatically load components from standard locations.
Complete Schema
{
"name": "plugin-name",
"version": "1.2.0",
"description": "Brief plugin description",
"author": {
"name": "Author Name",
"email": "author@example.com",
"url": "https://github.com/author"
},
"homepage": "https://docs.example.com/plugin",
"repository": "https://github.com/author/plugin",
"license": "MIT",
"keywords": ["keyword1", "keyword2"],
"commands": "./custom/commands/",
"agents": "./custom/agents/",
"skills": "./custom/skills/",
"hooks": "./config/hooks.json",
"mcpServers": "./mcp-config.json",
"outputStyles": "./styles/",
"lspServers": "./.lsp.json"
}
Field Reference
Required Fields
| Field | Type | Description |
|---|---|---|
name |
string | Unique identifier, kebab-case, max 64 chars |
version |
string | Semantic version (x.y.z) |
description |
string | Brief explanation of the plugin |
Optional Metadata Fields
| Field | Type | Description |
|---|---|---|
author |
object | {name, email?, url?} |
homepage |
string | Documentation URL |
repository |
string | Source code URL |
license |
string | License identifier (MIT, Apache-2.0, etc.) |
keywords |
array | Discovery tags (strings) |
Component Path Fields
| Field | Type | Auto-Discovery Location |
|---|---|---|
commands |
string | array | commands/ |
agents |
string | array | agents/ |
skills |
string | array | skills/ |
hooks |
string | object | hooks/hooks.json |
mcpServers |
string | object | .mcp.json |
lspServers |
string | object | .lsp.json |
outputStyles |
string | array | (none) |
Auto-Discovery
Claude Code automatically loads components from standard directories without needing explicit paths in plugin.json:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Only manifest required here
├── commands/ # Auto-discovered: all .md files
├── agents/ # Auto-discovered: all .md files
├── skills/ # Auto-discovered: subdirs with SKILL.md
├── hooks/
│ └── hooks.json # Auto-discovered
├── .mcp.json # Auto-discovered
└── .lsp.json # Auto-discovered
Key insight: If using standard directories, omit the fields entirely from plugin.json. Explicit paths are only needed for non-standard locations.
When to Use Explicit Paths
Use explicit paths only when components are in non-standard locations:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Plugin with custom paths",
"commands": "./src/custom-commands/",
"agents": ["./ai/agents/reviewer.md", "./ai/agents/tester.md"],
"hooks": "./config/hooks.json"
}
Custom paths supplement (don't replace) auto-discovered components.
Path Format Rules
Correct Path Formats
// Directory path
"commands": "./custom/commands/"
// Single file path
"hooks": "./config/hooks.json"
// Array of paths
"agents": ["./agents/agent1.md", "./agents/agent2.md"]
Invalid Path Formats (Will Cause Validation Errors)
// WRONG: Missing leading ./
"commands": "commands/"
// WRONG: Absolute path
"commands": "/Users/me/plugins/commands/"
// WRONG: Path traversal (../)
"commands": "../shared/commands/"
// WRONG: Relative to plugin.json location
"commands": "../commands"
Inline Configuration
hooks, mcpServers, and lspServers can be inline objects instead of file paths:
Inline Hooks
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh"
}
]
}
]
}
}
Inline MCP Servers
{
"mcpServers": {
"database": {
"command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"]
}
}
}
Common Validation Errors
"hooks: Invalid input"
- Cause: Using path traversal (
../) or wrong type - Fix: Use
./hooks/hooks.jsonor omit field for auto-discovery
"commands: Invalid input"
- Cause: Wrong path format or invalid type
- Fix: Use string (
"./commands/") or array (["./cmd.md"]), or omit for auto-discovery
"agents: Invalid input"
- Cause: Wrong path format, often using object instead of string/array
- Fix: Use string (
"./agents/") or array (["./agent.md"]), or omit for auto-discovery
General Validation Failures
- Check all paths start with
./ - Remove component fields if using standard directories
- Verify no path traversal (
../) - Ensure arrays contain only strings (paths)
Best Practices
- Prefer minimal manifests - Only specify what's non-standard
- Use auto-discovery - Put components in standard directories
- Avoid explicit paths for standard locations - Don't add
"commands": "./commands"if that's the default - Use
${CLAUDE_PLUGIN_ROOT}- In hook scripts for portable paths - Validate before publishing - Run
claude plugin validate /path/to/plugin
Directory Structure Template
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Minimal manifest
├── README.md # Plugin documentation
├── commands/ # Slash commands (auto-discovered)
│ ├── deploy.md
│ └── status.md
├── agents/ # Agents (auto-discovered)
│ └── reviewer.md
├── skills/ # Skills (auto-discovered)
│ └── analysis/
│ └── SKILL.md
├── hooks/ # Hooks (auto-discovered)
│ ├── hooks.json
│ └── scripts/
│ └── post-edit.py
└── scripts/ # Shared scripts
└── utils.py
Debugging
# Validate plugin structure
claude plugin validate /path/to/plugin
# Debug mode for detailed loading info
claude --debug
# Check what components are loaded
claude /help # Lists available commands from plugins
Converted and distributed by TomeVault — claim your Tome and manage your conversions.