Official Claude Code plugin.json schema reference and validation guide. Use when creating or troubleshooting plugin.json manifest files. Covers all fields, auto-discovery behavior, path formats, and common validation errors.
Install
npx skillscat add mikeparcewski/wicked-garden/plugin-json-schema Install via the SkillsCat registry.
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-discoveredKey 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.pyDebugging
# 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