Technical documentation · v1.0

X-EGO Human Proof

An MCP server that lets AI agents verify there is a real, present human on the other end — using passkey biometrics and short-lived, EdDSA-signed proofs. No accounts, no personal data, no cross-service tracking.

// 01 · Overview

What it is.

X-EGO Human Proof exposes the X-EGO proof-of-human verification as tools for AI agents over the Model Context Protocol (MCP). It runs as a Cloudflare Worker and gives any MCP-capable agent three tools: request a verification link for a user, verify the signed proof the user brings back, and check whether a returning user has been seen before.

The human side of the flow is a Planetary ID — a digital identity bound to a person by their passkey (fingerprint or Face ID, WebAuthn). The human verifies on x-ego.com/verify; their biometrics never leave their device.

What it proves: a person with a registered passkey, who paid for their ID, approved this verification — now, for your service specifically.

What it doesn't prove: global uniqueness. Sybil resistance is cost-bounded: one identity, one payment.

// 02 · Architecture

How the pieces fit.

AI agent  ──MCP──>  xego-mcp-server  ──HTTPS──>  X-EGO API
(Claude…)           (Cloudflare Worker)           /api/verify
                                                  /.well-known/jwks.json

The MCP server does not verify anything cryptographically "from scratch" — it fetches the public signing keys from the X-EGO API's JWKS endpoint and verifies token signatures against them. The registry of seen users (seen_pairwise) lives in the Durable Object's built-in SQL storage, scoped to that MCP server instance.

MCP endpoint · https://xego-mcp-server.bizarcoin.workers.dev/mcp JWKS · https://api.x-ego.com/.well-known/jwks.json Verification page · https://x-ego.com/verify?audience=<your-domain>

Transport is streamable HTTP on /mcp. A health check is available at the worker root (/ or /health).

// 03 · MCP tools

Three tools, one loop.

1 · xego_request_proof_url

Returns the URL the agent sends a human user to, so they can prove they are human. The user verifies on the page with their passkey and receives a short-lived signed token (JWT), which they hand back to the agent. This tool performs no verification itself — it only prepares the link. No personal data is transferred.

ArgumentDescription
audienceRequired. The domain of the service requesting verification (e.g. forum.example.com). A URL is accepted too — it is always normalized to a bare lowercase hostname (max 253 chars). It determines who the proof will be valid for.

Returns: verification_url (link for the user), audience (the normalized hostname — pass this exact value as expected_audience to xego_verify_proof), and instructions. A non-normalizable audience returns invalid_audience.

2 · xego_verify_proof

Verifies the token (JWT) the user brought back. It cryptographically checks the Ed25519 signature against the X-EGO public keys, validates the claims, the expiry, and the audience. A valid result means: there is a verified human on the other end who holds the passkey.

ArgumentDescription
tokenRequired. The JWT obtained by the user after X-EGO verification. Three dot-separated parts.
expected_audienceRequired. Your own service's domain the token must have been issued for. Domain or URL — normalized to a bare hostname exactly like in xego_request_proof_url. A token issued for a different audience is rejected (wrong_audience). This prevents token reuse across services and preserves pairwise isolation.
mark_as_seenOptional, default false. If true and the token is valid, the pairwise ID is recorded as seen for that audience — useful to immediately guard against repeat use.

Returns on success: valid: true, pairwise_id (anonymous ID, stable per user-and-audience), audience, expires_at (Unix time), and human_verified: true. On failure: valid: false with a machine-readable code and a human-readable reason (see error codes below).

Proofs are single-use. Each token passes verification exactly once. A second attempt to verify the same token returns token_replayed. The jti registry is a global singleton Durable Object with an atomic check-and-mark, so there is no window for a concurrent replay.

3 · xego_check_pairwise_seen_before

Checks whether a given pairwise ID has already been seen within an audience. It protects against one person acting as multiple different users — multiple accounts, repeat voting, and similar. Only the pair (audience, pairwise_id) and the time of first occurrence are recorded. No personal data.

ArgumentDescription
audienceRequired. The service domain being asked about.
pairwise_idRequired. The user's pairwise identifier (from the xego_verify_proof result).
record_if_newOptional, default false. If true and the user has not been seen yet, they are recorded immediately — an atomic "is new? then mark" in one call.

Returns: seen_before (boolean), first_seen (Unix time or null), recorded_now (boolean). Note: this registry is bound to the MCP server instance — it is per-service protection, not a global registry.

// 04 · Verification flow

From request to proof.

  1. Agent calls xego_request_proof_url with its service domain as audience and receives a verification URL.
  2. Agent sends the URL to the human user.
  3. User opens x-ego.com/verify?audience=…, sees exactly which service the proof is being issued for, and approves with their passkey (fingerprint / Face ID). The biometric check happens entirely on their device — WebAuthn with user verification required.
  4. X-EGO API validates the passkey assertion (full W3C WebAuthn §7.2 checks: origin, challenge, rpIdHash, UP+UV flags, signature counter), derives the pairwise ID, and signs a short-lived JWT.
  5. User copies the token and hands it to the agent. The page shows a live countdown of the token's validity.
  6. Agent calls xego_verify_proof with the token and its expected_audience. Optionally it calls xego_check_pairwise_seen_before to detect returning users.
// 05 · Proof token

Anatomy of a proof.

Proofs are JWTs signed with EdDSA (Ed25519). The verifier accepts exclusively alg: EdDSA — a defense against algorithm-confusion and none attacks. Claims:

ClaimMeaning
issThe X-EGO issuer.
audThe audience — the bare lowercase hostname of the service the proof was issued for.
subThe pairwise ID: xego_ + HMAC(secret, owner | audience). Stable per user-and-audience, different for every audience.
originThe verified WebAuthn origin — taken from the validated client data, never from the request body.
iat / expIssued-at and expiry. Tokens live 180 seconds. Verification allows 30 s of clock skew.
jtiUnique token ID — the basis of single-use replay protection.

Public keys are published at the JWKS endpoint (kty: OKP, crv: Ed25519). The verifier caches JWKS for 5 minutes and force-refreshes on an unknown kid, so signing keys can rotate with a grace period without breaking verification.

// 06 · Privacy & pairwise identity

Anonymous by construction.

Each service sees only a pairwise identifier — deterministically derived from the user and the audience, different for every audience. Two services can never link their users to each other, and no service ever learns the user's Planetary ID number, name, or any personal data — X-EGO stores none of it in the first place.

// 07 · Error codes

When verification says no.

CodeMeaning
invalid_audienceThe audience could not be normalized to a domain.
malformed_tokenThe token is not a well-formed JWT.
unsupported_algorithmThe token is not signed with EdDSA.
unknown_keyNo JWKS key matches the token's kid (the kid is included so a key rotation can be told apart from a corrupt token).
bad_signatureThe Ed25519 signature does not verify.
expiredThe token is past its 180-second lifetime.
wrong_issuerThe iss claim is not X-EGO.
wrong_audienceThe token was issued for a different audience than expected_audience.
missing_claimsA required claim (sub, aud, exp, jti) is absent.
token_replayedThis token has already been verified once. Proofs are single-use — the user must verify again.
jwks_unavailableThe public keys could not be fetched from the JWKS endpoint.
// 08 · Pricing

What it costs.

For humans: a Planetary ID costs €3 once and includes unlimited self-verification, forever.

For services: verifying proofs is free up to 500 verifications per audience per month. Need more? Higher-volume tiers are available — get in touch. Quotas are counted per audience (the domain proofs are issued for), never per human.

// 09 · Quick start

Connect an agent.

Add the MCP endpoint as a connector in any MCP-capable client. In Claude: Settings → Connectors → Add custom connector, then paste the endpoint URL:

https://xego-mcp-server.bizarcoin.workers.dev/mcp

The three tools appear automatically. A minimal integration is three calls:

1. xego_request_proof_url({ audience: "your-domain.com" })
2. — user verifies at the returned URL and brings back a token —
3. xego_verify_proof({ token, expected_audience: "your-domain.com",
                       mark_as_seen: true })

← Back to x-ego.com