---
title: "Claude Code Plugins: The Bundle Layer Explained"
excerpt: "Claude Code plugins package skills, subagents, hooks, and MCP server definitions into one versioned, installable unit. This guide covers plugin anatomy, marketplaces, the /plugin command, namespacing, and when a plain skill folder is the better choice."
metaDescription: "Claude Code plugins bundle skills, agents, hooks, and MCP servers into one versioned install. Anatomy, marketplaces, namespacing, and when to skip them."
publishedAt: 2026-08-03
author: Feng
categories:
 - Guides
 - Engineering
tags:
 - claude-code-plugins
 - claude-code-plugin-marketplace
 - claude-code
 - claude-code-skills
 - claude-code-hooks
 - mcp-servers
 - subagents
 - coding-agents
metaTitle: "Claude Code Plugins: The Bundle Layer Explained"
featuredImage: ./cover.png
featuredImageAlt: "Shiplight blog cover, light gradient, indigo accents, diagram of a plugin package bundling skill, agent, hook, and MCP server cards into a single installable box"
---

A Claude Code plugin is a versioned bundle that ships skills, subagents, hooks, MCP server definitions, and commands together as one installable unit. Instead of asking every teammate to copy a skill folder here, paste a hooks block into settings there, and register an MCP server somewhere else, you publish one directory with a manifest, and a single install brings the whole configuration in at once.

That is the organizing idea worth holding onto: Claude Code has two layers of customization. The first layer is the individual primitive, a skill in `.claude/skills/`, a subagent in `.claude/agents/`, a hook in `settings.json`, an MCP server in `.mcp.json`. Each is useful alone, and each has its own file format and its own place in the repo. The second layer is the bundle. A plugin wraps any combination of those primitives in a self-contained directory, gives the collection a name and a version, and makes it distributable through marketplaces, catalogs that Claude Code can browse and install from.

The distinction matters because most teams start at the first layer and hit its ceiling. A code-review skill works fine as a lone folder. But the moment it needs a dedicated reviewer subagent, a `PostToolUse` hook to lint what the agent writes, and an MCP server to reach your ticket tracker, you are maintaining four configurations in four places, and every teammate has to assemble them by hand. The plugin layer exists to collapse that assembly into one step.

This guide covers what a plugin contains, how installation and marketplaces work, how namespacing keeps bundles from colliding, and the decision that trips most people up: when to promote a skill into a plugin, and when a committed skill folder is honestly the better distribution mechanism.

## What a plugin bundles

A plugin is a directory. At minimum it holds one component; in practice it can carry:

- **Skills** in `skills/`, each a folder with a `SKILL.md` file. Claude invokes them by name or picks them up automatically from their descriptions.
- **Subagents** in `agents/`, markdown definitions that run in their own context window with their own tool restrictions.
- **Hooks** in `hooks/hooks.json`, event handlers that fire on tool use, session start, and other lifecycle points. Same format as the `hooks` block in `settings.json`.
- **MCP servers** in `.mcp.json` at the plugin root, so an install can wire Claude to external tools without a separate registration step.
- **Commands** in `commands/`, flat markdown files. This is the older layout; official docs recommend `skills/` for new plugins.

Newer component types keep landing in the same envelope: LSP server configs (`.lsp.json`) for code intelligence, background monitors, executables in `bin/`, and a plugin-level `settings.json` that can activate one of the plugin's own agents as the default. The envelope is the stable part. Whatever Claude Code learns to load next, a plugin is how you ship it with everything else.

## Why the bundle matters for teams

Consider a deploy workflow. Standalone, it needs a `/deploy` skill, a `deploy-checker` subagent, a `PreToolUse` hook that blocks pushes to protected branches, and an MCP server for your CI provider. That is five files across three locations, plus a README explaining the assembly order. Every new teammate re-does the assembly. Every update means "everyone please re-copy the hook."

As a plugin, the same workflow is one directory and one install command. Versioning is built in: set a `version` in the manifest and users get updates when you bump it, or omit it for git-distributed plugins and every commit counts as a new version. Updates propagate through the marketplace instead of through Slack messages.

The bundle also travels across projects. Skills committed to a repo's `.claude/` folder serve that repo. A plugin installed at user scope follows you into every project, and one enabled at project scope reaches everyone who clones the repo. One artifact, three distribution radii.

## Plugin anatomy

The layout is strict in one place and loose everywhere else:

```text
my-plugin/
├── .claude-plugin/
│   └── plugin.json      # manifest: name, version, description
├── skills/
│   └── code-review/
│       └── SKILL.md
├── agents/
│   └── reviewer.md
├── hooks/
│   └── hooks.json
└── .mcp.json            # MCP server definitions
```

The strict part: only `plugin.json` lives inside `.claude-plugin/`. Everything else sits at the plugin root. Putting `skills/` or `hooks/` inside `.claude-plugin/` is the most common structural mistake, and the components silently fail to load.

The manifest itself is small. `name` is the only required field:

```json
{
  "name": "deploy-tools",
  "description": "Deploy workflow with checks and CI access",
  "version": "1.2.0",
  "author": { "name": "Platform Team" }
}
```

The manifest is even optional: a directory of components with no `plugin.json` still loads as a plugin, deriving its name from the directory. Add the manifest when you want explicit versioning or metadata.

Two mechanics worth knowing before you ship one. First, any file path inside hook commands or MCP configs should use `${CLAUDE_PLUGIN_ROOT}`, which resolves to the plugin's installation directory; installed plugins are copied into a cache, so relative paths that escape the plugin break. Second, you develop against a local checkout with `claude --plugin-dir ./my-plugin` and pick up edits with `/reload-plugins`, no marketplace needed during iteration. `claude plugin validate ./my-plugin` checks the manifest, frontmatter, and hooks file for schema errors.

## How installation works

Distribution runs through **marketplaces**: catalogs described by a `.claude-plugin/marketplace.json` file in a git repo, a local directory, or behind a plain URL. Using one is a two-step motion, like adding an app store and then choosing apps:

```shell
/plugin marketplace add your-org/claude-plugins
/plugin install deploy-tools@your-org-plugins
```

The `/plugin` command also opens an interactive manager with Discover, Installed, Marketplaces, and Errors tabs, and shows what a plugin will install plus its estimated context cost before you commit. Anthropic auto-registers an official curated marketplace (`claude-plugins-official`, with plugins like `github` and `commit-commands`), and a community marketplace (`anthropics/claude-plugins-community`) accepts reviewed third-party submissions.

Every install lands in a scope, which decides who else gets the plugin:

| Scope | Written to | Who gets it |
| :-- | :-- | :-- |
| `user` | `~/.claude/settings.json` | You, in every project (default) |
| `project` | `.claude/settings.json` | Everyone who clones the repo |
| `local` | `.claude/settings.local.json` | You, in this repo only |
| `managed` | Managed settings | Set by administrators, read-only |

Project scope is where team distribution gets interesting. A repo can declare its own marketplaces and plugins directly in `.claude/settings.json`:

```json
{
  "extraKnownMarketplaces": {
    "my-team-tools": {
      "source": { "source": "github", "repo": "your-org/claude-plugins" }
    }
  }
}
```

Combined with `enabledPlugins` entries, this makes the repo self-describing: when a teammate clones it and trusts the folder, Claude Code prompts them to install the declared marketplaces and plugins. Nobody reads a setup doc; the repo carries its own tooling manifest. Repo-declared plugins do pass through trust gates, sensibly: MCP servers a project plugin declares go through the same per-server approval as a project `.mcp.json`, since that code arrives from the repository rather than from you.

For scripted setups, the shell command mirrors the slash command: `claude plugin install formatter@my-marketplace --scope project`.

## Namespacing: how bundles avoid collisions

Every skill a plugin ships is invoked as `/plugin-name:skill-name`. A `hello` skill inside `my-first-plugin` becomes `/my-first-plugin:hello`; a `reviewer` agent inside `plugin-dev` appears as `plugin-dev:reviewer`. The prefix comes from the `name` field in `plugin.json`.

This is the visible cost of the bundle layer, and it is deliberate. Two plugins can both ship a `deploy` skill without clobbering each other, because they resolve to `/team-a:deploy` and `/team-b:deploy`. Standalone skills in `.claude/skills/` keep their short names, so `/deploy` stays available for personal use even after a plugin ships a namesake. If you migrate a standalone skill into a plugin, both names exist until you delete the original, which is the documented cleanup step.

## Bare skill or plugin: the promotion decision

The practical default: start as a skill, promote when the skill stops being alone. A skill is one folder with one markdown file, editable in place, live-reloading, invoked with a short name. A plugin adds a manifest, namespacing, and a distribution pipeline. That overhead buys nothing until you have either multiple components or multiple consumers.

| Signal | Stay a bare skill | Promote to a plugin |
| :-- | :-- | :-- |
| Components | One skill, maybe support files | Skill needs an agent, hook, or MCP server alongside it |
| Consumers | You, or one repo's contributors | Multiple repos, teams, or the community |
| Updates | Edit the file, git handles it | Users should pull versioned releases |
| Invocation | Short `/deploy` names matter | Namespaced `/tools:deploy` is acceptable |
| Iteration speed | Editing constantly | API is stable enough to version |

The promotion path is mechanical, not a rewrite: create `.claude-plugin/plugin.json`, copy `skills/`, `agents/`, and the `hooks` object from settings into the plugin layout, and test with `--plugin-dir`. There is even a halfway house: drop a `.claude-plugin/plugin.json` inside a folder in `~/.claude/skills/` and it loads as a plugin (`my-tool@skills-dir`) with no marketplace at all, which is a good staging ground before publishing. `claude plugin init` scaffolds exactly this.

This bundle logic is not unique to Claude Code plugins, and it is worth recognizing elsewhere. Shiplight, our verification platform for AI-native development, ships the same way: one install line adds a browser MCP server plus skills (`/shiplight verify`, `/shiplight create-yaml-tests`, `/shiplight fix`) to your coding agent, so the agent gets browser eyes and a test-writing workflow in a single step instead of separate MCP and skill setups. How that works across agents is covered on our [coding agents page](/coding-agents). The pattern generalizes: when capability spans tools plus instructions, ship them as one unit.

## When a plugin is overkill

Honest scoping: many teams reaching for a marketplace would be better served by a committed `.claude/skills/` folder, and the official docs say as much.

Skip the plugin when the tooling serves exactly one repository. Skills and agents committed to the repo travel with `git clone`, need no marketplace, no install prompt, no version bumps, and review like any other code change in a pull request. A plugin adds a second distribution channel to maintain, and update lag: marketplace plugins update on their own cadence, while committed skills are always exactly at the commit you checked out. Repo-local skills also keep short names; if your team types `/deploy` fifty times a day, `/platform-tools:deploy` is a real papercut.

Skip it too while the skill is churning. `SKILL.md` edits in `.claude/skills/` take effect immediately; plugin component changes need `/reload-plugins` or a restart, and published changes need a version bump. Package the workflow after it stabilizes, not before.

The plugin earns its overhead at the boundary crossing: the same tooling in three repos, a hook or MCP server that must arrive pre-wired, or an audience beyond people who already clone your code.

## Frequently Asked Questions

### What is a Claude Code plugin?

A Claude Code plugin is a self-contained directory that bundles skills, subagents, hooks, MCP server definitions, and commands into one versioned, installable unit. It carries a manifest at `.claude-plugin/plugin.json` and installs through marketplaces with the `/plugin` command, so one install replaces several separate configuration steps.

### How do I install a Claude Code plugin?

Add a marketplace, then install from it: `/plugin marketplace add owner/repo` followed by `/plugin install plugin-name@marketplace-name`. You choose a scope at install time (user, project, or local), and `/reload-plugins` activates the plugin without restarting. The `claude plugin install` shell command does the same non-interactively.

### What is a Claude Code plugin marketplace?

A marketplace is a catalog of plugins described by a `.claude-plugin/marketplace.json` file, hosted in a git repository, local directory, or URL. Anthropic auto-registers an official curated marketplace, and anyone can publish their own, including private ones for internal team plugins.

### Why are plugin skills namespaced?

Plugin skills always invoke as `/plugin-name:skill-name` so two plugins shipping same-named skills cannot collide. The prefix is the `name` field in `plugin.json`. Standalone skills in `.claude/skills/` keep short un-prefixed names, which is one reason to keep single-project tooling standalone.

### Should I build a skill or a plugin first?

Start with a skill. A bare skill in `.claude/skills/` is one markdown file, live-reloads, and keeps a short name. Promote it to a plugin when it accumulates agents, hooks, or MCP servers, or when people outside the repo need to install it. The migration is a file-copy operation, not a rewrite.

### How do teams share plugins through a repository?

Declare marketplaces under `extraKnownMarketplaces` and plugins under `enabledPlugins` in the repo's `.claude/settings.json`. When teammates clone and trust the folder, Claude Code prompts them to install the declared plugins, so the repository documents and distributes its own agent tooling.

## Related Reading

- [Claude Code skills](/blog/claude-code-skills): the primitive plugins bundle, and the layer to master first.
- [Create a Claude Code skill](/blog/create-claude-code-skill): the authoring walkthrough for the `SKILL.md` files a plugin ships.
- [Claude Code hooks](/blog/claude-code-hooks): the event-handler format that moves into `hooks/hooks.json` when packaged.
- [Claude and MCP](/blog/claude-mcp): how MCP servers work before you declare them in a plugin's `.mcp.json`.
- [Subagents explained](/blog/subagent): what the `agents/` directory of a plugin actually defines.
- [Testing layer for AI coding agents](/blog/testing-layer-for-ai-coding-agents): where a verification bundle fits in an agent-driven workflow.

References: [Claude Code plugin docs](https://code.claude.com/docs/en/plugins), [plugins reference](https://code.claude.com/docs/en/plugins-reference), [discover and install plugins](https://code.claude.com/docs/en/discover-plugins).
