A plugin bundles slash commands, subagents, MCP server configs and hooks into one unit a team installs from a marketplace or a repo, instead of copy-pasting a .claude/ directory between machines. The manifest shape, how a team keeps a shared set of commands and agents in sync, and what versioning actually needs to cover.
the problem plugins solve
Anyone who has set up Claude Code for a team has done the same thing: write a couple of useful slash commands in .claude/commands/, define a subagent or two in .claude/agents/, wire up an MCP server in .claude/mcp.json, maybe add a hook that runs a linter before every commit. Then a teammate asks for the same setup, and the honest answer is: copy the directory, or copy the files you remember to copy, and hope nothing drifts.
That drift is the actual problem. Six months later one person's .claude/ has a bugfix in a subagent's prompt that nobody else got, another person added a hook that quietly changed everyone else's workflow except theirs, and there is no single place to look to find out what changed or when. A plugin is Anthropic's answer to that: instead of a directory of loose files that gets copied by hand, you get one installable unit with a name and a version.
.claude/ or arrive packaged in a plugin. What changes is how they get onto a second machine.what a plugin actually bundles
A plugin is a directory (typically checked into its own git repo, or a subfolder of a marketplace repo) containing some subset of the same four things you'd otherwise hand-assemble in .claude/:
- Slash commands. Markdown files with frontmatter, same shape as
.claude/commands/*.md-- a name, a description, and the prompt body that runs when someone types/your-command. - Subagents. Named agent definitions -- system prompt, allowed tools, model choice -- the same shape as
.claude/agents/*.md, just distributed alongside the commands that use them. - MCP server configuration. The connection details for one or more MCP servers the plugin's commands or agents expect to have available, so installing the plugin also wires up the tool access it needs rather than leaving that as a separate manual step.
- Hooks. Lifecycle scripts -- pre-commit checks, session-start setup, whatever a team wants enforced automatically -- packaged so they travel with the rest of the setup instead of being a README instruction someone has to remember to follow.
None of these are new file formats. A plugin author is writing the same command markdown, the same agent frontmatter, the same MCP JSON, and the same hook scripts as anyone hand-rolling a .claude/ directory. The plugin is the container, not the content.
the manifest, roughly
A plugin needs a manifest at its root that tells Claude Code what it is and what it contains -- a name, a version, and pointers to its commands, agents, MCP config, and hooks. Treat the shape below as illustrative of what that manifest is doing conceptually, not as a byte-for-byte copy of a spec -- check the current plugin documentation for the exact field names and required structure before you ship one:
{
"name": "our-review-toolkit",
"version": "1.4.0",
"description": "Shared code review commands and the review subagent",
"commands": ["./commands/review.md", "./commands/changelog.md"],
"agents": ["./agents/reviewer.md"],
"mcpServers": {
"linear": {
"command": "npx",
"args": ["-y", "@linear/mcp-server"]
}
},
"hooks": {
"preCommit": "./hooks/lint-check.sh"
}
}The point of the manifest is that it is one file a reviewer can read to understand everything the plugin will install, and one file a version bump touches. Compare that to a .claude/ directory copied by hand, where there is no single artifact that says "this is the full set of things that changed."
installing from a marketplace or repo
Plugins install from two kinds of source: a marketplace listing, or a git repository directly. The marketplace case is the polished path -- browse, pick a plugin, install -- and it's the right fit for adopting something a third party built and maintains. The repo case is the one that matters for teams: point Claude Code at your own git repo (public or private, internal or on GitHub) and every teammate installs from that same source of truth instead of a folder someone emailed around.
That last row matters more than it looks. Installing from a repo is easy; making sure five teammates all re-installed after last week's bugfix is a process problem the tooling doesn't solve for you, in the same way that npm install doesn't make sure everyone ran it after a package.json change.
versioning and what it doesn't give you
A plugin repo with tagged releases gets you further than a hand-copied directory ever could: a version string in the manifest, a git history you can bisect, and a tag you can roll back to if a change breaks someone's workflow. That is real progress. It is not the same as the version guarantees a package manager gives you for a library dependency, and it is worth being precise about where the gap is rather than assuming a git tag closes it.
- No compatibility contract with the Claude Code release itself. A plugin written against one version of the hook or MCP interface has no built-in signal that says it's incompatible with a newer or older Claude Code build -- unlike a library with a documented API surface and semver expectations, this is closer to two independently evolving tools that happen to interoperate today.
- No staged rollout. There is no equivalent of a canary percentage or a gradual ramp built into plugin installation. A version bump in the source repo is live for everyone who reinstalls, all at once.
- Pinning is only as strong as your install command. If teammates install from
maininstead of a tagged ref, "version 1.4.0" in the manifest is aspirational, not enforced -- the manifest can claim a version number that has nothing to do with which commit actually got installed.
a reasonable convention
Tag every release in the plugin repo, bump the manifest's version string in the same commit as the tag, and have the team's install instructions point at a tag rather than a branch. None of that is enforced by the tooling -- it is a discipline you adopt, the same discipline any small internal package needs, just applied here instead of assumed away.
sharing one across a team
The actual payoff of a plugin is boring in the best way: a new teammate runs one install command and has the same commands, the same review subagent, the same MCP servers, and the same pre-commit hook as everyone else -- on day one, not after someone remembers to send them a folder. When the team changes something -- tightens a subagent's prompt, adds a command, swaps an MCP server -- that change is a commit and a tag in one repo, not a message in a chat channel asking everyone to manually edit a file.
It also gives the setup a place to live that isn't someone's laptop. A .claude/ directory that only exists on the one engineer who set it up is a bus-factor problem; a plugin repo with a manifest and a README is not.
when a plugin is overkill
Not every .claude/ customization deserves to become a plugin. If it's one command you use alone, or a hook specific to a single repo's build system, the packaging overhead -- a manifest, a separate repo, a versioning convention -- probably costs more than the copy-paste it's avoiding. Plugins earn their keep at the point where more than one person needs the same setup and keeping it in sync by hand has already started to fail, not before.
A rough rule of thumb: if you've had to tell a second teammate "oh, also copy this file" more than once, that's the signal to package it. Before that point, a loose .claude/ directory is simpler and there is nothing wrong with simple.