Identity for your AI agent.
Wink's face, voice, palm and ID-verification APIs, wrapped as a Model Context Protocol server. Drop it into Claude — web, desktop, mobile, Code — or any MCP-capable agent. Point it at an image, get a winktag back. If your workspace admin has enabled Wink as a connector, it's zero config.
Drop any image
HEIC from your iPhone, PNG, JPEG, WebP — any format, any size. The local shim resizes and converts; Wink sees a clean JPEG.
Masked by default
Names return as A****x K****m unless a scoped token explicitly asks for full PII. Winktags are the real identifier; the rest is UX garnish.
Real liveness
Opt-in per call. Wink flags static-photo spoofs and low-confidence matches distinctly, so the agent can ask for a clearer shot or a second factor.
How to connect.
Two paths. Pick the first that matches what you see in Claude — they do the same thing, one just skips a step.
You see Wink in Claude's connector list.
Your workspace admin already enabled Wink as a custom connector. Nothing to install.
- 1Open Claude — web, desktop, or mobile. Go to Settings → Connectors.
- 2Find Wink in the list. Click Connect.
- 3A WinkKey auth page opens. Complete Face ID / passkey.
- 4Return to Claude. Flip the Wink tools to Always allow. Start talking.
Don't see Wink in the list? Ask your admin to add it, or follow Path B to install the local shim just for yourself.
You don't see Wink yet. Install the shim.
Works on Claude Desktop (macOS / Windows) and Claude Code. Mobile and web need Path A.
- 1Request a token below. Auto-approved, shown once on screen.
- 2Download and install the shim:↓ wink-mcp-0.17.0.tgzthen in a terminal:
npm install -g ~/Downloads/wink-mcp-0.17.0.tgz - 3Paste the six-line
mcpServersblock (shown with your token) into Claude Desktop's config. - 4Restart Claude Desktop. Wink tools appear in the tools picker.
Path B unlocks local file paths and batch directory tools that browser-based Claude can't reach. See the matrix below.
Already have a token? Just download the latest tarball above and re-run the install command — your existing token and Claude Desktop config keep working. No need to request a new one for shim updates.
BetaChatGPT (Apps SDK) support is in early testing.
What works where.
Mobile, web, and the connector path all go through Claude's hosted runtime — no access to your local filesystem. Claude Desktop + shim can also reach local files and directories.
| Capability | Claude Web / Mobile(Path A) | Claude Desktop(A or B) |
|---|---|---|
| Biometric auth via WinkKey (Face ID / passkey) | ||
| Enroll a new Wink user (face capture + profile) | ||
| Inline QR code for mobile hand-off | ||
| Active-session reuse (one auth per conversation) | ||
| Brand the WinkKey screen (display_title / display_subtext) | ||
| Cancel a pending auth or enrollment link | ||
| Recognize from a public image URL | ||
| Recognize from a photo attached in chat | inline uploads limited; Sonnet mobile often asks for a URL | |
| Recognize from a local file path on your Mac | Path B only | |
| Batch recognize a directory of faces | Path B only | |
| Batch recognize a directory of voice samples | Path B only | |
| HEIC / iPhone photos auto-normalized | Path B only | |
| Voice recognition (m4a / mp3 / wav / etc.) | ||
| Liveness signal (anti-spoof) | ||
| Card wallet inline with recognition | ||
| Saved cards / addresses (post-auth wallet read) | ||
| Save a new shipping or billing address | ||
| Delete a saved address | ||
| Read user's Wink profile (winktag, name, email, phone) | ||
| Check if user is age-verified (21+ gate, alcohol / cannabis) | ||
| Update profile fields (email, phone, name, etc.) | ||
| Pre-flight: is this phone already a Wink user? | ||
| Generate WinkPin (Wink emails it OOB; agent never sees it) | ||
| In-room checkout (URL + inline QR) | ||
| Email checkout link to a remote recipient | ||
| Force Wink cloud (suppress passkey on user request) |
What your agent can do.
recognize_face(image_path, pii_mode?, liveness?, threshold?)Single image (HEIC, PNG, JPEG, WebP — any size). Returns verdict (Green/Yellow/Red), confidence, winktag, masked name, and liveness signal. Yellow surfaces 2FA options; Red flags liveness failures.
recognize_faces_in_directory(directory_path, recursive?, max_files?, liveness?)Desktop · shimBatch face recognition. Globs a directory, processes with bounded concurrency, returns one row per file in the same flat shape. Default cap 20 files, hard max 50.
recognize_face_wallet(image_path, pii_mode?, liveness?, threshold?)Everything recognize_face returns plus the user's default saved card (token, last 4, issuer, nickname, expiry/autopay flags). Useful right before a payment step so the agent can confirm both identity and which card will be charged.
recognize_face_cards(image_path, pii_mode?, liveness?, threshold?)Everything recognize_face returns plus the user's FULL list of saved cards — each with last 4, issuer, nickname, default flag, expiry, autopay. Use this when the user has multiple cards and needs to pick one (e.g. 'charge my Amex' or 'use the one ending in 4242'). Default card sorted first.
recognize_voice(audio_path, pii_mode?, liveness?)Single voice sample (m4a, mp3, wav, webm, ogg). Same flat output contract as face — verdict, confidence, winktag, masked name. Liveness runs Wink's active phrase-matching check; a pre-recorded sample goes Red.
recognize_voices_in_directory(directory_path, recursive?, max_files?, liveness?)Desktop · shimBatch voice recognition. Same glob-and-aggregate pattern as the face batch, with bounded concurrency and a per-file summary.
request_biometric_auth(ttl_seconds?, user_hint_email?, callback_url?, force_wink_cloud?, display_title?, display_subtext?)LIVE biometric auth via WinkKey for an EXISTING user on-device. Returns a one-time URL plus an inline QR code — laptop users click, mobile users scan. WinkKey handles camera/mic capture, Yellow-case 2FA, cross-merchant consent, and passkey setup. The three display_* fields let the agent brand the screen (heading, subtitle, button label).
send_biometric_auth_email(email, lock_to_email?, ttl_seconds?, callback_url?, force_wink_cloud?, display_title?, display_subtext?)Remote auth for an EXISTING user off-device. WinkKey emails them a one-time sign-in link (SendGrid); the URL stays in the inbox only. Open by default — any Wink user with the link can complete it. Pass lock_to_email when the agent wants to enforce that one specific Wink account must complete (delivery and Wink-account emails are often different, so auto-locking misfires).
request_enrollment(ttl_seconds?, user_hint_email?, callback_url?, display_title?, display_subtext?)Generate a one-time enrollment LINK (URL + inline QR) for a NEW user to create their Wink identity. WinkKey captures face + profile on the user's device. NO prior auth required — this is the FIRST step for a new user, not a follow-on. Returns enroll_url + QR + 48h TTL (vs auth's 15 min). forceWinkCloud is implicit since passkey doesn't apply pre-enrollment. Pair with request_biometric_auth: this CREATES the user; that one signs an existing one in.
send_enrollment_email(email, lock_to_email?, ttl_seconds?, callback_url?, display_title?, display_subtext?)Email a one-time enrollment LINK to a NEW user. NO prior auth required. Open by default — recipient picks their Wink-account email at the start of the flow. Pass lock_to_email to bind the new account to a specific email at creation time (typical for invited-user onboarding). Default TTL ~48 hours so the recipient has time to read the message. Pair with send_biometric_auth_email: this creates a NEW Wink user; that one emails a sign-in link to an EXISTING one.
wait_for_biometric_auth(request_id, timeout_seconds?, pii_mode?)Block up to 55s waiting for a biometric auth request to complete. One call, server-side polling. Returns winktag + masked name + email when consumed, or timed_out=true if still pending. Preferred over check_biometric_auth for single-shot flows.
check_biometric_auth(request_id, pii_mode?)Non-blocking poll of a live auth request. One call = one poll. Useful when the agent wants to show intermediate progress to the user — otherwise prefer wait_for_biometric_auth.
cancel_biometric_auth(request_id)Cancel a pending auth or enrollment link — covers both kinds in one tool. Transitions the rid to status='failed' on WinkKey, which collapses any in-flight wait_for_biometric_auth to a terminal state. If the cancelled rid was the caller's active biometric session, that session is also cleared as a side effect. Idempotent (re-cancel is safe), no-op on already-CONSUMED rids (auth has already happened, can't undo). Use when a link was sent to the wrong email, an enrollment was misrouted, or the user wants to abort a long wait.
get_user_cards(request_id?)After a biometric auth completes, fetch the user's saved Wink cards via the vaulted Wink session WinkKey holds — no fresh face image required. Returns the same card shape as recognize_face_cards (default first, expired last). request_id is optional: if the agent already authed the user in this conversation, the server reuses that active session for up to 30 minutes of idle time. Both consume paths (passkey and wink_cloud) produce a valid Wink session, so cards normally return regardless of how the user authenticated.
get_user_addresses(request_id?)Same pattern as get_user_cards but for the user's saved billing + shipping addresses. Returns billing_addresses, shipping_addresses, default_billing, default_shipping, address_count. Both arrays sorted default-first. request_id optional — reuses the active session. Pairs with get_user_cards for full checkout context.
get_user_profile(request_id?)Read the authenticated user's Wink profile (winktag, first/last name, email, phone, age-verified status). Surfaces both a shaped {profile} field and the unmodified raw_profile, so the agent can fall back when Wink renames keys between deployments. profile.age_verified is true once the user has completed Wink's age-verification flow (Wink's isProfileVerified flag). request_id optional — reuses the active session.
check_age_verified(request_id?)Single-purpose check: has this user completed Wink's age-verification flow? Returns {age_verified, has_wink_session, winktag} where age_verified is true / false / null (null = Wink didn't surface the field on this deployment). Use as a pre-flight gate for age-restricted actions (alcohol, cannabis, 21+ checkouts). Same data also available inline on get_user_profile — pick this one when the agent only needs the boolean and wants to express the intent crisply.
update_user_profile(request_id?, first_name?, last_name?, email?, phone?, date_of_birth?, qc_token?)Patch any subset of editable profile fields. Sparse body — fields not passed are left untouched. Returns the freshly-read profile after the write so the agent can confirm what Wink stored. NOT for cards or addresses — those have their own tools. request_id optional.
add_user_address(request_id?, full_name, line1, line2?, city, state, zip, country?, phone?, type, custom_label?, is_default?)Save a new billing or shipping address to the user's Wink wallet. Phone is auto-filled from the user's Wink profile when omitted (Wink's API requires it). request_id optional — reuses the active session. Caveat: Wink doesn't expose an update API — to edit a saved address, add the corrected version then delete_user_address on the old id. No equivalent for cards: Wink's wallet API has no card update or delete.
delete_user_address(request_id?, address_id)Delete a saved address by id. Use as the second step of an edit-by-replace flow, or for general clean-up. request_id optional. Returns {ok, has_wink_session}.
generate_winkpin(request_id?)Trigger Wink to generate a fresh WinkPin and email it to the user out-of-band. The PIN itself NEVER reaches the agent or this MCP server's response — the agent only gets {ok, sent_to} so it can tell the user where to look. Use for cross-device confirmation, or any flow that needs a one-time code the user types into another surface. request_id optional.
validate_contact_no(phone)Pre-flight check: is this phone number already a Wink user? Uses merchant credentials — no biometric auth required. Returns {exists, raw}. exists is true/false, or null when Wink's response shape isn't recognized (raw exposed for inspection). Useful before send_biometric_auth_email to choose between sign-in and sign-up phrasing.
prepare_inline_checkout(kind?, product_label?, amount_cents?, lock_to_email?, force_wink_cloud?, ttl_seconds?)In-room checkout. No email arg — buyer is the chat user themselves. Returns the URL + a QR image content block (rendered inline by Claude Desktop, surfaced as a link by ChatGPT). The two-tool split exists because models over-asked for an 'optional' email arg in the unified tool — splitting eliminates the conditional ambiguity.
prepare_email_checkout(email, kind?, product_label?, amount_cents?, lock_to_email?, force_wink_cloud?, ttl_seconds?)Remote checkout. Email REQUIRED — link is delivered via SendGrid; the URL stays in the inbox. Pass lock_to_email when the agent wants to enforce that a specific Wink account must complete (delivery and Wink-account emails are often different). force_wink_cloud=true suppresses the passkey path on the verify screen — only set on explicit user request, not required for the wallet lookup.
wait_for_checkout(checkout_id, timeout_seconds?)Block waiting for a checkout session to reach a terminal state: confirmed, declined, or expired. Returns the user's chosen amount, card (token + last4 + issuer), and shipping address (or null for digital). Surfaces auth-side failures as terminal too — declined/no_wink_session, expired/auth_expired — so the agent never loops forever. Loop the tool if 55s isn't enough.
Session model: any tool that takes request_id? reuses the agent's most recent successful biometric auth automatically (30-minute idle TTL). One WinkKey flow per conversation; subsequent wallet, profile, and PIN ops just work.
Coming next: verify_id_document, recognize_from_video, authorize_payment.
Try it.
Plain English in, structured calls out. Below: how the agent translates common phrasings into tool sequences. Each card shows the prompt, what the agent does, and either the resolved args (single tool) or the chained tool calls (multi-step flows).
Authenticate someone
Open vs locked magic-link delivery. The delivery address is just where the email lands; locking the completion identity is opt-in via explicit "lock to" / "restrict to" phrasing.
"Authenticate alice@home.com via email."
Sends a magic link to alice@home.com. Anyone who opens it authenticates as their own Wink account (alice's mailbox and Wink-account emails may differ — keeps the flow forgiving).
- email:
- alice@home.com
- lock_to_email:
- (omitted)
"Authenticate alice@home.com by sending a link locked to this email."
Same delivery, but WinkKey enforces that the user completing the flow has alice@home.com on their Wink account. Anyone else gets user_mismatch.
- email:
- alice@home.com
- lock_to_email:
- alice@home.com
"Email a sign-in link to ops@team.com but only allow alex@acme.com to complete."
Delivery and identity addresses diverge. The team inbox receives the message; only Alex's Wink account can pass the user_mismatch check at completion.
- email:
- ops@team.com
- lock_to_email:
- alex@acme.com
Enroll a new user
Two onboarding tools — request_enrollment for an in-room user (URL + QR back), send_enrollment_email for a remote one (link delivered by email). Both create a brand-new Wink identity via face capture. The auth pair (request_biometric_auth / send_biometric_auth_email) signs in an EXISTING user; the enroll pair CREATES one. Pick by the user's intent — the two flows are mutually exclusive.
No prior auth required. Enrollment is the first step for a new user — they have nothing to sign into yet. The same wait_for_biometric_auth tool resolves both kinds; its kind field tells the agent which one just completed.
"Enroll me with Wink — set up a new Wink account."
In-room enrollment. QR + URL render inline; user scans with their phone, completes face capture and profile. The agent calls request_enrollment FIRST — no auth step in front of it. Active session is recorded on completion, so subsequent profile/wallet ops in the same turn need no rid.
- 1.request_enrollment() → rid + enroll_url + QR
- 2.wait_for_biometric_auth(rid) → {kind: 'enroll', winktag, …}
- 3.get_user_profile() → confirm what the new user picked
"Invite alice@acme.com to Wink."
Remote new-user onboarding. SendGrid emails the link; recipient opens it on their own device, completes enrollment. TTL defaults to 48 hours since recipients often delay acting on enrollment emails. Loop the wait — emails are read on human time.
- 1.send_enrollment_email({email: alice@acme.com}) → rid + sent_to
- 2.wait_for_biometric_auth(rid) → {kind: 'enroll', …} // loop on timeout
"Sign up bob@example.com — lock the new Wink account to that email and brand the screen 'Welcome to Acme'."
Identity-locked enrollment with a branded screen. lock_to_email pre-binds the new Wink account to bob@example.com so he can't pick a different email mid-flow. display_title / display_subtext customize WinkKey's heading and subtitle (also available on the auth pair).
- 1.send_enrollment_email({email: bob@example.com, lock_to_email: bob@example.com, display_title: 'Welcome to Acme', display_subtext: 'Quick face setup, then youre in'}) → rid
- 2.wait_for_biometric_auth(rid) → {kind: 'enroll', …}
"Wait, I sent that to the wrong email — cancel it and resend to alice@correct.com."
Cancellation works for both auth and enroll links. The cancelled rid moves to status='failed' on WinkKey, so any wait_for_biometric_auth still in flight resolves to a terminal state instead of stalling for the full TTL. Same tool also covers 'I sent the auth link to the wrong inbox' — works regardless of kind.
- 1.send_enrollment_email({email: alice@wrong.com}) → rid_old
- 2.cancel_biometric_auth({request_id: rid_old}) → {ok, status: 'failed'}
- 3.send_enrollment_email({email: alice@correct.com}) → rid_new
- 4.wait_for_biometric_auth(rid_new) → {kind: 'enroll', …}
Common pitfalls
- Don't pre-authenticate before enrolling. Enrollment CREATES the user — they have no identity to authenticate with yet. If the agent is in a stale active-session state and tries to "refresh auth before enrolling", it's misrouting. Call
request_enrollment/send_enrollment_emaildirectly. - "Enrollment link" ≠ "WinkPin". Both arrive by email, but they're different artifacts:
request_enrollment/send_enrollment_emailreturn a URL the user opens to create their identity.generate_winkpinreturns a 4-6 digit one-time code for an existing user. Never substitute one for the other.
Authenticate + get cards or addresses
The agent chains: kick off auth, block until the user completes, then call get_user_cards or get_user_addresses (or both). WinkKey vaults a fresh Wink access token at consume time, so wallet data returns server-to-server without any token ever touching the agent or chat. After the first auth in a conversation, subsequent wallet calls can OMIT the request_id entirely — the server reuses the active session for 30 minutes of idle time.
"Authenticate me with Wink and show my saved cards."
The user is at the same device as the agent. QR + URL render inline; user scans / clicks; cards come back automatically. Notice get_user_cards omits request_id — the server falls back to the just-completed session.
- 1.request_biometric_auth() → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.get_user_cards() → cards // rid reused from active session
"Email a sign-in link to alice@home.com and list her cards once she completes."
Remote user. Magic link goes to alice's inbox; agent blocks on the wait, then fetches cards using the auth event's vaulted token. Open delivery — alice authenticates as herself on her own device.
- 1.send_biometric_auth_email({email: alice@home.com}) → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.get_user_cards() → cards
"Ping jordan@example.com for their cards."
Same shape as 'via email' but the user phrasing is informal. The mobile router still picks send_biometric_auth_email because of the email + identity-fetch intent. Loops on wait_for_biometric_auth if the user takes longer than 55s.
- 1.send_biometric_auth_email({email: jordan@example.com}) → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.get_user_cards() → cards
"Authenticate alice@home.com via email and pull her default shipping address and a card to charge."
Same auth front-end as the email flow above, but the agent fans out to both wallet endpoints once auth is consumed. Both reads omit request_id — they reuse the same active session, no extra arg threading needed.
- 1.send_biometric_auth_email({email: alice@home.com}) → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.get_user_addresses() → addresses
- 4.get_user_cards() → cards
Build a checkout
A Stripe-style checkout page where the user picks card + shipping address (pre-selected to their defaults) and confirms an amount. The agent watches for the result via wait_for_checkout. Both auth paths (passkey and wink_cloud) produce a valid Wink session, so card/address pre-fill works either way. Add "force wink cloud" only when the user explicitly asks to skip the passkey shortcut.
"Build a checkout for alice@home.com — $42.50 for a coffee subscription."
Physical product (default kind), fixed price. The named recipient routes the agent to prepare_email_checkout (email is required there). Passkey path allowed — fastest UX for users with one set up.
- 1.prepare_email_checkout({email: alice@home.com, kind: physical, product_label: 'coffee subscription', amount_cents: 4250}) → checkout_id
- 2.wait_for_checkout(checkout_id) → {status: confirmed, amount, card, address}
"Build a high-security checkout for alice@home.com — $1,200 for a watch. Force wink cloud."
User-requested ceremony. force_wink_cloud=true suppresses the passkey button on WinkKey's verify screen, routing the buyer through a full Wink cloud sign-in. Both paths produce a valid session — this flag is purely a UX preference for high-trust ceremony, not a requirement for downstream wallet calls. Triggered by phrases like 'force wink cloud', 'no passkeys', 'enforce wink auth', 'high-security checkout'.
- 1.prepare_email_checkout({email: alice@home.com, amount_cents: 120000, force_wink_cloud: true}) → checkout_id
- 2.wait_for_checkout(checkout_id) → {status: confirmed, …}
"Build me a checkout for $15 — digital. Show me the QR."
In-room flow. No email mentioned → agent picks prepare_inline_checkout (no email arg at all, eliminating the model's habit of asking for one). kind='digital' hides the shipping picker. Returns URL + a QR image content block — rendered inline by Claude Desktop, surfaced as a link by ChatGPT.
- 1.prepare_inline_checkout({kind: digital, amount_cents: 1500}) → {auth_url, qr_url} + QR image
- 2.wait_for_checkout(checkout_id) → {status: confirmed, amount, card}
Manage saved addresses
Two surfaces for the same wallet writes: a direct add_user_address tool the agent calls conversationally, and an inline form on the checkout page (uncheck "Use my billing for shipping" → fill fields → leave "Save to my Wink profile" checked → Confirm). Wink doesn't expose an update API for either addresses or cards, so editing a saved row means add-new + delete_user_address the old id. Phone is auto-filled from the user's Wink profile when omitted — Wink's API requires it even though the field looks optional.
"Save a shipping address for me — Alex Kim, 999 Oak Ave, Austin TX 78701."
Agent collects the fields conversationally and posts in one call. Phone backfilled from the user's Wink profile. Returns the new address_id which subsequent get_user_addresses + prepare_email_checkout pick up automatically.
- 1.request_biometric_auth() → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.add_user_address({full_name, line1, …, type: shipping}) → {address_id}
"Build a $25 checkout for me, physical."
On the page, uncheck 'Use my billing for shipping' → form appears → fill it → leave 'Save to my Wink profile' checked → Confirm. The server saves the address to Wink (server-to-server) before recording the checkout intent. The address shows up in your wallet for next time.
- 1.prepare_inline_checkout({kind: physical, amount_cents: 2500}) → checkout_id
- 2.<page form: address fields + save_address: true>
- 3.wait_for_checkout(checkout_id) → {status: confirmed, amount, card, address}
"Update my shipping to 100 New St — replace the old Austin one."
Wink has no PUT/PATCH for addresses, so 'edit' is add-new + delete-old. Agent runs both tools in sequence; both omit request_id (active session reused).
- 1.add_user_address({…new fields…, type: shipping}) → {address_id: NEW}
- 2.delete_user_address({address_id: OLD}) → {ok: true}
Profile + account ops
Reads and writes against the user's Wink profile, plus the merchant-level account-existence check (no auth required) and the WinkPin generator (PIN delivered out-of-band by Wink — agent never sees the value). All session-aware tools below omit request_id and ride the active session.
"What's on my Wink profile?"
Pulls the shaped {winktag, first_name, last_name, email, phone} plus raw_profile (the full body Wink returned). The raw passthrough is a debug aid for when Wink renames a field between deployments and the shaped view comes back null.
- 1.request_biometric_auth() → rid
- 2.wait_for_biometric_auth(rid) → identity
- 3.get_user_profile() → {profile, raw_profile}
"Change my Wink email to alice@new.com and update my phone too."
Sparse PUT — only the fields the agent passes get written. The server reads the profile back after the write and returns the fresh state in the same response, so the agent confirms what landed without a separate get_user_profile call.
- 1.update_user_profile({email: alice@new.com, phone: '+1...'}) → {ok, updated_fields, profile}
"Send me a Wink PIN so I can complete checkout on my laptop."
Wink generates the PIN and emails it to the user's profile address. The MCP server discards Wink's response body (which contains the PIN) and returns only {ok, sent_to: <email>}. The agent tells the user to check their inbox; nobody in the chat surface ever sees the digits.
- 1.generate_winkpin() → {ok: true, sent_to: 'a***@example.com'}
"Does +1 415 555 1212 already have a Wink account?"
Merchant-level check — no biometric auth required. Useful as a pre-flight before send_biometric_auth_email so the agent can phrase the prompt as 'sign in' vs 'create an account'. Returns {exists, raw}; raw is exposed when Wink's response shape isn't recognized so the agent can fall back gracefully.
- 1.validate_contact_no({phone: '+14155551212'}) → {exists: true}
Routing cheat sheet: request_biometric_auth / send_biometric_auth_email for EXISTING users (sign-in); request_enrollment / send_enrollment_email for NEW users (sign-up). On-device variant when the user is at the same machine; email variant when remote. validate_contact_no before either, when the agent needs to know whether to phrase the prompt as sign-in vs sign-up. After auth completes, the active-session model means every wallet/profile tool ( get_user_cards, get_user_addresses, get_user_profile, update_user_profile, add_user_address, delete_user_address, generate_winkpin) can omit request_id for the next hour. prepare_inline_checkout for in-room buyers, prepare_email_checkout when sending to a named recipient — both pair with wait_for_checkout. Add "force wink cloud" only on explicit user request — both consume paths produce a valid session, so it's a UX choice now, not a requirement. No card writes — Wink's wallet API doesn't expose them.
Get access.
Beta is open. Submit the form and you'll get your bearer token on the next screen, along with a one-click tarball download and the Claude Desktop config snippet.
- Token is yours — save it. It's shown once.
- No email verification for now — treat it like a beta keycard.
- We can revoke individual tokens instantly without affecting anyone else.