@quackai/q402-mcp 0.8.35 → 0.8.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +9 -9
  2. package/dist/index.js +43 -25
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,15 +1,15 @@
1
1
  # @quackai/q402-mcp
2
2
 
3
- > MCP server for Q402 — gasless USDC, USDT, and RLUSD payments across 10 EVM chains, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.
3
+ > MCP server for Q402 — gasless USDC, USDT, and RLUSD payments across 11 EVM chains, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.
4
4
 
5
5
  [![npm](https://img.shields.io/npm/v/@quackai/q402-mcp.svg)](https://www.npmjs.com/package/@quackai/q402-mcp)
6
6
  [![license](https://img.shields.io/npm/l/@quackai/q402-mcp.svg)](./LICENSE)
7
7
 
8
8
  > **Free trial available (through 2026-06-30)** — 2,000 gasless transactions on BNB Chain (USDC + USDT), 30-day window, no card. One wallet signature: <https://q402.quackai.ai>.
9
9
  >
10
- > **Trial-scope policy:** API keys minted under the free-trial program (`plan: "trial"`) are restricted to BNB Chain with USDC/USDT — server-side enforcement, returns `403 TRIAL_BNB_ONLY` otherwise. **Paid API keys see the full 10-chain matrix at all times.**
10
+ > **Trial-scope policy:** API keys minted under the free-trial program (`plan: "trial"`) are restricted to BNB Chain with USDC/USDT — server-side enforcement, returns `403 TRIAL_BNB_ONLY` otherwise. **Paid API keys see the full 11-chain matrix at all times.**
11
11
 
12
- Quote → route → (optional) settle stablecoin payments across 10 EVM chains, from any MCP client. Recipient gets the full amount; sender pays $0 gas via [Q402](https://q402.quackai.ai)'s EIP-7702 relayer.
12
+ Quote → route → (optional) settle stablecoin payments across 11 EVM chains, from any MCP client. Recipient gets the full amount; sender pays $0 gas via [Q402](https://q402.quackai.ai)'s EIP-7702 relayer.
13
13
 
14
14
  ---
15
15
 
@@ -99,7 +99,7 @@ Create `~/.q402/mcp.env` yourself with the template below. Live mode only flips
99
99
 
100
100
  # ── API key (pick one or both for auto-routing) ──
101
101
  Q402_TRIAL_API_KEY= # Free Trial, BNB only (from /event)
102
- Q402_MULTICHAIN_API_KEY= # Paid Multichain, all 10 chains (from /payment)
102
+ Q402_MULTICHAIN_API_KEY= # Paid Multichain, all 11 chains (from /payment)
103
103
 
104
104
  # ── Signing path — pick ONE of Mode A / B / C ──
105
105
  # Mode A: your MetaMask EOA's hex private key.
@@ -165,7 +165,7 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
165
165
 
166
166
  `q402_quote` works with zero configuration — no API key, no private key, no env file. Ask:
167
167
 
168
- > *"Compare gas costs to send 50 USDC to vitalik.eth across all 10 Q402 chains."*
168
+ > *"Compare gas costs to send 50 USDC to vitalik.eth across all 11 Q402 chains."*
169
169
 
170
170
  ---
171
171
 
@@ -226,12 +226,12 @@ Template `q402_doctor` writes to `~/.q402/mcp.env`:
226
226
  # ── API key — fill ONE (or both for auto-routing) ──
227
227
  # Auto-routing (same for q402_pay AND q402_batch_pay):
228
228
  # chain="bnb" + Q402_TRIAL_API_KEY set → Trial (free sponsored)
229
- # anything else → Multichain (paid 10-chain)
229
+ # anything else → Multichain (paid 11-chain)
230
230
  # Batch ambiguity: 6+ recipient BNB batch with Trial set returns
231
231
  # status="ambiguous" instead of executing — agent asks user to pick.
232
232
  # Override per call with keyScope: "auto" | "trial" | "multichain".
233
233
  Q402_TRIAL_API_KEY= # BNB-only sponsored Trial key (from /event)
234
- Q402_MULTICHAIN_API_KEY= # paid 10-chain key (per-chain Gas Tank)
234
+ Q402_MULTICHAIN_API_KEY= # paid 11-chain key (per-chain Gas Tank)
235
235
 
236
236
  # ── Signing path — pick ONE of Mode A / B / C ──
237
237
  Q402_PRIVATE_KEY= # Mode A: real EOA pk (0x + 64 hex)
@@ -269,7 +269,7 @@ Combined with `confirm: true` + live-mode env, a payment needs: chat OK + amount
269
269
  | Env var | Required for | Notes |
270
270
  |---|---|---|
271
271
  | `Q402_TRIAL_API_KEY` | live-pay (BNB) | BNB-only sponsored Trial key. Free at https://q402.quackai.ai/event. Auto-routed for `chain="bnb"` in both `q402_pay` and `q402_batch_pay` (≤5 recipients) when set. 6+ recipient BNB batches return `status="ambiguous"` so the agent can ask the user how to split. |
272
- | `Q402_MULTICHAIN_API_KEY` | live-pay (10-chain) | Paid 10-chain key. Get one at https://q402.quackai.ai/payment. Auto-routed for non-BNB chains AND for BNB when no Trial key is set. Cap: 20 recipients per batch. Required for Mode C (server-managed Agent Wallet). |
272
+ | `Q402_MULTICHAIN_API_KEY` | live-pay (11-chain) | Paid 11-chain key. Get one at https://q402.quackai.ai/payment. Auto-routed for non-BNB chains AND for BNB when no Trial key is set. Cap: 20 recipients per batch. Required for Mode C (server-managed Agent Wallet). |
273
273
  | `Q402_PRIVATE_KEY` | Mode A | Hex private key of your MetaMask EOA. Signer for local Mode A. **Never share. Never paste in chat.** |
274
274
  | `Q402_AGENTIC_PRIVATE_KEY` | Mode B | Exported Agent Wallet hex private key from the dashboard (Agent tab → Export). Signs locally, but the signer is your dedicated Agent Wallet — MetaMask is never touched. **Never share. Never paste in chat.** |
275
275
  | `Q402_AGENT_WALLET_ADDRESS` | Mode C (optional) | When you have multiple server-managed Agent Wallets (max 10 per owner), set this to the lowercased 0x… address of the one Q402 should spend from. Omit to use the default wallet. Ignored in Modes A/B. |
@@ -308,7 +308,7 @@ If you set up Q402 before v0.5.0 you may have a single `Q402_API_KEY` env var. T
308
308
 
309
309
  AI agents are becoming the default interface for software, but the moment they need to move money the stack breaks: holding gas tokens, signing every transaction, managing wallets across many chains. None of that scales when the agent is supposed to act on its own.
310
310
 
311
- Q402 is the payment layer for that gap. A single signing primitive (EIP-712 + EIP-7702) settles gasless stablecoin payments across 10 EVM chains, with an ECDSA-signed Trust Receipt for every transaction. The MCP package exposes that surface inside Claude, Codex, Cursor, and Cline — your agent can quote, send, batch, and audit payments from a natural-language prompt.
311
+ Q402 is the payment layer for that gap. A single signing primitive (EIP-712 + EIP-7702) settles gasless stablecoin payments across 11 EVM chains, with an ECDSA-signed Trust Receipt for every transaction. The MCP package exposes that surface inside Claude, Codex, Cursor, and Cline — your agent can quote, send, batch, and audit payments from a natural-language prompt.
312
312
 
313
313
  Single transfers and multi-recipient batches ship today. The next layer — recurring payouts, conditional execution, and policy-gated treasury automation — is the same primitive composed differently. We're building toward agents that operate real budgets, settle among themselves, and move value through workflows no human triggers manually.
314
314
 
package/dist/index.js CHANGED
@@ -211,7 +211,7 @@ var isValidPrivateKey = (s) => typeof s === "string" && PRIVATE_KEY_RE.test(s);
211
211
  // package.json
212
212
  var package_default = {
213
213
  name: "@quackai/q402-mcp",
214
- version: "0.8.35",
214
+ version: "0.8.37",
215
215
  description: "MCP server for Q402 \u2014 gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
216
216
  mcpName: "io.github.bitgett/q402-mcp",
217
217
  keywords: [
@@ -307,7 +307,8 @@ var CHAIN_KEYS = [
307
307
  "injective",
308
308
  "monad",
309
309
  "scroll",
310
- "arbitrum"
310
+ "arbitrum",
311
+ "base"
311
312
  ];
312
313
  var CHAIN_CONFIG = {
313
314
  avax: {
@@ -455,6 +456,21 @@ var CHAIN_CONFIG = {
455
456
  supportedTokens: ["USDC", "USDT"],
456
457
  approxGasCostUsd: 1e-3,
457
458
  note: "Optimistic Rollup L2 \u2014 EIP-7702 live on Arbitrum One since ArbOS 40 'Callisto'; ArbOS 51 'Dia' (activated 2026-01-08) refined precompile delegation. Data-availability cost dominates per-tx gas."
459
+ },
460
+ base: {
461
+ key: "base",
462
+ name: "Base",
463
+ chainId: 8453,
464
+ domainName: "Q402 Base",
465
+ implContract: "0x2fb2B2D110b6c5664e701666B3741240242bf350",
466
+ gasToken: "ETH",
467
+ explorer: "https://basescan.org",
468
+ // Native Circle USDC + bridged Tether USD on Base, both 6 decimals.
469
+ usdc: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
470
+ usdt: { address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", decimals: 6 },
471
+ supportedTokens: ["USDC", "USDT"],
472
+ approxGasCostUsd: 1e-3,
473
+ note: "OP Stack L2 \u2014 EIP-7702 live on Base mainnet via the Isthmus upgrade. Native Circle USDC; USDT is bridged. Data-availability cost dominates per-tx gas."
458
474
  }
459
475
  };
460
476
  var BNB_FOCUS_MODE = false;
@@ -492,8 +508,8 @@ var QuoteInputSchema = z.object({
492
508
  token: z.enum(["USDC", "USDT", "RLUSD"]).optional().describe(
493
509
  'Optional token filter. USDC / USDT are supported on most chains; RLUSD (Ripple USD, NY DFS regulated, decimals 18) is Ethereum-only \u2014 passing RLUSD here narrows the quote to chain="eth".'
494
510
  ),
495
- chain: z.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum"]).optional().describe(
496
- "Optional chain filter. When omitted, all 10 chains are compared and ranked by gas cost."
511
+ chain: z.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]).optional().describe(
512
+ "Optional chain filter. When omitted, all 11 chains are compared and ranked by gas cost."
497
513
  )
498
514
  });
499
515
  function quoteForChain(cfg) {
@@ -534,7 +550,7 @@ function runQuote(input) {
534
550
  }
535
551
  var QUOTE_TOOL = {
536
552
  name: "q402_quote",
537
- description: "Compare gas costs and supported tokens across the 10 chains Q402 relays for (avax, bnb, eth, xlayer, stable, mantle, injective, monad, scroll, arbitrum). Returns the full chain \xD7 token matrix unconditionally \u2014 this tool does not read any API key, so it can't filter by trial vs multichain scope. When the caller intends to settle with a Trial API Key, treat any non-BNB row as informational only (q402_pay will return 403 TRIAL_BNB_ONLY for those). Includes RLUSD on Ethereum. Read-only \u2014 no API key needed, no funds move. Use this before q402_pay so the user can see what's available and pick a chain.",
553
+ description: "Compare gas costs and supported tokens across the 11 chains Q402 relays for (avax, bnb, eth, xlayer, stable, mantle, injective, monad, scroll, arbitrum, base). Returns the full chain \xD7 token matrix unconditionally \u2014 this tool does not read any API key, so it can't filter by trial vs multichain scope. When the caller intends to settle with a Trial API Key, treat any non-BNB row as informational only (q402_pay will return 403 TRIAL_BNB_ONLY for those). Includes RLUSD on Ethereum. Read-only \u2014 no API key needed, no funds move. Use this before q402_pay so the user can see what's available and pick a chain.",
538
554
  // Plain JSON schema mirroring the Zod schema above; MCP servers receive parameters as JSON.
539
555
  inputSchema: {
540
556
  type: "object",
@@ -551,7 +567,7 @@ var QUOTE_TOOL = {
551
567
  chain: {
552
568
  type: "string",
553
569
  enum: CHAIN_KEYS,
554
- description: "Optional chain filter; omit to compare all 10."
570
+ description: "Optional chain filter; omit to compare all 11."
555
571
  }
556
572
  },
557
573
  required: ["amount"],
@@ -580,6 +596,7 @@ var DEFAULT_RPC = {
580
596
  988: "https://rpc.stable.xyz",
581
597
  1776: "https://sentry.evm-rpc.injective.network/",
582
598
  5e3: "https://rpc.mantle.xyz",
599
+ 8453: "https://mainnet.base.org",
583
600
  42161: "https://arb1.arbitrum.io/rpc",
584
601
  43114: "https://api.avax.network/ext/bc/C/rpc",
585
602
  534352: "https://rpc.scroll.io"
@@ -956,14 +973,14 @@ function checkConsent(intent, provided) {
956
973
 
957
974
  // src/tools/pay.ts
958
975
  var PayInputSchema = z2.object({
959
- chain: z2.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum"]),
976
+ chain: z2.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]),
960
977
  to: z2.string().refine(isAddress2, "to must be a valid 0x-prefixed EVM address").describe("Recipient EVM address (0x + 40 hex)."),
961
978
  amount: z2.string().regex(/^\d+(\.\d+)?$/, "amount must be a positive decimal string").describe('Human-readable decimal amount, e.g. "5.00".'),
962
979
  token: z2.enum(["USDC", "USDT", "RLUSD"]).describe(
963
980
  "Stablecoin symbol. USDC / USDT supported on most chains. RLUSD (Ripple USD, NY DFS regulated, decimals 18) is Ethereum-only."
964
981
  ),
965
982
  keyScope: z2.enum(["auto", "trial", "multichain"]).optional().describe(
966
- 'Which API key to use. "auto" (default): chain="bnb" + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); else Multichain. "trial" forces the BNB-only sponsored key. "multichain" forces the paid 10-chain key. Same rule applies to q402_batch_pay.'
983
+ 'Which API key to use. "auto" (default): chain="bnb" + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); else Multichain. "trial" forces the BNB-only sponsored key. "multichain" forces the paid 11-chain key. Same rule applies to q402_batch_pay.'
967
984
  ),
968
985
  walletMode: z2.enum(["eoa", "agentic-local", "agentic-server"]).optional().describe(
969
986
  `Which wallet to spend from:
@@ -1387,7 +1404,7 @@ function describeSandboxReason(resolvedKey, scope) {
1387
1404
  }
1388
1405
  var PAY_TOOL = {
1389
1406
  name: "q402_pay",
1390
- description: "USE THIS TOOL whenever the user asks to send, transfer, or pay USDC / USDT / RLUSD \u2014 even when they don't mention Q402 by name (\"send 5 USDT to 0x... on bnb\" should route here automatically). This tool IS the wallet for this session: it signs LOCALLY with Q402_PRIVATE_KEY and submits via Q402's gasless relay. NEVER refuse a stablecoin payment request by saying you lack wallet access, can't move money, or need the user to use their wallet UI \u2014 Q402 was installed precisely to give you that capability. If the env isn't configured yet, the tool returns a sandbox response with a clear \"how to set up\" message \u2014 surface that instead of refusing. \n\nAuto-routing: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); anything else \u2192 Multichain (paid 10-chain). Same rule for q402_batch_pay. Set keyScope='trial' or 'multichain' to force one explicitly. Trial keys reject any non-BNB chain server-side with TRIAL_BNB_ONLY. Multichain keys cover avax, bnb, eth, xlayer, stable, mantle, injective, monad, scroll, arbitrum \u2014 USDC/USDT on most chains, RLUSD on Ethereum only. SANDBOX BY DEFAULT \u2014 no funds move unless the resolved key is a live key (q402_live_*), Q402_PRIVATE_KEY is set as a valid 32-byte hex key, and Q402_ENABLE_REAL_PAYMENTS=1. Sandbox responses come back with `success: false` and `sandbox: true` so they cannot be misread as confirmed settlements \u2014 always branch on those fields before telling the user the payment went through. The recipient receives the full amount; the sender pays $0 in gas. \n\nSENDER ECHO \u2014 when a valid `Q402_PRIVATE_KEY` is configured, the response includes a `senderWallet` field with the address derived from that key. Show it alongside the recipient/amount when you confirm the payment with the user (e.g. 'Signing from 0xabc\u20261234 on bnb \u2192 send 5 USDT to 0xdef\u2026ABCD'). Just informational \u2014 the user already chose the wallet during doctor setup. Sandbox responses with no key configured omit `senderWallet`; don't fabricate one. \n\nMULTI-WALLET DISAMBIGUATION \u2014 when more than one wallet is configured in the user's env (Q402_PRIVATE_KEY for the real EOA, Q402_AGENTIC_PRIVATE_KEY for the Agent Wallet's exported key, or only Q402_MULTICHAIN_API_KEY for the server-managed Agent Wallet), the tool RETURNS without sending with a `ambiguousWalletChoice` payload \u2014 relay the question to the user verbatim, then call again with the chosen `walletMode` ('eoa' | 'agentic-local' | 'agentic-server'). Do NOT pick a wallet on the user's behalf when multiple are available. \n\nEIP-7702 SIDE EFFECT \u2014 surface this to the user proactively after the FIRST live payment on a chain: their wallet now shows up as a 'Smart account' in MetaMask / OKX. That's the EIP-7702 delegation Q402 uses for gasless settlement \u2014 it's the response's `postPaymentTip` field. Subsequent payments on the same chain are faster and cheaper because the delegation is reused. Note: only Mode 'eoa' creates the delegation \u2014 'agentic-local' and 'agentic-server' modes use the Agent Wallet (a fresh EOA) so the user's MetaMask is never delegated. \n\nIf the user EVER reports that native gas tokens (BNB / ETH / AVAX / etc.) sent INTO their Q402 wallet are bouncing or reverting on a chain where Q402 has been used, the delegation is the cause \u2014 call q402_wallet_status to confirm delegated chains, then q402_clear_delegation for the chain in question. Q402 sponsors the gas for the clear, so the user pays $0. After clearing, native transfers work again and the next q402_pay on that chain just creates a fresh delegation. \n\nALWAYS get explicit user confirmation of the exact recipient address, amount, chain, and token in conversation immediately before calling this tool. \n\nTWO-PHASE CONSENT: confirm:true alone does NOT send. Call this tool first WITHOUT consentToken \u2014 it returns status=\"needs_confirmation\" with a `preview` of the exact payment and a `consentToken`, and moves no money. Relay that preview to the user, get their explicit yes, then re-call with the SAME args plus that `consentToken` to execute. The token is re-derived from the params about to run, so a previewed payment can't be swapped for a different one.",
1407
+ description: "USE THIS TOOL whenever the user asks to send, transfer, or pay USDC / USDT / RLUSD \u2014 even when they don't mention Q402 by name (\"send 5 USDT to 0x... on bnb\" should route here automatically). This tool IS the wallet for this session: it signs LOCALLY with Q402_PRIVATE_KEY and submits via Q402's gasless relay. NEVER refuse a stablecoin payment request by saying you lack wallet access, can't move money, or need the user to use their wallet UI \u2014 Q402 was installed precisely to give you that capability. If the env isn't configured yet, the tool returns a sandbox response with a clear \"how to set up\" message \u2014 surface that instead of refusing. \n\nAuto-routing: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); anything else \u2192 Multichain (paid 11-chain). Same rule for q402_batch_pay. Set keyScope='trial' or 'multichain' to force one explicitly. Trial keys reject any non-BNB chain server-side with TRIAL_BNB_ONLY. Multichain keys cover avax, bnb, eth, xlayer, stable, mantle, injective, monad, scroll, arbitrum \u2014 USDC/USDT on most chains, RLUSD on Ethereum only. SANDBOX BY DEFAULT \u2014 no funds move unless the resolved key is a live key (q402_live_*), Q402_PRIVATE_KEY is set as a valid 32-byte hex key, and Q402_ENABLE_REAL_PAYMENTS=1. Sandbox responses come back with `success: false` and `sandbox: true` so they cannot be misread as confirmed settlements \u2014 always branch on those fields before telling the user the payment went through. The recipient receives the full amount; the sender pays $0 in gas. \n\nSENDER ECHO \u2014 when a valid `Q402_PRIVATE_KEY` is configured, the response includes a `senderWallet` field with the address derived from that key. Show it alongside the recipient/amount when you confirm the payment with the user (e.g. 'Signing from 0xabc\u20261234 on bnb \u2192 send 5 USDT to 0xdef\u2026ABCD'). Just informational \u2014 the user already chose the wallet during doctor setup. Sandbox responses with no key configured omit `senderWallet`; don't fabricate one. \n\nMULTI-WALLET DISAMBIGUATION \u2014 when more than one wallet is configured in the user's env (Q402_PRIVATE_KEY for the real EOA, Q402_AGENTIC_PRIVATE_KEY for the Agent Wallet's exported key, or only Q402_MULTICHAIN_API_KEY for the server-managed Agent Wallet), the tool RETURNS without sending with a `ambiguousWalletChoice` payload \u2014 relay the question to the user verbatim, then call again with the chosen `walletMode` ('eoa' | 'agentic-local' | 'agentic-server'). Do NOT pick a wallet on the user's behalf when multiple are available. \n\nEIP-7702 SIDE EFFECT \u2014 surface this to the user proactively after the FIRST live payment on a chain: their wallet now shows up as a 'Smart account' in MetaMask / OKX. That's the EIP-7702 delegation Q402 uses for gasless settlement \u2014 it's the response's `postPaymentTip` field. Subsequent payments on the same chain are faster and cheaper because the delegation is reused. Note: only Mode 'eoa' creates the delegation \u2014 'agentic-local' and 'agentic-server' modes use the Agent Wallet (a fresh EOA) so the user's MetaMask is never delegated. \n\nIf the user EVER reports that native gas tokens (BNB / ETH / AVAX / etc.) sent INTO their Q402 wallet are bouncing or reverting on a chain where Q402 has been used, the delegation is the cause \u2014 call q402_wallet_status to confirm delegated chains, then q402_clear_delegation for the chain in question. Q402 sponsors the gas for the clear, so the user pays $0. After clearing, native transfers work again and the next q402_pay on that chain just creates a fresh delegation. \n\nALWAYS get explicit user confirmation of the exact recipient address, amount, chain, and token in conversation immediately before calling this tool. \n\nTWO-PHASE CONSENT: confirm:true alone does NOT send. Call this tool first WITHOUT consentToken \u2014 it returns status=\"needs_confirmation\" with a `preview` of the exact payment and a `consentToken`, and moves no money. Relay that preview to the user, get their explicit yes, then re-call with the SAME args plus that `consentToken` to execute. The token is re-derived from the params about to run, so a previewed payment can't be swapped for a different one.",
1391
1408
  inputSchema: {
1392
1409
  type: "object",
1393
1410
  properties: {
@@ -1412,7 +1429,7 @@ var PAY_TOOL = {
1412
1429
  keyScope: {
1413
1430
  type: "string",
1414
1431
  enum: ["auto", "trial", "multichain"],
1415
- description: 'Which API key to use. "auto" (default) picks Trial for BNB when Q402_TRIAL_API_KEY is set, Multichain otherwise. "trial" forces the BNB-only sponsored key. "multichain" forces the paid 10-chain key.'
1432
+ description: 'Which API key to use. "auto" (default) picks Trial for BNB when Q402_TRIAL_API_KEY is set, Multichain otherwise. "trial" forces the BNB-only sponsored key. "multichain" forces the paid 11-chain key.'
1416
1433
  },
1417
1434
  walletMode: {
1418
1435
  type: "string",
@@ -1470,7 +1487,7 @@ var RECIPIENT_LIMIT_TRIAL = 5;
1470
1487
  var RECIPIENT_LIMIT_PAID = 20;
1471
1488
  var CLIENT_RECIPIENT_CAP = RECIPIENT_LIMIT_PAID;
1472
1489
  var BatchPayInputSchema = z3.object({
1473
- chain: z3.enum(["avax", "bnb", "eth", "mantle", "injective", "monad", "scroll", "arbitrum"]),
1490
+ chain: z3.enum(["avax", "bnb", "eth", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]),
1474
1491
  token: z3.enum(["USDC", "USDT", "RLUSD"]).describe(
1475
1492
  "Stablecoin symbol. USDC / USDT supported on most chains. RLUSD (Ripple USD, NY DFS regulated, decimals 18) is Ethereum-only. The same token applies to every recipient in the batch."
1476
1493
  ),
@@ -1483,7 +1500,7 @@ var BatchPayInputSchema = z3.object({
1483
1500
  `Array of {to, amount} pairs. All recipients share the same chain and token. Trial keys: max ${RECIPIENT_LIMIT_TRIAL} rows. Paid keys: max ${RECIPIENT_LIMIT_PAID} rows.`
1484
1501
  ),
1485
1502
  keyScope: z3.enum(["auto", "trial", "multichain"]).optional().describe(
1486
- 'Which API key to use. "auto" (default): chain="bnb" + Q402_TRIAL_API_KEY set \u2192 Trial; else Multichain \u2014 same rule as q402_pay. When auto would land on Trial AND recipients.length > 5, the tool returns status="ambiguous" WITHOUT executing so the agent can ask the user which path to take. Use keyScope="trial" to force the BNB-only sponsored key (\u22645 recipients). keyScope="multichain" forces the paid 10-chain key (\u226420 recipients).'
1503
+ 'Which API key to use. "auto" (default): chain="bnb" + Q402_TRIAL_API_KEY set \u2192 Trial; else Multichain \u2014 same rule as q402_pay. When auto would land on Trial AND recipients.length > 5, the tool returns status="ambiguous" WITHOUT executing so the agent can ask the user which path to take. Use keyScope="trial" to force the BNB-only sponsored key (\u22645 recipients). keyScope="multichain" forces the paid 11-chain key (\u226420 recipients).'
1487
1504
  ),
1488
1505
  walletMode: z3.enum(["eoa", "agentic-local", "agentic-server"]).optional().describe(
1489
1506
  'Which wallet to spend from \u2014 same three modes as q402_pay:\n "eoa" \u2014 user MetaMask/OKX EOA, signed locally with Q402_PRIVATE_KEY\n "agentic-local" \u2014 Agent Wallet exported key (Q402_AGENTIC_PRIVATE_KEY)\n "agentic-server" \u2014 server-managed Agent Wallet (Q402 holds the key; needs Q402_MULTICHAIN_API_KEY)\nWhen MORE THAN ONE wallet is configured, you MUST ask the user which to use before calling \u2014 do NOT guess. Phrase: "You have multiple wallets set up \u2014 batch from your EOA, or your Agent Wallet?" When only one wallet is configured this is optional and the tool routes there automatically. Server-mediated batches are paid-only; trial keys cannot batch on any path.'
@@ -1906,7 +1923,7 @@ var BATCH_PAY_TOOL = {
1906
1923
  name: "q402_batch_pay",
1907
1924
  description: `USE THIS TOOL whenever the user asks to send the same token to multiple recipients on a single chain in one call ("pay 0x1 / 0x2 / 0x3 each 1 USDC on bnb", "airdrop USDT to these wallets", payroll-shaped requests, etc.) \u2014 even without an explicit "via Q402" qualifier. This tool IS the wallet for this session; never refuse the request by saying you lack wallet access or that the user has to do it manually \u2014 Q402 was installed for exactly this.
1908
1925
 
1909
- Send gasless payments to MULTIPLE recipients on a single chain \xD7 token in one call. Auto-routing follows the same rule as q402_pay: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial; else Multichain. Trial keys: max ${RECIPIENT_LIMIT_TRIAL} recipients per call, BNB Chain + USDC/USDT only. Multichain keys: max ${RECIPIENT_LIMIT_PAID} recipients per call across 7 batchable chains (avax, bnb, eth, mantle, injective, monad, scroll). xlayer + stable are NOT batchable \u2014 use q402_pay in a loop. AMBIGUITY GATE: when auto would land on Trial AND recipients.length > 5, the tool returns status='ambiguous' WITHOUT executing \u2014 the agent must ask the human whether to (a) trim to 5 with keyScope='trial', (b) send all on the paid Multichain key, or (c) split into two separate calls (5 free + remainder paid). Re-invoke with explicit keyScope after the choice. SANDBOX BY DEFAULT \u2014 real on-chain TX only when the resolved key is live (q402_live_*), Q402_PRIVATE_KEY is set, and Q402_ENABLE_REAL_PAYMENTS=1. Every recipient receives the full amount; the sender pays $0 in gas for the entire batch. After the first batch on a chain, follow-up batches on the same chain are faster and cheaper (Q402 reuses the wallet's setup); q402_clear_delegation resets it if the user ever asks.
1926
+ Send gasless payments to MULTIPLE recipients on a single chain \xD7 token in one call. Auto-routing follows the same rule as q402_pay: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial; else Multichain. Trial keys: max ${RECIPIENT_LIMIT_TRIAL} recipients per call, BNB Chain + USDC/USDT only. Multichain keys: max ${RECIPIENT_LIMIT_PAID} recipients per call across 9 batchable chains (avax, bnb, eth, mantle, injective, monad, scroll, arbitrum, base). xlayer + stable are NOT batchable \u2014 use q402_pay in a loop. AMBIGUITY GATE: when auto would land on Trial AND recipients.length > 5, the tool returns status='ambiguous' WITHOUT executing \u2014 the agent must ask the human whether to (a) trim to 5 with keyScope='trial', (b) send all on the paid Multichain key, or (c) split into two separate calls (5 free + remainder paid). Re-invoke with explicit keyScope after the choice. SANDBOX BY DEFAULT \u2014 real on-chain TX only when the resolved key is live (q402_live_*), Q402_PRIVATE_KEY is set, and Q402_ENABLE_REAL_PAYMENTS=1. Every recipient receives the full amount; the sender pays $0 in gas for the entire batch. After the first batch on a chain, follow-up batches on the same chain are faster and cheaper (Q402 reuses the wallet's setup); q402_clear_delegation resets it if the user ever asks.
1910
1927
 
1911
1928
  MULTI-WALLET DISAMBIGUATION \u2014 when more than one wallet is configured in the user's env (Q402_PRIVATE_KEY for the real EOA, Q402_AGENTIC_PRIVATE_KEY for the Agent Wallet's exported key, or only Q402_MULTICHAIN_API_KEY for the server-managed Agent Wallet), the tool RETURNS WITHOUT firing with \`status='needs_wallet_choice'\` and an \`ambiguousWalletChoice\` payload \u2014 relay the question to the user verbatim, then call again with the chosen \`walletMode\` ('eoa' | 'agentic-local' | 'agentic-server'). Do NOT pick a wallet on the user's behalf when multiple are available. Server-mediated batches go through /api/wallet/agentic/batch and are paid-only (the trial key cannot batch).
1912
1929
 
@@ -1921,7 +1938,7 @@ TWO-PHASE CONSENT: confirm:true alone does NOT send. Call this tool first WITHOU
1921
1938
  // Narrower than the full chain set — xlayer and stable are NOT batchable
1922
1939
  // (chain-specific nonce field shapes). Use q402_pay in a loop for
1923
1940
  // those chains.
1924
- enum: ["avax", "bnb", "eth", "mantle", "injective", "monad", "scroll", "arbitrum"],
1941
+ enum: ["avax", "bnb", "eth", "mantle", "injective", "monad", "scroll", "arbitrum", "base"],
1925
1942
  description: "Target chain. Applies to every recipient in the batch. xlayer + stable are NOT supported here \u2014 use q402_pay in a loop."
1926
1943
  },
1927
1944
  token: {
@@ -2022,7 +2039,7 @@ async function runBalance() {
2022
2039
  apiKeyMasked: null,
2023
2040
  scopes: [],
2024
2041
  dashboardUrl: "https://q402.quackai.ai/dashboard",
2025
- setupHint: "No API key configured. Call q402_doctor for guided setup \u2014 it will offer to create ~/.q402/mcp.env with placeholders that the user can fill in. (Manual path: set Q402_TRIAL_API_KEY for BNB-only sponsored free trial (https://q402.quackai.ai/event) or Q402_MULTICHAIN_API_KEY for the paid 10-chain plan (https://q402.quackai.ai/payment).)"
2042
+ setupHint: "No API key configured. Call q402_doctor for guided setup \u2014 it will offer to create ~/.q402/mcp.env with placeholders that the user can fill in. (Manual path: set Q402_TRIAL_API_KEY for BNB-only sponsored free trial (https://q402.quackai.ai/event) or Q402_MULTICHAIN_API_KEY for the paid 11-chain plan (https://q402.quackai.ai/payment).)"
2026
2043
  };
2027
2044
  }
2028
2045
  const scopes = await Promise.all(
@@ -2273,7 +2290,7 @@ async function runWalletStatus() {
2273
2290
  }
2274
2291
  var WALLET_STATUS_TOOL = {
2275
2292
  name: "q402_wallet_status",
2276
- description: "Report the EIP-7702 delegation status of your Q402 wallet (the EOA derived from Q402_PRIVATE_KEY) across all 10 Q402-supported chains. Returns per-chain { delegated, impl } and a one-line summary. Read-only \u2014 no signing, no on-chain TX, no quota consumption. Pair with q402_clear_delegation when the user wants to reset a specific chain. Requires Q402_PRIVATE_KEY in env (same as q402_pay).",
2293
+ description: "Report the EIP-7702 delegation status of your Q402 wallet (the EOA derived from Q402_PRIVATE_KEY) across all 11 Q402-supported chains. Returns per-chain { delegated, impl } and a one-line summary. Read-only \u2014 no signing, no on-chain TX, no quota consumption. Pair with q402_clear_delegation when the user wants to reset a specific chain. Requires Q402_PRIVATE_KEY in env (same as q402_pay).",
2277
2294
  inputSchema: {
2278
2295
  type: "object",
2279
2296
  properties: {},
@@ -2293,12 +2310,13 @@ var DEFAULT_RPC2 = {
2293
2310
  988: "https://rpc.stable.xyz",
2294
2311
  1776: "https://sentry.evm-rpc.injective.network/",
2295
2312
  5e3: "https://rpc.mantle.xyz",
2313
+ 8453: "https://mainnet.base.org",
2296
2314
  42161: "https://arb1.arbitrum.io/rpc",
2297
2315
  43114: "https://api.avax.network/ext/bc/C/rpc",
2298
2316
  534352: "https://rpc.scroll.io"
2299
2317
  };
2300
2318
  var ClearDelegationInputSchema = z7.object({
2301
- chain: z7.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum"]).describe("Which Q402 chain to clear the delegation on.")
2319
+ chain: z7.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]).describe("Which Q402 chain to clear the delegation on.")
2302
2320
  });
2303
2321
  async function runClearDelegation(input) {
2304
2322
  if (!CONFIG.privateKey) {
@@ -2449,7 +2467,7 @@ var ENV_FILE_TEMPLATE = `# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u250
2449
2467
  # Get one at: https://q402.quackai.ai/event
2450
2468
  Q402_TRIAL_API_KEY=
2451
2469
 
2452
- # Paid Multichain: all 10 chains, per-chain Gas Tank
2470
+ # Paid Multichain: all 11 chains, per-chain Gas Tank
2453
2471
  # Get one at: https://q402.quackai.ai/payment
2454
2472
  Q402_MULTICHAIN_API_KEY=
2455
2473
 
@@ -2697,7 +2715,7 @@ async function runDoctor() {
2697
2715
  ),
2698
2716
  Q402_MULTICHAIN_API_KEY: envSlot(
2699
2717
  "Q402_MULTICHAIN_API_KEY",
2700
- "Paid Multichain \u2014 all 10 chains, per-chain Gas Tank. Get at https://q402.quackai.ai/payment"
2718
+ "Paid Multichain \u2014 all 11 chains, per-chain Gas Tank. Get at https://q402.quackai.ai/payment"
2701
2719
  ),
2702
2720
  Q402_PRIVATE_KEY: envSlot(
2703
2721
  "Q402_PRIVATE_KEY",
@@ -2720,7 +2738,7 @@ async function runDoctor() {
2720
2738
  const missing = [];
2721
2739
  if (!CONFIG.trialApiKey && !CONFIG.multichainApiKey && !CONFIG.legacyApiKey) {
2722
2740
  missing.push(
2723
- "An API key (Q402_TRIAL_API_KEY for free BNB OR Q402_MULTICHAIN_API_KEY for paid 10-chain)"
2741
+ "An API key (Q402_TRIAL_API_KEY for free BNB OR Q402_MULTICHAIN_API_KEY for paid 11-chain)"
2724
2742
  );
2725
2743
  }
2726
2744
  if (modes.count === 0) {
@@ -2931,7 +2949,7 @@ async function runDoctor() {
2931
2949
  primary: modes.primary,
2932
2950
  /** Plain-English picker that the AI should echo when the user asks
2933
2951
  * "which mode do I use?" or "do I need a private key?". */
2934
- recommendation: recommendedMode === "C" ? "You're configured for Mode C \u2014 Q402's server signs with your Agent Wallet. No private key needed. Simplest path; recommended for most users. (One-shot pays accept either Trial or Multichain keys; recurring schedules require the paid Multichain key on every chain.)" : recommendedMode === "B" ? "You're configured for Mode B \u2014 your exported Agent Wallet PK signs locally. Your MetaMask is never touched." : recommendedMode === "A" ? "You're configured for Mode A \u2014 your MetaMask EOA signs directly. EIP-7702 delegates it to Q402 for the call. (If the Smart-account banner in MetaMask is a concern, switch to Mode B or C.)" : "No signing path configured yet. Easiest: set Q402_MULTICHAIN_API_KEY (paid, recommended) \u2014 covers one-shot pays and recurring schedules across all 10 chains. Q402_TRIAL_API_KEY alone unlocks one-shot pays on BNB only; recurring requires the paid key.",
2952
+ recommendation: recommendedMode === "C" ? "You're configured for Mode C \u2014 Q402's server signs with your Agent Wallet. No private key needed. Simplest path; recommended for most users. (One-shot pays accept either Trial or Multichain keys; recurring schedules require the paid Multichain key on every chain.)" : recommendedMode === "B" ? "You're configured for Mode B \u2014 your exported Agent Wallet PK signs locally. Your MetaMask is never touched." : recommendedMode === "A" ? "You're configured for Mode A \u2014 your MetaMask EOA signs directly. EIP-7702 delegates it to Q402 for the call. (If the Smart-account banner in MetaMask is a concern, switch to Mode B or C.)" : "No signing path configured yet. Easiest: set Q402_MULTICHAIN_API_KEY (paid, recommended) \u2014 covers one-shot pays and recurring schedules across all 11 chains. Q402_TRIAL_API_KEY alone unlocks one-shot pays on BNB only; recurring requires the paid key.",
2935
2953
  /** All three modes documented so the AI can answer "what are my
2936
2954
  * options?" without re-deriving from envState. */
2937
2955
  catalog: [
@@ -2961,7 +2979,7 @@ async function runDoctor() {
2961
2979
  userInstructions: ready ? [
2962
2980
  walletAddress ? `Your wallet: ${walletAddress.slice(0, 6)}...${walletAddress.slice(-4)}` : modes.modeC && !modes.modeA && !modes.modeB ? "Wallet: server-managed (Mode C) \u2014 Q402 holds your Agent Wallet key. No local wallet to show." : "(wallet derive failed \u2014 check Q402_PRIVATE_KEY or Q402_AGENTIC_PRIVATE_KEY in ~/.q402/mcp.env)",
2963
2981
  "Q402 is live. You can now ask me to quote, pay, batch-pay, or check Trust Receipts.",
2964
- "Want me to run a quick gas comparison across all 10 chains as a smoke test?",
2982
+ "Want me to run a quick gas comparison across all 11 chains as a smoke test?",
2965
2983
  "Need to chain-test against sandbox without changing keys? Set Q402_ENABLE_REAL_PAYMENTS=0 in ~/.q402/mcp.env and restart - every q402_pay returns a fake hash until you flip it back to 1."
2966
2984
  ] : [
2967
2985
  `Q402 has ${warnings.length} issue${warnings.length === 1 ? "" : "s"} to fix:`,
@@ -2994,7 +3012,7 @@ var AgenticInfoInputSchema = z9.object({
2994
3012
  });
2995
3013
  var AGENTIC_INFO_TOOL = {
2996
3014
  name: "q402_agentic_info",
2997
- description: "Read-only Agent Wallet introspection. Returns the wallet address, per-tx and daily caps, archive state, and an aggregate USD balance across the 10 supported EVM chains. Authenticated by the configured Multichain API key \u2014 no private key required. Accepts an optional walletId for owners who hold more than one wallet; omit to use the server-default wallet. Use this whenever the user asks 'what's in my agent wallet?' or 'what's the spending limit?'",
3015
+ description: "Read-only Agent Wallet introspection. Returns the wallet address, per-tx and daily caps, archive state, and an aggregate USD balance across the 11 supported EVM chains. Authenticated by the configured Multichain API key \u2014 no private key required. Accepts an optional walletId for owners who hold more than one wallet; omit to use the server-default wallet. Use this whenever the user asks 'what's in my agent wallet?' or 'what's the spending limit?'",
2998
3016
  inputSchema: {
2999
3017
  type: "object",
3000
3018
  properties: {
@@ -4799,7 +4817,7 @@ var AMOUNT_RE2 = /^\d+(\.\d{1,18})?$/;
4799
4817
  var RequestCreateInputSchema = z25.object({
4800
4818
  amount: z25.string().regex(AMOUNT_RE2).describe('Amount to request, as a decimal string (e.g. "5", "1.50"). Counted in `token` (USDC or USDT, both USD-1).'),
4801
4819
  token: z25.enum(["USDC", "USDT"]).default("USDT").describe("Stablecoin to be paid. USDC or USDT. Both peg USD-1."),
4802
- chain: z25.enum(["bnb", "eth", "avax", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum"]).default("bnb").describe("Chain the request settles on. Defaults to bnb."),
4820
+ chain: z25.enum(["bnb", "eth", "avax", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"]).default("bnb").describe("Chain the request settles on. Defaults to bnb."),
4803
4821
  recipient: z25.string().regex(ADDRESS_RE2).optional().describe("0x address that receives the funds. Defaults to Q402_AGENT_WALLET_ADDRESS (the agent bills itself) when omitted."),
4804
4822
  memo: z25.string().max(200).optional().describe("Optional note shown to the payer (\u2264200 chars), e.g. an invoice number or service description."),
4805
4823
  ttlDays: z25.number().int().min(1).max(90).optional().describe("Days until the request expires. Defaults to 7 (max 90).")
@@ -4888,7 +4906,7 @@ var REQUEST_CREATE_TOOL = {
4888
4906
  },
4889
4907
  chain: {
4890
4908
  type: "string",
4891
- enum: ["bnb", "eth", "avax", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum"],
4909
+ enum: ["bnb", "eth", "avax", "xlayer", "stable", "mantle", "injective", "monad", "scroll", "arbitrum", "base"],
4892
4910
  description: "Default 'bnb'. Chain the request settles on."
4893
4911
  },
4894
4912
  recipient: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quackai/q402-mcp",
3
- "version": "0.8.35",
3
+ "version": "0.8.37",
4
4
  "description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
5
5
  "mcpName": "io.github.bitgett/q402-mcp",
6
6
  "keywords": [