Skip to content

Plugins & marketplaces

You’ve spent the last month tuning the way you work with your agent: a deploy-checklist skill, a security-reviewer subagent, a hook that runs the linter after every edit, an MCP server pointed at your issue tracker, three slash commands for the team’s pre-merge workflow. It all lives in your tool’s dot-directory at the root of one repo. It works beautifully.

Then you start a second repo. You want the same setup, so you copy the directory across. Then a new teammate joins - “how do you get this stuff?” - and the answer is “clone my dotfiles, copy these directories, edit your settings file, install these MCP servers, oh, you also need…” The setup that worked beautifully in one repo doesn’t survive contact with anyone else’s filesystem.

A plugin is the packaging unit that closes that gap. It bundles a CLI’s extension primitives - skills, hooks, subagents, MCP servers, commands - into one installable thing, namespaced so two plugins don’t fight, distributed through a marketplace so your teammate runs one install command instead of following eleven steps.

What the tools disagree about is not whether that’s useful. It’s whether there’s a bundle at all, and what the bundle is allowed to contain. So “install this” means something different in each one, and in most of them part of your setup stays behind.

Real-world examples of what teams actually package as plugins:

  • Team conventions bundle - your repo’s style guide as a skill, a pre-commit linting hook, a code-review subagent, an MCP server for your issue tracker. One install, whole-team consistency.
  • Domain plugins - a “payments” plugin with PCI-aware skills, an audit-log hook, and a subagent that knows the payment processor’s API.
  • Personal toolkit - your own /tldr, /skeptic, /pre-ship commands plus your favourite review subagent. Install on every machine you use, kept in sync via the marketplace.
  • Open-source plugins - community-maintained bundles for a specific stack (Rust + Tokio, Next.js + Drizzle, Django + Celery). Skill + agent + permissions tuned for that stack.
  • Org-wide standards - managed-scope plugin installed on every dev’s machine: enforce the security hook, the audit MCP server, the approved-subagent list. The team has no choice about installing it.
  • Workshop / tutorial materials - pin a known-good toolkit for a workshop so every attendee starts from the same baseline.

The test: if you’ve ever zipped up your agent’s dot-directory and emailed it to someone, or opened a message with “first, copy these files…”, you wanted a plugin.

One team setup - a skill, a subagent, a hook, an MCP server, a slash command - and what happens to each piece when you ship it to a teammate. Read the pieces marked as loose files: those are the ones your teammate ends up missing.

  • in the pluginSkillLands in the plugin’s skills/ directory.
  • in the pluginSubagentagents/<name>.md inside the plugin.
  • in the pluginHookShips in the bundle and registers on install.
  • in the pluginMCP serverServer config ships in the bundle.
  • in the pluginSlash commandNamespaced on install: /team-stack:pre-merge.
how it ships
/plugin marketplace add our-org/team-plugins
/plugin install team-stack@team-plugins
  • distScopes: user by default, --scope project commits the install to .claude/settings.json, and managed scope lets an org enforce it. The official claude-plugins-official marketplace is preinstalled.
  • noteInstalled plugins are copied into ~/.claude/plugins/cache/ - a plugin can’t reference files outside its own directory.

Pi isn’t in the widget above. Its unit is a package, installed with pi install npm:<pkg> or pi install git:<repo>, carrying extensions, skills, prompt templates and themes together. MCP servers are the one piece it can’t bundle, because Pi has no native MCP at all.

Only Claude Code carries all five pieces. Everywhere else the honest install instruction has a second step - copy the agent files too, register the MCP server yourself, commit the commands directory - and the second step is the one people forget. Write it down somewhere the plugin can’t: a README next to the marketplace entry, or the repo it ships from.

What “install this plugin” actually does

Section titled “What “install this plugin” actually does”

The word covers three different kinds of object, and they behave differently the moment you install one.

  • A static bundle of files. Claude Code, Codex, Copilot, and Pi packages all ship content: directories of skills, hook definitions, MCP configs, agent files, named by a manifest. Codex makes the shape explicit - .codex-plugin/plugin.json, one optional field per component type (skills, mcpServers, apps, hooks), each a path relative to the plugin root. The gotcha: the installed copy is not the repo you installed from. Claude Code copies plugins into ~/.claude/plugins/cache/, so a path reaching outside the plugin’s own directory stops resolving after install.
  • Live code. An OpenCode plugin is a JS/TS module exporting a function that returns hook handlers and tool definitions. Installing one means the npm packages listed in opencode.json are fetched with Bun at startup and cached in ~/.cache/opencode/node_modules/. You aren’t copying content into place; you’re adding a program, and its dependencies, to the startup path.
  • Nothing native. Cursor has no bundle format for rules plus skills plus subagents plus hooks. Its packaging surfaces are inherited ones: OpenVSX-backed VS Code extensions, and the MCP Marketplace for servers. Sharing a Cursor setup means committing the .cursor/* files and letting git pull be the installer.

That difference decides what you can check before you trust someone else’s bundle: a static bundle reads as files, a live plugin has to be read as code. Either way the install isn’t free - every skill a bundle brings in contributes its description to the always-loaded part of the window in every session afterwards, so a twelve-skill plugin installed for one skill charges you for twelve.

You want to…Reach forNot
Bundle multiple primitives (skills + hooks + agents + MCP) as one unitPluginLoose files
Share that bundle with teammates / a communityPlugin (via a marketplace)A README with copy-paste instructions
Distribute just a single skillA standalone skill folder (especially SKILL.md is cross-tool portable)Wrapping it in a plugin
Add one MCP serverMCP config directlyPlugin-wrapping it
Enforce a configuration across the orgManaged-scope plugin (Claude Code) / managed configPlugin marketplace alone
Add live event-handling code (OpenCode)OpenCode plugin (JS/TS)Static skill

A plugin pays its weight when there are multiple extension pieces that belong together. A single skill or single hook doesn’t need a plugin wrapper - keep it as a loose file until you find yourself shipping it alongside something else.

A plugin is a directory bundling some combination of:

  • Skills (skills/<name>/SKILL.md)
  • Subagents (agents/<name>.md)
  • Hooks
  • MCP servers
  • Commands

Each plugin’s skills/commands are namespaced when installed - they appear as /my-plugin:cmd so multiple plugins coexist without colliding.

Marketplaces are hosted collections of plugins. You point Claude Code at a marketplace URL and browse/install from inside the CLI.

Marketplace commands:

/plugin marketplace add <owner/repo | git-url | local-path | marketplace.json-url>
/plugin marketplace list
/plugin marketplace update <marketplace-name>
/plugin marketplace remove <marketplace-name>

(/plugin market is a shortcut for /plugin marketplace; rm aliases remove.)

Plugin commands:

/plugin install <plugin>@<marketplace>
/plugin enable|disable <plugin>@<marketplace>
/plugin uninstall <plugin>@<marketplace>
/reload-plugins # hot-reload without restart
claude plugin install <plugin>@<marketplace> --scope project

Scopes: user (default), project (committed to .claude/settings.json), local (this repo, not shared), managed (admin-set).

On-disk layout: installed plugins are copied into a cache rooted at ~/.claude/plugins/cache/. Because plugins live in the cache (not their source repo), paths referencing files outside the plugin directory don’t work. Plugin skills are namespaced under the plugin (e.g. commit-commands exposes /commit-commands:commit). Project-scope marketplaces are registered in .claude/settings.json under extraKnownMarketplaces. The official Anthropic marketplace claude-plugins-official is auto-available.

AspectClaude CodeCodexOpenCodeCursorCopilotPi
First-class plugin formatYes (static bundle)Yes (skills + apps + MCP + hooks; subagents are not documented as a plugin component)Yes (live JS/TS)No (no rules + skills + agents + hooks bundle)Yes (preview, 2026)Yes - Pi packages
Bundles skills + hooks + agents + MCPYesPartial - skills + hooks + MCP + app connectors; subagents are documented separatelyYes (via plugin code)-Yes (skills + agents + hooks + MCP + LSP)Extensions + skills + prompts + themes (no MCP - no native MCP at all)
Namespacing/plugin:cmdPlugin name is the identifier; no documented skill/command invocation-prefixSlash commands not a documented plugin capability-Plugin-scopedPackage-scoped
Distribution mechanismMarketplacesMarketplaces (marketplace.json: local path, Git repo, or npm source)npm + community awesome-opencode indexOpenVSX extensions + MCP Marketplace (cursor.directory)GitHub Marketplace (Extensions), plus plugin marketplaces (default: github/copilot-plugins, github/awesome-copilot)pi install npm:<pkg> / pi install git:<repo>
Closest analogue (if no native plugins)-- (has native plugins now)-Share .cursor/* files directly-- (has native packages)
Separate @-invocable extension surface----Copilot Extensions (Skillsets / Agents) via GitHub Marketplace-
  • A Claude Code plugin is a static bundle of files. An OpenCode plugin is live JS/TS code. They are not the same abstraction layer - one is content packaging, the other is event-driven code.
  • In Copilot, Extensions and plugins are two distinct primitives that both ship in 2026. Extensions are @-invocable Chat agents distributed via GitHub Marketplace; plugins are marketplace-registered bundles (skills + agents + hooks + MCP + LSP) for VS Code Chat and Copilot CLI. Don’t conflate them.

Start from what you already have. List the extension files in your busiest repo, check each one against your tool’s bundle above, and you end up with two lists: the pieces a plugin will carry, and the pieces your install instruction still has to name out loud. Package the first, write down the second, and the next teammate is one command and one short paragraph away from your setup rather than an afternoon.