Publish a plugin
Choose how to distribute a finished Claude Code plugin, run the pre-release checklist, and ship updates, renames and removals without breaking users.
Publishing means listing your plugin in a marketplace so people can install it by name and pick up your updates. You can run your own marketplace (a JSON file in a git repo) or submit to Anthropic's directory. If you just want two colleagues to try it, you do not need to publish at all.
This page assumes the plugin already works. If it does not yet, start at /docs/plugins/create.
Pick a route
| Route | Who can install | You need | Automatic updates for users? |
|---|---|---|---|
| No marketplace | Whoever you send the folder or .zip to | The plugin folder | No, they load the copy you sent |
| Your own marketplace | Anyone who can reach the repo (private repos work) | A repo with .claude-plugin/marketplace.json listing the plugin | Off by default, users can turn it on |
| Anthropic's directory | People who add it on claude.ai or in Cowork; it reaches their Claude Code via account sync | A GitHub repo and a paid claude.ai plan to submit from | Yes, once your new version is published |
Auto-update is a per-marketplace switch on the user's side. For client work I nearly always use a private marketplace in the client's own GitHub organisation: access control comes free with repo permissions.
Pre-release checklist
Run through this before the first release and again before each subsequent one.
-
Pick a permanent name. Users install, enable and configure by
name@marketplace, so renaming creates a different plugin as far as existing installs are concerned. Use kebab-case likeinvoice-tools(validation warns on anything else) and put the friendly label indisplayName. -
Decide on versioning. If
plugin.jsonsetsversionand you push commits without bumping it,claude plugin updatereports<name> is already at the latest version (1.0.0).and nobody gets your changes. Either bumpversionevery release, or leave it out in a git-hosted marketplace so the commit SHA is used. Details in /docs/plugins/loading. -
Validate strictly.
claude plugin validate --strict ./invoice-toolsA clean run prints
✔ Validation passed.--strictalso fails (exit 1) on warnings such as unknown manifest fields or a missingversion, which is what you want in CI. Drop--strictif you deliberately omitversion. Validation also flags component paths that do not start with./; in hook commands and MCP configs, reference files as${CLAUDE_PLUGIN_ROOT}/.... -
Install it from a local marketplace, not just
--plugin-dir. Runclaude plugin marketplace add ./path-to-marketplace, install, start a session and check it loads. This catches problems with cached copies that--plugin-dirhides. See /docs/plugins/create-marketplace and /docs/plugins/loading. -
Fill in the metadata. Set
description,author,homepageandrepositoryinplugin.json, and add aREADME.mdat the plugin root.homepagemust parse as a URL. All fields: /docs/plugins/manifest-reference. -
Run your evals. If you have a suite,
claude plugin evalcatches behavioural regressions. See /docs/plugin-evals.
A minimal CI job for step 3 and 6:
# .github/workflows/plugin.yml
name: plugin
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm install -g @anthropic-ai/claude-code
- run: claude plugin validate --strict ./invoice-tools
Sharing without a marketplace
If the plugin lives in a git repo, people can clone and load the checkout, or point --plugin-url at a .zip attached to a release. To update they pull or download again. Otherwise just send the folder or a .zip.
They load it either:
- for one session:
claude --plugin-dir ./invoice-tools(a folder, or the.zipitself); or - for every session: move the folder, including
.claude-plugin/plugin.json, under~/.claude/skills/.
Adding a .claude-plugin/marketplace.json to the same repo is all it takes to graduate to installs by name.
Shipping a plugin alongside your own tool
If you maintain a CLI or SDK, have your installer or post-install message run or print two commands: claude plugin marketplace add <source> then claude plugin install <name>@<marketplace>. For prompting users while Claude is running your tool, see /docs/plugins/cli-hints.
Publishing through your own marketplace
A marketplace is a .claude-plugin/marketplace.json committed to a git repo. Push it and you are published; there is no form to fill in. It can live in the plugin's own repo or a separate one.
For a single plugin in its own repo, put the marketplace file next to plugin.json and use "./" as the source:
{
"name": "shields-tools",
"owner": { "name": "Cameron Shields" },
"plugins": [
{ "name": "invoice-tools", "source": "./" }
]
}
Keep the entry's name identical to the name in plugin.json. Run claude plugin validate . before pushing. Multi-plugin layouts are covered in /docs/plugins/create-marketplace.
Access follows the repository: a private repo is a private marketplace. For non-git hosting, or reaching everyone in a company including non-git users, see /docs/plugins/host-marketplace.
Tell users how to install, from their shell:
claude plugin marketplace add cameronshields/shields-tools
claude plugin install invoice-tools@shields-tools
Or in one step inside a session on v2.1.275+:
/plugin install invoice-tools --marketplace cameronshields/shields-tools
Updates reach users when they run claude plugin update invoice-tools@shields-tools (refreshes the marketplace and installs the new copy if the version changed) or when they have auto-update on for your marketplace, which does the same thing shortly after a session starts. It is off by default for third-party marketplaces; /docs/plugins/host-marketplace explains how to encourage it.
Submitting to Anthropic's directory
The directory at claude.ai/directory is what people browse on claude.ai and in Cowork to add plugins and connectors. One listing reaches claude.ai, Cowork and Claude Code. You submit through the developer portal at claude.ai/directory/manage; the walkthrough lives on claude.com.
The official marketplace, claude-plugins-official, does not take submissions through the portal. If you have an Anthropic partner contact, ask them about an official listing.
Steps:
- Check you can submit. It needs a paid plan. Pro and Max users submit from their own account. On Team and Enterprise an Owner submits; on Enterprise an Owner can also grant the Directory permission via a custom role under Organization settings > Roles.
- Validate locally with
claude plugin validate ./invoice-tools --strict. The portal applies extra directory rules the CLI does not, so a clean local run is necessary but not sufficient. claude.com has a pre-submission checklist. - Check what loads where. Some components are Claude Code-only. For example, claude.ai and Cowork will not install a plugin with a top-level
bin/folder. claude.com publishes a component support table by app. - Submit in the developer portal.
Review, publishing of new versions, submitting an MCP server as a connector alongside, and migrating older form-based submissions are documented on claude.com.
Users who install from the directory see your plugin in Claude Code as <name>@synced; see /docs/plugins/loading.
Updates, renames and removals
New versions
In your own marketplace with version set: bump it and push. Users get it on claude plugin update or via auto-update. Directory listings follow the update process on claude.com.
Tagging
Tag releases in git only if other plugins put a version range on yours, since ranges resolve against tags. From the plugin folder:
claude plugin tag --push
This creates {name}--v{version} and pushes it to origin. See /docs/plugins/dependencies and /docs/plugins/cli-reference.
Renaming and removing
Warning: Do not change a published plugin's
name. Existing installs are recorded under the old name and will fail withPlugin "<name>" not found in marketplace.
Change displayName if you just want a new label. If a rename really is unavoidable, add a renames map to the marketplace file so existing installs migrate. Removing a plugin and the full renames syntax are covered in /docs/plugins/host-marketplace and /docs/plugins/marketplace-reference.
Declaring dependencies
If your plugin needs another plugin from the same marketplace, list it in dependencies in plugin.json, either as a bare name or as an object with a semver version range. Installing yours then installs and enables the dependency. See /docs/plugins/dependencies.