How to submit an MCP server to Official MCP Registry

By Jonah EasePublished Last checked
The official registry has no form and no reviewer in the route. You write a server.json, prove you own the package it points to, sign in with the mcp-publisher tool, and publish[1]. It stores metadata only, and the packages stay on npm, PyPI, Docker Hub or wherever you put them[7]. Most of the work is getting the name and the proof to agree.
A server.json that validates
Three fields are required: name, description and version. The schema caps the description at 100 characters and requires the name to look like namespace/server[8]. This is the quickstart's file after its edit[1]:
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-12-11/server.schema.json",
"name": "io.github.my-username/weather",
"description": "An MCP server for weather information.",
"repository": {
"url": "https://github.com/my-username/mcp-weather-server",
"source": "github"
},
"version": "1.0.1",
"packages": [
{
"registryType": "npm",
"identifier": "@my-username/mcp-weather-server",
"version": "1.0.1",
"transport": { "type": "stdio" }
}
]
}For a hosted server, replace packages with a remotes entry holding type (streamable-http is the one to use) and a public url[4].
Your namespace decides how you sign in
| Sign-in | Name must start with |
|---|---|
| GitHub | io.github.username/ or io.github.orgname/ |
| Your own domain (DNS or HTTP proof) | com.example.*/, your domain written backwards |
Registry docs, read [2]
Proof you own the package
| Package | Proof, inside the published package |
|---|---|
| npm | "mcpName" in package.json, equal to the server name |
| PyPI, NuGet, Cargo | mcp-name: your-server-name in the README. Crates.io strips HTML comments, so a Cargo README needs it as visible text. |
| Docker / OCI | LABEL io.modelcontextprotocol.server.name="your-server-name" |
| MCPB | A URL containing "mcp", and a fileSha256 in server.json |
| Remote URL | None named in the docs; the server must be publicly reachable. |
[3][4]. Publish the package version first: the registry hosts metadata only, and the quickstart publishes the package before the server.
Sign in and publish
mcp-publisher init
mcp-publisher login github
mcp-publisher publish
curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.my-username/weather"login github prints a code and the page github.com/login/device; you enter the code there yourself[2]. Every change after that needs a new version. Published metadata is immutable, and there is no way to unpublish today[6][5]. Version ranges such as ^1.2.3 or 1.x are refused.
Errors people hit
- "Registry validation failed for package": the proof is missing from the published version. Add
mcpNameor the README line, publish the package again, then retry[1]. - "You do not have permission to publish this server": your sign-in method and the name's namespace do not match[1]. For an organisation namespace a user reported a 403 as an organisation owner, and a maintainer called it a bug on the registry's side[11].
- "cannot publish duplicate version". In one reported case the cause was a server.json that still said the old version, and the fix was to put the new one in it[9].
- "Expected mcpName X, got x": a casing mismatch between the organisation name and the namespace. This report was still open on [10].
- "Invalid or expired Registry JWT token": run
mcp-publisher login githubagain[1].
Error: publish failed: server returned status 400:
{"title":"Bad Request","status":400,"detail":"Failed to publish server",
"errors":[{"message":"invalid version: cannot publish duplicate version"}]}By hand or with help
Everything above is the by-hand route: three commands and one approval in your browser. The registry expects downstream aggregators to pull from it[7], and two of them have their own pages: PulseMCP and the GitHub MCP Registry.
Current status,
The registry's own pages still call it a preview, where breaking changes or data resets may occur[7]. The latest release of the registry software was v1.8.1, published [12].
Sources
- MCP Registry docs: Quickstart · checked
- MCP Registry docs: How to authenticate when publishing · checked
- MCP Registry docs: Supported package types · checked
- MCP Registry docs: Publishing remote servers · checked
- MCP Registry docs: Versioning · checked
- MCP Registry docs: Frequently asked questions · checked
- MCP Registry docs: About the registry (preview notice) · checked
- server.json schema, 2025-12-11 · checked
- Registry issue 1615: publish rejected as a duplicate version · checked
- Registry issue 1525: mcpName rejected for a casing mismatch · checked
- Registry issue 1468: 403 publishing under an organisation namespace · checked
- Registry repository: releases · checked
ManyCP is not affiliated with, endorsed by or sponsored by any directory, Docker, OpenAI, Anthropic or GitHub named here. Names are used to say which service a fact is about.
Or skip all of that
Or let ManyCP do it in one click
ManyCP builds the server.json, checks it with the registry, and publishes with your GitHub sign-in. If your package is missing the mcpName proof, it opens a pull request on your own repo to add it.