Home · Guides

One remote URL belongs to exactly one server name, forever

The official MCP registry refuses a server.json whose remotes[].url is already claimed by a server with a different name. The publish fails with 400 and this message:

400: remote URL https://mcp.zovo.one/mcp/pdf is already used by server
     io.github.theluckystrike/pdf-merge-split-stamp-extract-pages

That is not documented on the registry's publishing pages. It is in the code. From internal/service/registry_service.go in modelcontextprotocol/registry, function validateNoDuplicateRemoteURLs, read 2026-09-09:

for _, remote := range serverDetail.Remotes {
    filter := &database.ServerFilter{RemoteURL: &remote.URL}
    conflictingServers, _, err := s.db.ListServers(ctx, tx, filter, "", 1000)
    ...
    for _, conflictingServer := range conflictingServers {
        if conflictingServer.Server.Name != serverDetail.Name {
            return fmt.Errorf("remote URL %s is already used by server %s", ...)
        }
    }
}

The check runs inside the publish transaction, on every remote in the submission, against every row in the table.

The four consequences that bite

  1. A hosted server cannot be renamed. The registry has no rename operation, so a new name means a new publish, and the new publish carries the same URL. It is refused.
  2. You cannot run a namespace experiment on a hosted server. Publishing the same endpoint under a second namespace to compare their search ranks is exactly what the rule forbids. Any move is a migration, and reversing it is another one.
  3. Inactive rows still block. The filter is on the URL alone. Open issues #1317 and #1193 both ask for deleted and deprecated servers to be excluded, which tells you they are not excluded today.
  4. Nothing can be unpublished. The registry FAQ answers "Can I delete/unpublish my server?" with "Currently, no", pointing at issue 104. So a URL claimed by a name you regret stays claimed.

It is not just a rule for one project

Other publishers hit it and filed:

What to do before your first hosted publish

Give every server its own URL path and treat that path as permanent. A gateway at https://example.com/mcp serving several logical servers can list only one of them, because they would all declare the same URL. Paths of the form https://example.com/mcp/<server> give each name something of its own to claim.

If you have already collided, one escape exists and it is legitimate rather than a trick: add a second, distinct endpoint path that answers the same server, and publish the new name against that path. Both rows then work, both are honest about where they point, and neither is a duplicate of the other's URL. Nothing in the schema requires two names to share an endpoint.

The other case that works is a server with no remotes block at all. A stdio package or a downloadable bundle has no URL to collide with, so the same code can be published under two names for comparison. That is how the namespace comparison behind how registry search works was run at all: the one server in this catalogue that ships without a hosted endpoint.

What the check does not do

It compares URLs, not hosts. Two servers on the same domain with different paths are fine. It also does not follow redirects or resolve DNS, so a URL that no longer works still holds its claim. An independent survey filed as #1485 on 2026-07-28 found 80 remote hosts that no longer resolve, still listed.

Sources: the registry's own source at internal/service/registry_service.go and internal/database/postgres.go, read from the main branch on 2026-09-09; the publish failure above, produced by mcp-publisher publish against the live registry on 2026-09-08 and recorded in docs/NAMESPACE_R1.md in this repository; the registry FAQ at modelcontextprotocol.io/registry/faq; the linked issues.

Questions

Does the rule apply to sse remotes too?

Yes. The loop runs over every entry in the remotes array whatever its type, so a streamable-http URL and an sse URL are each claimed independently. Publishing both types at different URLs under one name is fine, because the name comparison only fires when the conflicting row has a different name.

Can I republish the same name with the same URL?

Yes. The conflict check skips rows whose name matches the one being published, so new versions of your own server are unaffected. What it stops is a second name pointing at a URL you already used.

What if the other server is mine?

It makes no difference. The comparison is on the server name string, not on the publisher or the authenticated namespace, so two names you both own still collide.

Is this ever going to change?

Open issues ask for deleted and deprecated rows to be excluded from the check, which would help anyone reusing a URL after retiring a name. Nothing suggests the basic one-URL-one-name rule is going away, and designing around it costs nothing.

Why does the registry enforce this at all?

A directory that resolved one endpoint to several names would let anyone attach their own name and description to somebody else's running service. Binding the URL to the first name that claimed it makes the listing mean something.

Related

All MCP servers and prices · All guides · Buy the bundle $39