--- name: claude-code-plugin-development description: This skill should be used when the user asks to "create a plugin", "build a plugin", "write a plugin", or wants to bundle agents, hooks, commands, skills, or MCP servers into a distributable Claude Code plugin. --- # Claude Code Plugin Development Create distributable plugins that bundle commands, agents, skills, hooks, MCP servers, and LSP servers. **Official docs:** https://code.claude.com/docs/en/plugins-reference ## Quick Reference You MUST read these references for detailed schemas and examples: - [Plugin Manifest](./references/plugin-manifest.md) - Complete plugin.json schema - [Plugin Components](./references/plugin-components.md) - Commands, agents, skills, hooks, MCP, LSP - [CLI Commands](./references/cli-commands.md) - Install, uninstall, enable, disable, update - [Debugging](./references/debugging.md) - Common issues and troubleshooting ## Plugin Structure ``` my-plugin/ ├── .claude-plugin/ │ └── plugin.json # Required manifest ├── commands/ # Slash commands (.md files) ├── agents/ # Subagents (.md files) ├── skills/ # Skills (subdirs with SKILL.md) ├── hooks/ │ └── hooks.json # Hook configuration ├── .mcp.json # MCP server definitions ├── .lsp.json # LSP server configurations └── scripts/ # Hook and utility scripts ``` **Important:** Components go at plugin root, NOT inside `.claude-plugin/`. Only `plugin.json` belongs in `.claude-plugin/`. ## Marketplace Structure A marketplace can contain multiple plugins. The marketplace root has its own `.claude-plugin/marketplace.json`: ``` my-marketplace/ ├── .claude-plugin/ │ └── marketplace.json # Lists all plugins in this marketplace ├── plugins/ │ ├── plugin-a/ │ │ ├── .claude-plugin/ │ │ │ └── plugin.json │ │ └── skills/ │ └── plugin-b/ │ ├── .claude-plugin/ │ │ └── plugin.json │ └── commands/ ``` ### marketplace.json ```json { "name": "my-marketplace", "owner": { "name": "author-name" }, "plugins": [ { "name": "plugin-a", "source": "./plugins/plugin-a", "description": "First plugin description", "version": "1.0.0" }, { "name": "plugin-b", "source": "./plugins/plugin-b", "description": "Second plugin description", "version": "0.2.0" } ] } ``` **Critical:** When adding a new plugin to a marketplace: 1. Add it to `marketplace.json` or it won't be installable 2. If using release-please, add a jsonpath entry to the config for the new plugin's version ## Minimal plugin.json ```json { "name": "my-plugin", "version": "1.0.0", "description": "Brief plugin description" } ``` ## Installation Scopes | Scope | Location | Use case | |-------|----------|----------| | user | `~/.claude/settings.json` | Personal plugins (default) | | project | `.claude/settings.json` | Team plugins via version control | | local | `.claude/settings.local.json` | Project-specific, gitignored | | managed | `managed-settings.json` | Read-only managed plugins | ## Environment Variables Use `${CLAUDE_PLUGIN_ROOT}` for paths in hooks and MCP configs: ```json { "command": "${CLAUDE_PLUGIN_ROOT}/scripts/validate.sh" } ``` ## Plugin Components Summary | Component | Location | Format | |-----------|----------|--------| | Commands | `commands/` | Markdown with frontmatter | | Agents | `agents/` | Markdown with frontmatter | | Skills | `skills/*/SKILL.md` | Directories with SKILL.md | | Hooks | `hooks/hooks.json` | JSON configuration | | MCP servers | `.mcp.json` | MCP server config | | LSP servers | `.lsp.json` | Language server config | ## CLI Quick Reference ```bash # Install claude plugin install @ --scope user # Manage claude plugin enable claude plugin disable claude plugin update claude plugin uninstall # Debug claude --debug ``` ## Permissions **Problem:** Using `!` backticks to run plugin scripts fails with permission error: ``` Error: Bash command permission check failed for pattern "!`${CLAUDE_PLUGIN_ROOT}/scripts/my-script.sh 2>&1 || true`": This Bash command contains multiple operations. ``` **Cause:** `!` backticks have their own permission model separate from `allowed-tools`. Complex commands or scripts fail. **Solution:** Use the Bash tool instead of `!` backticks for scripts: ```yaml --- allowed-tools: Bash(${CLAUDE_PLUGIN_ROOT}/scripts/my-script.sh:*) --- Run the script: ```bash ${CLAUDE_PLUGIN_ROOT}/scripts/my-script.sh ``` ``` Simple git commands still work with `!` backticks: `!`git branch --show-current`` ## Common Issues **Plugin installed but commands don't appear?** The plugin may be disabled. Check `~/.claude/settings.json`: ```json "enabledPlugins": { "my-plugin@my-marketplace": false // ← Disabled! } ``` Fix with: `claude plugin enable my-plugin@my-marketplace` then restart Claude Code. **Local changes not picked up?** Use `claude plugin update ` or do a full reinstall: ```bash claude plugin marketplace remove my-marketplace claude plugin marketplace add ./ claude plugin install my-plugin@my-marketplace ``` ## Important After creating or modifying plugins, inform the user: > **Plugin changes take effect immediately** after installation. Use `claude --debug` to verify plugin loading. ## Checklist Before finalizing a plugin: - [ ] `plugin.json` has name, version, description - [ ] Components at plugin root (not in `.claude-plugin/`) - [ ] All paths use `${CLAUDE_PLUGIN_ROOT}` variable - [ ] Scripts are executable (`chmod +x`) - [ ] If part of a marketplace, plugin is listed in `marketplace.json` - [ ] If using release-please, add jsonpath for new plugin version in config - [ ] Test with `claude --debug` to verify loading