Reference app demonstrating VGS Agentic Tokens API integration flows for Visa, Mastercard, and Amex.
You need a VGS Client ID and Client Secret to run this app. Follow the Authentication guide to generate your credentials.
cp .env.example .env
# Set VGS_CLIENT_ID and VGS_CLIENT_SECRET (see Prerequisites)
docker compose up --buildOpen https://localhost:4200 (accept the self-signed certificate warning).
- Caddy (port 4200) — serves the static frontend over HTTPS
- Server (port 3000) — Node.js API proxy that authenticates with VGS and forwards requests
How the cardholder is verified depends on your vault's configuration, and the app finds out
from the API: the enroll response (step 2) reports cardholder_verification and
agentic_enrollment_required, and the remaining steps follow from those two fields. Nothing to
configure — the header shows which flow was detected.
Passkey (FIDO) — cardholder_verification: "passkey":
- Create Card — creates a sandbox test card
- Enroll Token — provisions the card for agentic payments
- Device Binding — FIDO/OTP authentication via the VgsAgenticAuth library (Visa iframe)
- Create Intent — creates a spending authorization with mandates, using the
assurance_datafrom step 3 - Get Cryptogram — retrieves DPAN + cryptogram for payment
- Confirm Transaction — reports the payment outcome back to the intent
Cardholder ID&V — cardholder_verification: "otp", for passkey-exempt vaults. No iframe, no passkey, no assurance_data:
- Create Card
- Enroll Token
- Cardholder Verification (ID&V) — fetch verification options, send a one-time code, submit it
- Complete Enrollment — finishes enrolling the token; required after verification and before any intent
- Create Intent — no
assurance_datafield - Get Cryptogram
- Confirm Transaction
A vault may also report cardholder_verification: "none" — no verification step at all — in
which case the app goes straight from enrollment to creating an intent.
Both flows above are Visa. Mastercard runs Create Card → Enroll Token → Checkout Cryptogram. Amex runs Create Card → Enroll Token → Get Payment Credential through the Amex ACE endpoint. Neither uses cardholder verification, intents, or confirmation.
Each step auto-populates IDs into the next step.
The entire client side of the ID&V flow lives in one file — client-react/src/idv.ts — as four
plain fetch calls with no library dependency. If you're implementing this flow yourself, read
that file; the components around it are just forms.
Sandbox tip: When prompted for a one-time code, use
456789— it is always accepted in sandbox.
| Variable | Default | Description |
|---|---|---|
VGS_CLIENT_ID |
(required) | OAuth client ID (how to get one) |
VGS_CLIENT_SECRET |
(required) | OAuth client secret |
VGS_API_URL |
https://gw-01-sandbox.vgsapi.com |
Agentic Tokens API base URL |
VGS_CMP_API_URL |
https://sandbox.vgsapi.com |
Card Management Platform (CMP) API base URL |
PORT |
3000 |
Server port |
| Sandbox | Live | |
|---|---|---|
VGS_API_URL |
https://gw-01-sandbox.vgsapi.com |
https://gw-01-live.vgsapi.com |
VGS_CMP_API_URL |
https://sandbox.vgsapi.com |
https://vgsapi.com |
The repo is set up to deploy as a Netlify site: the React build is served as static assets and the Express proxy is replaced by Netlify Functions that share the same VGS client (server/vgs.js).
- In Netlify, Add new site → Import from Git and connect this repo.
- Build settings are picked up from
netlify.toml— no overrides needed. - Set Site settings → Environment variables:
VGS_CLIENT_ID,VGS_CLIENT_SECRET(required), plus any optional VGS URLs / vault settings. - Branches → Production branch =
main. Every push tomaintriggers a fresh deploy.
Docker (docker compose up) still works as before. To run the Netlify build locally instead:
npm install -g netlify-cli
netlify devnetlify dev serves the Vite frontend and emulates the Functions, so the local environment matches production.
On top of the Agentic Tokens building blocks, the repo ships a quick-start demo of a fictional dev-tool startup called Vellum. It lets any AI agent connected via MCP:
- render a marketing landing page preview from a small JSON params object,
- attempt to publish — the server returns
payment_requiredfor a one-time $5 hosting charge, - on approval, run the existing VGS device-binding flow (TouchID / FIDO / OTP) and capture a cryptogram-backed payment,
- retry
publish_sitewith the same params — site becomes live athttps://<your-site>/s/<siteId>.
The HTML is rendered by the MCP server from a fixed template. The LLM only supplies the structured params that fill the page.
Two transports ship together:
- HTTP — deployed at
/mcpvianetlify/functions/mcp.js. Connect a remote MCP client tohttps://<your-site>/mcp— no local install. - stdio —
node mcp-server/src/index.jsfor desktop MCP clients. Desktop mode can auto-open browser tabs at the right moments. - Codex CLI stdio —
npm run mcp:codexstarts the same MCP server with URL handoff: it writes local previews to/tmp, opens the preview when possible, returns browser-flow URLs, and does not block waiting for GUI browser steps.
Codex CLI users can install the GitHub-hosted server directly:
codex mcp add vellum \
--env AGENTIC_CLIENT_MODE=codex-cli \
--env AGENTIC_APP_BASE_URL=https://vgs-agentic-tokens.netlify.app \
-- npx -y github:vgs-samples/agentic-tokensRecommended test prompt:
Use the Vellum MCP server for this. Create a marketing landing page for Acme Coffee Co — premium coffee with a subscription. Call create_marketing_site first and show me the preview URL.
See mcp-server/README.md for the demo script, the tool contract, and copy-paste configs.