MCP registry security starts after publisher verification
MCP registry security requires more than a verified name. Learn how to check publishers, pinned artifacts, permissions, updates, and squatting risks.

Table of Contents
An MCP registry entry can tell you who controlled a namespace when they published a server. It cannot tell you whether that server deserves access to source code, customer records, deployment credentials, or an employee's browser session. Treating publisher verification as a security review collapses two different questions into one, and that is how a clean installation screen becomes a supply chain incident.
The useful way to read a registry entry is as a signed claim that points elsewhere. The name points to an identity. The package field points to executable code, or the remote field points to a running service. The requested configuration points to secrets and systems. You need to follow that chain all the way to the capability the agent receives before you approve anything.
Publisher verification proves control, not good behavior
The Official MCP Registry verifies that a publisher controls the namespace used in a server name. That is meaningful evidence, but its scope is narrow. A name such as io.github.example/weather is tied to a GitHub user or organization, while a reverse DNS name is tied to control of a domain through DNS or HTTP authentication. This blocks an unauthenticated stranger from publishing directly inside somebody else's verified namespace.
It does not prove that the publisher wrote secure code, still controls every dependency, protects its release credentials, or operates a remote server safely. It also does not prove that a familiar-looking namespace belongs to the organization you have in mind. A verified owner can ship a malicious release. An honest owner can have an account compromised. A domain can change hands. A package maintainer can add a dependency that later turns hostile.
The registry's own documentation is explicit about this boundary. The MCP Registry overview says the service focuses on namespace authentication and metadata hosting. It delegates code scanning to underlying package registries and downstream aggregators. The Official MCP Registry Terms of Service goes further and recommends that users evaluate each server for their own use case. I agree with that split: a central metadata service should not pretend that schema validation equals code review. The mistake is asking it to provide a guarantee it never claims to provide.
Keep four claims separate during review:
- Identity: who controlled the publishing namespace?
- Binding: does the registry record point to the package or remote endpoint claimed by the publisher?
- Integrity: is the artifact you fetched exactly the version you reviewed?
- Suitability: should this code receive these permissions in this environment?
Registry verification helps most with the first two. Your installation and operating controls must answer the last two. If an approval screen shows one green badge for all four, the screen is lying by omission.
Publishing creates a chain that reviewers can trace
A sound publication connects the registry name, release metadata, and executable artifact without making reviewers guess. For an npm-distributed server, the official quickstart requires the package's mcpName value to match the name in server.json. The package must be public before its metadata is published because the registry stores metadata, not the artifact itself.
A reduced example looks like this:
{
"name": "@example/weather-mcp",
"version": "1.4.2",
"mcpName": "io.github.example/weather"
}
{
"name": "io.github.example/weather",
"version": "1.4.2",
"repository": {
"url": "REPOSITORY_LOCATION",
"source": "github"
},
"packages": [
{
"registryType": "npm",
"identifier": "@example/weather-mcp",
"version": "1.4.2",
"transport": { "type": "stdio" }
}
]
}
The values worth reconciling are boring on purpose. The MCP name must match across the package and registry metadata. The server version should match the package version for a local server. The package identifier must resolve to the expected artifact. The repository location should lead to the source and release history you intend to inspect. Any unexplained disagreement breaks the chain.
Authentication determines which namespace a publisher may use. GitHub OAuth supports user and organization namespaces under io.github.*. GitHub OIDC supports automated publication from GitHub Actions. DNS and HTTP challenges support domain-based reverse DNS namespaces. The official authentication guide describes the domain methods as proof of access to a DNS TXT record or a file at a well-known location. None of these methods vouches for every person behind the account. They establish control at publication time.
The mcp-publisher flow gives a publisher a reproducible path: initialize server.json, authenticate with the matching method, then publish. A successful response names the server and version. Teams should preserve that output beside the release commit and artifact digest. This small receipt makes later questions answerable: which workflow published, which identity authenticated, which commit built the package, and which version entered the registry?
Versioning also matters. The official versioning guide says every publication needs a unique version string and published version metadata is immutable. That is useful for audit history, but immutability does not make an old version harmless or a new one trustworthy. It gives you a stable object to review. Use that stability by pinning the exact artifact instead of installing whatever a package registry labels latest.
Familiar names are where namespace squatting works
Namespace squatting succeeds when a reviewer recognizes the shape of a name and stops checking its owner. Verification prevents an outsider from entering io.github.real-org/* without control of that GitHub organization. It does not prevent the outsider from registering io.github.realorg/*, buying a similar domain, or publishing a package whose descriptive name resembles a popular project.
People often call all of this namespace squatting, but three risks deserve different controls. Namespace squatting claims an unused identity space before the expected owner does. Typosquatting creates a lookalike name that catches hurried readers. Package squatting claims a desired name in npm, PyPI, or another artifact registry. An MCP record can have a verified namespace while pointing to a package whose ownership and history require a separate check.
Reverse DNS names reduce collisions, yet they shift attention to domain governance. A small team may verify a domain, publish a server, then let the domain expire after a product rename. A later registrant can prove current DNS control even though users still associate the namespace with the prior company. Registry operators can add moderation and transfer rules, but an installer should still examine ownership continuity, publication dates, and release history.
GitHub-based names have their own lifecycle problem. A personal account can be renamed. Organization membership can change. A repository can move while the package keeps its old metadata. The namespace tells you which account authorized publication, not whether that account remains the canonical home of the project. Check the organization profile, repository ownership, package publisher, and release workflow as one identity story.
Squatting becomes dangerous because MCP servers do more than expose library functions. A convincing clone may ask for a token, filesystem path, database connection, or browser session during setup. Once an agent can call its tools, the clone receives requests in the context of real work. The attacker does not need to fool every engineer. They need one person to choose the almost-right name and grant a useful secret.
Reserve your own namespaces before you need them. Publish a minimal, accurate record for internal or public servers when appropriate, and document canonical names in your engineering handbook. For third-party servers, maintain an allowlist keyed by the full MCP server name plus artifact identity, not by a friendly display title. Display titles are for people; they are a poor security boundary.
Discovery should produce candidates, not approvals
Registry search is a way to find possible servers, not a ranking of trusted software. The Official MCP Registry API provides case-insensitive substring search over server names. Its documentation deliberately points advanced search, ratings, curation, and extra security checks toward downstream registries and aggregators. The official service is also intended primarily as an upstream metadata source for those aggregators rather than a direct catalog for host applications.
That architecture has a practical consequence. The first result for a search term is not necessarily the server maintained by the organization you expect, and a marketplace badge may describe the marketplace's review rather than the official registry's verification. Your interface should label evidence precisely: namespace verified, package binding checked, source reviewed, malware scan passed, approved by your organization, and approved version. One word such as "trusted" hides too much.
For every candidate, collect five facts before anyone installs it:
- The exact server name, namespace owner, and authentication type.
- The package identifier and pinned version, or the exact remote origin.
- The source repository and release commit, if source is available.
- The requested secrets, data paths, network destinations, and write actions.
- The reviewer, decision date, approved environment, and expiry or review trigger.
This is the first practical element I insist on because it turns a search result into a reviewable record. It also works when a downstream catalog disappears. You retain the identity and artifact coordinates needed to reproduce the decision.
Discovery tools should preserve registry status and version history. The official API distinguishes active, deprecated, and deleted versions. A deleted item may vanish from default listings, while an incremental synchronizer can request deleted records. If your internal mirror ignores tombstones, a removed server can remain searchable inside the company long after the upstream registry hid it. If it ignores deprecation messages, engineers lose the publisher's warning at the moment they need it.
Do not auto-install from search results, model suggestions, chat messages, or copied configuration. Models are good at matching a capability description to a plausible name and bad at proving ownership. A safe host can suggest candidates, but it should require a policy decision before it writes configuration or launches a process.
Inspect the artifact that will actually execute
Review the resolved package, not the repository landing page. Repositories and published artifacts drift for ordinary reasons: generated files are omitted, build scripts modify output, a release comes from another branch, or package metadata points to an old location. Attackers exploit the same gaps deliberately. The code you install is the tarball or container digest, while the repository is supporting evidence.
For an npm package, these commands expose the identity fields and the exact file set before installation:
npm view @example/[email protected] \
name version dist.integrity dist.tarball repository.url scripts
npm pack @example/[email protected]
tar -tf example-weather-mcp-1.4.2.tgz
The first command prints the published name, version, integrity value, tarball location, repository, and lifecycle scripts as labeled fields. The pack command writes the named archive and prints its filename. The final command lists the paths inside it. A reviewer should expect an output shape like this, with real values in place of the placeholders:
name = '@example/weather-mcp'
version = '1.4.2'
dist.integrity = 'INTEGRITY_VALUE'
repository.url = 'REPOSITORY_LOCATION'
scripts = { build: 'BUILD_COMMAND' }
example-weather-mcp-1.4.2.tgz
package/dist/index.js
package/package.json
Look closely at install, preinstall, and postinstall scripts because a package manager can run them before the MCP host launches the server. Check bundled JavaScript rather than assuming it matches TypeScript in the repository. Inspect unexpected binaries, large generated blobs, dependency changes, network clients, telemetry paths, and code that reads broad areas of the home directory. An empty lifecycle script field does not make the runtime safe; it only removes one execution path.
For a container, pin a digest rather than a mutable tag and inspect the image configuration, entrypoint, user, mounts, and exposed ports. For a remote MCP server, there is no local package to inspect. Confirm the remote origin, authentication flow, data handling terms, tenant boundaries, and who operates the endpoint. A verified domain namespace and a TLS connection prove different things. Neither shows what the service stores after receiving a tool call.
Compare registry metadata with the artifact. If server.json says a secret is optional but the process refuses to start without it, record the discrepancy. If the declared repository differs from package metadata, stop. If a remote URL redirects across domains, treat the final origin as a new identity. Small inconsistencies often reveal abandoned releases, and abandoned releases make attractive takeover targets.
Tool descriptions are not permission boundaries
An MCP server's advertised tools describe intended operations, but the process permissions determine what it can actually do. A filesystem server that claims to read one project can read every path visible to its operating system account unless the host or container restricts it. A database tool described as read-only can issue writes if its credential has write permission. Descriptions guide models; credentials and isolation constrain software.
Review capabilities at three layers. First, list the tools, resources, and prompts the server exposes after initialization. Second, map each operation to operating system, cloud, database, browser, and network permissions. Third, check which actions the MCP host allows the model to invoke without human approval. Teams frequently review the first layer and leave the other two implicit.
Give each server a dedicated credential with the smallest useful scope. Keep production and development credentials separate. Mount only required directories, preferably read-only when writes are unnecessary. Restrict outbound network access to known destinations. Run local servers as an unprivileged account in a container or sandbox that does not inherit the engineer's entire environment.
Approval prompts need the same specificity. "Allow weather tool" is weak. "Send city and date to this remote origin" tells the user what crosses the boundary. "Allow file operation" is weak. "Write these generated files under this repository" states the path and effect. Reject blanket approval when a server combines read, write, and destructive actions behind one friendly name.
Secrets deserve attention before launch. Configuration examples often encourage putting tokens directly into a host JSON file. That file may enter dotfile backups, support bundles, screenshots, or source control. Prefer a secret manager or environment injection with explicit names, then ensure the server process receives only the variables it needs. A server that asks for a general cloud credential when it performs one narrow API call has failed review even if its namespace is genuine.
Remote authorization screens require a second review after the registry check. Read the scopes the service requests and compare them with the tools you plan to enable. If a server offers search but asks to administer users, billing, or organization settings, do not assume those scopes are harmless implementation details. Ask the publisher for a narrower authorization path or put the integration in an isolated test tenant.
Logs can cross the same boundary as tool calls. A local server may write prompts, file contents, command output, or secret-bearing errors to its own log directory. A remote operator may retain request bodies for debugging. Decide where logs go, who can read them, how long they remain, and whether the host redacts credentials before production use. Disabling model transcript retention while leaving verbose server logs enabled solves the wrong problem.
Every upgrade is a new security decision
Approval attaches to a version and capability set, not to a server name forever. The registry preserves immutable published versions, but package tags, container tags, dependencies, remote behavior, and exposed tools can change. Auto-updating an MCP server silently converts yesterday's code review into trust of tomorrow's publisher account.
Pin local packages to an exact version and integrity value or container digest. Store the registry metadata and resolved dependency lock beside the approval record. When a new version appears, compare source commits, packaged files, lifecycle scripts, dependencies, requested configuration, and the tool list. A patch number can contain a complete rewrite; semantic versioning communicates compatibility intent, not risk.
A common failure path looks harmless. An engineer approves version 1.4.2 of a source-reading server for one repository. The host configuration uses a floating package tag for convenience. Version 1.4.3 adds an analytics dependency and a new tool that can open arbitrary files. The package manager fetches it on the next launch, the host remembers the old server-level approval, and the model calls the new tool without a fresh decision. Every component behaved as configured, yet nobody approved the code that ran or the capability it used.
Prevent that failure at two points. Resolve a mutable reference to an immutable artifact during installation, then bind approvals to a fingerprint of the server version and declared capabilities. If either changes, disable the server until review finishes. Remote servers need a comparable mechanism, such as a provider version, capability snapshot, or contract-controlled change notice. If a remote service offers none, assume its implementation can change between calls and reduce its permissions accordingly.
Rollback is part of upgrade review. Keep the previous approved artifact available, but do not retain revoked credentials or a server version removed for abuse. Registry deprecation and deletion signals should open an incident ticket, identify every installed copy, and force a decision. Quietly pinning a known-bad version is not stability.
A usable policy fits into the delivery workflow
Teams bypass MCP review when it takes longer than the task the server would automate. The answer is a small, evidence-based gate owned by engineering, not a committee that debates every tool for a week. High-risk access deserves deeper work, while a local server restricted to synthetic data can move faster.
Use this approval sequence for public servers:
- A requester records the exact registry name, intended job, data class, and required actions.
- A reviewer verifies namespace ownership, artifact binding, source history, and release provenance.
- An engineer pins the artifact, isolates the runtime, and supplies a least-privilege credential.
- A test host captures the initialized tool list and exercises expected calls with non-production data.
- The owner approves one version, environment, and capability set, with triggers for re-review.
That is the second and last structured walkthrough. Automate the evidence collection, not the judgment. A script can compare metadata, fetch package manifests, record integrity values, diff tool lists, and flag lifecycle scripts. A person still decides whether the requested capability makes sense for the business process.
Define three outcomes rather than a vague pass or fail. Approved means the server can run within documented constraints. Quarantined means reviewers may test it with synthetic data and no sensitive credentials. Rejected means hosts must block its namespace, package, remote origin, or digest. Record the reason so the next engineer does not repeat the investigation.
Ownership must survive the person who requested the server. Assign an internal owner who receives registry status changes, package advisories, and credential alerts. Re-review after a version change, ownership transfer, new tool, broader permission, remote origin change, or a fixed time interval based on risk. Remove servers that no longer have a business use; dormant integrations retain secrets and receive less scrutiny.
During a Team & AI Audit at oleg.is, MCP adoption belongs in the same operating model as code review, deployment access, and engineering cost, because adding tools without ownership creates expensive cleanup later. The goal is not to ban useful servers. It is to make the safe path quick enough that engineers use it.
Publishers should reduce the installer's uncertainty
Publishers earn trust by making every link in the release chain inspectable. Verification gets your server into a namespace you control. Reviewers still need evidence that the package came from the repository, the release workflow protected its credentials, and the requested permissions match the advertised job.
Use a domain namespace when the organization can maintain domain governance for the server's lifetime. Use a GitHub organization namespace when that account is the clearer durable identity. Avoid publishing an organizational server under one employee's personal namespace. Document who owns DNS, GitHub, package registry, and release credentials, plus how access gets revoked when roles change.
Publish from a protected workflow with short-lived credentials where the registry supports it. GitHub OIDC can authenticate automated publication without storing a long-lived registry token. Protect the release environment, require reviewed commits, and bind builds to tags or commits. Preserve package digests and publisher output so consumers can reconcile a registry version with a specific build.
Keep server.json honest and minimal. Declare the exact package version or remote endpoint, required environment variables, secret fields, transport, and source repository. Do not use descriptions to soften dangerous capabilities. If a tool deletes records, say so. If a remote service stores inputs, document it outside the registry metadata and point reviewers to the applicable terms through your normal product documentation.
Claim canonical package names and namespaces early, even if publication comes later, but do not flood registries with placeholder projects that users could mistake for working servers. Monitor similar names and prepare an abuse-reporting path. The Official MCP Registry FAQ directs reports toward both the underlying package registry and the registry maintainers, which makes sense because a malicious listing and a malicious artifact live in different control planes.
When a release is compromised, mark affected versions deprecated or deleted where registry controls allow, revoke publishing and service credentials, publish a clean version through a restored chain, and tell users exactly which artifacts to remove. A status flag without an incident explanation leaves downstream teams guessing whether they face a cosmetic issue or credential theft.
Production approval needs evidence at every boundary
I would approve an MCP server for production only when I can connect the verified publisher to the exact artifact, the artifact to reviewed behavior, and that behavior to constrained credentials. Missing source does not always force rejection, especially for a remote commercial service, but it raises the burden on isolation, contract terms, logging, and the amount of data I am willing to send.
I would reject a server that relies on a familiar display name, floats to the latest package, requests a broad personal token, or runs with the developer's full home directory mounted. I would quarantine one whose publisher identity checks out but whose release provenance is unclear. A registry badge would not change either decision.
The Official MCP Registry is useful precisely because it creates a common metadata and namespace layer. Use its evidence for what it proves. Then inspect the artifact, narrow the runtime, pin the release, and make capability changes trigger a fresh review. The server that cannot survive those checks should not sit between an agent and your production systems.
Frequently Asked Questions
Does an MCP registry verify that a server is safe?
No. The Official MCP Registry verifies namespace control and checks metadata bindings, but it delegates code scanning to package registries and downstream services. You still need to review the artifact, permissions, and operating environment.
What does a verified MCP publisher mean?
It means the publisher proved control of the GitHub account, organization, or domain behind that namespace at publication time. It does not certify every release, dependency, employee, or runtime behavior.
How can I check an MCP server before installing it?
Match the full server name to the expected namespace owner, then reconcile registry metadata with the exact package or remote origin. Inspect the pinned artifact, lifecycle scripts, requested secrets, initialized tools, and effective permissions.
What is MCP namespace squatting?
Namespace squatting claims an identity space that users may expect another publisher to own. A related typosquatting attack uses a similar-looking verified name, so verification alone does not replace careful ownership checks.
Should I trust the first server in registry search results?
No. Search finds candidates and does not rank software by organizational approval or code safety. Verify the owner and artifact independently before installation.
Should MCP server versions be pinned?
Yes. Pin a package version plus integrity value, or a container digest, so the code cannot change on the next launch. Bind internal approval to that artifact and its capability set.
Are remote MCP servers safer than local packages?
Not automatically. A remote server reduces local code execution but sends data and tool requests to an operator you must assess. Check the origin, authorization scopes, retention, tenant isolation, and change controls.
What permissions should an MCP server receive?
Give it a dedicated credential and only the files, network destinations, data, and actions required for its job. Tool descriptions inform the model, while operating system controls and credential scopes enforce the boundary.
When should an MCP server be reviewed again?
Review it after any version, owner, package, remote origin, tool, permission, or data-class change. Deprecation, deletion, and credential alerts should also reopen the decision.
Can a company run a private MCP registry?
Yes. The official registry documentation recommends a private registry for servers limited to private networks or private package repositories. Apply the same provenance and permission checks because private publication does not make code safe.


