@latticepay/mcp
v0.2.0
Published
Model Context Protocol server for integrating LatticePay's checkout-widget, merchant-console-widget, and transaction-widget — agent-friendly tools, prompts, and codegen for developer integrators.
Readme
@latticepay/mcp
Model Context Protocol server for integrating the LatticePay checkout-widget, merchant-console-widget, and transaction-widget. Drop it into your AI-aware editor (Claude Code, Cursor, Windsurf, Cline, Continue, Gemini CLI) and your agent can scaffold backend mint routes, frontend embeds, webhook receivers, Apple Pay domain files, Playwright tests, and a production-cutover checklist — and validate the result against the LatticePay integrator API.
- 18 tools (12 offline codegen + 6 live against
api.latticepay.io) - 10 prompts (1 persona + 9 phase-specific)
- 6 frontend frameworks · 5 backend stacks · 5 PSPs
- stdio transport — no hosted endpoint required, no telemetry
- BYO credentials — your LatticePay OAuth client id/secret stay on your machine; they're exchanged for a short-lived, cached Bearer token
Install
The server is published as @latticepay/mcp. npx -y @latticepay/mcp fetches and runs it on demand — no global install needed. The credentials you set in the client's env block are passed to the server process at startup.
Claude Code (.mcp.json)
{
"mcpServers": {
"lattice": {
"command": "npx",
"args": ["-y", "@latticepay/mcp"],
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
}
}Cursor (.cursor/mcp.json)
{
"mcpServers": {
"lattice": {
"command": "npx",
"args": ["-y", "@latticepay/mcp"],
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
}
}Windsurf (~/.codeium/windsurf/mcp_config.json)
{
"mcpServers": {
"lattice": {
"command": "npx",
"args": ["-y", "@latticepay/mcp"],
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
}
}Cline (VS Code → Cline settings → MCP servers)
{
"mcpServers": {
"lattice": {
"command": "npx",
"args": ["-y", "@latticepay/mcp"],
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
}
}Continue (~/.continue/config.json)
{
"experimental": {
"modelContextProtocolServers": [
{
"transport": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@latticepay/mcp"]
},
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
]
}
}Gemini CLI (~/.gemini/mcp.json)
{
"mcpServers": {
"lattice": {
"command": "npx",
"args": ["-y", "@latticepay/mcp"],
"env": {
"LATTICE_CLIENT_ID": "<paste-your-oauth-client-id>",
"LATTICE_CLIENT_SECRET": "<paste-your-oauth-client-secret>",
"LATTICE_API_BASE_URL": "https://api.latticepay.io"
}
}
}
}Quick start
Once installed, ask your agent:
"Help me embed the LatticePay checkout widget in my Next.js app. The merchant is
<merchant-uuid>, amount 49.99 USD."
A well-behaved agent should:
- Call
lattice_get_integration_overview(the bootstrap tool — returns persona + phase rules inline so tool-only clients can read them). - Call
lattice_list_merchantsto confirm the merchant UUID resolves under your integrator. - Call
lattice_generate_token_mint_endpointfornode-nextjs-route+ scopecheckout. - Call
lattice_generate_embed_snippetfornextjs-app+ widgetcheckout-widget. - Call
lattice_generate_event_handlerfor thelatticeCallback. - Offer to run
lattice_lint_integration_codeover the pasted result andlattice_prod_cutover_checklistwhen you're ready to ship.
(Point the server at the sandbox — LATTICE_API_BASE_URL=https://api.sandbox.latticepay.io — and lattice_mint_test_token and lattice_simulate_payment exercise the full mint-and-pay flow end-to-end. Against production they return a structured sandbox-required error.)
Tools
Offline codegen (no network, no credentials required)
| Tool | What it does |
|---|---|
| lattice_get_integration_overview | Bootstrap — returns recommended widgets, integration sequence, and the persona/phase rules inline. |
| lattice_generate_token_mint_endpoint | Backend mint route across 5 stacks (Express, Next.js route, FastAPI, Spring, net/http). |
| lattice_generate_embed_snippet | Frontend widget embed across 6 frameworks (React, Next.js app, Vue 3, Angular 17, Svelte, vanilla HTML). |
| lattice_generate_event_handler | Framework-idiomatic latticeCallback with success / failure / error branches. |
| lattice_generate_apple_pay_domain | .well-known/apple-developer-merchantid-domain-association body + hosting instructions for 6 hosting targets. |
| lattice_generate_webhook_handler | HMAC-SHA256 webhook receiver across 5 backend stacks with constant-time signature compare and replay protection. |
| lattice_generate_e2e_test | Playwright (default) or Cypress checkout-flow spec. |
| lattice_lint_integration_code | Static rules for 7 known anti-patterns (hard-coded token, missing callback, mount mismatch, dev URL in prod, secret leaked client-side, missing webhook HMAC, non-constant-time compare). |
| lattice_compare_integration_configs | Diffs two configs; flags expected vs unexpected divergence; redacts secret-shaped values. |
| lattice_prod_cutover_checklist | Stack-tailored checklist (frontend × backend × Apple Pay × webhook). |
| lattice_decode_session_token | Local JWT decode + expiry / scope inspection (no signature verification). |
| lattice_decode_error | Catalog-backed diagnosis for runtime/widget errors from the Phase 8 anti-pattern table. |
Live (require LatticePay OAuth credentials)
| Tool | Endpoint / behavior | Status |
|---|---|---|
| lattice_list_merchants | Paginated walk of GET /v1/merchants under the integrator owning the OAuth client. | ✅ available |
| lattice_list_supported_psps | Static PSP catalog (Stripe, Braintree, PayPal, Klarna, Coinbase). | ✅ available |
| lattice_inspect_session_token | Local decode + expiry check. Does NOT verify the JWT signature; JWKS-based verification ships in a future release. | ✅ available |
| lattice_mint_test_token | Real POST /v1/auth/merchant-session round-trip + auto-decode of the returned JWT. | 🧪 sandbox |
| lattice_simulate_payment | Real mint + synthesized complete event keyed off the test card's expected outcome. | 🧪 sandbox |
| lattice_get_test_credentials | Curated PSP test cards with expectedOutcome annotations. | 🧪 sandbox |
Live tools authenticate with OAuth2 client-credentials: the LATTICE_CLIENT_ID / LATTICE_CLIENT_SECRET pair is exchanged against the Auth0 token endpoint for a short-lived Bearer token that is cached in memory and reused until near-expiry (Auth0 meters issuance against a low monthly quota). The token endpoint and audience are derived from LATTICE_API_BASE_URL — production uses the production Auth0 tenant, and https://api.sandbox.latticepay.io auto-selects the sandbox tenant + audience — so a single base-URL switch moves the whole auth flow between environments. Override LATTICE_OAUTH_TOKEN_URL / LATTICE_OAUTH_AUDIENCE only to point at a non-standard tenant. Live tools fail closed when LATTICE_CLIENT_ID / LATTICE_CLIENT_SECRET are unset — the error response carries copy-paste mcpServers config blocks for Claude Code, Cursor, and Windsurf.
The three write-side tools (lattice_mint_test_token, lattice_simulate_payment, lattice_get_test_credentials) are gated to the LatticePay sandbox environment. Set LATTICE_API_BASE_URL=https://api.sandbox.latticepay.io and they auto-enable; against production they return a structured sandbox-required error. Advanced users running their own internal test merchant against production can re-enable lattice_mint_test_token and lattice_simulate_payment with LATTICE_ALLOW_PROD_MINT=1 (each invocation emits a stderr banner naming the merchant, amount, and currency); lattice_get_test_credentials stays gated even with the flag because PSP test cards do not work in production.
Environments
LatticePay exposes two audience-scoped API edges per environment:
- Customer edge (
api.{env}.latticepay.io) — server-to-server calls authenticated with your OAuth2 Bearer token: token minting (POST /v1/auth/merchant-session) and merchant reads (GET /v1/merchants). This is what the MCP's live tools call. - Widget edge (
widgets-api.{env}.latticepay.io) — browser widget traffic authenticated with the short-lived session token. This is the host your CSPconnect-srcmust allow; the generated embed snippets target it automatically.
| | Production (default) | Sandbox |
|---|---|---|
| LATTICE_API_BASE_URL | https://api.latticepay.io | https://api.sandbox.latticepay.io |
| Widget edge (CSP connect-src) | https://widgets-api.latticepay.io | https://widgets-api.sandbox.latticepay.io |
| Widget CDN (sdk) | https://sdk.latticepay.io | https://sdk.sandbox.latticepay.io |
Switching environments is a single variable: set LATTICE_API_BASE_URL and the MCP derives the matching Auth0 tenant, audience, widget edge, and CDN host. Sandbox uses the same OAuth2 client-credentials model as production.
Prompts
persona-rules— cross-cutting rules every integration session should obey (read tool descriptions before calling, never invent merchant IDs, redact secrets, etc).phase-0-discoverthroughphase-8-troubleshoot— phase-specific playbooks an agent can pull when the user asks about a specific stage of the journey.
Security model
- stdout is reserved for MCP JSON-RPC. All diagnostics go to stderr. Never
console.logfrom a tool — it would corrupt the protocol stream. - No credentials reach the browser. Every backend codegen template documents this; the lint tool catches it as
api-secret-client-side. - Secrets only in the MCP client's env. The server reads
LATTICE_CLIENT_ID/LATTICE_CLIENT_SECRETat startup and exchanges them for a Bearer token held only in memory; nothing is persisted to disk by the server itself. - Tool descriptions are the only routing signal. Each is ≥120 chars with what / when / required-args / next-tool structure, enforced by snapshot test.
See ARCHITECTURE.md for the full design.
Versioning
Pre-1.0: minor versions can introduce breaking changes. After 1.0, semver. See CHANGELOG.md.
License
Apache-2.0
