Skip to content

Course · Claude Code · Extending Claude Code

Ship it to your team through a marketplace

Suppose you have a plugin - a directory bundling skills, agents, hooks, and MCP servers into one installable unit, with a manifest at .claude-plugin/plugin.json - and it runs on your machine from claude --plugin-dir ./payments-kit. The example here is payments-kit, built for the small TypeScript payments service this course uses: two MCP servers, db and jira, for a constructed team’s database and ticket board, a PreToolUse hook, ledger-needs-test, that refuses ledger commits without a test, a finish-pr skill, and a ledger-auditor subagent. The bundle lesson assembles it.

To get it onto your team’s machines you need one more layer: a marketplace - a catalog that lists one or more plugins and tells Claude Code where to fetch each one. Your teammates add the marketplace once, then install and update plugins from it by name. For a team, that is the difference between “here’s a folder, good luck wiring it in” and “run one command, you’re set up.”

A marketplace is itself just a file in a git repo: .claude-plugin/marketplace.json at the repo root. It names the marketplace and lists the plugins it offers, each with a source saying where the plugin directory lives:

{
"name": "payments-team",
"owner": {
"name": "Payments Platform"
},
"plugins": [
{
"name": "payments-kit",
"source": "./plugins/payments-kit",
"description": "Database + board reach, the ledger gate, and the wrap-up ritual"
}
]
}

The name and owner identify the marketplace; each plugin entry needs a name and a source. Here source is a relative path because the plugin lives in the same repo as the catalog - you moved the payments-kit directory into this repo, to plugins/payments-kit in the example above - the common case for a team that keeps its tooling in one place. A source can also point at a separate GitHub repo, a plain git URL, an npm package, or a zip archive. The full schema is on the marketplace reference.

Hosting is nothing exotic. Push the repo to GitHub or any git host - in the example the repo is payments-team/payments-tooling - and the marketplace is live: there is no registry to register with and no build step. The catalog is the repo.

Now the payoff - what someone joining the payments team actually does. They add your marketplace once and install the kit:

/plugin marketplace add payments-team/payments-tooling
/plugin install payments-kit@payments-team

The first command points Claude Code at your repo, here by its owner/repo shorthand; a full git URL works too. The second installs the plugin from it, namespaced by the marketplace so the target is unambiguous. If they would rather look before installing, /plugin opens the browsing interface over everything the marketplace offers.

With that single install, the whole kit lands on their machine at once: the db and jira MCP servers, the ledger-needs-test gate, the finish-pr skill, the ledger-auditor subagent - wired and versioned. They copied no files and read no settings.json. They ran two commands.

You improve the kit - tighten the gate’s grep, add a server - and ship it the same way you ship code. Bump version in plugin.json and push: that string pins updates, so installed users pick up the new release when it changes. Your teammates run /plugin marketplace update to refresh the catalog and /plugin update to pull the release; a background refresh also notices new marketplace commits on its own and swaps the new catalog in. That refresh updates the catalog, not necessarily the installed plugin - auto-updating installed plugins is a separate setting on each machine - so for a release that matters, say so and have the team run /plugin update.

The setup stays in sync without anyone hand-merging config. A team that shares a marketplace converges on one agent configuration the way it converges on one set of lint rules: by reference, not by copy.

That is the chapter. An agent that could only act on what it could already reach now has three things: reach into external systems via MCP, a gate the model cannot talk past via a command hook, and a way to ship the whole setup as one installable plugin. Reach, gate, ship - the three ways this chapter extended Claude Code past its defaults.

The shipped gate is what makes unattended runs safe

Section titled “The shipped gate is what makes unattended runs safe”

Look at the ledger gate once more - the wall that fires with nobody in the loop. At a terminal, with you watching every step, that property is a safety net. Its real job is a situation this chapter has not covered: running Claude Code with nobody watching at all.

Everything here assumed you were there - approving an edit, reacting to a blocked commit. Automation drops that assumption: Claude Code running headless, in a CI pipeline, wired into GitHub, kicked off by an event instead of a person. The moment no human can answer a prompt, hooks and scoped permissions - the course’s control layer - are what stand between the agent and a production mistake. A gate shipped in a plugin is a gate every unattended run carries.