·4 min read#skills#marketplace#how-to
How to Share Claude Code Skills Across a Whole Team
Your team already has shared skills. They live in Slack threads titled "the prompt that works for release notes" and in one senior engineer's dotfiles. A private Claude Code marketplace turns that folklore into a git repo, and turns onboarding into two slash commands.
One repo, one marketplace.json
A Claude Code marketplace is not a service. It is a git repo with a manifest at .claude-plugin/marketplace.json. That is the whole infrastructure:
team-skills/
├── .claude-plugin/
│ └── marketplace.json
└── plugins/
├── release-notes/
│ ├── .claude-plugin/plugin.json
│ └── skills/
│ └── release-notes/
│ ├── SKILL.md
│ └── references/style-guide.md
└── incident-runbook/
├── .claude-plugin/plugin.json
└── skills/
└── incident-runbook/SKILL.md
The manifest lists your plugins and points at their sources:
{
"name": "acme-skills",
"owner": { "name": "Acme Platform Team" },
"plugins": [
{
"name": "release-notes",
"source": "./plugins/release-notes",
"description": "Drafts release notes in house style",
"version": "1.2.0"
},
{
"name": "incident-runbook",
"source": "./plugins/incident-runbook",
"description": "Walks Claude through our incident process",
"version": "0.4.1"
}
]
}
Each skill is a SKILL.md with YAML frontmatter (name, description) plus an optional references/ directory for the heavy material. Claude loads the frontmatter cheaply and pulls the full body only when the description matches the task. This matters for teams: you can ship a 40-page style guide in references/ and it costs nothing until someone actually writes release notes.
One trap worth naming: if you serve a marketplace over a URL, the plugin sources must be git-backed. Relative HTTP paths resolve to nothing and fail silently, no error, just a plugin that never materializes. A plain git repo (GitHub, GitLab, self-hosted) sidesteps this entirely because Claude Code clones it and resolves ./plugins/... paths on disk.
Install: two commands per teammate
Make the repo private, grant your team read access, done. Claude Code fetches it with the user's existing git credentials, so whatever already lets them git clone (SSH keys, gh auth) lets them install:
/plugin marketplace add acme/team-skills
/plugin install release-notes@acme-skills
Put those two lines in your onboarding doc. That is the entire "distribute AI tooling to 30 engineers" project. No internal npm registry, no shared drive of prompt docs that drift out of date, no "check the pinned message."
Versioning is just git plus a version field
Treat the marketplace repo like any other production repo:
- Bump the
versionfield inplugin.jsonandmarketplace.jsonwhen a plugin changes behavior. Semver reads naturally here: patch for wording tweaks, minor for a new skill inside the plugin, major when you change what the skill is for. - Tag releases. If a skill update makes Claude worse at the task (it happens, descriptions are load-bearing),
git revertfixes everyone at the next update. - Require PRs. A skill's
descriptionfrontmatter decides when Claude invokes it, which makes it the highest-leverage line in the file. Review it like an API signature, because it is one.
The version field is not decoration. It is what lets a teammate answer "am I on the fixed version?" with /plugin instead of asking in Slack.
How updates actually reach installed users
This is the part teams get wrong by assuming push semantics. There is no push. The flow is pull:
- Someone merges a change to the marketplace repo.
- A teammate runs
/plugin marketplace update acme-skills. Claude Code re-fetches the repo, refreshing its local clone. - Installed plugins re-resolve against the refreshed marketplace, and updated plugins can be brought current from the
/plugininterface.
Until step 2 happens, teammates keep the version they installed. That is a feature during an incident (nobody's tooling changes under them mid-task) and a chore the rest of the time. Two mitigations:
- Announce meaningful skill releases the way you announce library releases: a line in the team channel with the version and what changed.
- Fold
claude /plugin marketplace update acme-skillsequivalents into whatever periodic setup script your team already runs, if you have one. Otherwise, habit works fine; the command is idempotent and fast.
Verified on Claude Code CLI 2.1.x: add, install, and marketplace update behave exactly as described.
The team workflow that makes this stick
Structure beats enthusiasm here. What works:
One plugin per domain, not one mega-plugin. release-notes, incident-runbook, sql-conventions. People install what their role needs, and version bumps stay legible. A single everything plugin turns every change into a change for everyone.
Skills own their context. If the release-notes skill needs the style guide, the style guide lives in that skill's references/, versioned with the skill. The moment a skill depends on "the doc in Drive," you have rebuilt the folklore problem with extra steps.
Assign owners. Each plugin gets a CODEOWNERS entry. Skills degrade like documentation does, silently, and an owner is the difference between "the runbook skill still references the old pager rotation" getting fixed in a day versus discovered during an incident.
Dogfood before merge. /plugin marketplace add ./team-skills works on a local path. Reviewers install the branch locally, run the skill against a real task, then approve. A skill PR that nobody executed is a prompt PR, and prompt PRs lie.
The pattern generalizes past commands and conventions. A marketplace can carry all four plugin surfaces: skills, slash commands, hooks, and MCP servers. Which means the thing you distribute does not have to be a procedure. It can be a person's judgment: how your staff engineer reviews schema migrations, how your head of product cuts scope. Write that down as skills and the two-command install distributes it too.
Install a person
installs.me turns your files, calendar and calls into a Claude Code plugin that thinks like you. Anyone installs it with two commands:
/plugin marketplace add https://installs.me/lautaro
/plugin install lautaro@lautaro-installs