ACTIVATE when creating a Claude Code plugin, writing plugin.json, marketplace.json, hooks.json, or structuring plugin directories. ACTIVATE for 'Claude plugin', 'plugin.json', 'marketplace.json', 'hooks.json', 'CLAUDE_PLUGIN_ROOT'. Covers: plugin directory structure, plugin.json/marketplace.json schemas, hooks.json format (matcher + hook types), CLAUDE_PLUGIN_ROOT portability, distribution best practices, validation commands. DO NOT use for: SKILL.md writing conventions (see npx-skills-conventions), general Claude Code usage.
From toolingnpx claudepluginhub fabiensalles/claude-marketplace --plugin toolingThis skill uses the workspace's default tool permissions.
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Migrates code, prompts, and API calls from Claude Sonnet 4.0/4.5 or Opus 4.1 to Opus 4.5, updating model strings on Anthropic, AWS, GCP, Azure platforms.
Configures Istio traffic management with VirtualServices, DestinationRules for routing, canary/blue-green deployments, circuit breakers, load balancing, and fault injection in service meshes.
Best practices for creating, structuring, and distributing Claude Code plugins and marketplaces, based on official documentation and the anthropics/claude-plugins-official repository.
plugin-name/
├── .claude-plugin/
│ └── plugin.json # Manifest (ONLY this file here)
├── commands/ # Slash commands (.md)
├── agents/ # Subagent definitions (.md)
├── skills/ # Skills (subdirectories with SKILL.md)
│ └── skill-name/
│ ├── SKILL.md
│ ├── scripts/
│ ├── references/
│ └── examples/
├── hooks/
│ ├── hooks.json # Hook configuration
│ └── scripts/ # Hook scripts
├── .mcp.json # MCP server definitions
├── .lsp.json # LSP configurations
├── settings.json # Default settings
├── scripts/ # Shared utilities
├── LICENSE
└── README.md
Critical rules:
.claude-plugin/ contains ONLY plugin.json — never nest components inside it{
"name": "plugin-name"
}
{
"name": "plugin-name",
"version": "1.0.0",
"description": "Brief plugin description",
"author": {
"name": "Author Name",
"email": "author@example.com",
"url": "https://github.com/author"
},
"repository": "https://github.com/author/plugin",
"license": "MIT",
"keywords": ["keyword1", "keyword2"]
}
{
"skills": "./skills/",
"agents": "./agents/agent-name.md",
"hooks": "./hooks/hooks.json",
"commands": "./commands/command-name.md",
"mcpServers": "./.mcp.json",
"lspServers": "./.lsp.json",
"outputStyles": "./styles/"
}
Path rules:
./{
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
"name": "marketplace-name",
"description": "Brief marketplace description",
"owner": {
"name": "Owner Name",
"email": "owner@example.com"
},
"metadata": {
"version": "1.0.0",
"description": "Detailed marketplace description"
},
"plugins": [
{
"name": "plugin-name",
"source": "./plugins/plugin-name",
"description": "Plugin description",
"version": "1.0.0",
"author": { "name": "Author" },
"category": "development",
"license": "MIT",
"keywords": ["keyword"],
"tags": ["community-managed"]
}
]
}
name — kebab-case, no spacesowner — object with name (required), email (optional)plugins — array of plugin entries, each with name and sourceclaude-code-marketplace, claude-code-plugins, claude-plugins-official, anthropic-marketplace, anthropic-plugins, agent-skills, life-sciences. Names impersonating official Anthropic marketplaces are blocked.
| Type | Format |
|---|---|
| Local path | "./plugins/name" |
| GitHub | { "source": "github", "repo": "org/repo", "ref": "main", "sha": "abc" } |
| Git URL | { "source": "url", "url": "https://github.com/org/repo.git" } |
| Git subdir | { "source": "git-subdir", "url": "org/repo", "path": "plugins/name" } |
| npm | { "source": "npm", "package": "name", "version": "^1.0" } |
development, productivity, security, testing, database, deployment, monitoring, design, learning
The official format uses nested matcher + hooks[] with type:
{
"description": "Human-readable description of hooks purpose",
"hooks": {
"PreToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/hooks/scripts/validate.sh",
"timeout": 30
}
]
}
],
"PostToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "python3 ${CLAUDE_PLUGIN_ROOT}/hooks/scripts/check.py",
"timeout": 10
}
]
}
]
}
}
| Type | Field | Description |
|---|---|---|
command | command | Shell command, receives JSON on stdin |
http | url | HTTP POST to endpoint |
prompt | prompt | Single-turn LLM evaluation |
agent | prompt | Agentic verifier with Read/Grep/Glob tools |
| Event | Matcher | Can block? |
|---|---|---|
SessionStart | startup, resume, clear, compact | No |
UserPromptSubmit | No | Yes (exit 2) |
PreToolUse | Tool name regex | Yes (exit 2) |
PostToolUse | Tool name regex | No |
Stop | No | Yes (exit 2) |
SubagentStart / SubagentStop | Agent type | No / Yes |
Notification | Types | No |
PreCompact / PostCompact | manual, auto | No |
Always use ${CLAUDE_PLUGIN_ROOT} for intra-plugin path references. Never hardcode paths.
In hooks.json: "command": "${CLAUDE_PLUGIN_ROOT}/scripts/tool.sh"
In MCP config: "args": ["${CLAUDE_PLUGIN_ROOT}/servers/server.js"]
In shell scripts: source "${CLAUDE_PLUGIN_ROOT}/lib/common.sh"
sha for reproducible builds in production marketplacesclaude --plugin-dir ./my-plugin/reload-pluginsclaude --debug or /debug# Validate marketplace
claude plugin validate .
# Validate individual plugin
claude plugin validate plugins/my-plugin
# Validate from within Claude Code
/plugin validate .
| Component | Convention | Example |
|---|---|---|
| Plugin | kebab-case | code-review-assistant |
| Skills | kebab-case directories | api-testing/ |
| Commands | kebab-case .md | run-tests.md |
| Agents | kebab-case .md | code-reviewer.md |
| Hooks | kebab-case with ext | validate-input.sh |
| Config | Standard names | hooks.json, .mcp.json |
Plugin skills are namespaced as /plugin-name:skill-name to prevent conflicts.