skribbl
productpricingfree!questionswriting
download
guides · 10 August 2026 · 6 min read

Claude Code plugins: what they are, how to build one

What a team stops copy-pasting once the .claude/ directory becomes a plugin.

skribbl/writing/guides
one install instead of a copied folder

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.

Worth saying up front: a plugin does not add a new capability to Claude Code. Commands, subagents, MCP servers, and hooks all work exactly the same whether they live loose in .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.

MARKETPLACE INSTALLdiscoverable, vetted listing; good for adopting third-party tooling
GIT REPO INSTALLpoints at a URL and a ref; the natural fit for an internal team plugin
WHAT BOTH GIVE YOUone command to install, one manifest to read, one version string to track
WHAT NEITHER GIVES YOU AUTOMATICALLYenforcement that everyone is actually on the same version

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 main instead 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.

Once a team's Claude Code setup involves several people's agents running against a shared plugin, watching what those agents are actually doing -- and spending -- stops being something you can eyeball in a terminal. Skribbl is a menu-bar canvas for exactly that: multiple coding agents, live token spend, in one view. Try it, or read the docs.
READ NEXT
Claude Code hooks: a practical guide with examplesEvery event, the payload it carries, and the exit code that blocks a tool call.12 minClaude Code subagents: a practical guideThe isolation is the feature. Reach for it only when you actually need it.6 minWhat is MCP? Model Context Protocol, explainedWrite the integration once. Every MCP-speaking agent gets it for free.6 min
ON THIS PAGE
the problem plugins solvewhat a plugin actually bundlesthe manifest, roughlyinstalling from a marketplace or repoversioning and what it doesn’t give yousharing one across a teamwhen a plugin is overkill
run them on a canvasSkribbl puts every agent, its terminal and what it is spending on one board. macOS, one day free.

get the next one by email.

One email when there is something worth reading. Unsubscribe is one click and it is in every issue.

download
productpricingdocsquestionswhat it iscomparereleaseswritingnewsletterlaunchesprivacycancel
give them infinity.© skribbl