Chapter 7 · Plugins

Plugins — One Install, Whole Workflow

Slash commands, skills, subagents, MCP servers, and hooks bundled into a single installable package — with marketplaces to distribute them, a manifest that does real work, and a context price tag you can read before you buy.

01 · The Problem

Six chapters of setup, copied by hand, is how teams drift — a plugin installs it all in one command

Manual setup means installing slash commands one by one, creating subagents individually, configuring MCPs separately, wiring hooks, documenting everything — 2+ hours, and you hope teammates configure it correctly. Plugins are bundled collections of customizations — slash commands, subagents, MCP servers, and hooks — that install with a single command: 2 minutes, and the team reproduces the exact setup.

  • The highest-level extension mechanism — it bundles every feature from chapters 1–6 plus configuration
  • /plugin install pr-review → 3 slash commands, 3 subagents, 2 MCP servers, 4 hooks — ready to use
  • Four distribution tiers: Official (Anthropic, all users) · Community (public) · Organization (internal teams) · Personal (single developer)
The mental model: chapters 1–6 taught the instruments; a plugin is the orchestra packed in a flight case — versioned, shareable, and unpacked identically on every machine.
02 · Anatomy

A plugin is a directory with a manifest — every folder inside is a feature you already know

// .claude-plugin/plugin.json — the manifest
{
  "name": "my-first-plugin",
  "description": "A greeting plugin",
  "version": "1.0.0",
  "author": { "name": "Your Name" },
  "homepage": "https://example.com",
  "repository": "https://github.com/user/repo",
  "license": "MIT"
}

Plus optional top-level dirs: templates/, scripts/, docs/, tests/, and themes/ (ship custom Claude Code themes, v2.1.118+).

commands/Slash commands as Markdown files — chapter 1
skills/Agent Skills with SKILL.md files — chapter 3
agents/Custom subagent definitions — chapter 4
.mcp.jsonMCP server configurations — chapter 5
hooks/hooks.jsonEvent handlers — chapter 6
.lsp.jsonLSP servers for code intelligence
bin/Executables added to the Bash tool's PATH
settings.jsonDefaults applied when enabled (agent key)
Only .claude-plugin/plugin.json is structural — everything else is the same Markdown and JSON you wrote in earlier chapters, just living together so it ships together.
03 · The Install Pipeline

One command fans out into four configuration lanes — then converges to "ready"

1 · Request
User installs
/plugin install pr-review
download
2 · Manifest
Marketplace returns the plugin definition
name · version · components
extract
slash commandsconfigure ✓
subagentsconfigure ✓
MCP serversconnect ✓
hooksregister ✓
all ready
3 · Installed
Plugin ready ✅
every component live in the session

The lifecycle continues after install: use → update (when available) → disable → re-enable — components come and go as a unit, never one by one.

No marketplace required (v2.1.157+): plugins placed in .claude/skills directories auto-load without any marketplace at all. Scaffold a fresh one with claude plugin init <name>.
04 · Standalone vs Plugin

Plugins namespace their commands — and trade manual copies for versioned installs

Standalone /helloManual setup in CLAUDE.md — best for personal, project-specific workflows
Plugin /plugin-name:helloAutomated via plugin.json — best for sharing, distribution, team use

Spaced invocation (v2.1.136+): /myplugin review resolves to the canonical /myplugin:review. Either form works; the colon form is recommended in scripts.

InstallationManual copy → one command
Setup time5–15 min per feature → 2 min total
BundlingSingle file each → multiple components
Versioning / updatesManual → automatic, auto-available
Team sharingCopy files around → install ID
MarketplaceNo → yes
Use standalone slash commands for quick personal workflows; reach for a plugin when you want to bundle multiple features, share with a team, or publish for distribution.
05 · Manifest Powers

Plugins handle secrets, state, monitors, and defaults — each through its own channel

userConfig (v2.1.83+)Declare user-configurable options — a description, an optional default, and "sensitive": true values stored in the system keychain rather than plain-text settings files (API keys belong here)
${CLAUDE_PLUGIN_DATA} (v2.1.78+)Per-plugin persistent state directory that survives across sessions — caches, databases, usage logs. Created on install, removed on uninstall; reference it in hook commands like node ${CLAUDE_PLUGIN_DATA}/track-usage.js
monitors (v2.1.105)Background monitors that auto-arm"trigger": "session_start" arms when a session begins, "skill_invoke" when the plugin's skill fires. Streams stdout lines as events Claude can react to
settings.jsonDefault settings applied on installation — currently the agent key, which sets the plugin's main-thread agent (e.g. "agent": "agents/specialist-1.md"). Users can override in their own config
source: "settings" (v2.1.80+)Define a plugin inline in your settings file as a marketplace entry — no separate repository or marketplace needed for small local tools
Together these make a plugin stateful and configurable: secrets in the keychain, state in its own directory, watchers that arm themselves — none of which a copied Markdown file could carry.
06 · Code Intelligence

Plugins can ship a language server and a toolbox — diagnostics on every edit, binaries on PATH

.lsp.json — Language Server Protocol

{
  "go": {
    "command": "gopls",
    "args": ["serve"],
    "extensionToLanguage": {
      ".go": "go"
    }
  }
}

Once configured: instant diagnostics after edits, go-to-definition / find references, hover types, symbol listing. Optional fields tune transport, env, timeouts, and restartOnCrash. Official marketplace ships pyright-lsp, typescript-lsp, rust-lsp pre-configured.

bin/ — executables on the session PATH

my-plugin/
├── plugin.json
└── bin/
    └── my-tool   # chmod +x

# with the plugin enabled:
$ my-tool --help

While the plugin is enabled, bin/ is prepended to PATH — hooks, skills, and commands in the same plugin can shell out to its helpers by bare name. Mark files executable in the repo; git preserves the bit.

The LSP server's command must already be installed and on PATH (pip install pyright, rustup component add rust-analyzer) — the plugin carries the configuration, not the binary.
07 · Skill-Shaped Plugins

Three recent changes made a skill the lightest possible plugin

skills/ merge (v2.1.136+)A skills entry in plugin.json no longer hides the plugin's default skills/ directory — skills declared in both places are merged, so you can list a few highlights in the manifest without losing the rest
Root SKILL.md (v2.1.142+)A plugin with a top-level SKILL.md and no skills/ subdirectory is itself surfaced as a single skill — the plugin is the skill. An additional pattern for small single-skill plugins where directory layout adds no value
No marketplace needed (v2.1.157+)Plugins placed in .claude/skills directories auto-load without a marketplace. claude plugin init <name> scaffolds a new one
The on-ramp is now gradual: start with a bare SKILL.md, add a manifest when you need versioning, add commands / agents / hooks as the workflow grows — same folder the whole way.
08 · Worked Example

The pr-review plugin: one command orchestrates a hook, an MCP server, and three subagents

pr-review/
├── .claude-plugin/plugin.json
├── commands/
│   ├── review-pr.md
│   ├── check-security.md
│   └── check-tests.md
├── agents/
│   ├── security-reviewer.md
│   ├── test-checker.md
│   └── performance-analyzer.md
├── mcp/github-config.json
└── hooks/pre-review.js

Each agent is ~10 lines of frontmatter + focus areas; the GitHub MCP config reads ${GITHUB_TOKEN} from the environment — never hardcoded.

What /review-pr actually runs

  • pre-review.js hook validates you're in a git repo, warns on uncommitted changes
  • GitHub MCP fetches the PR data
  • security-reviewer, test-checker, performance-analyzer each analyze their slice
  • Findings synthesized: ✅ security clean · ⚠️ coverage 65%, recommend 80%+ · ✅ no perf impact · 📝 12 recommendations
This is the chapter's whole thesis in one run: hook gates, MCP feeds, subagents analyze, the command conducts — and a teammate gets the identical pipeline from one install.
09 · The Example Shelf

The chapter ships three complete plugins — each a different mix of the same parts

1pr-review

3 commands (/review-pr, /check-security, /check-tests) · 3 subagents · GitHub MCP · pre-review hook. Requires a GitHub token via export GITHUB_TOKEN.

2devops-automation

4 commands (/deploy, /rollback, /status, /incident) · 3 subagents (deployment-specialist, incident-commander, alert-analyzer) · Kubernetes MCP · shell scripts (deploy, rollback, health-check) · pre/post-deploy hooks.

3documentation

4 commands (/generate-api-docs, /generate-readme, /sync-docs, /validate-docs) · 3 subagents · GitHub docs MCP · templates: api-endpoint, function-docs, ADR.

Note the third shape: documentation bundles templates as a first-class component — plugins can ship reference material, not just executable parts.

Read them as a progression: pr-review orchestrates analysis, devops-automation adds real shell scripts with side effects, documentation adds reusable templates. Your own plugin will be some remix of these three.
10 · Marketplaces

A marketplace is just a repo with marketplace.json — official, community, or private

// .claude-plugin/marketplace.json
{
  "name": "my-team-plugins",
  "owner": "my-org",
  "plugins": [
    {
      "name": "code-standards",
      "source": "./plugins/code-standards",
      "version": "1.2.0"
    },
    {
      "name": "deploy-helper",
      "source": { "source": "github",
        "repo": "my-org/deploy-helper",
        "ref": "v2.0.0" }
    }
  ]
}
  • The official Anthropic-managed directory is anthropics/claude-plugins-official; enterprise admins can run private marketplaces for internal distribution
  • Required fields: name, owner, plugins[] with name + source each — description, version, author are optional
  • Strict mode: strict: true (default) — the local plugin.json is authoritative and the marketplace entry supplements it; strict: false — the marketplace entry is the entire plugin definition
Three tiers mirror the plugin types: official (curated categories), community (searchable public), enterprise private (company standards, legacy systems, compliance).
11 · Source Types

Six places a marketplace can pull a plugin from — all pinnable to a version

Relative path"./plugins/my-plugin" — plugin lives in the marketplace repo itself
GitHub{ "source": "github", "repo": "acme/lint-plugin", "ref": "v1.0" }
Git URL{ "source": "url", "url": "https://git.internal/plugin.git" } — any git host
Git subdirectory{ "source": "git-subdir", "url": "…/monorepo.git", "path": "packages/plugin" } — one plugin out of a monorepo
npm{ "source": "npm", "package": "@acme/claude-plugin", "version": "^2.0" }
pip{ "source": "pip", "package": "claude-data-plugin", "version": ">=1.0" }

GitHub and git sources accept optional ref (branch/tag) and sha (commit hash) for version pinning — reproducible environments. Plugins can also specify custom npm registries, and the default git timeout is 120 s for large plugin repositories.

Pin with sha when reproducibility matters more than freshness — a tag can be moved; a commit hash can't.
12 · Distribution & Publishing

Distribution is "add my repo"; publishing adds a tag, a review, and a one-command install

Getting your marketplace to users

# GitHub (recommended)
/plugin marketplace add owner/repo-name

# other git services — full URL
/plugin marketplace add \
  https://gitlab.com/org/marketplace-repo.git

Private repositories work via git credential helpers or environment tokens — users need read access. Official-marketplace submissions go through claude.ai/settings/plugins/submit or platform.claude.com/plugins/submit.

The publishing path

  • Build the structure + plugin.json, write a README documenting components and requirements
  • Test locally with claude --plugin-dir ./my-plugin
  • Cut the release with claude plugin tag v0.3.0 (v2.1.118+) — validates the version format and creates the matching git tag
  • Submit → review → approval → published; users install with one command
plugin tag is the recommended way to cut releases — it keeps the git tag and the manifest version honest with each other, which is what marketplace version pinning depends on.
13 · Context Cost

Every plugin charges context rent per turn — and you can read the bill before installing

The /plugin marketplace browser shows each plugin's projected per-turn context-token cost (v2.1.143) — the sum of its always-loaded skills, hooks, and MCP server descriptors:

docs-helper 0.9.0 · community+610 / turn
doc-style guide enforcement
code-reviewer 1.2.0 · anthropic+1,420 / turn
multi-agent PR review
devops-toolkit 0.4.1 · acme+3,180 / turn
SRE playbooks, on-call helpers — 5× the rent of docs-helper
Post-install, claude plugin details code-reviewer (v2.1.139+) prints the full inventory — skills, hooks, MCP, LSP, monitors, commands — plus +1,420 tokens per turn · +9,800 per /review invocation.
Size before you adopt — the per-turn cost is paid on every turn whether or not you use the plugin, which matters most on context-constrained models.
14 · The CLI Surface

Everything has a CLI form — and two commands that sound alike do different things

install <name>@<mkt>Install from a marketplace
uninstall / update / listRemove · update to latest · list installed
enable / disableToggle without uninstalling (auto-detected scope)
validateCheck plugin structure before publishing
tag <version>Release tag with version validation (v2.1.118+)
pruneRemove orphaned auto-installed dependencies (v2.1.121+); uninstall --prune cascades in one step
details <name>Inventory + projected token cost (v2.1.139+)

Dependency enforcement (v2.1.143)

  • plugin disable refuses if another enabled plugin still depends on the target — the dependency graph can't be broken
  • plugin enable force-enables transitive dependencies after a single confirmation prompt
  • In-session equivalents exist too: /plugin list, /plugin info, /plugin install ./local-path, /plugin install github:username/repo
The classic mix-up: marketplace update only refreshes the catalog of what's installable — it does NOT update installed plugins. That's plugin update <name>.
15 · The Dev Loop

--plugin-dir loads your work-in-progress; /reload-plugins picks up edits without restarting

# load one or many local plugins
claude --plugin-dir ./my-plugin
claude --plugin-dir ./a --plugin-dir ./b

# .zip archives work too (v2.1.128+)
claude --plugin-dir ./my-plugin.zip

# fetch a .zip from a URL (v2.1.129+)
claude --plugin-url \
  https://example.com/releases/my-plugin-0.3.0.zip

# after editing plugin files mid-session
/reload-plugins

The test checklist

  • All slash commands available · subagents function · MCP servers connect · hooks execute · LSP configs load · no config errors
  • /reload-plugins re-reads all manifests, commands, agents, skills, hooks, and MCP/LSP configs — plugins also support change auto-detection
  • First diagnostics when something won't load: plugin.json paths match the actual directory layout · scripts are chmod +x · JSON validates · /plugin debug name shows the logs
Same discipline as hooks in chapter 6: test the plugin as a unit before publishingclaude plugin validate for structure, --plugin-dir for behavior.
16 · Auto-Update

Official plugins update themselves at startup — everything else waits for you

claude-plugins-officialAuto-update ✅ enabled by default
Third-party / localAuto-update ❌ disabled by default
Toggle/plugin → Marketplaces → Select

When auto-update runs it: 1) refreshes the marketplace catalog, 2) updates installed plugins to latest, 3) shows a notification prompting /reload-plugins.

DISABLE_AUTOUPDATER=1Disable all auto-updates — Claude Code and plugins
+ FORCE_AUTOUPDATE_PLUGINS=1Keep plugin updates while Claude Code updates stay off
CLAUDE_CODE_PLUGIN_PREFER_HTTPS=1(v2.1.141+) Clone GitHub plugin sources over HTTPS instead of SSH — for CI runners and containers without SSH keys
The split default is deliberate: curated sources stay fresh automatically; third-party code changes only when you say so.
17 · Admin & Security

Admins control what installs; the sandbox controls what installed plugins can do

Managed settings (org-level)

enabledPluginsAllowlist enabled by default
deniedPluginsBlocklist — cannot be installed
extraKnownMarketplacesAdditional marketplaces made available to users
strictKnownMarketplacesNot set = any · [] = lockdown · patterns = allowlist (e.g. "my-org/*"). Managed-only
blockedMarketplacesBlocklist; hostPattern / pathPattern regex since v2.1.119
allowedChannelPluginsPermitted plugins per release channel

Enforced on every lifecycle event since v2.1.117 — install, update, refresh, and autoupdate, not just at first add. Managed settings take precedence over user-level settings.

The plugin-subagent sandbox

  • Plugin subagents run restricted — three frontmatter keys are banned in their definitions:
  • hooks — can't register event handlers
  • mcpServers — can't configure MCP servers
  • permissionMode — can't override the permission model

So a plugin can't escalate privileges or modify the host environment beyond its declared scope — what you saw in the manifest is what it gets.

Two fences, two audiences: marketplace controls stop bad plugins from arriving; the subagent sandbox limits what any plugin can do once it's in.
18 · When to Build One

A plugin earns its weight with multiple components or a team — otherwise use the smaller tool

Team onboarding✅ Plugin — instant setup, all configurations
Framework setup✅ Plugin — bundles framework-specific commands
Enterprise standards✅ Plugin — central distribution, version control
Quick task automation❌ Command — plugin is overkill complexity
Single domain expertise❌ Skill — too heavy as a plugin
Specialized analysis❌ Subagent — create manually or use a skill
Live data access❌ MCP — keep standalone, don't bundle

The don'ts that bite

  • Don't bundle unrelated features — keep plugins focused and cohesive
  • Don't hardcode credentials — env vars or userConfig sensitive values
  • Don't skip versioning — semver properly; maintain backward compatibility
  • Don't ship untested — test all components together, document dependencies and requirements
The decision gates from the source: multiple components? share with a team? needs auto-configuration? Any "yes" points to a plugin — three "no"s mean the individual feature was enough.
19 · Recap

Plugins are the distribution layer — everything you've built becomes something you can hand over

A plugin is a directory: .claude-plugin/plugin.json plus the commands, skills, agents, MCP servers, hooks, LSP configs, and bin/ tools you already know — installed in one command, namespaced as /plugin:command, updated as a unit. The manifest carries real machinery (keychain-backed userConfig, persistent data, background monitors). Marketplaces are just repos with marketplace.json, pulling plugins from paths, git, npm, or pip — pinnable by sha, governed by managed settings, and priced in context tokens per turn that you can read before installing. Develop with --plugin-dir, reload with /reload-plugins, release with plugin tag.

Start tonight: claude plugin init my-plugin, drop in one command and one hook, load it with --plugin-dir. Chapter 8: checkpoints — /rewind, five restore options, and what the checkpoint system can't track.
Sid Dani · June 2026