Plugin Creator
Quick Start
Step 1: Create the plugin
my-plugin/
├── .claude-plugin/
│ └── plugin.json
└── commands/
└── hello.md
// .claude-plugin/plugin.json
{
"name": "my-plugin",
"version": "1.0.0",
"description": "My first Claude Code plugin"
}
## <!-- commands/hello.md --> ## description: Say hello Say "Hello from my-plugin!" to the user.
Step 2: Validate (required)
Always run validation after creating or modifying a plugin:
uv run .claude/skills/meta-plugin-creator/scripts/validate-plugin.py path/to/my-plugin
Fix any errors before publishing.
Plugin Manifest
Required Fields
{
"name": "plugin-name"
}
The name must be kebab-case with no spaces.
Complete Schema
{
"name": "my-plugin",
"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",
"lspServers": "./.lsp.json",
"outputStyles": "./styles/"
}
Field Reference
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Unique identifier (kebab-case) |
version | string | No | Semantic version (e.g., "1.2.0") |
description | string | No | Brief explanation |
author | object | No | {name, email, url} |
homepage | string | No | Documentation URL |
repository | string | No | Source code URL |
license | string | No | License identifier |
keywords | array | No | Discovery tags |
Component Paths
| Field | Type | Default 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 | - |
Custom paths supplement default directories—they don't replace them.
Directory Structure
my-plugin/ ├── .claude-plugin/ # Metadata (ONLY plugin.json here) │ └── plugin.json # Required manifest ├── commands/ # Slash commands (.md files) │ ├── deploy.md │ └── status.md ├── agents/ # Subagents (.md files) │ ├── reviewer.md │ └── tester.md ├── skills/ # Agent skills (directories) │ └── code-review/ │ ├── SKILL.md │ └── scripts/ ├── hooks/ # Event hooks │ └── hooks.json ├── .mcp.json # MCP server config ├── .lsp.json # LSP server config ├── scripts/ # Utility scripts │ └── format.sh ├── LICENSE └── CHANGELOG.md
Critical: Components go at plugin root, NOT inside
.claude-plugin/. Onlyplugin.jsonbelongs in.claude-plugin/.
Plugin Components
Commands
Location: commands/*.md
--- description: Deploy to production argument-hint: [environment] --- Deploy the application to $ARGUMENTS environment.
Commands are namespaced: /plugin-name:command-name
Agents
Location: agents/*.md
--- name: security-reviewer description: Review code for security vulnerabilities. Use proactively after auth changes. tools: Read, Grep, Glob model: haiku --- # Security Reviewer You review code for security issues...
Skills
Location: skills/*/SKILL.md
skills/
└── pdf-processor/
├── SKILL.md
├── reference.md
└── scripts/
Skills are auto-discovered based on context.
Hooks
Location: hooks/hooks.json or inline in plugin.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/format.sh"
}
]
}
]
}
}
MCP Servers
Location: .mcp.json or inline in plugin.json
{
"mcpServers": {
"my-server": {
"command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
"env": {
"DB_PATH": "${CLAUDE_PLUGIN_ROOT}/data"
}
}
}
}
LSP Servers
Location: .lsp.json or inline in plugin.json
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": {
".go": "go"
}
}
}
Required: command, extensionToLanguage
Environment Variables
| Variable | Purpose |
|---|---|
${CLAUDE_PLUGIN_ROOT} | Absolute path to plugin directory |
${CLAUDE_PROJECT_DIR} | Project root directory |
Always use ${CLAUDE_PLUGIN_ROOT} for plugin file paths.
Installation Scopes
| Scope | Settings File | Use Case |
|---|---|---|
user | ~/.claude/settings.json | Personal, all projects |
project | .claude/settings.json | Team, version controlled |
local | .claude/settings.local.json | Personal, gitignored |
managed | managed-settings.json | Enterprise, read-only |
Common Mistakes
| Mistake | Impact | Correct Pattern |
|---|---|---|
Components in .claude-plugin/ | Not discovered | Put at plugin root |
| Absolute paths | Break on install | Use ${CLAUDE_PLUGIN_ROOT} |
Missing plugin.json | Plugin won't load | Create in .claude-plugin/ |
Path traversal (../) | Files not copied | Keep files in plugin dir |
| Non-executable scripts | Hooks fail | chmod +x script.sh |
Validation
Run the validator to check plugin structure:
uv run .claude/skills/meta-plugin-creator/scripts/validate-plugin.py ./my-plugin
Checklist
- •
.claude-plugin/plugin.jsonexists withnamefield - • Components at plugin root (not in
.claude-plugin/) - • All paths relative, starting with
./ - • Scripts are executable
- • Uses
${CLAUDE_PLUGIN_ROOT}for paths - • Version follows semver (MAJOR.MINOR.PATCH)
Delegation
- •After creating/modifying plugins: Run
uv run .claude/skills/meta-plugin-creator/scripts/validate-plugin.py <plugin-dir> - •Pattern discovery: For existing plugin patterns, use
Exploreagent - •Component creation: Use
meta-skill-creator,meta-command-creator,meta-agent-creator,meta-hook-creator
Additional Resources
- •For CLI commands, marketplace, debugging: reference.md
References
- •Official Plugins Reference: code.claude.com/docs/en/plugins-reference
- •Discover Plugins: code.claude.com/docs/en/discover-plugins
- •Plugin Marketplaces: code.claude.com/docs/en/plugin-marketplaces