Skip to content

SEP-1086: Using Domain Verification for serverInfo.name #1086

@trent-j

Description

@trent-j

Preamble

Title: Using Domain Verification for serverInfo.name
Author: Trent Jones (@trent-j), Thomas Sickert (@thomas-sickert), Ameya Phansalkar (@aphansal123)
Status: proposal
Type: Standards Track
Created: 2025-07-29

Abstract

This SEP standardizes domain-ownership verification for MCP server identifiers (the value of InitializeResult.serverInfo.name).

Publishers must prove control of the domain used as the reverse-DNS prefix of their server name (e.g com.example/my-server) before the MCP Registry accepts new publications. Two complementary verification methods are
defined:

  1. DNS TXT challenge: Add a TXT record mcp-verify=<token> to the domain's authoritative DNS zone.

  2. HTTP-01 web challenge: Serve the same token at https://<domain>/.well-known/mcp/verify.

Either path is sufficient to verify ownership. The registry re-checks the chosen indicator(s) at publish time and
via a periodic background job; if a domain fails verification on three consecutive runs, it is marked
unverified and publishing is blocked.

Motivation

The current MCP specification allows any UTF-8 string for serverInfo.name, leaving consumers unable to assess
provenance or trustworthiness.

Without verification an attacker could, for example, upload a malicious server called com.microsoft/autoupdater,
relying on name recognition to trick users.

Reverse-DNS naming plus verifiable control:

  • Prevents name squatting and impersonation.
  • Enables decentralized governance.
  • Aligns MCP with established ecosystems such as Maven Central, PyPI, npm and ACME.

Specification

serverInfo.name Syntax

Aspect Requirement
Prefix SHOULD be a domain the publisher controls (reverse-DNS, e.g. com.example).
MAY use the pseudo-domain io.github<user or org>.
Separator Exactly one / (solidus)
Suffix Lower-case alphanumerics plus -/_; MUST match ^[a-z0-9]([a-z0-9-_]{0,61}[a-z0-9])?$
Length ≤ 255 UTF-8 bytes.

Servers SHOULD reuse the identical string wherever the "name" appears (e.g. server.json discovery files).

Supported Verification Methods

  1. DNS TXT Record Verification

    • The registry issues a 128-bit random token for the requested domain namespace.
    • The publisher adds a DNS TXT record mcp-verify=<token> to the domain's DNS zone.
    • The registry queries the DNS record to confirm control; periodic re-checks ensure continuous ownership.
  2. HTTP-01 Web Challenge

    • The registry issues a 128-bit random token for the requested domain namespace.
    • The publisher serves the token over HTTPS at the well-known path (e.g. https://<domain>/.well-known/mcp/verify).
      The publisher can satisfy this by placing a plain-text file containing the token at that location or by configuring
      a web server to return the token at that location.
    • The registry fetches this URL to confirm control; periodic re-checks ensure continuous ownership.

Verification succeeds if either method passes.

Continuous verification

To guard against later ownership changes, the registry re-checks both indicators:

  • Every publish immediately queries DNS and/or fetches the well-known file; publishing is allowed if at least one
    token still matches.

  • Background job (run on a regular cadence) re-checks every verified domain using both DNS and HTTP tokens. The
    job will apply a failure-tolerance policy. For example, if a domain fails the check three times in a row, it is
    marked unverified and new publishes are blocked. After the second consecutive failure, maintainers receive a
    warning; if the check fails a third time, they are notified again as the domain status is downgraded. This guards
    against transient outages while still revoking trust when ownership indicators consistently disappear.

GitHub-Namespaced Fallback

For io.github.<slug>/<server>:

  • Registry records the GitHub account/org numeric ID (immutable).
  • A nightly job calls the GitHub API; if the slug is transferred or deleted, that counts as a failure in the
    three-strike policy.

Rationale

  • Dual channel (DNS + HTTP) mirrors ACME practice and covers teams lacking DNS access.
  • Reverse-DNS names provide human-friendly provenance and leverage the global domain registry instead of
    introducing a new authority.
  • Three-strike tolerance prevents false positives from transient outages, balancing availability and security.
  • The either-method-passes rule keeps CI/CD pipelines running if one infrastructure plane (DNS or web) is
    temporarily impaired.
  • Alternative naming schemes considered:
    • GitHub repo names lock the ecosystem into GitHub and remain vulnerable to repo-jacking.
    • Flat global names invite squatting and provide no ownership signal.
    • Other verification methods (CAA, e-mail, OAuth) were rejected for either misuse, operational burden, or
      exclusion of significant publisher groups.

Backward Compatibility

  • Existing servers uploaded before this SEP that already follow reverse-DNS naming MUST pass verification within
    a grace period set by maintainers (e.g. 90 days) or be flagged as unverified.
  • GitHub-namespaced servers remain valid until the GitHub-rename check is deployed and active.

Reference Implementation

Coming soon

Security Implications

Threat Mitigation
DNS cache poisoning Use multi-perspective DNS queries and honor DNSSEC when available.
Web-server compromise (HTTP-01 only) Encourage maintainers to enable both methods; DNS must also be compromised to bypass dual verification.
Domain expiration & re-registration Continuous checks revoke publishing rights after failures; ownership must be re-proved by the new registrant.
Denial-of-service via fals failures Three-strike policy and warning notifications prevent immediate lock-outs.
Token brute-force 128-bit entropy ensures infeasibility of guessing.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions