---
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/<name>/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
