# AffixIO MCP server Canonical page: https://www.affix-io.com/mcp/ Remote MCP endpoint: https://www.affix-io.com/mcp/ Protected resource metadata: https://www.affix-io.com/.well-known/oauth-protected-resource/mcp/ Authorization server: https://api.affix-io.com AffixIO Hub: https://hub.affix-io.com/ OpenAPI: https://api.affix-io.com/v1/openapi.json AffixIO provides a remote Model Context Protocol server for account-scoped access to the AffixIO verification API. ## Connection 1. The user creates an API key in AffixIO Hub. 2. The MCP client connects to https://www.affix-io.com/mcp/. 3. The client discovers OAuth 2.1 metadata and starts an authorization code flow with PKCE. 4. AffixIO Hub requires the signed-in user to enter an active API key owned by that Hub account. 5. The MCP client receives a short-lived, revocable OAuth token bound to the AffixIO MCP resource. The raw AffixIO API key is not returned to the MCP client and is not included in the OAuth token. ## Protocol - Model Context Protocol over Streamable HTTP - Current protocol support: 2026-07-28, with stateless 2025 client compatibility from the official TypeScript SDK - OAuth 2.1 authorization code grant - PKCE using S256 - RFC 9728 protected resource metadata - RFC 8414 authorization server metadata - RFC 8707 resource indicator - Dynamic client registration for compatible remote MCP clients - CORS on the public MCP endpoint and discovery metadata ## Tools - `affix_api_read`: authenticated GET requests to published AffixIO `/v1` and supported `/api` paths - `affix_api_write`: authenticated POST, PATCH and DELETE requests to non-administrative AffixIO API paths - `affix-openapi`: the current AffixIO OpenAPI schema as an MCP resource Hub administration, API key administration, OAuth administration and webhook administration are excluded from MCP tool calls. ## Client compatibility Clients need remote Streamable HTTP and OAuth support. Current products in the ChatGPT, Claude, Cursor and Gemini families provide remote MCP support, though product plans and configuration differ. The connecting component is the MCP client or host, not the language model itself. ## Security - API keys must be active and owned by the signed-in Hub account. - API keys remain on AffixIO infrastructure. - OAuth access tokens are short-lived. - Refresh connections and API keys can be revoked. - Write calls are marked as destructive in MCP tool annotations. - Tokens are audience-bound to https://www.affix-io.com/mcp/. ## SDKs Two Node.js packages reach the same API. Both require Node.js 18 or later, default to https://api.affix-io.com, keep an offline queue, anchor Merkle audit, and receive ML-DSA-65 attestation from AffixIO. Both are Apache-2.0. `@affix-io/sdk` (version 1.1.1, https://www.npmjs.com/package/@affix-io/sdk) - Install: `npm install @affix-io/sdk` - Entry point: `import { AffixSDK } from "@affix-io/sdk"`, then `new AffixSDK({ apiKey: process.env.AFFIX_API_KEY })` - Local prove: Barretenberg UltraHonk via `@aztec/bb.js` over bundled Noir circuits including `simple_yesno` and `yesno` - Modes: `auto` (local prove when AffixIO is unreachable), `offline` (always local prove and enqueue), `online` (live licence required, ZK still runs locally) - Storage: JSON under `.affix/` by default, plus pluggable Redis, SQL or custom get/set backends - Merkle audit: client batches of up to 50,000 digests per submission - Carriers: PII-free QR and barcode output, presentment links use your host base only - Reference: https://www.affix-io.com/sdk/ `@affix-io/sdk-light` (version 1.1.3, https://www.npmjs.com/package/@affix-io/sdk-light) - Install: `npm install @affix-io/sdk-light` - Entry point: `import { AffixLightSDK } from "@affix-io/sdk-light"`, then `new AffixLightSDK({ apiKey: process.env.AFFIX_API_KEY })` - Local prove: AffixIO Light HMAC-SHA256 on Node crypto. These are not SNARKs. They bind a yes or no decision and witness with a shared light key. - Dependencies: Node crypto plus optional QR libraries. No Noir, no `bb.js`. - Flush: adaptive, roughly every second, with higher batch ceilings once ingest rises above 20 proofs per second - Signing: every proof is ML-DSA-signed individually at AffixIO - CLI: `affix-sdk-light` binary ships with the package - Intended hosts: phones, kiosks, POS terminals and ordinary servers where UltraHonk runtime cost is unacceptable - Reference: https://www.affix-io.com/sdk-light/ Choosing: use `@affix-io/sdk` when the proof itself must stand on its own. Use `@affix-io/sdk-light` when presentment must feel instant and the threat model accepts an HMAC-bound decision rather than a full SNARK. ## API surface Base URL https://api.affix-io.com. Authenticate with `Authorization: Bearer ` or `X-API-Key: `. Circuits, prove and verify - `GET /v1/circuits`: catalogue of available circuits - `POST /v1/circuits/{id}/prove`: generate a proof, optionally attest, anchor the digest - `POST /v1/circuits/{id}/verify`: verify a proof and spend the digest on success - `POST /v1/witness/prepare`: build witness inputs without proving - `POST /v1/aggregate/verify`: verify up to 25 proofs in one request Attestation - `POST /api/attest`: sign a JSON payload with ML-DSA-65 - `POST /api/attest/verify`: check a payload against its attestation - `GET /v1/attestation/public-key` and `GET /.well-known/affix-mldsa65.json`: publish the verification key Merkle audit - `GET /v1/merkle`: root, leaf count, algorithm and limits - `GET /v1/merkle/proof/{digest}`: inclusion proof for a digest - `POST /v1/merkle/audit`: append a single audit leaf - `POST /v1/merkle/audit/batch`: append up to 1000 leaves per request - `POST /v1/merkle/verify-proof`: check inclusion client-side against a root Gates, spend and revocation - `POST /v1/gate/verify`: admit or refuse, with optional consume - `GET /v1/spent/{digest}`: look up whether a digest has been spent - `POST /v1/spent/revoke`: mark a proof spent or revoked - `GET /v1/edge/spent-pack` and `GET /v1/edge/revocation-pack`: bulk sets for edge sync - `GET /v1/verify/reason-codes`: the reason codes a gate can return Carriers and presentment - `POST /v1/token/issue`, `POST /v1/link/issue`, `POST /v1/claims/issue`, `POST /v1/wallet/pass`, `POST /v1/otp/issue`, `POST /v1/nfc/encode`, `POST /v1/ble/challenge`, `POST /v1/emv/challenge`, `POST /v1/magstripe/encode`, each with a matching verify path Higher-assurance gate operations - `POST /v1/devices`: register a device, secret returned once - `POST /v1/gate/multifactor/start`: multi-factor gate session - `POST /v1/gate/quorum/start`: quorum approval across devices - `POST /v1/delegate/issue` and `POST /v1/delegate/verify`: delegation tokens - `POST /v1/mdl/verify`: mobile driving licence device response Identity parsing - `POST /v1/mrz/parse`: parse a passport MRZ and suggest a prove path. Passport PII is not stored. - `POST /v1/aamva/parse`: parse AAMVA PDF417 from a driving licence. Licence PII is not stored. Open, no API key required - `GET /api/health`: service status, circuit readiness and policy version - `GET /api/governance-stats`: leaf counts and circuit breakdown - `GET /v1/merkle/root`: current Merkle root snapshot ## Engineering contract - Rate limit: 10 requests per second per key by default, scoped to the key or to key and IP. Responses carry `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. Exceeding the limit returns 429 with `Retry-After`. - Idempotency: send `Idempotency-Key` on prove and verify POST requests. A replay within 24 hours returns the original 2xx body with `Idempotency-Replayed: true`. - Single use: a successful verify spends the digest. Presenting it again returns 409 `double_spend_detected`. This is intended behaviour for a one-time eligibility proof. - Tracing: every response carries `X-Request-Id`. - Limits: JSON request bodies are capped at 2 MB. Responses are `no-store`, except the attestation public key, which is cacheable for one hour. ## Questions and answers Q: What is the difference between @affix-io/sdk and @affix-io/sdk-light? A: @affix-io/sdk proves locally with UltraHonk zero-knowledge proofs over bundled Noir circuits via Barretenberg, and suits servers with a zero-knowledge budget. @affix-io/sdk-light proves with AffixIO Light HMAC-SHA256 on Node crypto for phones, kiosks and ordinary hosts. Light proofs are not SNARKs. Both require Node.js 18 or later, keep an offline queue, anchor Merkle audit, and receive ML-DSA-65 attestation from AffixIO. Q: How do I authenticate with the AffixIO API? A: Send your API key as `Authorization: Bearer ` or `X-API-Key: ` against https://api.affix-io.com. The default rate limit is 10 requests per second per key. Q: How do I safely retry an AffixIO verify request? A: Send an `Idempotency-Key` header. A repeat of the same key within 24 hours returns the original successful response with `Idempotency-Replayed: true`. Note that a successful verify spends the digest, and presenting it again returns 409 `double_spend_detected`. Q: Does the language model receive my AffixIO API key? A: No. AffixIO Hub checks the key and issues the MCP client a revocable OAuth access token. The raw API key is not included in that token. Q: What signature does AffixIO use for attestation? A: ML-DSA-65, the post-quantum signature scheme standardised by NIST in FIPS 204. The verification public key is published at https://api.affix-io.com/.well-known/affix-mldsa65.json. ## Limits of these claims - AffixIO is not a compliance certification. - Light proofs are not SNARKs. - MCP client capability varies by product and plan. The connecting component is the client or host, not the language model. - Rate limits and batch ceilings stated here are defaults and may differ under contract. Last updated: 2026-08-14