How to Publish a Plugin to the Claude Directory (Developer Portal Guide)

TL;DR
Submit a plugin to the Claude directory: validate it, clear the security scan, publish, and read 90 days of usage analytics. Needs a paid plan.
Anthropic's directory submission portal at claude.ai/directory/manage, live since September 25, 2026, is where you submit a plugin bundle (a GitHub repo) or a remote MCP connector (a URL) to be listed in the Claude directory. One listing reaches claude.ai on the web, the desktop and mobile apps, Cowork and Claude Code. If you already ship a remote MCP server or a useful set of skills, submit now: each push to GitHub is picked up and scanned as a new version with no resubmission, review is an automated scan plus a human check, and the Usage tab gives you install and funnel numbers you would otherwise have to build yourself. The costs are a paid plan, strict packaging rules and no fixed review time.
Last updated: October 17, 2026. Commands checked on Claude Code 2.1.302; portal steps taken from Anthropic's directory docs (no portal submission was made for this guide).
What the portal is (and what changed on September 25)#
Anthropic's launch post calls plugins the main way to build third-party extensions for Claude. A plugin packages MCP connectors, Agent Skills, or both, and in Claude Code it can also carry LSP servers, commands, hooks and agents. The build overview is explicit that a plugin with a single component (just an MCP connector, just skills, just an MCP App, or just commands and agents) is complete. There is no partner program to apply to first.
The portal accepts two kinds of submission:
| Plugin bundle | MCP connector | |
|---|---|---|
| What you submit | A GitHub repository (and optional folder) | The URL of your remote MCP server |
| What it can hold | Skills, MCP server references, commands, agents, hooks, MCP Apps | One remote server and its tools |
| Repo visibility | Can be private while you validate; must be public before it goes live | Not applicable |
| Review | Automated validation and security scan on every version, plus a human review of each new listing | Automated scan; listed as a Community connector by default, and Anthropic may escalate it to Verified review |
| Updates | Push to the tracked branch or move the tag | Ship changes to your server |
Three things were retired along the way, per the publishing docs. The old Claude Console plugin submission form is no longer supported. The directory no longer accepts local MCP servers packaged as desktop extensions (MCPB), and desktop extension listings are deprecated, so a local server now ships inside a plugin bundle. And skills cannot be submitted on their own: they go in a bundle.
The launch post also confirms that Claude supports MCP spec version 2026-07-28 (commonly called MCP 2.0) with its stateless core, plus two extensions: MCP Apps for interactive UI in chat, and Enterprise Managed Auth for zero-touch OAuth for enterprise users. If your connector still targets the older spec, read our MCP 2026-07-28 breaking changes guide before you submit.
%% title: What goes into a directory listing
flowchart LR
S[Skills] --> B[Plugin bundle<br/>GitHub repo]
R[MCP server ref] --> B
A[MCP App] --> B
C[Commands / agents] --> B
M[Remote MCP server] --> K[MCP connector<br/>URL]
B --> D[Claude directory]
K --> D
D --> X[Chat]
D --> W[Cowork]
D --> CC[Claude Code]Who can submit#
You need a Pro, Max, Team or Enterprise plan. Free accounts cannot submit. On Team and Enterprise, an Owner submits, and on Enterprise an Owner can grant the "Directory" permission to other people through a custom role (source).
The listing belongs to the organization that submits it, and for a plugin bundle the first organization to submit a given repository folder holds the listing. A second organization's submission of the same folder is refused. In practice that means you should submit from the organization that will own the product long term, not from a personal Pro account you happen to be signed into.
Two rate limits from the submission docs matter if you plan to list several plugins at once:
- An organization can create up to 10 submissions in any 24-hour period, and drafts and withdrawn submissions count toward that.
- Each repository-plus-folder combination gets one submission.
Step 1: Lay out the plugin#
Here is the example plugin used for the local checks in this guide. It pairs one skill with a hosted MCP server:
acme-invoices/
.claude-plugin/
plugin.json
skills/
draft-invoice/
SKILL.md
.mcp.json
README.md
LICENSE
Only plugin.json goes inside .claude-plugin/, per the plugin quickstart. The manifest uses the quickstart's fields:
{
"name": "acme-invoices",
"displayName": "Acme Invoices",
"version": "1.0.0",
"description": "Draft, look up and send Acme invoices from Claude.",
"author": { "name": "Acme Inc.", "url": "https://acme.example" },
"license": "MIT"
}
The remote server reference in .mcp.json:
{
"mcpServers": {
"acme": {
"type": "http",
"url": "https://mcp.acme.example/mcp"
}
}
}
And the skill. Write the description around the situations a user is in, because that is what Claude matches against:
---
name: draft-invoice
description: Use when the user asks to bill a client, draft an invoice, or turn tracked hours into an invoice for an Acme account.
---
# Draft an invoice
1. Ask which client and billing period the invoice covers if the user did not say.
2. Look up the client's existing invoices with the `get_invoice` tool to reuse line-item names.
3. Draft the invoice as a table: line item, quantity, rate, total.
4. Show the draft and ask for confirmation before calling `send_invoice`.
Finally the README, which the portal reads for your listing and the security scan reads for disclosure. It needs at least 40 words outside code blocks, and it should say plainly what the plugin runs, sends and fetches:
# Acme Invoices
Acme Invoices lets Claude draft, look up and send invoices in your Acme account. It adds one skill, draft-invoice, which turns a request like "bill Northwind for September" into a reviewed invoice draft, and it connects to the hosted Acme MCP server at https://mcp.acme.example/mcp.
## What it runs, sends and fetches
The plugin runs no local code. Claude calls the Acme MCP server over HTTPS to read invoices and, only after you confirm, to send one. No data goes anywhere else.
Add a LICENSE file as well (or keep the license field in plugin.json).
A few rules to settle before you write more code, all from the pre-submission checklist:
- Choose the name carefully. Use lowercase letters, digits and hyphens, up to 64 characters (non-ASCII blocks; other deviations warn), and pick one that is not already taken. Don't use a reserved word (
claude,anthropic,official,plugin,mcp,test) as the whole name; generic names liketest-pluginare held for a reviewer. - No secrets in files. Declare anything sensitive under
userConfigwithsensitive: trueand reference it as${user_config.KEY}. - Remote MCP URLs must be absolute
https://orwss://URLs, a${user_config.KEY}reference, or empty ("") when the plugin has no fixed endpoint. - Launcher packages must be pinned:
npx pkg@1.2.3oruvx pkg==1.2.3, never@latest.
Then check where each component will actually run. The platform support table is the thing most likely to change your design:
| Component | Chat | Cowork | Claude Code |
|---|---|---|---|
| Skills | Loads | Loads | Loads |
| Commands | Loads as a skill | Loads (/plugin-name:command) | Loads |
| Agents, hooks | Ignored | Loads | Loads |
| Remote MCP server with a fixed URL | Works once connected from the plugin's Connectors tab | Loads; connect it from the plugin's Connectors tab | Loads |
| Local MCP server | Ignored | Loads when Cowork runs on your computer | Loads |
MCP URL containing ${user_config.*} | Ignored | Ignored if the option has no default | Loads, prompts for values |
Top-level bin/ | Refuses the whole plugin | Refuses the whole plugin | Loads |
| LSP servers, output styles, themes, settings | Ignored | Ignored | Loads |
The portal derives your listing's supported surfaces from these same rules. A plugin that leans on hooks or a local server will show up as Claude Code and Cowork only, which may be fine, but you should choose that on purpose. The directory also lists mods (code a plugin names under modules in hooks/hooks.json) for Claude Code.
Step 2: Test locally, then validate twice#
Load the plugin for one session without installing it:
claude --plugin-dir ./acme-invoices
The skill shows up as /acme-invoices:draft-invoice. Then run the local validator:
claude plugin validate ./acme-invoices
On Claude Code 2.1.302 the example above printed "Validation passed" with one advisory note (shortened here; it does not change the verdict):
i Advice (does not change the verdict):
> .../acme-invoices/README.md: This README has no line that installs
"acme-invoices" from a marketplace. Add the install line, which works
in one step on Claude Code 2.1.275 or later. ...
/plugin install acme-invoices --marketplace <owner>/<repo>
Validation passed
Now the gotcha that will cost you a round trip if you miss it. We made a second copy of the plugin with three problems the portal treats as Blocking: an unpinned npx -y acme-mcp@latest server in .mcp.json, a stray .DS_Store file, and no README at all. claude plugin validate printed "Validation passed" for that copy too, with exit code 0.
That is documented behavior, not a bug. The checklist says the local command only checks that files are well-formed. It does not check directory requirements like the README, license or name availability. Only the portal's Validate button runs those. Treat the local command as a syntax and schema check and the portal as the real gate.
One more step before submitting is worth the time: claude plugin eval, which runs eval cases against your plugin and a no-plugin baseline so you can see whether it actually helps. Our plugin evals in CI guide covers the setup. Each eval run is a real model call billed to your plan or API (source), so size the suite accordingly. Anthropic also ships plugin-dev and mcp-server-dev plugins in anthropics/claude-plugins-official, plus a skill-creator skill for drafting skills, and /skill-doctor to see each skill's context cost and how often it fires.
Step 3: Submit in the portal#
Before you open the portal, get GitHub in order (source):
- Connect a GitHub account on claude.ai in the same organization you are submitting from.
- That account needs push access to the repository.
- A private repo can be validated and submitted if you consent to the source upload and install the Claude GitHub App, but it must be public before you publish.
Then the flow:
- Go to claude.ai/directory/manage/new (the portal's Submit new entry point) and choose Plugin bundle.
- Source: enter the repository URL or
owner/repo, an optional plugin path (for a monorepo or marketplace repo with several plugins), and an optional branch or tag. The repository and folder cannot be changed after you submit. - Select Validate. Fix every finding marked Blocking, push, then select Re-validate. A validation report applies to exactly one commit, so a fix only counts once it is pushed.
- Listing details: these are read from
plugin.jsonand the README. Edit the files, not the form, if something looks wrong. - Data handling: describe what the plugin collects and where it goes.
- Compliance: a contact email plus four acknowledgements.
- Review and submit: choose how the directory learns about new versions (the GitHub push webhook, which is the default, or a scheduled check only) and set the Auto-publish passing versions toggle.
- Select Submit for review.
%% title: Plugin submission lifecycle
flowchart TD
A[Draft] --> B[Validate]
B --> C{Blocking findings?}
C -- yes --> D[Fix and push]
D --> B
C -- no --> E[Submit for review]
E --> F[Scanning]
F --> G{Result}
G -- pass --> H[Approved]
G -- held --> I[In review]
I --> H
G -- fail --> J[Needs changes]
J --> D
H --> K[Publish]
K --> L[Published]Step 4: Submit your MCP server as a connector too#
If your plugin references a remote MCP server you run, Anthropic's guidance is to always submit that server as an MCP connector as well (source). The connector listing gives you a dashboard with server health and usage by tool, and the two listings can be paired when both come from the same organization. Point the bundle's .mcp.json at the same URL so users see one set of tools rather than two.
Connector submission is stricter than the bundle flow. Per the connector submission docs, you need:
- A remote server over HTTPS.
- OAuth 2.0 if the server acts on user accounts.
- A
titleon every tool, plus areadOnlyHintordestructiveHintannotation. - Test-account credentials for reviewers, along with your docs, privacy and listing details across a 10-step form (Connection, Tools, Listing, Use cases, Company, Authentication, Data handling, Test and launch, Compliance with seven acknowledgements, Review and submit).
- For MCP Apps, 3-5 PNG carousel screenshots at least 1000px wide.
The annotations are the part people miss. With the TypeScript SDK they go on registerTool:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { z } from "zod";
const server = new McpServer({ name: "acme-invoices", version: "1.0.0" });
server.registerTool(
"get_invoice",
{
title: "Get invoice",
description: "Look up one invoice by its number.",
inputSchema: { invoiceNumber: z.string() },
annotations: { readOnlyHint: true },
},
async ({ invoiceNumber }) => ({
content: [{ type: "text", text: `Invoice ${invoiceNumber}: draft, 3 line items` }],
}),
);
server.registerTool(
"send_invoice",
{
title: "Send invoice",
description: "Email an invoice to the client. Cannot be undone.",
inputSchema: { invoiceNumber: z.string() },
annotations: { readOnlyHint: false, destructiveHint: true },
},
async ({ invoiceNumber }) => ({
content: [{ type: "text", text: `Sent invoice ${invoiceNumber}` }],
}),
);
export { server };
This snippet was type-checked with tsc --noEmit (strict, moduleResolution: bundler) against @modelcontextprotocol/sdk@1.32.1, zod@4.6.7 and typescript@7.0.2. It was not run against a live client, and the transport setup is left out. For the full server walkthrough, see how to build MCP servers.
Pick the connector's listing slug carefully: claude.ai/directory/connectors/SLUG is permanent (source).
Review results and statuses, decoded#
The portal sorts every validation finding into one of four results (source):
| Result | What it means | What to do |
|---|---|---|
| Blocks (marked Blocking) | The version cannot go forward | Fix, push, Re-validate |
| Held for a reviewer (Policy hold) | Allowed, but a person has to look | Nothing, unless you can remove the cause; expect a slower review |
| Warning | Likely problem that does not stop submission | Fix if you can |
| Note | Advice | Read it |
Blocking checks include a README of at least 40 words (words inside code blocks do not count), a LICENSE file or a license field in plugin.json, no .DS_Store, Thumbs.db, desktop.ini or __MACOSX, a valid and available name, pinned launcher packages, no real credentials in files, and remote MCP URLs that are absolute https:// or wss:// URLs (or a ${user_config.KEY} reference, or empty when there is no fixed endpoint).
Two things are always held for a reviewer even when every other check passes: any package run by a launcher (even a pinned one), and a package.json with a lockfile in the plugin root, because dependencies resolve at install time. If you can ship your MCP server as a remote URL instead of an npx launcher, your review path gets simpler.
The security scan looks for undisclosed behavior: sending data elsewhere, running hidden code, or changing Claude's permission settings. A first submission that fails it is rejected outright. The checklist's advice is to commit readable source, not minified bundles, and to describe in the README everything the plugin runs, sends or fetches. That is why the example README above has a "What it runs, sends and fetches" section. Our post on plugin URL supply chain risk explains why plugins get this level of scrutiny.
Once submitted, a plugin moves through these statuses (source):
| Status | Meaning | Who acts next |
|---|---|---|
| Draft | Started, not submitted | You |
| Scanning | Automated checks running | Anthropic |
| Needs changes | Findings to fix | You |
| In review | A person is reviewing | Anthropic |
| Approved | Passed, but not installable yet | Whoever the card names: an Anthropic reviewer, you, or the directory automatically |
| Published | Live and installable | Nobody |
| Not live yet | Marked published, but the directory team has not listed it yet | Anthropic |
| Delisted | Removed from the directory | You, if you want to request relisting |
| Withdrawn | You pulled the submission | Nobody |
Only Published is installable. For help with a plugin, use the portal's Get help / Contact Anthropic menu or email directory@anthropic.com. For a connector, the address is mcp-review@anthropic.com.
Shipping updates and reading the Usage tab#
After launch you update by pushing to the tracked branch, or by moving the tag if you track one. The directory scans each commit as a new version. A failing or held version does not take the listing down: the last published version keeps serving. One catch: if the security scan fails a new version, later versions also wait until an Anthropic reviewer clears the plugin. If you set version in plugin.json, raise it with each release (source).
Who presses the button depends on the publish setting, and that is not your choice. Anthropic decides which publish setting applies, and the Auto-publish row on the plugin's Overview tab shows it. By default an Anthropic reviewer publishes each passing version after you select Publish. Anthropic may instead apply a setting where the reviewer publishes only the first version, or where you publish the first version yourself. Under either of those, later passing versions go live automatically unless you turn off Publish new versions automatically on the Settings tab.
%% title: Update loop after launch
sequenceDiagram
participant Dev
participant GitHub
participant Directory
participant Portal
participant Users
Dev->>GitHub: push to tracked branch
GitHub->>Directory: webhook or scheduled check
Directory->>Directory: validate + security scan
Directory-->>Portal: new version result
alt passes and auto-publish on
Directory->>Users: serve new version
else held or fails
Directory->>Users: keep last published version
endThe Usage tab is where the directory adds data you would not otherwise have: how many accounts install and use the plugin, broken out by surface and by install source such as the Discover tab, plus a funnel of listing views, install clicks and installs. The tab lives in the developer portal, so only the people who can submit for your organization see it. (Self-distributed plugins are not blind: Claude Code documents context-cost and OpenTelemetry usage measurement for them, but that covers your own org, not strangers who found you.) Per the after-publishing docs, it covers a chosen period of up to 90 days, exports CSV, and shows:
- Reach: installs, active accounts, retention, and installs by surface and source.
- Versions: which versions people are on.
- Components: use of each skill, command, agent, hook and MCP server.
- Quality: load errors by Claude Code version, plus MCP tool calls, error rate and latency.
- Directory funnel: listing views, install clicks and installs.
Numbers are computed daily in UTC, and the tab shows Preview sample numbers until real usage is recorded, so do not read anything into the first day's charts. The launch post adds that analytics show which searches lead people to your listing. The Components view is the one to watch after a release: a skill nobody triggers usually has a description problem, not a code problem.
Gotchas and limits#
- Local validate is not the portal check. It passed a plugin with no README, a
.DS_Storefile and an@latestlauncher in our test. Always run the portal's Validate. - Size limits stop validation. The repo must be under 50 MiB as GitHub archives it and under 256 MiB unpacked, with fewer than 10,000 files and folders, and every plugin-folder file under 5 MiB. A non-image, non-font file over 256 KiB, more than 512 files, or binaries such as
.pdf,.zipor.icoget held for a reviewer. Monorepos should point the plugin path at a lean folder. ${user_config}in an MCP URL means no Chat support. Chat ignores that server. If chat users matter, use a fixed URL and handle per-user auth with OAuth.- A top-level
bin/makes Chat and Cowork refuse the whole plugin, not just skip the binaries. - Repo and folder are fixed after you submit. Moving the plugin means a new submission, and it counts toward the 10-per-day limit.
- Delisting has consequences for users. Delisting a live plugin stops updates for people who installed it, and their copy may be removed. Relisting is a request Anthropic can decline.
- No fixed review time, and no way to apply for Verified. Connectors start as Community, and Verified review happens only if Anthropic escalates.
- Moving off the Console form is manual. Withdraw the old submission in the Console and resubmit in the portal, or email directory@anthropic.com if there is no Withdraw button.
- Discovery is still converging. Anthropic says one discovery experience will roll out across Claude and Claude Code "over the coming weeks." Today users browse via Discover in Customize > Plugins on paid plans, or
/plugin directoryin Claude Code v2.1.287 and later. A plugin added on claude.ai syncs to Claude Code. - Team and Enterprise admins decide what their members see. An Owner can set your plugin to Not available, Available to install, Installed by default, or Required, so enterprise reach depends on admins, not just on your listing.
Directory vs your own marketplace#
The closest alternative is the route Claude Code has supported for a while: host a marketplace repo yourself. Claude Code's publishing docs list three options (no marketplace, your own marketplace, or Anthropic's directory), and the self-hosted one is good at what it does.
| Claude directory | Your own marketplace | |
|---|---|---|
| Reach | Every Claude surface the plugin supports, plus Discover and /plugin directory | Claude Code users who add it; claude.ai users can add GitHub, GitHub Enterprise, public GitLab and Bitbucket marketplaces, up to 25 per account per organization |
| Gatekeeping | Automated validation, security scan, human review of new listings | None beyond what you set up |
| Speed to ship | Review queue on the first version; later versions can auto-publish | Instant on push; users get it via claude plugin update, or auto-update if they turn it on (off by default) |
| Analytics | Usage tab: reach, versions, components, quality, funnel | Claude Code context-cost and OpenTelemetry usage events for your org; no directory funnel or cross-organization install counts |
| Requirements | Paid plan, public GitHub repo at publish time, README, license, available name | Any Git host in Claude Code, no plan requirement for the repo itself |
| Best for | Public products and anything you want strangers to find | Internal tools, pre-release builds, experiments |
The self-hosted route wins on speed and control: no queue, no packaging rules beyond a valid manifest, and you can lock it down with managed settings. Our Claude Code plugins for teams guide covers that setup end to end. The directory wins on reach, trust signals and directory-wide install and funnel data. Many teams will reasonably do both: an internal marketplace for pre-release builds and the directory for the public listing, fed from the same repo on different branches or tags.
%% title: Which distribution path
flowchart TD
A{Public users?} -- no --> B[Own marketplace<br/>or org rollout]
A -- yes --> C{Paid plan and<br/>public repo?}
C -- no --> B
C -- yes --> D[Claude directory]
D --> E{Host a remote<br/>MCP server?}
E -- yes --> F[Also submit a connector]
E -- no --> G[Bundle only]FAQ#
Do I need a paid plan to submit a Claude plugin?#
Yes. Submitting requires a Pro, Max, Team or Enterprise plan; Free accounts cannot submit. On Team and Enterprise an Owner submits, and Enterprise Owners can grant a custom "Directory" permission to others.
Can I submit just a skill to the Claude directory?#
No. Skills cannot be submitted on their own. Put the skill in a plugin bundle; a plugin with only skills is a complete plugin, so this costs you a plugin.json, a README and a license.
How long does Claude directory review take?#
Anthropic does not publish a fixed review time. Check the status: Scanning or In review means Anthropic acts next, Needs changes means you do. Launcher packages and lockfiles always add a human hold, so avoiding them helps.
Do I have to resubmit every time I update my plugin?#
No. Push to the tracked branch (or move the tag) and the directory scans each commit as a new version. A version that fails or is held never replaces the live one, and if the security scan fails a version, later versions also wait until an Anthropic reviewer clears the plugin.
Will my existing connector listing break?#
No. Anthropic says existing skills, connectors and plugins on the directory need no changes, and that developers will later be able to turn a connector listing into a plugin. Desktop extension (MCPB) listings are deprecated and the directory no longer accepts new ones; ship a local server inside a plugin bundle instead.
Sources#
- Build plugins for Claude with the directory submission portal - Anthropic, September 25, 2026
- Build overview
- Publish to the directory
- Submit a plugin
- Pre-submission checklist
- Submission status
- After publishing
- Connector submission
- Plugin feature support across platforms
- Plugin quickstart
- Claude Code: publish plugins
- Claude Code: measure plugin cost and usage
- MCP specification 2026-07-28
Continue Reading#
Get the next deep dive like this in your inbox
One email a week on Claude and the rest of the AI dev stack. Free.
Read next on Claude Code
Claude Code Plugins for Teams: Share, Require, Lock Down
Share Claude Code plugins with a team: commit a marketplace to one repo, require it in managed settings, and allowlist sources. Checked on v2.1.295.
13 min readAgent Plugins 1.0.0: One Package Format for Agent Skills and MCP Servers
Agent Plugins 1.0.0 is an open standard that packages Agent Skills and MCP servers into one plugin, with ChatGPT, Codex, Cursor and Copilot support at launch.
7 min readClaude Code Plugin Evals Make Agent Extensions Testable
Claude Code plugin evals score a plugin against a no-plugin baseline, write JSON and HTML reports and gate CI, making plugins testable agent infrastructure.
8 min readTechnical content at the intersection of AI and development. Building with AI agents, Claude Code, and modern dev tools - then showing you exactly how it works.







