# @worldcitisim/mcp-esim MCP server that lets Claude and other MCP-compatible agents search and buy WorldCitiSim eSIM plans. Wraps `https://shop.worldcitisim.com/wp-json/esim/v1/*`. ## Install ### Claude Desktop / Claude Code ```bash claude mcp add --scope user wcs-esim npx -y @worldcitisim/mcp-esim ``` Or paste into `~/Library/Application Support/Claude/claude_desktop_config.json`: ```json { "mcpServers": { "worldcitisim-esim": { "command": "npx", "args": ["-y", "@worldcitisim/mcp-esim"] } } } ``` ### Cursor / Windsurf / other MCP clients Same shape — `command: "npx", args: ["-y", "@worldcitisim/mcp-esim"]`. ### ChatGPT Developer Mode Settings → Developer Mode → Add MCP server → same npx command. ## Tools exposed | Tool | Purpose | |---|---| | `esim_search_plans` | Filter catalog by country / region / days / GB. Returns matching plans with their first 5 variations. | | `esim_get_plan` | Fetch one plan by slug with all variations. | | `esim_create_order` | Create a pending order. `payment_method: "stripe"` (default) returns a Stripe Checkout URL for the user to tap; `payment_method: "btc"` returns an on-chain `btc` block (address + amount + QR) to show the user directly. Both return an `order_token` for polling. | | `esim_check_order` | Poll an order's status. Returns activation data (ICCID, QR URL) once payment clears. | ## Example interaction ``` User: I'm going to Japan for 10 days, what eSIM should I get? Claude calls: esim_search_plans({ country: "japan", min_days: 7, max_days: 15 }) → returns matching plans with variations priced and in stock. Claude picks the best match, presents 2–3 options to the user. User: the 10GB one Claude: "Pay by card or Bitcoin?" User: card Claude calls: esim_create_order({ email: "user@example.com", variation_id: 44941 }) → returns { order_id, order_token, payment_link_url }. Claude: "Tap this link to pay: . You'll get the eSIM QR in your email within ~30 seconds." User pays. Claude optionally polls esim_check_order until status=completed. ``` For Bitcoin, Claude calls `esim_create_order({ ..., payment_method: "btc" })` and gets back a `btc` block — `{ address, sats_amount, btc_amount, qr_data_uri, expires_at }` — which it shows the user to pay from any on-chain wallet. No redirect. If BTC is declined for a small order during a network-fee spike, the call returns a `btc_unavailable` error and Claude offers card instead. Either way, `esim_check_order` polls until `status=completed`. ## Environment - `WCS_ESIM_API_BASE` — override the API base URL. Default: `https://shop.worldcitisim.com/wp-json/esim/v1`. ## Runtime - Node 20.11+ (for native fetch + ESM). - No secrets. No Stripe credentials touch this process. Payment happens on Stripe's hosted checkout page; the MCP just hands the agent the URL. - Catalog is client-side cached 5 minutes + ETag-aware; multiple search calls within a minute don't hit the network. ## Development ```bash npm install npm run dev # stdio MCP server on this terminal npm run build # compile to dist/ ``` Point a Claude Code session at the local dev build: ```bash claude mcp add wcs-esim-dev node "$(pwd)/dist/index.js" ``` ## Related - [WorldCitiSim](https://worldcitisim.com) — eSIM travel service for 193 countries. - [WorldCitiSim eSIM API](https://shop.worldcitisim.com/wp-json/esim/v1/openapi.json) — OpenAPI 3.1 spec the server wraps. ## License MIT