Engineering Guide

The MCP Registry: What a Verified Namespace Actually Proves (July 2026)

Almost every article about the MCP Registry repeats the same sentence: reverse-DNS namespaces mean only the legitimate owner of a GitHub account or domain can publish under that name, which gives you trust and accountability. That is true, and it is also much narrower than it sounds. A verified namespace proves who published the metadata record. It does not prove that the publisher controls the endpoint that record points at — and you can confirm that gap in the registry's own source code and in one live API call. This is a working developer's map of what the registry is, what it explicitly refuses to do, and what you should check before letting one of its entries near your agent.

Diagram of the MCP Registry trust boundary showing namespace verification covering the publisher and metadata record but not the remote endpoint

What the MCP Registry actually is

The Official MCP Registry lives at registry.modelcontextprotocol.io. Its about page describes it as the official centralized metadata repository for publicly accessible MCP servers. Two words in that sentence do all the work: centralized and metadata.

Metadata is the load-bearing one. The docs put it flatly: the MCP Registry only hosts metadata, not artifacts. Your code ships to npm, PyPI, NuGet, crates.io or a container registry; the MCP Registry stores a server.json record that points at it. Publishing order is therefore fixed — package first, registry second. If you are still building the thing that gets published, start with how to build an MCP server; this piece is about what happens after the code exists.

Every registry documentation page currently carries the same banner: the MCP Registry is in preview, and breaking changes or data resets may occur before general availability. That banner was live when this article was written (17 July 2026), and no GA date has ever been announced. The API version is v0.1, introduced on 17 October 2025 as the stable line that takes only additive, backward-compatible changes. A v0 still sits alongside it in the OpenAPI spec, and the two sources disagree about its health: the registry's own API changelog calls v0 the development version and says it remains fully supported, while GitHub's Copilot registry docs go further and describe v0 as unstable and say it should not be implemented. Build against v0.1 and expect the ground to move.

The FAQ also defines four terms that most coverage blends into mush, and getting them straight makes the rest of this article readable:

A fifth term lives one page over, in the aggregators guide: a subregistry is an aggregator that also implements that OpenAPI spec. That is a technical test, not a vibe about curation quality.

Scale, honestly stated: Anthropic's December 2025 donation post says there are now more than 10,000 active public MCP servers, covering everything from developer tools to Fortune 500 deployments. That is a dated floor for servers in the wild, not a count of registry entries. You will see round numbers like 500 or 21,000 in listicles; none of them trace to a primary source. Paginating the live API on 17 July 2026, we were still inside the ai.* namespace 500 entries in — the listing is sorted alphabetically, so that is nowhere near the end of the catalogue, and any published figure of 500 is measuring a loop that gave up rather than a registry. We could not finish a full census, and we are not going to print a number we cannot stand behind.

Who runs it — and who does not

Write this down, because most of the internet still gets it wrong: this is not Anthropic's registry. MCP is established as "Model Context Protocol a Series of LF Projects, LLC", and it joined the Linux Foundation's Agentic AI Foundation on 9 December 2025 — AAIF co-founded by Anthropic, Block and OpenAI, with Google, Microsoft, AWS, Cloudflare and Bloomberg named as supporters. The Linux Foundation's stated role is to provide a neutral home and infrastructure while not dictating MCP's technical direction. The governance page is blunter still: membership in the technical governance process is for individuals, not companies, and there are no seats reserved for specific companies.

Now the nuance worth surfacing. The registry's about page says it is backed by major trusted contributors to the MCP ecosystem such as Anthropic, GitHub, PulseMCP and Microsoft. That is the docs' own wording, and it is fine to quote — but "backed by" is not "staffed by". The Registry working group roster in the repo README names Tadas Antanavicius (PulseMCP), Radoslav Dimitrov (Stacklok), Bob Dickinson (TeamSpark) and Preeti Dewani (Ravenmail). Not one of them is from Anthropic, GitHub or Microsoft. The September 2025 launch post separately credited contributors including Adam Jones (Anthropic) and Toby Padilla (GitHub). Both things are true. If your risk model says "big companies operate this", check the roster, not the marketing line.

One more dateline, since it is easy to get wrong right now: the current protocol revision is 2025-11-25. A 2026-07-28 revision exists as a Release Candidate — locked on 21 May 2026, scheduled to publish on 28 July 2026 — and it makes the protocol layer stateless. Read the change list precisely, because coverage routinely flattens it: the initialize/initialized handshake and the Mcp-Session-Id header are removed, while Roots, Sampling and Logging are deprecated, with at least twelve months between deprecation and the earliest possible removal. Deprecated is not gone, and writing that those primitives have been deleted will make your migration plan wrong in both directions. As of this writing the RC has not shipped at all — anything you read describing MCP as stateless today is describing a future.

What a verified namespace proves

Server names in the registry are reverse-DNS, and the shape you get is decided by how you authenticated. GitHub-based auth gives you io.github.username/* or io.github.orgname/* — for example io.github.alice/weather-server. Domain-based auth gives you the reverse-DNS of a domain you control, e.g. io.modelcontextprotocol/everything.

The docs page narrates three ways to prove it. The live OpenAPI spec exposes five auth endpoints, and if you are writing tooling you want all five:

Each exchanges a proof for a short-lived Registry JWT. Signing keys can live in Google Cloud KMS or Azure Key Vault, which is the right answer if you publish from CI.

So far, so standard. Here is the part nobody writes down.

The chain stops at the metadata

Read the registry's Go source and the scope becomes obvious. IsValidRemoteURL() in internal/validators/utils.go checks exactly three things: that the URL parses, that the scheme is https, and that the host is not localhost, 127.0.0.1 or a *.localhost name. validateRemoteTransport() in internal/validators/validators.go adds that the transport type is streamable-http or sse and resolves template variables. At the service layer, the only additional rule is validateNoDuplicateRemoteURLs(), which rejects a URL already claimed by another server — a global, first-come-first-served land grab.

There is no check anywhere that the remote host has anything to do with your verified namespace. And it shows in live data: sampling the first ~60 entries with remotes on 17 July 2026, ai.1325/mcp holds a domain-verified namespace for 1325.ai while pointing its remote at agoclnqfyinwjxdmjnns.supabase.co. Most publishers do self-align — ac.tandem/docs-mcp resolves to tandem.ac, ai.adramp/google-ads to mcp.adramp.ai — but alignment is convention, not enforcement.

This is not a vulnerability disclosure and the registry never claimed otherwise; namespace auth is explicitly scoped to metadata publishing. The finding is that readers routinely over-read the docs' "trust and accountability" phrasing as endpoint verification. It is not. A verified namespace answers who filed this record. It does not answer who answers when you connect. If your servers are remote, pair this with how remote MCP servers actually work and treat the endpoint as its own trust decision.

Where the verified chain stops AUTHENTICATED BY THE REGISTRY NOT TIED TO THE NAMESPACE Publisher GitHub acct / domain Namespace proof OAuth · OIDC · DNS TXT · .well-known server.json metadata record io.github.you/thing remotes[].url host any HTTPS host on the internet — whoever actually answers no binding The only rules applied to a remote URL, per the registry source: 1. Parses as a URL · 2. Scheme is https · 3. Host is not localhost/127.0.0.1 · 4. Transport is streamable-http or sse 5. Not already claimed by another server (first-come-first-served uniqueness lock) Nowhere: does this host match the namespace you just proved you own? Live example, sampled 2026-07-17: ai.1325/mcp — namespace verified for 1325.ai, remote points at agoclnqfyinwjxdmjnns.supabase.co Reproduce: curl -G https://registry.modelcontextprotocol.io/v0.1/servers --data-urlencode limit=60
Namespace verification authenticates the publisher of the metadata, not the operator of the endpoint. Rules read from internal/validators/utils.go, internal/validators/validators.go and internal/service/registry_service.go in the registry repo; live example sampled 17 July 2026. Chart: DataLLM Lab

The does-not-do inventory

The single most useful thing you can read about the MCP Registry is its own list of disclaimers — except nobody has ever assembled them in one place. Each row below is sourced to a registry doc page, its terms of service, its moderation policy, or its source code. Read it once and most of the confusion in the ecosystem evaporates.

What people assumeWhat the registry actually says or doesWhere
It vets servers for securityIt delegates security scanning to underlying package registries and downstream aggregators, and focuses on namespace authentication plus metadata hosting. The moderation policy's do-not-remove list explicitly includes servers with security vulnerabilities./registry/about, /registry/moderation-policy
A verified namespace vouches for the endpointNo rule binds remotes[].url to your verified domain. Checks are: well-formed, HTTPS, non-localhost, allowed transport, globally unique.registry source: validators/utils.go, validators/validators.go, service/registry_service.go
Bad entries get removedPer the moderation policy, only illegal content, malware, spam and completely broken servers are removed. Low-quality or buggy servers, duplicates, and adult content stay. Consumers should assume minimal-to-no moderation./registry/moderation-policy
It hosts the server codeIt hosts metadata only, never artifacts. npm, PyPI, NuGet, crates.io and OCI registries hold the code./registry/about, /registry/quickstart
Your app should read it directlyThe docs say it is not intended to be directly consumed by host applications — it targets downstream aggregators, and host apps should consume those instead./registry/about
You can erase a mistakeYou can hide it, not erase it. mcp-publisher status --status deleted drops a server from default listings, but it stays retrievable with include_deleted=true and is restorable to active. Metadata is never permanently removed, and published version metadata is immutable./registry/faq
mcpb download hashes are checkedThe registry does not validate the fileSha256 hash; MCP clients validate it before installation./registry/package-types
It guarantees uptime and accuracyThe ToS (effective 2 September 2025) provides it as is with no warranties of any kind; the aggregator guide states there are no uptime or data durability guarantees./registry/terms-of-service, /registry/registry-aggregators
You can self-host or list private serversThe codebase is not designed for self-hosting and maintainers cannot support it; private servers are out of scope./registry/about
It is a stable, GA productEvery registry doc page still carries the preview banner warning of breaking changes or data resets before general availability. GA is planned but undated.all /registry/* pages

Two more that belong in the same drawer. Spam prevention today rests on namespace auth, character limits and validation, plus manual takedown — stricter rate limiting, AI-based spam detection and community reporting are listed as under consideration, not shipped. And abuse reporting is deliberately indirect: report to the underlying package registry first, then open a GitHub issue on the registry repo whose title begins with "Abuse report: ". There is no report button. If you are building a threat model around any of this, our MCP security guide is the companion piece.

Your MCP servers still need a model behind them

The registry tells your agent which tools exist. It says nothing about what reasons over them. DataLLM Lab is an OpenAI-compatible gateway at https://www.datallmlab.com/v1 — 300+ models on one key, so you can swap the model driving your tool loop without touching your MCP wiring.

Publishing: flow and ownership markers

The publish path is short, and the CLI is bigger than it first looks. The command reference documents six — init, login, validate, publish, status, logout — but the quickstart's own --help transcript prints only four, quietly dropping validate and status. That gap has consequences downstream: status is the command that deprecates or hides a server, and its absence from the page most people read is a good part of why the ecosystem believes the registry has no unpublish story at all. It does. Do not go looking for an mcp publish form, though; that one really does not exist.

  1. Add the ownership marker for your package type (table below).
  2. Publish the package to npm, PyPI, NuGet, crates.io or your container registry. This step is first.
  3. Install mcp-publisher — release binary via curl, or brew install mcp-publisher.
  4. mcp-publisher init generates a server.json against the current schema (2025-12-11): $schema, name, title, description, version, repository, packages[] and/or remotes[], _meta.
  5. mcp-publisher login github — an OAuth device flow that mints the short-lived registry token.
  6. mcp-publisher publish, then verify: curl "https://registry.modelcontextprotocol.io/v0.1/servers?search=<name>".

In CI, the recommended path is OIDC: give the workflow permissions: id-token: write and run ./mcp-publisher login github-oidc — no dedicated secret necessary. The fallbacks are a PAT or an Ed25519 DNS key. On the PAT, the docs are stricter than most write-ups: a classic PAT needs the read:org scope and the docs state read:user is explicitly not needed; a fine-grained PAT wants Organization permissions → Members → Read-only, and is bound to a single resource owner, so create it for the org you publish to. Either way the token needs no repository scopes — the registry never reads or writes your code.

Now the part that is scattered across one doc page and never tabulated: every package type proves ownership differently, and the naming is a trap. npm uses a camelCase JSON property; PyPI, NuGet and Cargo use a kebab-case string in the README — and Cargo refuses the hidden-comment trick the other two allow, because crates.io strips HTML comments when it renders the README the validator inspects.

registryTypeOwnership markerWhere it livesAllowed hostsRegistry validates the artifact?
npmmcpName propertypackage.jsonregistry.npmjs.orgOwnership marker only
pypimcp-name: <SERVER_NAME>README (an HTML comment is allowed)pypi.orgOwnership marker only
nugetmcp-name: <SERVER_NAME>README (an HTML comment is allowed)api.nuget.orgOwnership marker only
cargomcp-name: <SERVER_NAME>README — visible text only; crates.io strips HTML commentscrates.ioOwnership marker only
ociLABEL io.modelcontextprotocol.server.nameimage label / annotationdocker.io, ghcr.io, quay.io, *.pkg.dev, *.azurecr.io, mcr.microsoft.comOwnership marker only
mcpbURL must contain mcp + a fileSha256download URL + server.jsonGitHub or GitLab releases onlyNo — the registry does not validate the hash; clients do, before install

Two rows deserve a footnote. Cargo is the type most write-ups still omit, and it carries a runtime wrinkle: cargo install drops a binary on PATH, so there is no per-invocation runner equivalent to npx, uvx or dnx, and your users need the Rust toolchain. If you want the server to run without a toolchain on the user's machine, ship mcpb instead. mcpb is not the free-for-all its "URL must contain mcp" rule suggests — the host allowlist is GitHub and GitLab releases, and the validator deliberately refuses to follow redirects so that allowlist cannot be bounced through a CDN toward somewhere else.

Versioning has one documented footgun worth internalising. Your version string must be unique per publication and is immutable once published. SemVer is recommended but any string is accepted — and an unparseable version is always marked latest, even when a proper SemVer string would sort above it. Version ranges (^1.2.3, 1.x, >=1.2.3) are prohibited outright. One sloppy tag and your latest pointer is stuck on garbage you can hide but never delete.

Remotes get their own rules: only streamable-http (recommended) or sse, URL template variables like {tenant_id} with description/isRequired/default/choices/isSecret, and a headers[] array for things like an X-API-Key marked secret. remotes and packages can coexist so hosts choose an install method — which is exactly the local-vs-remote tradeoff we unpack in MCP vs a plain API.

Aggregators, subregistries, host apps

The registry's own about page states its target audience: it is intended to be consumed primarily by downstream aggregators, such as MCP server marketplaces. Its metadata is described as deliberately unopinionated, with curation and extras like community ratings left to those aggregators. Expected pull cadence is roughly once per hour, and because there are no durability guarantees, aggregators are told to persist data in their own store.

The read API is unauthenticated: GET /v0.1/servers, GET /v0.1/servers/{serverName}/versions, and GET /v0.1/servers/{serverName}/versions/{version} where version accepts the special value latest. Pagination is cursor-based (limit + nextCursorcursor), incremental sync uses updated_since with RFC 3339 timestamps, and path params must be URL-encoded (io.modelcontextprotocol%2Feverything). One subtlety that bites sync pipelines: include_deleted defaults to false, but passing updated_since flips it to true automatically — so the moment you graduate from full scrape to incremental sync, deleted servers start arriving whether you planned for them or not. That is a feature (you need the tombstones to expire your own copy) as long as you know it is happening.

Subregistries inject their own data via _meta under a reverse-DNS key — the docs' example fields are user_rating, download_count and a security_scan block. Publishers get _meta["io.modelcontextprotocol.registry/publisher-provided"], capped at 4KB. The registry's own bookkeeping sits under _meta["io.modelcontextprotocol.registry/official"] with status, statusChangedAt, publishedAt, updatedAt and isLatest.

Who is actually a subregistry? The moderation policy names one directly: it says the registry relies on upstream package registries and downstream subregistries like the GitHub MCP Registry for deeper moderation. That launched 16 September 2025 at github.com/mcp with partners including Figma, Postman, HashiCorp and Dynatrace, and the sync is one-way — self-publish to the community registry upstream and entries automatically appear downstream. Separately, GitHub Copilot lets orgs and enterprises point at a custom MCP registry, which must follow the v0.1 spec (the servers list, versions/latest, a specific version, plus CORS headers on every /v0.1/servers endpoint), self-hosted from the OSS registry fork or managed via Azure API Center. Note the elegant wrinkle: that is a host app consuming a v0.1 registry directly — not the intended pattern for the official registry, but precisely the intended pattern for a subregistry.

Who is not: AWS's Agent Registry (Bedrock AgentCore, Preview) is a separate managed catalog reached through AWS APIs or its own MCP endpoint. Read that endpoint claim carefully, because it is where the listicles slip: it speaks the MCP protocol (revision 2025-11-25), which is a different artefact from the MCP Registry OpenAPI spec. AWS never claims the latter, nor upstream sync — so it is not a subregistry in the technical sense. AWS's verified ties to MCP governance are as an AAIF supporter and via Clare Liguori as an MCP Core Maintainer.

Two legal details aggregator-builders miss. All submitted Registry Data is dedicated to the public domain under CC0 1.0 — perpetual, irrevocable, worldwide — and publishers waive rights to object to downstream processing, which is how a subregistry gets to bolt GitHub stars or a security scan onto your entry without asking. And the ToS has a branding clause with teeth: you may say your service keeps its data up to date by automatically pulling from the Official MCP Registry; you may not say you have partnered with it or that your site is it. Go read the marketing copy of a few directories with that in mind — it is a checkable test, and the results are entertaining. If you are choosing between directories rather than building one, our roundup of MCP servers worth running skips the count-inflation entirely.

A trust checklist you can run in one curl

Here is the decision rule this whole article exists to produce. Before you wire a registry entry into an agent that has real credentials, run these seven checks. Numbers 2, 3 and 4 are the ones the registry will never run for you.

  1. Read the namespace as an author claim, not a safety claim. io.github.acme/* tells you someone proved control of that GitHub org at publish time. Full stop.
  2. Diff the namespace against the remote host. Fetch the entry and compare name's reverse-DNS domain to the host in remotes[].url. Aligned is the healthy convention; mismatched is not forbidden and not flagged — it is on you to decide whether a supabase.co or vercel.app endpoint under a corporate namespace is expected or a smell.
  3. Verify the artifact, not the pointer. The ownership marker proves the publisher owns the package name. It says nothing about what the code does. For mcpb specifically, the registry never checks the hash — rely on your client.
  4. Assume no moderation. A live entry has not been reviewed for quality, duplication or known vulnerabilities. That is policy, not oversight.
  5. Pin the version. Published versions are immutable, so pin one. Do not trust latest: an unparseable version string wins that slot automatically.
  6. Check the status field. active / deprecated / deleted. Deleted entries drop out of default listings but are not gone — they come back with include_deleted=true, and incremental sync via updated_since turns that on for you. Filter deliberately in both directions.
  7. Cache it yourself. No uptime or durability guarantees, and a preview banner promising possible data resets. Pull about hourly, store your own copy, and re-check that banner before you build anything load-bearing.

The reframe worth carrying out of here: the MCP Registry is a well-designed naming and discovery system that has been widely misread as a trust system. It authenticates publishers and hosts pointers, deliberately and by written policy. Everything else — scanning, curation, ratings, endpoint attestation — was always meant to happen downstream, or in your own pipeline. Which is also why the tools you admit into an agent's context should be a curated decision rather than a firehose; see context engineering for the other half of that argument.

FAQ

Is the MCP Registry run by Anthropic?

No. MCP is established as Model Context Protocol a Series of LF Projects, LLC, and joined the Linux Foundation's Agentic AI Foundation on 9 December 2025. Governance is explicitly individual-based with no seats reserved for specific companies. The registry's about page does describe it as backed by major trusted contributors such as Anthropic, GitHub, PulseMCP and Microsoft — but the Registry working group roster in the repo README is Tadas Antanavicius (PulseMCP), Radoslav Dimitrov (Stacklok), Bob Dickinson (TeamSpark) and Preeti Dewani (Ravenmail). Backed by is not staffed by.

Does a verified namespace mean an MCP server is safe?

No. It proves who published the metadata. The registry delegates security scanning to package registries and downstream aggregators, and its moderation policy says servers with security vulnerabilities are not removed. In the registry's Go source, a remote URL is only checked for being well-formed, HTTPS, non-localhost, using an allowed transport, and globally unique — never for matching the publisher's verified domain.

Does the MCP Registry host the server code?

No — metadata only, never artifacts. Code lives on npm (registry.npmjs.org), PyPI, NuGet, crates.io, or an OCI registry (docker.io, ghcr.io, quay.io, *.pkg.dev, *.azurecr.io, mcr.microsoft.com). You publish the package first, then publish a server.json pointer.

Can I delete or unpublish a server?

Yes — but you are hiding it, not erasing it. Run mcp-publisher status --status deleted (add --all-versions to cover every version). Deleted servers drop out of default API listings but are still retrievable with include_deleted=true, and you can restore one by setting status back to active. Server metadata is never permanently removed, and published version metadata is immutable, similar to npm — to change anything else you publish a new server.json with a unique version string. Status is the one mutable field: active, deprecated, deleted.

Should my app read registry.modelcontextprotocol.io directly?

The docs say host applications are not the intended consumer — downstream aggregators and marketplaces are, and host apps should consume those via the same OpenAPI shape. If you do read it directly, persist your own copy: there are no uptime or data durability guarantees, and the suggested scrape cadence is about once per hour.

How do I publish a server to the MCP Registry?

Add the ownership marker (npm: an mcpName property in package.json; PyPI/NuGet/Cargo: an mcp-name: string in the README — visible text for Cargo, since crates.io strips HTML comments; OCI: a LABEL io.modelcontextprotocol.server.name), publish the package, install mcp-publisher, then run init, login github, and publish. In GitHub Actions use OIDC with id-token: write and login github-oidc — no dedicated secret necessary. Verify with a search query against the servers endpoint.

Written by
Kevin Fan

Founder of DataLLM Lab, the unified LLM gateway. Kevin tests models the boring way — same prompts, real costs, unedited outputs — and writes up what the runs actually show.

One API for every model

One API, every model.

Get a single API key for Claude Opus 4.7, GPT-5.4, and 300+ more — with automatic price comparison and routing to the best model for every request.