DEV Community

Chen Yuan
Chen Yuan

Posted on • Originally published at Medium

The Old Way of Publishing MCP Servers Is Gone. Here's What Replaced It.

I Assumed It Would Be Easy

I've been building MCP servers for a while now. Filesystem tools, search utilities, API wrappers — the pattern is familiar: write the server, test it locally, document it, call it done. The last step — making it discoverable — always felt secondary.

Back when the MCP Registry was a GitHub repo, "publishing" meant opening a PR and waiting. Sometimes days, sometimes weeks. It worked, but it was slow.

Then I heard the registry had moved. The new system lives at registry.modelcontextprotocol.io — a proper API-based registry with a CLI tool, OAuth authentication, and namespace verification. No more PR queues. No more JSON files in someone else's repo.

I was excited. Then I tried it.

What the Registry Actually Is Now

The new MCP Registry is a standalone service built in Go, backed by PostgreSQL. It doesn't host your server code — just metadata. Your actual package lives on npm (or PyPI, NuGet, etc.), and the registry stores a pointer with configuration details.

To publish, you use a CLI tool called mcp-publisher. The flow goes like this:

  1. Add an mcpName field to your npm package.json
  2. Publish your package to npm
  3. Install mcp-publisher (a single Go binary)
  4. Run mcp-publisher init to generate a server.json template
  5. Run mcp-publisher login github for authentication
  6. Run mcp-publisher publish

On paper, six steps. In practice, I hit unexpected walls at almost every one.

The First Wall: Namespace Verification

The registry uses a reverse-DNS naming convention. Your server name looks like io.github.your-username/server-name. This prevents naming collisions — nobody can squat on "weather" — but it also means you need to prove ownership of that namespace.

For GitHub-based auth, your server name must start with io.github.<your-github-username>. The mcpName field in package.json needs to match exactly. I initially used my-username/weather and got a generic "Registry validation failed for package" error.

The error message doesn't tell you why it failed. I spent twenty minutes cross-referencing the docs before I spotted the namespace format requirement.

The fix was simple:

{
  "name": "@my-username/mcp-weather-server",
  "mcpName": "io.github.my-username/weather"
}
Enter fullscreen mode Exit fullscreen mode

The Second Wall: Version Alignment

The server.json file has a version field that must match your npm package version. I bumped my npm version from 1.0.0 to 1.0.1 but forgot to update server.json. The CLI didn't throw a clear error — instead, it said "validation failed" with no further detail.

This is the kind of thing that's obvious in retrospect but frustrating in the moment. Both files need to be in sync. I now keep them open side by side and update both before running publish.

The CLI Tool Is Actually Good

Once I got past the configuration issues, the CLI experience was smooth. The mcp-publisher init command scans your project and generates a server.json with reasonable defaults:

{
  "$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.0",
  "packages": [
    {
      "registryType": "npm",
      "identifier": "@my-username/mcp-weather-server",
      "version": "1.0.0",
      "transport": {
        "type": "stdio"
      }
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

Authentication uses GitHub's device authorization flow — you run mcp-publisher login github, get a code from the terminal, enter it on github.com/login/device, and you're authenticated. No manual token management, no API key generation.

The publish command itself takes about two seconds. Compare that to the old PR process which could take weeks. Speed is the killer feature here.

My Workflow for a Painless First Publish

If you're publishing for the first time, here's what I'd do differently knowing what I know now:

  • Read the quickstart first — It's at github.com/modelcontextprotocol/registry. The docs are well-written. Don't skip them.
  • Set up mcpName before you publish to npm — Adding it retroactively means re-publishing your npm package, which creates a new version number. Better to add it from the start.
  • Run mcp-publisher init and carefully check every field — The generated server.json picks up environment variables from your project. I had to remove an old API key placeholder it found in my .env.
  • Keep versions in sync — npm version and server.json version must match. I use a post-version script to update both automatically.
  • Verify after publishing — The API endpoint registry.modelcontextprotocol.io/v0.1/servers?search=your-name lets you confirm your server is listed.

What's Still Missing

The registry is in preview, so gaps are expected. Here's what I wish existed:

  • Usage metrics — I have no idea if anyone searches for or installs my server. A download count would help me decide whether to keep maintaining it.
  • Version lifecycle commands — Can I unpublish a broken version? The docs don't mention deprecation or yanking.
  • A visual directory — The API is great for automation, but a web UI for browsing servers would make discovery much easier.
  • Better error messages — "Registry validation failed for package" could mean ten different things. The CLI needs to tell you which field failed and why.

Should You Publish?

If you've built an MCP server that you actually use, yes — go through the process. The friction is real but manageable: maybe an hour the first time, then five minutes for subsequent publishes. The registry is becoming the canonical way to make MCP servers discoverable, and clients like Claude Code, Cursor, and VS Code extensions are integrating registry search directly.

I still haven't figured out how to handle version updates cleanly, or whether I should unpublish servers I no longer maintain. If you've been through it, I'd genuinely love to hear how you handle these — drop a comment or reach out.

The old PR-based system is gone. The new one isn't perfect. But it's a real improvement — and it'll keep getting better.

Top comments (0)