MCP Identity
A small standard so MCP servers can publish a verifiable identity, and clients can decide whether to trust them before connecting.
Why
MCP is becoming the universal plumbing for AI tools. There is currently no standard for asking “is this MCP server actually who it says it is?” An MCP server with the same name as another can lie about being it; a malicious server can claim to be the official one for a bank, exchange, identity provider, or model lab and there is no canonical answer.
DNS solved this for hostnames. TLS solved this for in-flight authentication. MCP Identity solves it for “who built and operates this MCP server” by binding an MCP server endpoint to a verified AI Identity record on a public registry.
Shape
Servers publish a JSON file at a known well-known path:
GET https://your-mcp-server.example.com/.well-known/ai-identity.json
→ {
"version": "1",
"identity_id": "aii_HMB77VQ527B5Z062CNE31D",
"registry": "https://aiidentity.org",
"issued_at": "2026-04-12T10:30:00Z",
"signature": "ed25519:base64..." // optional v1, required v2
}The registry hosts the canonical record at https://aiidentity.org/api/v1/identities/<identity_id>. Clients fetch the well-known, look up the registry record, and decide whether to trust based on tier, status, and surface match.
Surface binding
For the well-known to be trustworthy, the registry record must list this MCP server's domain as a verified surface. Without that binding, anyone could publish a well-known referencing any identity ID.
Surface verification is performed at registry-record creation time (DNS TXT challenge or HTTP page-header challenge — see /spec/surfaces). The flow:
- Operator creates an AI Identity for their MCP server.
- Adds
https://your-mcp-server.example.comas a verifiable surface, completes DNS or header challenge. - Operator publishes
/.well-known/ai-identity.jsonon the same hostname referencing that identity ID. - Clients verify the well-known against the registry record. The match between domain-on-the-record and domain-of-the-server is what makes the binding meaningful.
Client verification (recommended algorithm)
- Resolve
https://<mcp-host>/.well-known/ai-identity.json. If absent, treat as unverified. - Extract
identity_id. Reject if format does not matchaii_[A-Za-z0-9]+. - Fetch
https://<registry>/api/v1/identities/<identity_id>.registrymust be a known trusted registry; clients should pin a default list (aiidentity.org+ any registries the user has explicitly trusted). - Confirm registry record
status === "active". - Confirm registry record contains
<mcp-host>in its verified surfaces list. - Read
tier. Apply local policy (e.g. only connect iftier >= business_verified).
v2 of this spec adds an Ed25519 signature field signed by the registry, so the registry round-trip can be skipped for offline / cached verification. v1 requires an online lookup.
Tier-gated access policies
Clients can implement progressive trust: connect freely to creator_verified and above, prompt the user before connecting to identity_verified, refuse issued and unverified servers entirely. This is policy, not protocol — the spec just provides the truthful tier and lets the client decide.
Reference SDK
The official @aiidentity/sdk ships a verifyMcpIdentity(host) helper that implements the recommended algorithm above. Drop-in use:
import { verifyMcpIdentity } from "@aiidentity/sdk";
const result = await verifyMcpIdentity("https://my-mcp-server.example.com", {
minTier: "business_verified",
});
if (!result.ok) throw new Error("Refusing to connect: " + result.reason);
// Safe to proceed with MCP handshake.Co-existence with mcp.txt and other proposals
We deliberately use /.well-known/ai-identity.json rather than mcp.txt because:
- Well-known URIs have an established security model (RFC 8615).
- JSON is unambiguous;
.txtformats invariably end up parser-divergent. ai-identityis verifier-agnostic — a non-AI-Identity registry can adopt the same format and just pointregistryelsewhere.
We will support mcp.txt as a compatibility format if a parallel proposal becomes widely adopted. The well-known is the canonical.
Status
Draft v1. We are publishing this so the format is fixed enough to build against. Breaking changes to v1 will only happen if we hear concrete feedback before any production deployment exists.
Feedback: spec@aiidentity.org.