Trust at first contact for MCP: adopt AID DNS record + key handshake (portable, decentralized, ongoing)
Is your feature request related to a problem? Please describe.
The registry is centralized for domain verification and there is no cryptographic binding between the published MCP URI and a server key that the publisher controls. Today a one-off registry token proves control once and only to this registry. It does not provide ongoing assurance that the live endpoint at the published URI is still controlled by the same party. If the endpoint changes, is fronted by a new service, or is hijacked, neither the registry nor clients have a built-in way to detect it at connect time.
Concrete pain points:
- Central issuance. A registry-minted challenge is the trust anchor. Proof is not portable to other registries or clients.
- No key continuity. There is no simple, standard handshake that proves private key control of the server behind the published MCP URI.
- No ongoing attestation. Tokens do not naturally support periodic re-verification. Changes or compromise are hard to detect.
- Fragmentation risk. Each registry could invent a different challenge and storage format.
This weakens trust at setup and over time.
Describe the solution you’d like
Adopt the Agent Identity and Discovery (AID) pattern for domain namespaces. AID uses a single DNS TXT record at _agent.<domain> to declare the MCP endpoint and carry a public key. A simple HTTP Message Signatures handshake proves private key control at the published URI. This creates decentralized publication, portable proofs, and continuous assurance without registry-issued tokens.
High level:
- Standing DNS declaration owned by the publisher
Publish a TXT record at
_agent.<domain>that declares the MCP endpoint, protocol, and an Ed25519 public key.
Example TXT:
_agent.example.com. 300 IN TXT "v=aid1;p=mcp;u=https://api.example.com/mcp;k=z7rW8rTq8o4mM6vVf7w1k3m4uQn9p2YxCAbcDeFgHiJ;i=g1;s=Example MCP;d=https://docs.example.com/agent"
Required keys:
v= spec versionaid1p= protocol token, heremcpu= absolute https URI for the MCP server
Strongly recommended:
k= multibase encoded Ed25519 public key for endpoint proofi= short rotation id for the key ink
Optional metadata:
s= short descriptiond= docs URLe= deprecation timestamp
- Trust at first contact handshake
When verifying a publish, and optionally on a cadence, the registry performs a lightweight HTTP Message Signatures handshake at
uto prove private key control.
Request:
GET /mcp HTTP/1.1
Host: api.example.com
AID-Challenge: <base64url 32 random bytes>
Date: Tue, 09 Sep 2025 10:00:00 GMT
Expected response headers:
HTTP/1.1 200 OK
Signature-Input: sig1=("@method" "@target-uri" "date" "aid-challenge");created=<unix_ts>;keyid="aid:<i>"
Signature: sig1=:<base64 signature>:
Verification rules:
- Verify Ed25519 signature with the public key from
k - Enforce reasonable clock skew on
created - If
uredirects to a different origin, treat as failure unless an explicit policy allows it - Pass only on 200 OK, correct coverage, and a valid signature
AID Documentation
- Registry behavior for domain namespaces
On publish:
- Resolve
_agent.<domain>TXT for the domain namespace in the server name, for examplecom.example/foochecks_agent.example.com - If no TXT, optionally fetch
.well-known/agentJSON fallback with equivalent keys - Validate
v=aid1,p=mcp, and thatumatches the MCP endpoint declared inserver.json - If
kis present, require handshake success - Persist
aid_domain,aid_uri,aid_proto,aid_pubkey,aid_kid,aid_dns_ttl,aid_dnssec_present, andaid_verified_at
On re-publish and on a periodic schedule:
- Repeat the handshake and update
aid_verified_at. If the result flips from pass to fail, set a warning status on the entry and surface in UI and API
- Client behavior (optional but recommended)
- When installing from the registry, a client may repeat the handshake once on first connect for defense in depth
- Respect the DNS TTL for revalidation cadence if the client chooses to re-check
- Backward compatibility
- Keep GitHub OAuth and OIDC for
io.github.*namespaces - Keep the current registry token flow as a fallback for domains that do not publish
_agent - Prefer AID when present
Describe alternatives you’ve considered
- Current MCP registry DNS or HTTP challenges
- Central issuance, one-off proof, not portable, no ongoing endpoint key binding
- ACME style HTTP-01 or DNS-01 challenges
- Same central issuance pattern as above. Great bootstrap, still no durable binding between domain namespace and the MCP endpoint key
- Google Search Console style HTML file or meta tag
- Central issuance and single-use control proof, no ongoing assurance, not portable
- DID:web
- Similar authority model under the domain but heavier stack and JSON-LD processing. Introduces another resolution layer and additional complexity for registries and clients. Viable, but higher operational friction than a single TXT
- TLS only
- Validates the certificate chain but not the mapping between MCP namespace and endpoint or continuity of control by the claimed publisher
- Signed manifests hosted by the publisher
- Useful but clients need a distribution and discovery bootstrap anyway. AID gives a single, well-known discovery point that any registry or client can consume
Additional context
Security guidelines:
- Encourage DNSSEC for
_agent.<domain>and record thataid_dnssec_presentin metadata - Require HTTPS for
uwith standard TLS checks - No secrets in TXT records. Public keys only
- Warn on downgrade if
kdisappears between verifications for the same domain - Do not auto-follow cross-origin redirects during the handshake
Failure modes and error codes the registry and CLI should surface:
ERR_NO_RECORD1000. No_agentTXT and no valid fallbackERR_INVALID_TXT1001. Missing required keys or malformed valuesERR_UNSUPPORTED_PROTO1002.pis notmcpERR_SECURITY1003. Handshake failure or cross-origin redirect without policyERR_DNS_LOOKUP_FAILED1004. Network failureERR_FALLBACK_FAILED1005..well-knowninvalid
Publisher CLI UX:
mcp-publisher verify-aid <domain>prints the TXT, validates structure, and performs the handshake with a clear pass or fail reportmcp-publisher publishfor domain namespaces runs AID checks first and fails fast with actionable errors- Human friendly messages that show which key failed, what header was missing, and a copy-pasteable TXT template when no record is present
Registry API and data model changes:
-
Store and expose:
aid_domainstringaid_uristringaid_protoenumaid_pubkeystringaid_kidstringaid_dns_ttlintegeraid_dnssec_presentbooleanaid_verified_attimestampaid_statusenum: ok, warn, fail
-
Optional endpoint:
GET /servers/:id/aid-proofreturns latest handshake status and diagnostics for transparency and ecosystem tooling
UI changes:
- Display AID verification status on the server page with last verified time
- Show DNSSEC present badge when detected
- Provide a small copy button that copies the exact TXT the registry expects for the entry
Operational policy knobs:
- Minimum re-verification interval, default daily, bounded by observed DNS TTL
- Grace periods for temporary failures to avoid noisy flapping
- Optional strict mode that requires
kfor domain namespaces once the ecosystem is ready
Example end-to-end flow:
- Publisher sets:
_agent.example.com. 300 IN TXT "v=aid1;p=mcp;u=https://api.example.com/mcp;k=z7rW8rTq8o4mM6vVf7w1k3m4uQn9p2YxCAbcDeFgHiJ;i=g1;s=Example MCP"
- Publisher runs:
mcp-publisher verify-aid example.com
mcp-publisher publish
- Registry:
- Resolves
_agent.example.com - Validates
v,p,u - Performs handshake at
https://api.example.com/mcp - Stores AID fields and sets
aid_status=ok,aid_verified_at=<ts>
- Client installs from registry and optionally performs a one-time handshake on first connect
Test plan outline:
- Unit tests for TXT parsing and validation including multi-string TXT concatenation
- Handshake success and failure cases, including clock skew, missing headers, and redirect handling
- DNS error handling and
.well-knownfallback parsing - Rotation handling where
ichanges and the new key passes handshake - Negative tests for downgrade where
kdisappears
Acceptance criteria:
- A publisher can prove control for
com.example/foowithout any registry-issued token if_agent.example.comadvertisesp=mcp,u, andk, and the handshake passes - Publisher CLI surfaces clear, actionable guidance for missing TXT, mismatch between
uin TXT andserver.json, and handshake failures - Registry UI and API show AID status and last verified time
- Periodic checks detect endpoint key rotation or control loss and flag the entry
Why this improves MCP:
- Moves the trust anchor from registry-minted secrets to DNS that the domain owner already controls
- Binds the published MCP URI to a server-controlled key
- Provides ongoing, low-friction assurance without bespoke challenges
- One DNS record can be consumed by any registry and by clients directly, which reduces fragmentation and vendor lock-in
References for implementers:
- AID v1.1 record format and handshake description as above
- HTTP Message Signatures RFC 9421 for header construction and verification
If maintainers prefer a phased roll-out, the registry can start by:
- Consuming AID when present and marking entries as AID-verified
- Keeping existing token flow as fallback
- Measuring adoption before moving toward stricter requirements on domain namespaces
Interesting. I guess another potentially simpler approach might be to provide a challenge key in the server.json, and then have an endpoint/something in the meta of the init handshake that proves ownership of the private key?
Although AID might be worth adopting instead to do this if it has a large community/backing etc. At the moment it looks like it might be quite new, so not sure whether we should adopt this.
Thanks for the thoughtful take. I read the concern as “newness,” not the spec itself.
Why AID fits here
- It solves discovery and trust in one step. One
_agent.<domain>TXT with keys and a small HTTP signature check. - No issuer. The domain owner publishes, anyone can verify. This keeps the internet a bit more decentralized.
- Reusable across the ecosystem. The same record and handshake work for this registry, other registries, clients, IDEs, scanners, enterprise control planes. The same trust in ownership and control.
On newness
- The surface is intentionally small and boring. DNS, HTTPS, HTTP Message Signatures, optional DNSSEC. All well tested parts.
- The scope is narrow. Endpoint location plus proof of key control. Low churn risk.
- There is an IETF BoF request on DNS anchored agent discovery for Toronto, which signals broader interest: https://datatracker.ietf.org/doc/bofreq-williams-bofreq-mozleywilliams-agent-to-agent-discovery/
If the goal is a simple, portable, decentralized way to assert “this domain speaks MCP at this URL and controls this key,” AID was written for exactly that use case.