Menu

AI

Lesson 28: Publish to the MCP Registry

Publish an MCP server to the official MCP Registry step by step with mcp-publisher, server.json, namespace login and a check that your listing went live.

By: Irina ShvayaOctober 28, 2026

Lesson 28: Publish to the MCP Registry

This lesson is part of Learn MCP, our free course on the Model Context Protocol, within The MCP Guide.

In this lesson you will publish an MCP server to the official MCP Registry. You will prepare your package, create a server.json file, prove you own the namespace, publish with the mcp-publisher command-line tool, and check that the listing is live.

The steps follow the official registry quickstart and related registry docs, checked on 28 October 2026. As of October 2026 the registry is in preview. The docs warn that "breaking changes or data resets may occur before general availability." Re-check the quickstart before you publish, because commands may change.

Publishing is public and permanent for each version. Finish Lesson 27: Version and Update Your Server first, so your version numbers are ready.

Key Takeaways

  • The MCP Registry stores metadata about public servers; your code still lives on npm, PyPI, NuGet, Docker Hub or your own remote URL.
  • Your server's registry name is tied to a namespace you prove you own: io.github.<username>/ via GitHub login, or a reverse-DNS domain via DNS or HTTP verification.
  • The registry checks that your package points back to the same name, for example with mcpName in package.json or an mcp-name: line in a PyPI README.
  • Each published version is immutable, and as of October 2026 you cannot delete or unpublish a server.
  • The registry does not security-scan servers; it relies on package registries and downstream aggregators for that.

What the registry is (and isn't)

The About the registry page calls it "the official centralized metadata repository for publicly accessible MCP servers." It hosts metadata that points to packages, not the packages themselves.

It is designed mainly for downstream aggregators, such as marketplaces, rather than for host apps to read directly. It does not support private servers. And it "delegates security scanning" to package registries and aggregators. For the business view, read what the MCP Registry is.

Step 1: Prepare a public package or a public URL

The registry accepts a server if its install method is public, such as a public npm package, or the server itself is publicly reachable.

For a local server, publish the package first. The quickstart uses an npm package and these commands:

npm install
npm run build
npm adduser
npm publish --access public

For a remote server, you need a public HTTPS endpoint. The remote servers guide says remote servers should use Streamable HTTP, and that the SSE transport is deprecated. Lesson 21 covers deployment.

Step 2: Add the ownership marker to your package

The registry verifies that your package claims the same server name you publish. The method depends on the package type, per the package types guide:

Package typeOwnership marker
npm"mcpName": "io.github.my-username/weather" in package.json
PyPImcp-name: io.github.my-username/weather in the README (may be an HTML comment)
NuGetmcp-name: line in the README
Cargomcp-name: as visible text in the README (crates.io strips HTML comments)
Docker/OCILABEL io.modelcontextprotocol.server.name="..."

The quickstart is strict about the name: with GitHub login, mcpName "must start with io.github.my-username/." Rebuild and republish the package after you add the marker.

Step 3: Install mcp-publisher

On macOS or Linux, the quickstart offers Homebrew or a prebuilt binary:

brew install mcp-publisher
mcp-publisher --help

The help output lists four commands: init, login, logout and publish. Windows users can download the binary with the PowerShell command in the quickstart.

Step 4: Create server.json

In your project folder, run:

mcp-publisher init

This generates a template. After editing, a minimal npm-based file from the quickstart looks like this:

{
  "$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"
      }
    }
  ]
}

Three rules to check:

  • name must match your package's mcpName.
  • version must be unique for every publication. The versioning guide recommends semantic versioning and prohibits ranges such as ^1.2.3.
  • If your server needs an API key, the template's environmentVariables entry can mark it isSecret: true. Never put a real key in this file.

A remote server uses a remotes array instead of, or alongside, packages, with "type": "streamable-http" and the URL. The remote guide also shows headers for API keys and URL variables for multi-tenant setups.

Write a plain, honest description. The moderation policy says maintainers remove spam, including "a server with a description stuffed with marketing copy and an unrelated implementation."

Step 5: Log in to prove namespace ownership

The authentication guide offers three methods:

MethodName formatHow you prove it
GitHubio.github.username/* or io.github.orgname/*Device-code login in the browser
DNScom.example.*/*A TXT record with your public key
HTTPcom.example.*/*A key file at /.well-known/mcp-registry-auth

For GitHub, run:

mcp-publisher login github

The tool prints a code. Open https://github.com/login/device, enter it and authorize. A company with its own domain will usually prefer DNS login so listings appear as com.yourcompany/... rather than under a personal GitHub account.

Step 6: Publish

mcp-publisher publish

The quickstart's sample output ends with "Successfully published" and the server name and version. If you see "You do not have permission to publish this server," your login method doesn't match your name's namespace. If you see "Registry validation failed for package," the ownership marker from Step 2 is missing or wrong.

Step 7: Verify the listing

Search the registry API for your server name:

curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=io.github.my-username/weather"

When we ran a search against this endpoint on 28 October 2026, each result included your server metadata plus a registry-added _meta block with fields such as status, publishedAt and isLatest.

Step 8: Automate future releases

The GitHub Actions guide shows a workflow that runs on version tags such as v1.0.0. It builds and tests, publishes the package, then runs mcp-publisher login github-oidc and mcp-publisher publish. The OIDC method needs id-token: write permission and no stored registry secret.

Try it

You can practice safely without publishing anything.

  1. Run mcp-publisher init in your project and read the generated server.json.
  2. Fill in name, description and version, and add the matching ownership marker to your package.
  3. Run the curl search above with your intended name to confirm it is not taken.
  4. Write a 1–2 sentence description a stranger would understand. Remove any marketing words.

Only run mcp-publisher publish when the server is ready for strangers, because you can't unpublish it.

Recap

You learned that the registry stores metadata, not code. You added an ownership marker, created server.json, proved your namespace with GitHub, DNS or HTTP, published, verified the listing and saw how to automate releases. Being listed also helps people find you; our guide on how to market an MCP server covers what comes next.

Course navigation

Previous lesson: Lesson 27: Version and Update Your Server.

Next lesson: Lesson 29: Long-Running Tasks and MCP Apps.

Back to the Learn MCP course outline.

Frequently asked questions

Does listing in the registry mean my server is approved or safe?

No. The registry verifies namespace ownership, not code quality. Its moderation policy says it is "quite permissive" and consumers "should assume minimal-to-no moderation." Users should still review servers, as in Lesson 9: Read a Server Before You Trust It.

Can I remove or edit a published version?

Not as of October 2026. The registry FAQ says you currently cannot delete or unpublish a server, and version metadata is immutable. To change details, publish a new version.

How do I update only the description without a new package release?

The versioning guide suggests a prerelease version such as 1.2.3-1 for registry-only updates. It warns that a prerelease published after 1.2.3 will not be marked "latest," because semantic versioning sorts it earlier.

Can I publish a private, internal server?

No. The registry does not support private servers. The About page suggests running your own registry that implements the official OpenAPI spec for that.

Will Claude or ChatGPT show my server automatically once it's listed?

Not necessarily. The registry is meant to feed aggregators and marketplaces, and each app has its own directory and review rules. The registry is one channel among several.

You Might Also like to Read

Get a FREE Website Audit

Enter your website and get a 20–30 page SEO, GEO, AEO & CRO audit within 24 hours. Completely free.

Don't have a site yet? Get in touch →

Ready to speak with a marketing expert?
Give us a call! (916) 866-7893

Websites Launched
1407
Websites Launched
Marketing Experts
29
Marketing Experts
Hours of Dedicated Work
204533
Hours of Dedicated Work
Irina S.Benjamin G.Jeanette M.David G.