Wink MCP
Make your AI agent recognise people, charge cards, and prove identity over the Model Context Protocol. One bearer token, one URL — agents in Claude Code, Claude Desktop, Cursor, and any MCP-aware host can call Wink's biometric and wallet primitives without a custom integration.
What is Wink MCP
Wink MCP is a hosted MCP server that wraps the Wink Core API as a set of agent-callable tools. You connect once with a bearer token; your agent then has access to face / voice recognition, wallet operations, biometric authentication, age verification, and checkout — all as ordinary tool calls in whatever MCP host you use.
Two things distinguish it from calling the Core API directly:
- Server-side credentials. Your Wink merchant
clientId/clientSecretnever leave Wink's infrastructure. The MCP server holds them and signs every call to Wink on your behalf, so the agent (and the model running it) can't see your secrets even if a prompt injection tries. - Agent-shaped tool surface. Tools encapsulate the multi-call flows the Core API needs — for example,
recognize_facehandles session-mint-then-multipart-recognise as a single call, returns just the fields an agent cares about, and masks PII by default so a chat transcript doesn't accidentally store full names.
Layer 3 in the Wink stack. Layer 1 (Core API + SDKs) is for direct integration. Layer 2 (WinkKey) is biometric sign-in for end users. Layer 3 (Wink MCP) is what you reach for when the consumer of Wink's primitives is an AI agent rather than a human-driven app.
Get an API key
Wink MCP keys are provisioned per-merchant. Reach out to your Wink contact (or use the Get keys link in the top-right of this site) and you'll receive a 64-character hex token tied to your merchant account.
Treat the token like a password:
- Don't paste it into a Git repo or share it in a chat.
- Each developer on your team gets their own token — revoke individually when someone leaves.
- If a token leaks, ask Wink to rotate it and your agents will need the new one.
Connect a client
Three of the most common MCP hosts cover most cases. The pattern is identical: point the host at https://mcp.wink.bio/api/mcp with an Authorization: Bearer <token> header.
Claude Code
One CLI invocation:
claude mcp add --transport http wink \
https://mcp.wink.bio/api/mcp \
--header "Authorization: Bearer <your-token>"
Then in any Claude Code session, ask the agent to call a Wink tool — it'll appear in /mcp alongside your other servers.
Claude Desktop
Edit claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"wink": {
"url": "https://mcp.wink.bio/api/mcp",
"headers": {
"Authorization": "Bearer <your-token>"
}
}
}
}
Restart Claude Desktop. The Wink tools appear in the tool picker.
Cursor
Settings → Cursor Settings → MCP → Add new MCP server:
{
"mcpServers": {
"wink": {
"url": "https://mcp.wink.bio/api/mcp",
"headers": {
"Authorization": "Bearer <your-token>"
}
}
}
}
Sanity check
Before you wire it into an agent, confirm the server answers a raw tools/list:
curl -i -X POST https://mcp.wink.bio/api/mcp \
-H "Authorization: Bearer <your-token>" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
You should see all 25 tools enumerated. A 401 means the token is wrong; a 502 means Wink is upstream-failing (rare on stage).
Tool reference
Tools are grouped by purpose. Each one is a single MCP tools/call on the server side; on the agent side it just looks like a tool the model can invoke. Argument and return shapes are advertised via JSON schema in the tools/list response — your MCP host pulls them automatically.
recognize_faceIdentify a person from a face image. Returns winkTag, confidence, masked name on match; null on no-match.
recognize_voiceIdentify a person from a short voice clip. Same return shape as recognize_face.
recognize_face_cardsRecognise face and return the user's saved cards in one call. For payment-shaped flows.
recognize_face_walletRecognise face and return the full wallet block (cards + addresses + profile).
get_user_profileFetch first/last name, email, contact no, dateOfBirth (where available) for an authenticated user.
update_user_profileUpdate profile fields. Only the fields you provide are touched.
validate_contact_noCheck whether a phone number is already registered with Wink. Useful for "have we met before?" branches.
check_age_verifiedBoolean: has this user passed age verification on this merchant? No DoB ever returned.
show_walletReturn cards + addresses + profile in one shot. The agent's go-to "tell me about this user" call.
get_user_cardsList saved cards (last-4, brand, expiry, token). Set merchantSpecific to scope to your merchant or pull cross-merchant.
get_user_addressesList saved billing + shipping addresses.
add_user_addressSave a new billing or shipping address. Returns the new address id.
delete_user_addressRemove a saved address by id.
request_biometric_authInitiate a biometric auth challenge (face / voice / palm). Returns a rid and a URL the agent can hand to the user.
check_biometric_authSingle-shot status poll for a rid. Returns pending / consumed / expired.
wait_for_biometric_authBlock-and-poll variant — convenient when the agent has time to wait. Times out after the auth-request's TTL.
cancel_biometric_authCancel a pending auth-request before the user completes it.
send_biometric_auth_emailEmail the auth-request URL to a user — handy when the agent doesn't have the user in front of it.
request_enrollmentStart an enrolment flow for a new user. Returns a URL the user opens to capture face / voice / palm.
send_enrollment_emailEmail the enrolment URL to the user.
prepare_checkoutMint a Wink checkout session. Agent attaches it to the human-facing UI / link.
prepare_email_checkoutVariant that emails the checkout URL directly to the user.
prepare_inline_checkoutVariant for embedding checkout inline (in-app webview, bot reply, etc.).
wait_for_checkoutBlock-and-poll until the checkout completes, fails, or times out. Returns the authorization result.
generate_winkpinGenerate a one-time numeric PIN for the user (sent via their preferred channel) — usable as a 2FA factor.
Example flows
"Identify the person in this photo"
The simplest possible flow — agent gets a JPEG, returns who it is.
- Agent receives an image (e.g. user uploads a photo to Claude Desktop).
- Agent calls
recognize_facewith the base64-encoded image. - Server returns
{ match: true, winktag: ";stage-…", first_name: "A****x", confidence: 0.99 }. - Agent narrates the masked result back to the user.
Names are masked by default. Full PII is reserved for a future scoped token; the pii_mode: "full" argument is accepted for forward-compat but currently falls back to masked.
"Charge this person for $20"
Recognition + wallet + checkout, three tools, one user-visible step (biometric auth on their device).
recognize_face_walleton a captured photo to identify the user and load their cards.request_biometric_authfor confirmation — the user gets a URL on their phone.wait_for_biometric_authblocks until they consent.prepare_checkoutwith the chosen card token + amount.wait_for_checkoutblocks until the authorization clears.
"Is this user old enough to buy alcohol?"
For age-gated commerce — no DoB ever leaves Wink.
recognize_faceidentifies the user.check_age_verifiedwith theirwinktagreturns{ verified: true }orfalse.- If false, agent points the user at
request_enrollmentto add ID-document verification, then loops back.
Self-host
If your data-residency or compliance posture rules out a hosted MCP server, the implementation is open. Clone wink-mcp-server, configure your own Wink merchant credentials and Turso DB, and deploy to your own Vercel project (or any Node 22 host that supports streaming HTTP).
git clone https://github.com/wink/wink-mcp-server.git
cd wink-mcp-server
pnpm install
cp .env.example .env.local
# fill in WINK_*, MCP_API_KEYS, TURSO_*
pnpm db:push
pnpm dev # http://localhost:3030/api/mcp
The server is intentionally framework-light — Next.js 15 App Router + @vercel/mcp-adapter + Drizzle + libsql. Roughly 4k LoC; review-friendly.
Notes & gotchas
Bearer tokens, not OAuth (yet)
The current scheme is a shared bearer per developer. We'll add OAuth 2.1 client credentials when the use case appears — for instance, when an agent platform wants to mint per-end-user tokens. Until then: keep your bearer where you keep API keys.
PII is masked by default
Names come back as A****x K****m (first + last char visible). This is so a chat transcript can't reconstruct identifying detail by accident. Tools that read profile fields (get_user_profile, show_wallet) honour the same default. To opt into full PII, you'd ask Wink for a scoped token — that mechanism doesn't exist yet but the wire format already accepts pii_mode: "full".
No biometric data ever leaves Wink
The MCP server only ever proxies recognition results. Face images, voice clips, and the embeddings Wink computes from them stay on Wink's infrastructure. The audit log on the MCP side captures tool name, latency, and Wink's response status code — never the inputs.
Single-use sessions are handled for you
Wink Core sessions are single-use; the MCP server mints fresh sessions per call and self-heals on stale-session 401s. You don't need to think about session lifecycle when using MCP — it's the same model as calling REST through the playground console.
Function timeout is 60 s on Vercel Pro
Most tools complete in under a second. The exceptions are the blocking polls — wait_for_biometric_auth and wait_for_checkout — which honour their own TTL but cap at the function deadline. If you need longer waits, use request_* + check_* (non-blocking) and poll from your agent's loop instead.