A Claude Code plugin is a self-contained directory that extends Claude Code with skills, subagents, hooks, MCP servers, LSP servers, monitors, and commands — bundled as one installable unit. This page is the complete reference: every component type, every schema field, every CLI command, verified against Anthropic’s official Claude Code plugin docs as of May 2026.
If you’re packaging functionality for distribution (your own or your team’s), this is the page to bookmark.
If you’ve read our Skills, Subagents, and Hooks references, this page is the “how to ship them together” story.
What a Plugin Is
From the official docs (May 2026): “A plugin is a self-contained directory of components that extends Claude Code with custom functionality. Plugin components include skills, agents, hooks, MCP servers, LSP servers, and monitors.”
In practice, a plugin is a Git repository (or local directory) with:
.claude-plugin/plugin.json— the manifestskills/— slash-command skills (orcommands/for simple ones)agents/— specialized subagentshooks/hooks.json— event-driven hooks.mcp.json— MCP servers bundled with the plugin.lsp.json— LSP servers for language intelligencemonitors/monitors.json— background watchers
Plugins are distributed via plugin marketplaces (or installed from a local path / Git URL) and managed by Claude Code’s /plugin interface.
Why Plugins (vs Loose Skills / Subagents / Hooks)
Skills, subagents, and hooks all work standalone — you don’t need a plugin to use them. So when is plugin packaging worth it?
| Need | Loose components | Plugin |
|---|---|---|
| Single user, single project | ✅ Drop files into .claude/skills/ etc. | Overkill |
| Reusable across your projects | Copy files around | ✅ Install once, available everywhere |
| Share with your team | Git submodule or manual sync | ✅ Plugin install |
| Public distribution | — | ✅ Marketplace |
| Bundle skills + hooks + MCP together | Manual coordination | ✅ Atomic install/uninstall |
| Version & update | Manual | ✅ Plugin update flow |
Rule of thumb: if more than 2 people use your component, plugin-ize it.
The Plugin Manifest (plugin.json)
Located at .claude-plugin/plugin.json (note: inside .claude-plugin/, while other components live at the plugin root). Minimal example:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Brief description",
"author": {
"name": "Your Name",
"email": "[email protected]"
}
}
Optional plugin.json fields can inline hooks, mcpServers, lspServers, monitors, userConfig (for user-provided values like API endpoints), and dependencies (other plugins required).
Critical layout rule from the docs: “Components must be at the plugin root, not inside .claude-plugin/, with only plugin.json belonging in .claude-plugin/ while commands/, agents/, and hooks/ stay at root level.”
The 7 Component Types
1. Skills
Plugins add skills as /name slash commands.
- Location:
skills/<skill-name>/SKILL.md(directories) orcommands/<command>.md(single files) - Auto-discovered when the plugin is installed
- Claude invokes them automatically based on task context, or users invoke manually via
/skill-name
Skill files can include supporting files (reference docs, scripts, templates) alongside SKILL.md. See our Skills guide for SKILL.md authoring.
2. Agents (Subagents)
Specialized subagents Claude can delegate to.
- Location:
agents/<agent-name>.md - Frontmatter fields:
name,description,model,effort,maxTurns,tools,disallowedTools,skills,memory,background,isolation
Plugin-specific security restrictions (different from user-defined agents): “For security reasons, hooks, mcpServers, and permissionMode are not supported for plugin-shipped agents.” If you need these, the user has to copy the agent file from the plugin into their own .claude/agents/.
The only valid isolation value for plugin agents is "worktree".
For full subagent reference, see Claude Code Subagents: Complete 2026 Reference.
3. Hooks
Event-driven shell commands, HTTP webhooks, MCP tool calls, prompts, or agents.
- Location:
hooks/hooks.json(separate file) or inline inplugin.jsonunder ahookskey - 27 event types supported (same as user hooks): SessionStart, PreToolUse, PostToolUse, PostToolBatch, SubagentStart, TaskCreated, etc. — see Hooks Complete Reference for the full list
Example hooks/hooks.json:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/format-code.sh"
}
]
}
]
}
}
${CLAUDE_PLUGIN_ROOT} is the plugin’s installation directory — use it for paths to scripts and assets inside the plugin.
4. MCP Servers
Bundle MCP servers that auto-start when the plugin is enabled.
- Location:
.mcp.json(plugin root) or inline inplugin.jsonundermcpServers - Auto-start when plugin enabled, auto-stop when disabled
- Configured independently of user-level MCP servers (don’t conflict)
Example .mcp.json:
{
"mcpServers": {
"plugin-database": {
"command": "${CLAUDE_PLUGIN_ROOT}/servers/db-server",
"args": ["--config", "${CLAUDE_PLUGIN_ROOT}/config.json"],
"env": {
"DB_PATH": "${CLAUDE_PLUGIN_ROOT}/data"
}
}
}
}
5. LSP Servers
Language Server Protocol servers that give Claude real-time code intelligence (diagnostics, go-to-definition, hover info).
- Location:
.lsp.json(plugin root) or inline inplugin.jsonunderlspServers - Required fields:
command,extensionToLanguage - Optional:
args,transport(stdioorsocket),env,initializationOptions,settings,workspaceFolder,startupTimeout,shutdownTimeout,restartOnCrash,maxRestarts
Example for Go:
{
"go": {
"command": "gopls",
"args": ["serve"],
"extensionToLanguage": { ".go": "go" }
}
}
Warning from official docs: “You must install the language server binary separately.” LSP plugins configure how Claude Code connects to a language server, but don’t include the server itself. pip install pyright, npm install -g typescript-language-server, etc.
Official marketplace plugins include pyright-lsp (Python), typescript-lsp, rust-analyzer-lsp.
6. Monitors
Background commands the plugin starts when it activates. Each monitor runs a shell command for the lifetime of the session and delivers every stdout line to Claude as a notification.
- Location:
monitors/monitors.jsonor inline inplugin.json - Requirement: Claude Code v2.1.105 or later
- Constraint: Interactive CLI sessions only, runs unsandboxed at the same trust level as hooks
Example:
[
{
"name": "deploy-status",
"command": "\"${CLAUDE_PLUGIN_ROOT}\"/scripts/poll-deploy.sh ${user_config.api_endpoint}",
"description": "Deployment status changes"
},
{
"name": "error-log",
"command": "tail -F ./logs/error.log",
"description": "Application error log",
"when": "on-skill-invoke:debug"
}
]
The optional when field lets a monitor start only when a specific skill is invoked, rather than at every session start.
7. Commands
Lightweight markdown-only versions of Skills. Same /name invocation pattern.
- Location:
commands/<command>.md - No frontmatter required (unlike Skills)
- Use when: the workflow is short enough to be a single markdown file with no supporting scripts
Layout Cheat Sheet
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Manifest (the ONLY thing in .claude-plugin/)
├── skills/
│ └── my-skill/
│ ├── SKILL.md
│ └── reference.md
├── commands/
│ └── quick-cmd.md
├── agents/
│ └── code-reviewer.md
├── hooks/
│ └── hooks.json
├── .mcp.json
├── .lsp.json
├── monitors/
│ └── monitors.json
└── README.md
The single layout rule that breaks half of all “my plugin doesn’t work” reports: everything except plugin.json lives at the plugin root, not inside .claude-plugin/.
CLI Commands
| Command | What it does |
|---|---|
/plugin list | List installed plugins |
/plugin install <source> | Install from marketplace, local path, or Git URL |
/plugin uninstall <name> | Remove a plugin |
/plugin enable <name> | Activate a plugin |
/plugin disable <name> | Deactivate without uninstalling |
/plugin update [<name>] | Update plugins to latest version |
/plugin info <name> | Show details about a plugin |
Source URI formats for /plugin install:
# From marketplace
/plugin install caveman
# From Git URL
/plugin install https://github.com/user/my-plugin
# From local directory
/plugin install ~/dev/my-plugin
# From npm-style scope
/plugin install @company/internal-plugin
Plugin Marketplaces
A plugin marketplace is a discoverable registry of plugins. The official Anthropic marketplace ships with Claude Code, and users can add additional marketplace URLs.
- Default marketplace:
https://marketplace.claude.ai/(or similar; check/plugin marketplace list) - Custom marketplaces:
/plugin marketplace add <url> - Marketplace format: a JSON catalog at
<marketplace>/catalog.jsonlisting plugins, versions, install URLs
For your team’s internal plugins, you can run a private marketplace at your company URL.
Production Patterns
Pattern 1: Team Onboarding Plugin
Bundle skills + hooks + MCP servers as a single plugin so new teammates get the same Claude Code setup with one command:
acme-onboarding/
├── .claude-plugin/plugin.json
├── skills/
│ ├── deploy/SKILL.md
│ └── postmortem/SKILL.md
├── hooks/hooks.json # secret-guard, format-after-edit, etc.
└── .mcp.json # internal API MCP server
New hire runs /plugin install acme-onboarding once → has same skills, hooks, MCP as the rest of the team.
Pattern 2: Vendor SDK Plugin
A vendor (say, Linear) ships a plugin that gives Claude Code access to their API:
linear-plugin/
├── .claude-plugin/plugin.json
├── skills/
│ ├── create-issue/SKILL.md
│ ├── list-issues/SKILL.md
│ └── sprint-summary/SKILL.md
└── .mcp.json # Linear MCP server
Users install once, Claude can talk to Linear without per-project config.
Pattern 3: Language Stack Plugin
LSP server + companion skills + linting hooks bundled for a specific language:
typescript-stack/
├── .claude-plugin/plugin.json
├── .lsp.json # typescript-language-server
├── hooks/hooks.json # PostToolUse → prettier --write
├── skills/
│ ├── add-type-guards/SKILL.md
│ └── eliminate-anys/SKILL.md
└── agents/
└── type-reviewer.md
Pattern 4: Caveman-Style Output Compression
The most popular example as of May 2026 — see our Caveman.MD complete guide for details. The Caveman plugin bundles:
- Rules in
skills/caveman/SKILL.md - Commands:
/caveman,/caveman-commit,/caveman-review,/caveman-stats - MCP middleware:
caveman-shrinkfor compressing other servers’ tool descriptions
One plugin install → 65% output token reduction across the entire session.
Security Model
Plugin components run at user trust level. Three key restrictions:
- Plugin agents cannot use
hooks,mcpServers,permissionMode— these fields are silently ignored if present in plugin agent frontmatter. If a user wants those, they must copy the agent file out of the plugin into~/.claude/agents/or.claude/agents/. - Plugin hooks run unsandboxed — same trust as user hooks. Verify plugin sources before installing.
disableAllHooks: truein user/project settings does NOT disable plugin hooks if those hooks are deployed via managed policy settings. Only managed-leveldisableAllHookscan disable managed hooks.
For untrusted plugins, audit before install:
git clone https://github.com/<user>/<plugin>
cd <plugin>
# Read plugin.json + hooks/hooks.json + any scripts before /plugin install
Common Pitfalls
- Putting components inside
.claude-plugin/. Onlyplugin.jsonlives there. Skills, agents, hooks, MCP, LSP, monitors all live at the plugin root. - Forgetting
${CLAUDE_PLUGIN_ROOT}in scripts. Without this variable, your shell commands reference paths that don’t exist for the user. Always:"command": "${CLAUDE_PLUGIN_ROOT}/scripts/my-script.sh". - LSP plugin without the LSP binary. The plugin configures how to connect; you (or the user) must
pip install pyright/npm install -g <lsp>separately. The plugin docs explicitly warn about this. - Plugin agent using
mcpServersorhooksfrontmatter. Silently ignored. Either drop those fields, or document that the user must copy the agent file to use them. - Monitor running blocking commands. Monitors deliver every stdout line to Claude. If your command produces 1000 lines/minute, you’ll flood Claude’s context. Filter at the source:
tail -F log | grep ERROR. - Forgetting to bump
versionin plugin.json. Users won’t get updates if the version doesn’t change. CI: bump on each merge to main.
FAQ
What’s the difference between a plugin and a loose skill/subagent/hook?
A plugin is a packaged directory containing one or more components (skills, subagents, hooks, MCP, LSP, monitors). Loose components are individual files you drop into ~/.claude/skills/, ~/.claude/agents/, etc. Plugins are the right answer when you want to (1) reuse across projects, (2) share with teammates, (3) distribute publicly, or (4) bundle multiple component types atomically.
Can a plugin contain only skills, or do I need all 7 component types?
Skills-only is perfectly fine. The minimum plugin is .claude-plugin/plugin.json + one skill in skills/<name>/SKILL.md. Add other components only as needed. Many popular plugins (Caveman, Impeccable) are skills-heavy with just one or two supporting components.
Where does plugin.json go?
In .claude-plugin/plugin.json. .claude-plugin/ (with a dot) is the manifest directory inside your plugin root. Everything else (skills, agents, hooks, MCP, LSP, monitors) lives at the plugin root, NOT inside .claude-plugin/.
What’s ${CLAUDE_PLUGIN_ROOT}?
The plugin’s installation directory at runtime. Use it in any command/script path within your plugin: "command": "${CLAUDE_PLUGIN_ROOT}/scripts/my-script.sh". Claude Code substitutes the actual path when executing.
Can plugin agents use hooks or MCP servers?
No, for security reasons. Plugin agent frontmatter silently ignores hooks, mcpServers, and permissionMode. If a user wants those, they have to manually copy the agent file from the plugin into their own .claude/agents/ or ~/.claude/agents/.
How do I distribute a plugin to my team?
Three options: (1) Git URL — /plugin install https://github.com/team/plugin (simplest), (2) Local path — /plugin install ~/dev/team-plugin (development), (3) Private marketplace — host a catalog.json at your company URL and ask teammates to /plugin marketplace add https://.... Public distribution uses the Anthropic marketplace.
Do plugin hooks run if I set disableAllHooks: true?
It depends. User/project-level disableAllHooks: true disables your own hooks and plugin hooks installed via plugin packages. However, hooks deployed via managed policy settings (organization admin) survive — only managed-level disableAllHooks can disable those.
What’s a Monitor and how is it different from a Hook?
A monitor is a background shell command started when the plugin activates; every stdout line becomes a notification to Claude. A hook is event-driven and fires once per matching event (PreToolUse, PostToolUse, etc.). Use monitors for “always watch X for Claude” workflows (deploy status, error log tail). Use hooks for “do Y when Z happens” workflows.
Can I require a specific Claude Code version in plugin.json?
Yes — "engines": { "claude-code": ">=2.1.105" } in plugin.json. Useful for Monitors (require 2.1.105+) and other version-dependent features. Users with older Claude Code get a clear install-time error instead of mysterious runtime failures.
How do I update an installed plugin?
/plugin update <name> updates a single plugin to the latest version from its source. /plugin update (no name) updates all installed plugins. Updates respect version pinning if you specified "version": "1.2.x" in your install command.
Related Articles
- Claude Code Subagents: The Complete 2026 Reference
- Claude Code Hooks: The Complete 2026 Production Reference
- Caveman.MD: Token Compression Complete Guide
- AGENTS.md vs CLAUDE.md vs .cursor/rules: Three-Way Comparison
- 15 Best Claude Code Skills You Should Install in 2026
- Browse 165+ Real AI Coding Rules