Claude Code plugins: install, build, and distribute
A plugin is a directory of skills, agents, hooks, and MCP servers that installs as one unit from a marketplace. It's how you share a setup with other people. If you only need it yourself, a `.claude/` directory does the same job with less ceremony.
This machine runs seven plugins from four marketplaces. One of them provides the plugin skill I invoke most, 132 times in the last few months. Another is a language server I installed in April and haven't thought about since, which is exactly what a good plugin feels like. The production platform we run for clients distributes the same kinds of components to around forty agents per server, and it does so with a three-layer file sync we built before plugins existed. So I have opinions on both sides of the install command.
A plugin does nothing a standalone .claude/ directory can't do. What it adds is namespacing, versioning, and a way to install the whole bundle on another machine with one command. That's worth a lot when you share and worth nothing when you don't.
What a plugin contains
A plugin is a directory at whose root you place skills/, agents/, hooks/hooks.json, .mcp.json, .lsp.json, monitors/, bin/, and an optional settings.json. The only file that goes inside .claude-plugin/ is plugin.json.
The official plugin guide, read on 2026-09-07, is unusually direct about the most common mistake: people put their components inside .claude-plugin/. Don't. The manifest lives there alone. Everything else sits at the plugin root, and the plugin root is the plugin's own directory, never ~/.claude/.
The manifest is small:
{
"name": "release-tools",
"description": "Release checks and changelog drafting",
"version": "1.0.0",
"author": { "name": "Your Name" }
}The name becomes the namespace. A skill at skills/check/SKILL.md in this plugin is invoked as /release-tools:check, and that prefix is what lets two plugins ship a check skill without colliding. The version field matters more than it looks: when it's set, users receive updates only when you change it, so bump it on every release.
Each component type works the way it does standalone, with a few plugin-specific rules. Plugin skills follow the same frontmatter as any Claude Code skill. Plugin subagents ignore the hooks, mcpServers, and permissionMode fields for security reasons, so an agent that needs those has to be copied into .claude/agents/ instead. Hooks move from settings.json into hooks/hooks.json with the same shape. An .mcp.json at the root adds servers the way a project file does, which makes plugins a clean way to package an MCP server for Claude Code together with the skill that knows how to use it.
Two components are plugin-only. monitors/monitors.json declares background commands whose stdout lines arrive as notifications while the plugin is active, and bin/ adds executables to the Bash tool's PATH. A settings.json at the root can set agent, which makes one of the plugin's agents the main thread when the plugin is enabled. That last one changes what Claude Code is by default, and it's the mechanism behind plugins that turn a session into a specialized reviewer.
Installing from a marketplace
Installing is two steps: add the marketplace, then install the plugin by name@marketplace. The official Anthropic marketplace is registered for you on first interactive launch.
/plugin install github@claude-plugins-official
/plugin marketplace add anthropics/claude-plugins-community
/plugin install <plugin-name>@claude-community
The /plugin panel has a Discover tab, an Installed tab, a Marketplaces tab, an Errors tab, and, in sessions where /skill-doctor is available, a Stats tab. The details pane for a plugin shows its context cost, its last-updated date, and a list of what it will install. Read that list. A plugin is code that runs with your user privileges, and Anthropic's own docs say it doesn't verify what plugins contain.
Scope is chosen at install time: user for all your projects, project for everyone who clones the repository, local for you in this repository only. Since v2.1.232 a named install refreshes the marketplace first, so a plugin published an hour ago installs without a manual update. The install summary tells you whether the plugin is already active or whether you need /reload-plugins, which since v2.1.221 is only required when activation would invalidate the prompt cache.
Three Anthropic-run marketplaces exist. claude-plugins-official is curated by Anthropic with no application process. claude-community at anthropics/claude-plugins-community takes third-party submissions after automated validation and pins each plugin to a commit SHA. claude-code-plugins at anthropics/claude-code holds demo plugins. The official catalog is where the language server plugins live, one per language, each needing its binary installed separately, and where the integration plugins for GitHub, GitLab, Linear, Notion, Figma, Slack, Sentry, and a few others bundle a pre-configured MCP server.
The Installed tab also lists plugins you haven't used in two weeks across at least ten sessions. That list exists because every plugin adds startup and context cost whether you use it or not. Mine currently shows nothing, which I checked before writing this sentence, but I have uninstalled two plugins because of it.
Build one without a marketplace
Point Claude Code at a directory with --plugin-dir and it loads as a plugin for that session. Or run claude plugin init and the plugin lives in your skills folder with no install step at all.
claude --plugin-dir ./release-toolsThat's the whole development loop. Edit, run /reload-plugins, try /release-tools:check. The flag accepts a .zip too, and --plugin-url fetches an archive from a URL for one session, which is how you test a CI build artifact. A --plugin-dir plugin with the same name as an installed one wins for that session, so you can test a change to a plugin you already have.
The newer path is claude plugin init my-tool. It scaffolds ~/.claude/skills/my-tool/ with a manifest and a starter SKILL.md, and on the next session it loads as my-tool@skills-dir. Any skill folder that contains a .claude-plugin/plugin.json gets this treatment, so a skill can grow into a plugin in place, gaining agents, hooks, and MCP servers, without ever touching a marketplace. In a project's .claude/skills/ this requires accepting the workspace trust dialog first.
Validate before you share. claude plugin validate ./release-tools runs the same check the community review pipeline runs, and --json gives a machine-readable report since v2.1.259. It also works on a bare .claude/skills or .claude/agents directory with no manifest, which is the fastest way to find a SKILL.md whose frontmatter doesn't parse.
Distribute with a marketplace file
A marketplace is a git repository with .claude-plugin/marketplace.json listing plugins and where to fetch each one. Users add it with /plugin marketplace add owner/repo.
{
"name": "acme-tools",
"owner": { "name": "Platform team" },
"plugins": [
{ "name": "release-tools", "source": "./plugins/release-tools" },
{ "name": "deploy", "source": { "source": "github", "repo": "acme/deploy-plugin", "sha": "a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0" } }
]
}Sources can be a relative path inside the marketplace repo, a GitHub repo, any git URL, a subdirectory of a repo fetched with a sparse clone, an npm package, a zip archive over HTTPS with an optional SHA-256 pin, or, since v2.1.229, a local command that prints the plugin directory and is re-run each session. When both ref and sha are set, the SHA is the effective pin, and on GitHub the install succeeds even if the branch was deleted, as long as the commit is reachable.
Two rules catch people. Relative paths resolve against the marketplace root, not the .claude-plugin/ directory, and they don't resolve at all when a user adds the marketplace by direct URL to the JSON file, because only that file is downloaded. And a list of names is reserved: claude-plugins-official, anthropic-plugins, agent-skills, and a dozen more, plus anything that impersonates them. Claude Code re-checks the reserved list every time it loads a marketplace, so a name that becomes reserved later stops loading.
For a team, put the marketplace in .claude/settings.json under extraKnownMarketplaces and the plugins under enabledPlugins. Once a collaborator trusts the repository folder, the marketplace is added for them. Since v2.1.195 a plugin from an external source isn't auto-installed from that file; Claude Code reports it as not installed and shows the install command. That was a deliberate change, and it's the right one.
What we do instead, and when a plugin would replace it
Our production platform syncs skills and agents into each container at spawn from three layers of markdown files. It's a private plugin system with no manifest, and it solves the problem plugins solve for people who can't use a marketplace.
Each container agent on the platform loads its skills and subagent definitions from a baseline directory in the app repository (container/.claude/agents/*.md), then a per-server overrides directory (overrides/agents/*.md in that server's config repository), then a per-group directory (groups/<group>/agents/*.md), in that order. The files are copied fresh on every container spawn, so a change to a skill is live on the next run with no rebuild and no restart. A server-level manifest gates which components each group receives. Around forty agents per server share the baseline and diverge only where they need to.
This is a marketplace with command sources, hand-rolled. It predates the plugin system and it has one property plugins don't: the config repositories are the deployment, so a git pull on the server is the install. If the platform ran on a plugin marketplace instead, each group's enabledPlugins would replace the manifest gates and versioning would come for free. We haven't migrated because the gating logic is the part we rely on most, and plugin settings.json supports only two keys today.
Where plugins have already won on my own machine is the integration case. The Codex plugin from OpenAI's marketplace ships the /codex:rescue skill and its subagent together, and I have invoked it 132 times. The Context7 plugin delivers the documentation MCP server this article was checked against. Neither is something I would want to assemble by hand from a .claude/ directory, and both are kept current by the marketplace auto-update, which checks within ten minutes of a session starting and prompts /reload-plugins when something changed.
The rule I use: if the components only ever live on one machine, they stay standalone. The moment a second machine or a second person needs them, they become a plugin, and the same day they get a version field.
We publish the skills we run in production, packaged as two plugins.
Security, and the reload cost
Plugins run arbitrary code as you. The docs say so, the hardening in the changelog shows what that has meant, and /reload-plugins has a token cost you should know about.
Recent releases closed a run of path issues: plugin components that were symlinks pointing outside the plugin directory, marketplace entries whose command paths escaped the plugin, and ${user_config.*} values in shell-form hook commands, which were rejected in v2.1.207 as a shell injection fix. Read hooks/hooks.json and .mcp.json in any plugin before installing it, because those are the parts that execute. A Claude Code hook from a plugin fires on every matching tool call in your session, including inside subagents.
Reloading isn't free. Newly loaded components announce themselves in content appended to the conversation, and a plugin that provides MCP servers invalidates the prompt cache when its tools aren't deferred by tool search, so the next request re-reads the whole conversation. The install summary says Plugin is now active. when Claude Code could activate without that cost, and Run /reload-plugins to activate. when it couldn't. Install plugins at the start of a session, not in the middle of a long one.
Frequently asked questions
What is a Claude Code plugin?
A plugin is a self-contained directory that bundles skills, agents, hooks, MCP servers, LSP servers, and background monitors, with an optional plugin.json manifest, so the whole set can be installed as one unit from a marketplace. Its skills are namespaced as /plugin-name:skill-name.
How do I install a Claude Code plugin?
Add the marketplace that lists it, then run /plugin install plugin-name@marketplace-name and choose a scope. The official Anthropic marketplace is registered automatically the first time you start Claude Code interactively. If the install summary says to run /reload-plugins, do that to activate it.
What is the difference between a plugin and a skill?
A skill is a single SKILL.md file with instructions that Claude loads when relevant. A plugin is a package that can contain many skills plus agents, hooks, and MCP servers, versioned and distributed through a marketplace. A skill folder becomes a plugin when you add a .claude-plugin/plugin.json to it.
How do I test a plugin locally?
Run claude --plugin-dir ./my-plugin to load the directory as a plugin for that session, then edit and run /reload-plugins to pick up changes. Run claude plugin validate ./my-plugin before sharing it, which is the same check the community marketplace review runs.
Are plugins safe to install?
Plugins execute code with your user privileges and Anthropic doesn't verify their contents. Read the hooks and MCP server definitions before installing, install only from sources you trust, and use the details pane to see what a plugin will add before you confirm.