@quackai/q402-mcp 0.7.2 → 0.7.4

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 (2) hide show
  1. package/dist/index.js +220 -12
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -211,7 +211,7 @@ var isValidPrivateKey = (s) => typeof s === "string" && PRIVATE_KEY_RE.test(s);
211
211
 
212
212
  // src/version.ts
213
213
  var PACKAGE_NAME = "@quackai/q402-mcp";
214
- var PACKAGE_VERSION = "0.7.2";
214
+ var PACKAGE_VERSION = "0.7.4";
215
215
 
216
216
  // src/tools/quote.ts
217
217
  import { z } from "zod";
@@ -1226,6 +1226,12 @@ var BatchPayInputSchema = z3.object({
1226
1226
  keyScope: z3.enum(["auto", "trial", "multichain"]).optional().describe(
1227
1227
  '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 9-chain key (\u226420 recipients).'
1228
1228
  ),
1229
+ walletMode: z3.enum(["eoa", "agentic-local", "agentic-server"]).optional().describe(
1230
+ '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.'
1231
+ ),
1232
+ walletId: z3.string().optional().describe(
1233
+ `Server-managed Agent Wallet only (walletMode="agentic-server"). Lowercased Agent Wallet address selecting which of the user's wallets to spend from when they hold more than one. Omit to use the default. Ignored for local-signing modes.`
1234
+ ),
1229
1235
  confirm: z3.literal(true).describe(
1230
1236
  "MUST be true. The user must have explicitly approved this exact set of recipients, amounts, chain, and token in the conversation right before this tool was called. Setting confirm=true on behalf of the user without that approval is a violation of the tool contract."
1231
1237
  )
@@ -1270,9 +1276,71 @@ async function runBatchPay(input) {
1270
1276
  if (CONFIG.allowedRecipients.length > 0) {
1271
1277
  guardsApplied.push(`recipient_allowlist[${CONFIG.allowedRecipients.length}]`);
1272
1278
  }
1279
+ const modes = detectAgenticModes(CONFIG);
1280
+ const available = [];
1281
+ if (modes.modeA && CONFIG.privateKey && isValidPrivateKey(CONFIG.privateKey)) {
1282
+ try {
1283
+ const addr = new Wallet3(CONFIG.privateKey).address;
1284
+ available.push({
1285
+ id: "eoa",
1286
+ label: "Your real MetaMask / OKX EOA",
1287
+ addressShort: `${addr.slice(0, 6)}\u2026${addr.slice(-4)}`,
1288
+ note: "Signs locally with Q402_PRIVATE_KEY. Your wallet becomes EIP-7702-delegated after the first payment on each chain."
1289
+ });
1290
+ } catch {
1291
+ }
1292
+ }
1293
+ if (modes.modeB && CONFIG.agenticPrivateKey && isValidPrivateKey(CONFIG.agenticPrivateKey)) {
1294
+ try {
1295
+ const addr = new Wallet3(CONFIG.agenticPrivateKey).address;
1296
+ available.push({
1297
+ id: "agentic-local",
1298
+ label: "Agent Wallet (local signing with exported key)",
1299
+ addressShort: `${addr.slice(0, 6)}\u2026${addr.slice(-4)}`,
1300
+ note: "Signs locally with Q402_AGENTIC_PRIVATE_KEY. Your MetaMask is never touched."
1301
+ });
1302
+ } catch {
1303
+ }
1304
+ }
1305
+ if (modes.modeC) {
1306
+ available.push({
1307
+ id: "agentic-server",
1308
+ label: "Agent Wallet (server-managed)",
1309
+ note: "Q402 holds the encrypted key; batch fires through /api/wallet/agentic/batch. Caps you set in the dashboard bound the spend."
1310
+ });
1311
+ }
1312
+ const requestedMode = input.walletMode;
1313
+ const requestedAvailable = requestedMode ? available.some((w) => w.id === requestedMode) : false;
1314
+ if (requestedMode && !requestedAvailable) {
1315
+ return {
1316
+ mode: "none",
1317
+ status: "wallet_mode_unavailable",
1318
+ guardsApplied: [
1319
+ ...guardsApplied,
1320
+ `wallet_modes_available=${available.length}`,
1321
+ `requested=${requestedMode}`
1322
+ ],
1323
+ ambiguousWalletChoice: {
1324
+ question: available.length === 0 ? `The "${requestedMode}" wallet isn't configured. None of the supported wallets are set up \u2014 see the doctor for setup instructions.` : `The "${requestedMode}" wallet isn't configured in this environment. Supported wallets here: ${available.map((w) => `"${w.id}"`).join(", ")}. Which would you like to use instead?`,
1325
+ available
1326
+ }
1327
+ };
1328
+ }
1329
+ if (available.length > 1 && !requestedMode) {
1330
+ return {
1331
+ mode: "none",
1332
+ status: "needs_wallet_choice",
1333
+ guardsApplied: [...guardsApplied, `wallet_modes_available=${available.length}`],
1334
+ ambiguousWalletChoice: {
1335
+ question: available.length === 2 ? `You have ${available.length} wallets set up \u2014 which one should I batch-pay from?` : `You have ${available.length} wallets set up. Which one should I batch-pay from?`,
1336
+ available
1337
+ }
1338
+ };
1339
+ }
1340
+ const effectiveMode = requestedMode && requestedAvailable ? requestedMode : available.length === 1 && available[0] ? available[0].id : "eoa";
1273
1341
  let senderWallet;
1274
- const echoPk = CONFIG.agenticPrivateKey && isValidPrivateKey(CONFIG.agenticPrivateKey) ? CONFIG.agenticPrivateKey : CONFIG.privateKey && isValidPrivateKey(CONFIG.privateKey) ? CONFIG.privateKey : null;
1275
- if (echoPk) {
1342
+ const echoPk = effectiveMode === "eoa" ? CONFIG.privateKey : effectiveMode === "agentic-local" ? CONFIG.agenticPrivateKey : null;
1343
+ if (echoPk && isValidPrivateKey(echoPk)) {
1276
1344
  try {
1277
1345
  const addr = new Wallet3(echoPk).address;
1278
1346
  senderWallet = {
@@ -1309,12 +1377,134 @@ async function runBatchPay(input) {
1309
1377
  }
1310
1378
  const resolved = resolveApiKey(input.chain, scopeRequest);
1311
1379
  guardsApplied.push(`scope=${resolved.scope}${resolved.fromLegacyFallback ? "(legacy)" : ""}`);
1380
+ if (effectiveMode === "agentic-server") {
1381
+ if (input.token === "RLUSD") {
1382
+ return {
1383
+ mode: "none",
1384
+ status: "sandbox",
1385
+ guardsApplied: [
1386
+ ...guardsApplied,
1387
+ "wallet=agentic-server",
1388
+ "token=RLUSD",
1389
+ "rejected_pre_relay"
1390
+ ],
1391
+ senderWallet,
1392
+ setupHint: 'RLUSD is not yet supported by the server-managed Agent Wallet (walletMode="agentic-server"). Switch to walletMode="eoa" or "agentic-local" (with a private key set), or pick USDC/USDT for this batch.'
1393
+ };
1394
+ }
1395
+ if (!resolved.apiKey || !resolved.apiKey.startsWith("q402_live_")) {
1396
+ const sandboxResults = input.recipients.map(
1397
+ (r) => sandboxPay(chain, { to: r.to, amount: r.amount, token: input.token })
1398
+ );
1399
+ guardsApplied.push("mode=sandbox", "wallet=agentic-server");
1400
+ const reason = resolved.sandboxReason ?? "Server-mediated Agent Wallet needs a live Q402_MULTICHAIN_API_KEY. Visit https://q402.quackai.ai/payment to activate a paid plan.";
1401
+ return {
1402
+ mode: "sandbox",
1403
+ status: "sandbox",
1404
+ result: { sandbox: sandboxResults, reason },
1405
+ senderWallet,
1406
+ guardsApplied,
1407
+ setupHint: reason
1408
+ };
1409
+ }
1410
+ if (!CONFIG.realPaymentsRequested) {
1411
+ const sandboxResults = input.recipients.map(
1412
+ (r) => sandboxPay(chain, { to: r.to, amount: r.amount, token: input.token })
1413
+ );
1414
+ guardsApplied.push("mode=sandbox", "wallet=agentic-server");
1415
+ const reason = "Set Q402_ENABLE_REAL_PAYMENTS=1 to fire a real server-mediated batch.";
1416
+ return {
1417
+ mode: "sandbox",
1418
+ status: "sandbox",
1419
+ result: { sandbox: sandboxResults, reason },
1420
+ senderWallet,
1421
+ guardsApplied,
1422
+ setupHint: reason
1423
+ };
1424
+ }
1425
+ const explicitWalletId = typeof input.walletId === "string" && input.walletId.length > 0 ? input.walletId.toLowerCase() : CONFIG.walletId;
1426
+ let resp;
1427
+ try {
1428
+ resp = await fetch(`${CONFIG.relayBaseUrl}/wallet/agentic/batch`, {
1429
+ method: "POST",
1430
+ headers: { "Content-Type": "application/json" },
1431
+ body: JSON.stringify({
1432
+ apiKey: resolved.apiKey,
1433
+ chain: input.chain,
1434
+ token: input.token,
1435
+ recipients: input.recipients,
1436
+ ...explicitWalletId ? { walletId: explicitWalletId } : {}
1437
+ })
1438
+ });
1439
+ } catch (e) {
1440
+ return {
1441
+ mode: "live",
1442
+ status: "aborted",
1443
+ guardsApplied: [
1444
+ ...guardsApplied,
1445
+ "wallet=agentic-server",
1446
+ "mode=live",
1447
+ "transport=fetch_failed"
1448
+ ],
1449
+ senderWallet,
1450
+ error: e instanceof Error ? e.message : String(e)
1451
+ };
1452
+ }
1453
+ const data = await resp.json().catch(() => ({}));
1454
+ if (!resp.ok) {
1455
+ const errMsg = data && typeof data === "object" && "error" in data ? String(data.error) : `relay_http_${resp.status}`;
1456
+ return {
1457
+ mode: "live",
1458
+ status: "aborted",
1459
+ guardsApplied: [
1460
+ ...guardsApplied,
1461
+ "wallet=agentic-server",
1462
+ "mode=live",
1463
+ `http=${resp.status}`
1464
+ ],
1465
+ senderWallet,
1466
+ error: errMsg,
1467
+ setupHint: resp.status === 402 ? "Server-mediated batch requires a paid Multichain subscription. Activate one at https://q402.quackai.ai/payment." : resp.status === 401 ? "apiKey was rejected by the server (stale or not bound to your owner). Rotate to the current key in your dashboard." : resp.status === 404 ? "No active Agent Wallet found. Create one in your dashboard before retrying." : void 0
1468
+ };
1469
+ }
1470
+ const serverResults = Array.isArray(data.results) ? data.results : [];
1471
+ const settled = serverResults.filter((r) => r.ok === true).length;
1472
+ const failed = serverResults.length - settled;
1473
+ const serverAborted = typeof data.aborted === "boolean" ? data.aborted : null;
1474
+ const isAborted = serverAborted ?? (settled === 0 && failed > 0);
1475
+ const status = failed === 0 ? "success" : isAborted ? "aborted" : "partial_failure";
1476
+ guardsApplied.push(
1477
+ "mode=live",
1478
+ "wallet=agentic-server",
1479
+ "scope=multichain (server enforced)",
1480
+ `batch_size=${serverResults.length}/${RECIPIENT_LIMIT_PAID}`
1481
+ );
1482
+ return {
1483
+ mode: "live",
1484
+ status,
1485
+ result: {
1486
+ ok: failed === 0,
1487
+ scope: "paid",
1488
+ limit: RECIPIENT_LIMIT_PAID,
1489
+ totalSuccess: settled,
1490
+ totalFailed: failed,
1491
+ aborted: isAborted,
1492
+ results: serverResults.map((r) => ({
1493
+ success: r.ok === true,
1494
+ txHash: r.txHash,
1495
+ error: r.error
1496
+ }))
1497
+ },
1498
+ guardsApplied,
1499
+ senderWallet
1500
+ };
1501
+ }
1312
1502
  const live = isLiveModeFor(resolved);
1313
1503
  if (!live) {
1314
1504
  const sandboxResults = input.recipients.map(
1315
1505
  (r) => sandboxPay(chain, { to: r.to, amount: r.amount, token: input.token })
1316
1506
  );
1317
- guardsApplied.push("mode=sandbox");
1507
+ guardsApplied.push("mode=sandbox", `wallet=${effectiveMode}`);
1318
1508
  const reason = resolved.sandboxReason ?? describeSandboxReason2(resolved.apiKey ?? "", resolved.scope);
1319
1509
  return {
1320
1510
  mode: "sandbox",
@@ -1325,13 +1515,13 @@ async function runBatchPay(input) {
1325
1515
  setupHint: reason
1326
1516
  };
1327
1517
  }
1328
- const signingPk = CONFIG.agenticPrivateKey ?? CONFIG.privateKey;
1518
+ const signingPk = effectiveMode === "eoa" ? CONFIG.privateKey : effectiveMode === "agentic-local" ? CONFIG.agenticPrivateKey : null;
1329
1519
  if (!signingPk) {
1330
- guardsApplied.push("mode=sandbox");
1520
+ guardsApplied.push("mode=sandbox", `wallet=${effectiveMode}`);
1331
1521
  const sandboxResults = input.recipients.map(
1332
1522
  (r) => sandboxPay(chain, { to: r.to, amount: r.amount, token: input.token })
1333
1523
  );
1334
- const reason = "No local signing key configured. Set Q402_AGENTIC_PRIVATE_KEY (Mode B) or Q402_PRIVATE_KEY (Mode A) to sign batch payments locally.";
1524
+ const reason = effectiveMode === "agentic-local" ? "Set Q402_AGENTIC_PRIVATE_KEY to your Agent Wallet's exported private key." : "Set Q402_PRIVATE_KEY to your EOA private key.";
1335
1525
  return {
1336
1526
  mode: "sandbox",
1337
1527
  status: "sandbox",
@@ -1352,13 +1542,13 @@ async function runBatchPay(input) {
1352
1542
  token: input.token,
1353
1543
  recipients: input.recipients.map((r) => ({ to: r.to, amount: r.amount }))
1354
1544
  });
1355
- guardsApplied.push("mode=live");
1545
+ guardsApplied.push("mode=live", `wallet=${effectiveMode}`);
1356
1546
  guardsApplied.push(`scope=${result.scope} (server enforced)`);
1357
1547
  guardsApplied.push(`batch_size=${input.recipients.length}/${result.limit}`);
1358
1548
  return { mode: "live", status: "success", result, guardsApplied, senderWallet };
1359
1549
  } catch (err) {
1360
1550
  if (err instanceof BatchPayError) {
1361
- guardsApplied.push("mode=live");
1551
+ guardsApplied.push("mode=live", `wallet=${effectiveMode}`);
1362
1552
  guardsApplied.push(`scope=${err.scope} (server enforced)`);
1363
1553
  guardsApplied.push(`batch_${err.aborted ? "aborted" : "partial_failure"}`);
1364
1554
  const status = err.aborted ? "aborted" : "partial_failure";
@@ -1408,7 +1598,11 @@ var BATCH_PAY_TOOL = {
1408
1598
  name: "q402_batch_pay",
1409
1599
  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.
1410
1600
 
1411
- 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. ALWAYS get explicit user confirmation of the complete recipient + amount list, chain, and token in conversation immediately before calling this tool \u2014 the user must approve the full batch, not the individual rows.`,
1601
+ 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.
1602
+
1603
+ 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).
1604
+
1605
+ ALWAYS get explicit user confirmation of the complete recipient + amount list, chain, and token in conversation immediately before calling this tool \u2014 the user must approve the full batch, not the individual rows.`,
1412
1606
  inputSchema: {
1413
1607
  type: "object",
1414
1608
  properties: {
@@ -1451,6 +1645,15 @@ Send gasless payments to MULTIPLE recipients on a single chain \xD7 token in one
1451
1645
  enum: ["auto", "trial", "multichain"],
1452
1646
  description: 'Which API key to use. "auto" (default): BNB + trial key set \u2192 Trial; else Multichain. 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.'
1453
1647
  },
1648
+ walletMode: {
1649
+ type: "string",
1650
+ enum: ["eoa", "agentic-local", "agentic-server"],
1651
+ description: 'Which wallet to spend from. "eoa" = user MetaMask EOA (Q402_PRIVATE_KEY). "agentic-local" = Agent Wallet exported key (Q402_AGENTIC_PRIVATE_KEY). "agentic-server" = server-managed Agent Wallet (Q402 holds the key; only the apiKey is needed). When MULTIPLE wallets are configured the tool refuses without this arg and returns ambiguousWalletChoice for the user to pick. Server-mediated batches are paid-only.'
1652
+ },
1653
+ walletId: {
1654
+ type: "string",
1655
+ description: `Server-managed Agent Wallet only (walletMode="agentic-server"). Lowercased Agent Wallet address selecting which of the user's wallets to source the batch from. Omit to use the default. Ignored for local-signing modes.`
1656
+ },
1454
1657
  confirm: {
1455
1658
  type: "boolean",
1456
1659
  const: true,
@@ -2505,12 +2708,14 @@ async function runAgenticInfo(input = {}) {
2505
2708
  asOf: null,
2506
2709
  erc8004AgentId: null,
2507
2710
  scan8004Url: null,
2711
+ reputation: null,
2508
2712
  dashboardUrl,
2509
2713
  setupHint: "No live Q402 API key configured. Run q402_doctor to set one up, or open your dashboard to create an Agent Wallet."
2510
2714
  };
2511
2715
  }
2512
2716
  let wallet = null;
2513
2717
  let balance = null;
2718
+ let reputation = null;
2514
2719
  let fetchError = null;
2515
2720
  try {
2516
2721
  const res = await fetch(`${base}/wallet/agentic/info-by-key`, {
@@ -2525,6 +2730,7 @@ async function runAgenticInfo(input = {}) {
2525
2730
  const data = await res.json();
2526
2731
  wallet = data.wallet ?? null;
2527
2732
  balance = data.balance ?? null;
2733
+ reputation = data.reputation ?? null;
2528
2734
  } else if (res.status === 404) {
2529
2735
  fetchError = "endpoint_not_deployed";
2530
2736
  } else if (res.status === 410) {
@@ -2546,6 +2752,7 @@ async function runAgenticInfo(input = {}) {
2546
2752
  asOf: null,
2547
2753
  erc8004AgentId: null,
2548
2754
  scan8004Url: null,
2755
+ reputation: null,
2549
2756
  dashboardUrl,
2550
2757
  setupHint: fetchError === "endpoint_not_deployed" ? "Agent Wallet info-by-key endpoint is not live yet. Open the dashboard to view your wallet directly." : fetchError === "wallet_archived" ? "The requested wallet is archived. Restore it from the dashboard before reading." : explicitWalletId ? `Could not fetch Agent Wallet ${explicitWalletId} for this apiKey. Verify the walletId is one of this owner's wallets, or omit it to read the default wallet.` : "Could not fetch Agent Wallet for this apiKey. Verify the key is bound to a wallet via the dashboard, then retry."
2551
2758
  };
@@ -2564,6 +2771,7 @@ async function runAgenticInfo(input = {}) {
2564
2771
  asOf: balance ? new Date(balance.asOf).toISOString() : null,
2565
2772
  erc8004AgentId: wallet.erc8004AgentId,
2566
2773
  scan8004Url: scan8004UrlFor(wallet.erc8004AgentId),
2774
+ reputation,
2567
2775
  dashboardUrl,
2568
2776
  setupHint: wallet.deletedAt ? "This Agent Wallet is archived and pending hard-delete. Restore it from the dashboard before sending." : void 0
2569
2777
  };
@@ -3288,8 +3496,8 @@ async function main() {
3288
3496
  return { content: [jsonText(await runClearDelegation(parsed))] };
3289
3497
  }
3290
3498
  case "q402_agentic_info": {
3291
- AgenticInfoInputSchema.parse(args ?? {});
3292
- return { content: [jsonText(await runAgenticInfo())] };
3499
+ const parsed = AgenticInfoInputSchema.parse(args ?? {});
3500
+ return { content: [jsonText(await runAgenticInfo(parsed))] };
3293
3501
  }
3294
3502
  case "q402_recurring_list": {
3295
3503
  const parsed = RecurringListInputSchema.parse(args ?? {});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quackai/q402-mcp",
3
- "version": "0.7.2",
3
+ "version": "0.7.4",
4
4
  "description": "MCP server for Q402 — gasless USDC, USDT, and RLUSD payments across 9 EVM chains, 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": [