GUIDE · MCP SERVER

Walletap is the agent-ready wallet platform.

Wire Walletap into Claude, Cursor, or any MCP-aware tool and your AI can build, issue, update and measure wallet passes — through plain conversation. No code, no API calls to wire up, no separate dashboard to learn.

Walletap was the first wallet platform to ship a Model Context Protocol server, and it's still the only one. The package is open source at github.com/walletap/walletap-mcp, published on npm as @walletap/mcp-server, and exposes every Walletap REST endpoint as a typed MCP tool. If you can describe what you want, you can build it, send it, or measure it.

Capabilities

What it can do

Four capability areas, mapped directly to Walletap's public API. Every tool is described to the AI so it can pick the right one for any request you make.

Template creation

Walletap signs every pass for you, so the agent doesn't need an Apple Developer account or certificates. Templates are created, deep-merged or deleted by name; image fields accept a public URL and the agent uploads it through upload_file_from_url automatically.

Create a loyalty template for "Aurora Coffee Co." with an 8-stamp card, black background and our logo at https://acme.co/logo.png.
Add a "Tier" field to the VIP membership template — populate it from customFields.tier on each issued pass.

Pass issuance

The agent reads the template's field ids, maps them to templateFields / customFields at issuance, and delivers the pass by email, SMS, or returns the Add-to-Wallet links. Batch issuance up to 10 passes per call.

Issue a VIP pass to ana@example.com with 1,200 points.
Send a coffee stamp card to +385 91 234 5678 with one stamp already collected.

Updates & push

Patch a single pass and Walletap propagates the change to Apple, Google and Huawei Wallets automatically. Per-template push notifications fan out to every active pass; the agent can write the message inline.

Add a stamp to Marko's coffee card and notify him.
Push a "Doors open at 19:00" notification to every pass holder of the Stellar Echoes event template.

Reads & analytics

The agent can list, fetch and inspect templates, passes, files, locations, readers and sub-accounts. Read-only tools are clearly marked so the agent never accidentally mutates state when you ask a question.

List all templates I have under the loyalty type.
Fetch the pass for member 8821-447-019 — what tier are they on?
Show me everything I uploaded to the file store this month.

Real example

A walkthrough

The owner of Aurora Coffee Co. opens Claude and types a single prompt:

Set up a loyalty card for Aurora Coffee Co.. Eight stamps to a free latte. Use our logo at https://tucanocoffee.com/brand/logo.png. Then issue one to marko@example.com with 2 stamps already collected.

The agent, via the Walletap MCP server, does this end to end:

  1. Calls upload_file_from_url with the logo URL → receives a file_… id with 1×/2×/3× variants.
  2. Calls create_template with { name: "Aurora Coffee Co.", type: "loyalty", pass: { backgroundColor: "#0E0E0E", logo: { fileId: "file_…" }, useStampCollection: true, stampCount: 8 } }.
  3. Calls create_pass with the new templateId, passing customFields.collectedStamps = 2 and the recipient's email.
  4. Reports back: template id, pass id, and the Apple / Google / Huawei wallet links.

Total elapsed time: under thirty seconds, no dashboard clicks, no API code written. The shop owner reads the result and the customer's phone receives the pass.

Two minutes

Connect to your AI

The recommended path is the hosted MCP server at https://mcp.walletap.io. Authentication is OAuth — first call walks you through Walletap sign-in and consent. No install, no local config. Pick your client below.

Claude · one click

Click the button — claude.ai opens with name + URL pre-filled. Review, confirm, sign in to Walletap, approve. Then ask Claude: “list my Walletap templates”.

Add to Claude →

Cursor · one click

Click below — cursor.com hands off to the Cursor app, which opens the MCP settings page with the Walletap server pre-filled. Click Install, sign in, approve.

Add to Cursor →

ChatGPT · Apps (developer mode)

ChatGPT now uses Apps (the Apps SDK) — they replace the older Connectors / Plugins flow. To connect Walletap as a personal app you first turn on developer mode, then add the MCP server URL:

  1. Open chatgpt.com, go to Settings → Apps & Connectors → Advanced settings and toggle Developer mode on.
  2. Back in Settings → Apps & Connectors, click Create.
  3. Name: Walletap. Description: “Issue Apple & Google Wallet passes.” URL: https://mcp.walletap.io.
  4. Save → sign in to Walletap on the OAuth popup → approve.
  5. In a new chat, click the + button by the composer → More, pick Walletap. Write tools (create_template, create_pass…) will ask for confirmation the first time you use them.

This adds Walletap as a private app for your account only. For organization-wide or public availability, submit Walletap through the OpenAI Apps dashboard.

Codex CLI · TOML config

OpenAI's Codex CLI reads MCP servers from ~/.codex/config.toml:

# ~/.codex/config.toml
[mcp_servers.walletap]
type = "http"
url  = "https://mcp.walletap.io"

Gemini · programmatic

Google AI Studio and the Gemini API support remote MCP servers, but there is no point-and-click install today — you wire it up via the Gemini SDK plus the MCP TypeScript client. Authenticate Walletap with an API key from app.walletap.io → Settings → API keys:

// Gemini SDK + MCP TypeScript client — connect once, expose every Walletap
// tool as a Gemini tool call. Auth is via Walletap API key (no UI step yet).
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
import { GoogleGenAI } from "@google/genai";

const transport = new StreamableHTTPClientTransport(
  new URL("https://mcp.walletap.io"),
  { requestInit: { headers: { "X-API-Key": process.env.WALLETAP_API_KEY } } }
);
const mcp = new Client({ name: "gemini-walletap", version: "0.1.0" });
await mcp.connect(transport);
const { tools } = await mcp.listTools();

const ai = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const chat = ai.chats.create({
  model: "gemini-2.5-pro",
  config: { tools: [{ functionDeclarations: tools.map(t => ({
    name: t.name, description: t.description, parameters: t.inputSchema,
  })) }] },
});

Local · stdio fallback

For clients that don't yet speak remote MCP over OAuth — Claude Desktop, Continue, Cline, Zed, custom integrations — run the server locally via npx. The same config works in any MCP-aware tool that accepts a stdio command:

{
  "mcpServers": {
    "walletap": {
      "command": "npx",
      "args": ["-y", "@walletap/mcp-server"],
      "env": {
        "WALLETAP_API_KEY": "wtap_sk_..."
      }
    }
  }
}

Grab the API key from app.walletap.io → Settings → API keys.

When things go sideways

Troubleshooting

The most common stumbles, in rough order of how often they come up. If none of these match, email support@walletap.io with the error message and which client you're using.

Claude shows “Cannot connect” or “Failed to connect” after authorize

Cause — Stale OAuth state from a previous beta build, or the connector URL was added with a wrong path.

Fix — Remove the connector from Claude → Settings → Connectors, then re-add it using exactly https://mcp.walletap.io (no trailing slash, no /mcp suffix). Re-authorize. The redirect lands you back in Claude with the connector listed as Connected.

OAuth popup opens, you sign in, then the popup closes but nothing happens

Cause — The browser blocked a popup-from-popup (Claude opened the authorize window, and Google sign-in tries to open a second popup inside it).

Fix — The server auto-falls-back to a redirect flow — close any leftover windows, click “Continue with Google” again. The redirect happens inside the existing authorize window and returns Claude to the consent screen. Email/password sign-in works regardless of popup-blocker settings.

“Insufficient OAuth scope for this tool”

Cause — You authorized with a narrower scope than the tool requires. Read-only scope can call list_*, get_*, search_*, export_*, translate_*; write scope is required for create_*, update_*, delete_*, upload_*; notify scope is required for notify_pass and send_template_notification.

Fix — Disconnect the connector and re-authorize, leaving all three scopes ticked on the consent screen. Claude does not currently expose a per-tool scope picker — the consent screen at /authorize is the one place granular scopes are chosen.

Pass created successfully but the customer never received the email or SMS

Cause — The pass payload was missing the recipient address inside the per-pass object, or sendToEmail / sendToPhone was set to false at the top level.

Fix — Email and phone live inside each pass object in the passes array (one per recipient). sendToEmail and sendToPhone are the global on/off flags. If you used the LLM to draft the call and the recipient ended up only at the top level, the SMS/email pipeline didn’t fire — re-issue the pass with the contact inside passes[0].

“Rate limit exceeded” (HTTP 429)

Cause — 60 requests per minute per access token. Bursting through dozens of pass creations or fan-out notifications hits the limit fast.

Fix — Pace the calls — wait for the RateLimit-Reset header value (seconds until the window resets) before the next call. For one-off bulk imports, prefer the dashboard or the API directly (the limit is per-MCP-token, not per-account).

Template created but the pass shows “Walletap” as the brand or has the default dark-blue background

Cause — The template was created without a logo image or without custom backgroundColor / foregroundColor / labelColor in the pass design.

Fix — Update the template with upload_file_from_url (purpose: template_logo) and update_template setting the pass JSON with your brand colors. Pair this MCP with the Walletap Pass Designer skill (github.com/walletap/walletap-skill) — it teaches Claude to ask for colors and logo up front and pick brand-coherent defaults when the user is vague.

“Origin not allowed” 403

Cause — A browser-based client called the MCP from an origin that isn’t in the allowlist. Claude.ai, Claude Desktop, and Cursor are all allowed; custom web clients on other domains are not.

Fix — Connect from one of the supported clients, or run a local stdio bridge via npx @walletap/mcp-server which sidesteps the CORS check entirely.

Tool call returns the right data but the LLM keeps re-fetching it on every turn

Cause — Claude doesn’t cache MCP tool responses across turns — that’s by design. The MCP doesn’t expose static resources because all reads go through scope-gated tools.

Fix — If a piece of context (template id, pass id) will be referenced repeatedly in the same conversation, tell Claude to keep it in mind explicitly — that lives in conversation memory, not the connector.

The agent era

Why it matters

Building wallet passes used to require a developer, a designer, a marketer, and a project manager working through three vendors and an Apple Developer membership. With MCP, the marketer talks to the agent and ships in an afternoon. The platform stops being a UI you learn and starts being a system you describe.

Walletap was built around an API-first contract from day one — the MCP server is a natural extension of that. Every endpoint is exposed; every tool is typed; every change is auditable. We ship the same machinery the dashboard uses, just spoken instead of clicked.

Try it.

Get an API key, install the server, and start a conversation. If you run into anything, email support@walletap.io.

Get an API key
Walletap is the agent-ready wallet platform — Walletap Documentation | Walletap