---
title: "The State of MCP Registries"
description: "Explore the architecture of the Model Context Protocol (MCP) and the state of its official registry. Learn how to consume server packages programmatically and discover the underlying challenges of data duplication and security in the current meta-registry ecosystem."
url: "https://safedep.io/blog/the-state-of-mcp-registries"
author: "Kunal Singh"
published: "2025-12-20"
---

# The State of MCP Registries

# What is MCP - Model Context Protocol

The `modelcontextprotocol.io` describes MCP in its fundamental form as "The USB-C for AI Applications". The Model Context Protocol allows applications to interact with the outer world with a simple plug-and-play architecture, solving the limited context problem that previous models of AI applications faced. The registry is at https://registry.modelcontextprotocol.io/

The architecture consists of 2 components: the MCP Client and the MCP Server. Examples of MCP Clients include Claude Code, VSCode, Cursor, etc., and examples of MCP Servers include `Exa` AI Search, SafeDep VET MCP, etc.

The Client part was sorted, but the server side was not. Discovering them was tedious, finding the current way of installing was painful, managing the state was difficult, and it was all manual. While most people were already publishing their MCPs in NPM and Docker registries, uniformity was needed. Every Client used to have their own "syntactic sugar" for "Installing MCP," much like Cursor has here: https://cursor.com/docs/context/mcp/directory.

This is a sample `.vscode/mcp.json` file as instructed in their docs: https://docs.github.com/en/copilot/how-tos/provide-context/use-mcp/extend-copilot-chat-with-mcp

```json
{
  "inputs": [
    // The "inputs" section defines the inputs required for the MCP server configuration.
    {
      "type": "promptString"
    }
  ],
  "servers": {
    // The "servers" section defines the MCP servers you want to use.
    "fetch": {
      "command": "uvx",
      "args": ["mcp-server-fetch"]
    }
  }
}
```

A Cursor Install link would look like:

```
cursor://anysphere.cursor-deeplink/mcp/install?name=Vercel&config=eyJ1cmwiOiJodHRwczovL21jcC52ZXJjZWwuY29tIn0
```

# MCP Registry to the rescue

Anthropic released an official MCP registry a few months back, meant to become the holy grail of everything involving discovering MCP servers. They say it's a "Single source of truth for MCP servers". Blog post link: https://blog.modelcontextprotocol.io/posts/2025-09-08-mcp-registry-preview/

This is actually a kind of meta-registry—a registry that stores metadata and installation instructions while the actual artifacts remain in package registries like NPM, PyPI, Container Registry, etc. It stores basic metadata with the actual installation command for the MCP server so that it becomes easy for Clients to simply run them.

<div className="dark:invert dark:brightness-90">![MCP Architecture Image](https://safedep.io/_next/static/immutable/media/mcp-architecture-diagram.1posf79d25qtc.png)</div>

It is an easy way to publish your MCP server for discovery and makes it even easier for Client Maintainers to install and use these servers.

However, it is not polished—seriously and fundamentally—since their primary goal is "to standardize how servers are distributed and discovered, providing a primary source of truth that sub-registries can build upon."

<div className="dark:invert dark:brightness-90">
  ![MCP Sub-Registries Image](https://safedep.io/_next/static/immutable/media/mcp-sub-registries-diagram.1im87-d093k9a.png)
</div>

# Consuming MCP Registry Packages

For an MCP Client to use an MCP server from the official registry, it just needs to make an HTTP GET request:

List all versions of a server:

```bash
curl --request GET \
  --url https://registry.modelcontextprotocol.io/v0.1/servers/{server_name}/versions \
  --header 'Accept: application/json, application/problem+json'
```

Getting a specific version of a server:

```bash
curl --request GET \
  --url https://registry.modelcontextprotocol.io/v0.1/servers/{server_name}/versions/{server_version} \
  --header 'Accept: application/json, application/problem+json'
```

Let's see the response for our own vet MCP server. The server_name will be `io.github.safedep/vet-mcp` and the version will be `1.12.16`.

```bash
curl -fsSL --request GET   --url https://registry.modelcontextprotocol.io/v0.1/servers/io.github.safedep%2Fvet-mcp/versions/1.12.16   --header 'Accept: application/json, application/problem+json' | jq
```

Response:

```json
{
  "server": {
    "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json",
    "name": "io.github.safedep/vet-mcp",
    "description": "Protect your AI agents and IDEs from malicious open-source packages.",
    "title": "SafeDep Vet MCP",
    "repository": {
      "url": "https://github.com/safedep/vet",
      "source": "github"
    },
    "version": "1.12.16",
    "websiteUrl": "https://safedep.io",
    "icons": [
      {
        "src": "https://raw.githubusercontent.com/safedep/.github/9275c7d1b59f718d73e47cecd93df92e7bfbea25/assets/logo/safedep-logo-darkshade.svg",
        "mimeType": "image/svg+xml",
        "sizes": ["48x48", "96x96"],
        "theme": "light"
      },
      {
        "src": "https://raw.githubusercontent.com/safedep/.github/9275c7d1b59f718d73e47cecd93df92e7bfbea25/assets/logo/safedep-logo.svg",
        "mimeType": "image/svg+xml",
        "sizes": ["48x48", "96x96"],
        "theme": "dark"
      }
    ],
    "packages": [
      {
        "registryType": "oci",
        "identifier": "ghcr.io/safedep/vet:v1.12.16",
        "runtimeHint": "docker",
        "transport": {
          "type": "stdio"
        },
        "runtimeArguments": [
          {
            "type": "named",
            "name": "--rm"
          },
          {
            "type": "named",
            "name": "-i"
          }
        ],
        "packageArguments": [
          {
            "value": "-s",
            "type": "positional"
          },
          {
            "value": "/tmp/vet-mcp.log",
            "type": "named",
            "name": "-l"
          },
          {
            "value": "server",
            "type": "positional"
          },
          {
            "value": "mcp",
            "type": "positional"
          }
        ]
      }
    ]
  },
  "_meta": {
    "io.modelcontextprotocol.registry/official": {
      "status": "active",
      "publishedAt": "2025-12-10T10:58:13.018394Z",
      "updatedAt": "2025-12-10T10:58:13.018394Z",
      "isLatest": true
    }
  }
}
```

We see lots of information about the server; the most important bit is `packages`. The `packages` section contains the actual artifact available to install and run the server in the client. We can also have multiple `packages`, and the client has the freedom to choose any.

If we parse the package info, we will end up with:

```bash
docker run --rm -i ghcr.io/safedep/vet:v1.12.16 -- -s -l /tmp/vet-mcp.log server mcp
```

The entire API documentation is at: https://registry.modelcontextprotocol.io/docs

# Sub Registries

You remember we mentioned that the official MCP registry is not polished? One of the reasons is the amount of unchecked data it has. Since publishing the same MCP server with the same version is allowed, what is happening is people are publishing their MCPs in CIs, causing duplicate entries for the same servers.

We tried to analyze the data in the registry, and to our surprise, for only 1691 unique underlying npm, pypi, etc. packages, there are about 64.7 Million server entries having a one-to-many relationship with 48.5 Million packages.

The number clearly shows how massive and duplicated the meta-registry is.

The servers are published with few authentication mechanisms, like GitHub OIDC or DNS verification for domains, but the issue of typosquatting still exists.

# Need for a Vetted Sub registry

The official MCP registry has successfully solved the problem of _discovery_. The next challenge for the community is to solve the problem of _trust_. As MCP moves from experimental hobby projects to enterprise AI agents, the existence of a curated, security-first sub-registry will be the deciding factor in its adoption.
