--- title: "Creating Claude Code Plugins" aliases: [claude-code-plugins, plugin-authoring, claude-plugins] tags: [claude-code, plugins, skills, agents, hooks, mcp, extensibility] sources: [raw/Create plugins.md] created: 2026-04-17 updated: 2026-04-17 --- # Creating Claude Code Plugins Plugins package skills, agents, hooks, MCP servers, LSP servers, and background monitors into a shareable, versioned unit. They are the distribution mechanism for Claude Code extensions. ## Standalone Config vs. Plugins | Approach | Skill names | Best for | |----------|-------------|----------| | **Standalone** (`.claude/` dir) | `/hello` | Personal workflows, single-project, quick experiments | | **Plugin** (dir with `.claude-plugin/plugin.json`) | `/my-plugin:hello` | Team sharing, multi-project reuse, marketplace distribution | - Start standalone → convert to plugin when ready to share - Plugins namespace skill names (`/plugin-name:skill`) to prevent conflicts ## Plugin Directory Structure ``` my-plugin/ ├── .claude-plugin/ │ └── plugin.json ← manifest (ONLY file inside .claude-plugin/) ├── skills/ │ └── code-review/ │ └── SKILL.md ├── commands/ ← legacy flat .md skills (use skills/ for new) ├── agents/ ← custom agent definitions ├── hooks/ │ └── hooks.json ├── monitors/ │ └── monitors.json ├── bin/ ← executables added to PATH ├── .mcp.json ← MCP server configs ├── .lsp.json ← LSP server configs └── settings.json ← default settings when plugin enabled ``` **Critical mistake to avoid:** Never put `skills/`, `agents/`, `hooks/`, or `commands/` inside `.claude-plugin/`. Only `plugin.json` lives there. ## Plugin Components ### Skills - Add `skills//SKILL.md` at plugin root - Include `description:` in frontmatter so Claude knows when to invoke - Model-invoked automatically based on task context - Run `/reload-plugins` after changes ```yaml --- description: Reviews code for best practices. Use when reviewing PRs or analyzing code quality. --- When reviewing code, check for: 1. Error handling 2. Security concerns 3. Test coverage ``` ### LSP Servers - Add `.lsp.json` at plugin root for language intelligence - Users must have the language server binary installed - Use pre-built marketplace LSP plugins for common languages (TS, Python, Rust) ```json { "go": { "command": "gopls", "args": ["serve"], "extensionToLanguage": { ".go": "go" } } } ``` ### Background Monitors - Add `monitors/monitors.json` — array of monitor entries - Each stdout line from `command` is delivered to Claude as a notification - Started automatically when plugin is active ```json [ { "name": "error-log", "command": "tail -F ./logs/error.log", "description": "Application error log" } ] ``` ### Default Settings - `settings.json` at plugin root applies config when plugin is enabled - Supported keys: `agent`, `subagentStatusLine` - Setting `agent` activates a plugin agent as the main thread ```json { "agent": "security-reviewer" } ``` ## Testing Locally ```shell # Load one plugin claude --plugin-dir ./my-plugin # Load multiple plugins claude --plugin-dir ./plugin-one --plugin-dir ./plugin-two ``` - Local `--plugin-dir` takes precedence over installed marketplace plugins of the same name - Run `/reload-plugins` during development to pick up changes without restart - Test skills: `/plugin-name:skill-name` | Check agents: `/agents` ## Migrating from Standalone to Plugin | Standalone (`.claude/`) | Plugin | |-------------------------|--------| | Available in one project | Shareable via marketplace | | `commands/` in `.claude/` | `commands/` at plugin root | | Hooks in `settings.json` | `hooks/hooks.json` | | Manual copy to share | Install with `/plugin install` | After migrating, remove original `.claude/` files to avoid duplicates. ## Distribution 1. Add `README.md` with install + usage instructions 2. Use semantic versioning in `plugin.json` 3. Submit to official marketplace via `claude.ai/settings/plugins/submit` or `platform.claude.com/plugins/submit` 4. Distribute through a plugin marketplace (official or team-hosted) ## Key Takeaways - Plugin root structure: manifest in `.claude-plugin/plugin.json`, everything else at root level - Skills are model-invoked; slash commands are user-invoked — they live in different dirs (`skills/` vs `commands/`) - Use `--plugin-dir` for local testing; run `/reload-plugins` to hot-reload changes - Background monitors run automatically and stream stdout lines to Claude as notifications - `settings.json` can activate a plugin agent as the default main-thread agent - Start with standalone `.claude/` config, convert to plugin when ready to distribute - Plugin skill names are always namespaced: `/plugin-name:skill-name` ## Related - [[wiki/claude-code/custom-subagents|Custom Subagents]] — agent definitions used inside plugins - [[wiki/claude-code/mcp-integration|MCP Integration]] — `.mcp.json` for adding MCP servers to a plugin - [[wiki/claude-code/overview|Claude Code Overview]] — full product context - [[wiki/agent-sdk/_index|Agent SDK]] — building agents that plugins can wrap ## Sources - Source: `raw/Create plugins.md` - Original: https://code.claude.com/docs/en/plugins