| name | description | allowed-tools |
|---|---|---|
plugin-maker |
Create, validate, and maintain Claude Code plugins. Use when the user wants to create a plugin, add a plugin, make a plugin, build a plugin, or mentions plugin creation. Also use when adding commands, agents, skills, or hooks to existing plugins, configuring plugin.json manifests, or debugging plugin discovery. |
Read Write Edit Bash Glob Grep |
Create discoverable Claude Code plugins that bundle commands, agents, skills, hooks, and MCP configurations.
- Plugins bundle components: A plugin is a container for related commands, agents, skills, hooks, and MCP configs
- Manifest-driven discovery: The
.claude-plugin/plugin.jsonfile makes the plugin discoverable - Convention over configuration: Standard directory names enable automatic component discovery
- Plugins vs Skills: Use plugins when bundling multiple component types; use standalone skills for single capabilities
Warning: Do not place
plugin.jsondirectly in the plugin directory. It must be inside the.claude-plugin/subdirectory for the plugin to be discovered.
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Required: manifest file (MUST be here)
├── README.md # Recommended: documentation
├── commands/ # Slash commands (*.md)
│ ├── my-command.md
│ └── help.md
├── agents/ # Subagent definitions (*.md)
│ └── my-agent.md
├── skills/ # Skills (subdirs with SKILL.md)
│ └── my-skill/
│ └── SKILL.md
├── hooks/ # Hook configurations
│ ├── hooks.json
│ └── handler.py
├── .mcp.json # MCP server configuration
└── .lsp.json # LSP server configuration
Every plugin requires .claude-plugin/plugin.json:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Brief description of what this plugin does"
}Optional author field for attribution:
{
"name": "my-plugin",
"version": "1.0.0",
"description": "Brief description of what this plugin does",
"author": {
"name": "Your Name",
"email": "you@example.com"
}
}mkdir -p ./my-plugin/.claude-plugin
mkdir -p ./my-plugin/commandsCreate .claude-plugin/plugin.json with required fields:
{
"name": "my-plugin",
"description": "What this plugin does"
}Add the components your plugin needs (see Component Quick Reference below).
Use the --plugin-dir flag to test your plugin without installing it:
claude --plugin-dir ./my-pluginThis loads your plugin for the current session only, allowing rapid iteration.
# Check manifest exists and is valid JSON
cat ./my-plugin/.claude-plugin/plugin.json | jq .
# List all components
ls -la ./my-plugin/Ask Claude to use your plugin's commands or agents to verify discovery works.
Slash commands users invoke explicitly. Plugin commands are namespaced as /plugin-name:command-name.
---
description: What this command does
argument-hint: [optional-args]
allowed-tools: ["Read", "Write", "Bash"]
---
# Command Name
Instructions for Claude when this command is invoked.
The user's input is available as $ARGUMENTS.
**Advanced argument access:**
- `$ARGUMENTS` - Full argument string
- `$1`, `$2`, `$3` - Individual arguments (space-separated)Fields:
| Field | Required | Description |
|---|---|---|
description |
Yes | Shown in /help and command completion |
argument-hint |
No | Hint text for arguments (e.g., [file-path]) |
allowed-tools |
No | Restrict available tools (JSON array) |
disable-model-invocation |
No | If true, only explicit /command triggers it |
model |
No | Override model: inherit, sonnet, opus, haiku |
Specialized subagents for parallel or delegated work.
---
name: my-agent
description: Use this agent when analyzing code for security issues. Examples: <example>Context: User asks about security\nuser: "Check this file for vulnerabilities"\nassistant: "I'll analyze with the security agent"</example>
model: sonnet
color: yellow
tools: ["Read", "Grep", "Glob"]
---
You are an expert at [specific task].
## Your Role
Detailed instructions for the agent...Fields:
| Field | Required | Description |
|---|---|---|
name |
Yes | Agent identifier (lowercase, hyphens) |
description |
Yes | When to use. Include Examples tags: <example>Context: ...\nuser: "..."\nassistant: "..."</example> |
model |
No | inherit, sonnet, opus, haiku |
color |
No | Visual indicator: yellow, blue, green, etc. |
tools |
No | Array of available tools |
Triggering Tip: Use <example> tags in descriptions for complex use cases. Include context, user message, and assistant response to guide invocation.
Model-invoked capabilities that Claude activates based on context. Plugin skills are namespaced as /plugin-name:skill-name.
---
name: my-skill
description: What this skill does. Use when user mentions [trigger terms].
---
# Skill Name
Instructions...Event-driven automation scripts. Use for validation, context injection, and workflow automation.
Hook Types:
- Prompt-based (recommended): LLM-driven decisions with
"type": "prompt" - Command-based: Bash scripts with
"type": "command"
{
"hooks": {
"PreToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "prompt",
"prompt": "Validate file write safety. Check: path traversal, credentials. Return 'approve' or 'deny'."
}]
}],
"Stop": [{
"matcher": "*",
"hooks": [{
"type": "prompt",
"prompt": "Verify task completion: tests run, build succeeded. Return 'approve' or 'block'."
}]
}]
}
}Available Events:
| Event | Trigger |
|---|---|
PreToolUse |
Before any tool executes |
PostToolUse |
After a tool executes |
UserPromptSubmit |
When user submits a prompt |
Stop |
When Claude wants to stop |
SubagentStop |
When subagent wants to stop |
SessionStart |
Session begins |
SessionEnd |
Session ends |
PreCompact |
Before context compaction |
Notification |
User notification sent |
Important: Use ${CLAUDE_PLUGIN_ROOT} for paths in hook commands.
See Hook Development Guide for comprehensive patterns.
Integrate Model Context Protocol servers for additional tools:
{
"mcpServers": {
"my-server": {
"command": "node",
"args": ["${CLAUDE_PLUGIN_ROOT}/mcp-server/index.js"],
"env": {
"NODE_ENV": "production"
}
}
}
}Server types: stdio, SSE, HTTP, WebSocket. Tools appear as mcp__plugin-name__tool-name.
Store per-project configuration with YAML frontmatter:
---
enabled: true
strict_mode: false
max_retries: 3
---
# Plugin Configuration
Settings documentation here.Usage:
- Read from hooks, commands, and agents
- Control plugin behavior per-project
- Store state and configuration
- Should be in
.gitignore
See Plugin Settings Guide for parsing techniques and patterns.
Configure Language Server Protocol servers for enhanced editor support:
{
"lspServers": {
"my-lsp": {
"command": "my-language-server",
"args": ["--stdio"],
"filetypes": ["mylang"]
}
}
}Fields:
| Field | Required | Description |
|---|---|---|
command |
Yes | The LSP server executable |
args |
No | Command-line arguments |
filetypes |
Yes | File extensions to activate for |
| Location | Purpose |
|---|---|
--plugin-dir ./path |
Development/testing (primary workflow) |
~/.claude/plugins/ |
Personal plugins (installed) |
.claude/plugins/ |
Project plugins (committed to git) |
| Feature | Standalone Skill | Plugin |
|---|---|---|
| Simplest option | One SKILL.md file | Multiple files/directories |
| Commands | No | Yes |
| Multiple skills | No | Yes |
| Agents | No | Yes |
| Hooks | No | Yes |
| MCP servers | No | Yes |
| LSP servers | No | Yes |
| Namespacing | None | /plugin-name:* |
| Distribution | Copy file | Package directory |
Create a plugin when:
- You need multiple component types (commands + agents, skills + hooks, etc.)
- You want to bundle and distribute related functionality
- Your team needs shared tooling with consistent behavior
Don't create a plugin when:
- You only need a single skill (use standalone skill instead)
- You only need a single command (consider a skill or CLAUDE.md instruction)
- The functionality is project-specific and simple
| Item | Convention | Example |
|---|---|---|
| Plugin directory | lowercase-hyphenated | my-plugin |
| plugin.json name | matches directory | "name": "my-plugin" |
| Commands directory | plural commands/ |
not command/ |
| Agents directory | plural agents/ |
not agent/ |
| Skills directory | plural skills/ |
not skill/ |
| Hooks directory | singular hooks/ |
with hooks.json inside |
Create:
mkdir -p ./my-plugin/.claude-pluginTest during development:
claude --plugin-dir ./my-pluginValidate manifest:
cat ./my-plugin/.claude-plugin/plugin.json | jq .Install plugin:
cp -r ./my-plugin ~/.claude/plugins/List installed plugins:
ls ~/.claude/plugins/*/
ls .claude/plugins/*/- Hook Development Guide - Events, prompt/command hooks, security patterns
- Plugin Settings Guide - Configuration files with YAML frontmatter
- Validation checklists
- Complete plugin examples
- Common mistakes
- Copy-paste templates