@quackai/q402-mcp 0.5.0 → 0.5.2

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 +4 -2
  2. package/dist/index.js +216 -9
  3. package/package.json +73 -73
package/README.md CHANGED
@@ -103,7 +103,7 @@ Then run `codex` and ask the same kind of question. The first call may take a fe
103
103
 
104
104
  ### Any other MCP client
105
105
 
106
- The server has no client-specific code. If your client speaks stdio MCP, point it at `npx -y @quackai/q402-mcp` and the five tools listed below will appear.
106
+ The server has no client-specific code. If your client speaks stdio MCP, point it at `npx -y @quackai/q402-mcp` and the seven tools listed below will appear.
107
107
 
108
108
  ---
109
109
 
@@ -120,6 +120,8 @@ The server has no client-specific code. If your client speaks stdio MCP, point i
120
120
  | `q402_pay` | API key + private key + flag | Send a gasless payment to a single recipient. **Sandbox by default** — see [Sandbox vs live mode](#sandbox-vs-live-mode). |
121
121
  | `q402_batch_pay` | API key + private key + flag | Send a gasless payment to **multiple** recipients in one call on a single chain × token. Trial keys: 5 rows max. Paid keys: 20 rows max. **Auto-routing:** same rule as `q402_pay` (BNB + Trial key set ⇒ Trial, else Multichain). **Ambiguity gate:** 6+ recipient BNB batches with Trial set return `status="ambiguous"` instead of executing — the agent asks the user to pick `keyScope="trial"` (first 5), `"multichain"` (all paid), or two calls (5 free + remainder paid). **Supported chains: avax, bnb, eth, mantle, injective, monad, scroll** (default EIP-7702 mode). xlayer + stable are NOT batchable — use `q402_pay` in a loop for those. Same sandbox gating as `q402_pay`. **Rate-limit note:** the inner `/api/relay` budget (30/min per key) is consumed per row, so a paid 20-row batch leaves ~10 inner slots for the next minute. |
122
122
  | `q402_receipt` | none | Look up a Trust Receipt by `rct_…` id and locally verify its ECDSA signature against the relayer EOA. Returns the public settlement record + a `verified` boolean. *receiptId-only today; tx-hash lookup reserved for a future release.* |
123
+ | `q402_wallet_status` | private key | Per-chain EIP-7702 delegation status for the EOA derived from `Q402_PRIVATE_KEY`, across all 9 Q402 chains. Read-only — no on-chain action, no quota consumption. Use to answer "why is my wallet showing Smart account?" and to pick chains for `q402_clear_delegation`. |
124
+ | `q402_clear_delegation` | API key + private key | Clear the EIP-7702 delegation on a single chain for the configured wallet. Local signing with `Q402_PRIVATE_KEY` (key never leaves the user's machine); Q402 broadcasts the type-0x04 TX from a sponsor wallet so the user pays $0 gas. After clearing, `eth_getCode` returns `0x` — the next `q402_pay` on that chain auto-recreates a fresh delegation. Useful when the wallet needs to receive native gas tokens (BNB/ETH/etc.) directly without revert, or to remove the wallet UI's "Smart account" indicator. |
123
125
 
124
126
  `q402_pay` and `q402_batch_pay` follow a "confirm in chat first" contract: the tool description instructs the model to never call it without explicit user approval of the recipient address(es), amount(s), chain, and token. For batch calls the user must approve the **full batch**, not the individual rows.
125
127
 
@@ -211,7 +213,7 @@ Combined with the `confirm: true` argument the tool requires, this means the mod
211
213
 
212
214
  x402 standardised "402 Payment Required" semantics for AI agents but the official Coinbase facilitator only covers a few chains and assumes ERC-3009 token support — which excludes BNB USDT, Mantle USDT0, Injective USDT, and the chains where most stablecoin volume actually lives.
213
215
 
214
- Q402 implements the same payer experience (single signature, $0 gas, instant settlement) on all 8 of those chains using EIP-7702 delegated execution, which works with any ERC-20. This MCP server makes that infrastructure addressable from Claude itself.
216
+ Q402 implements the same payer experience (single signature, $0 gas, instant settlement) on all 9 of those chains using EIP-7702 delegated execution, which works with any ERC-20. This MCP server makes that infrastructure addressable from Claude itself.
215
217
 
216
218
  If you want to dig into how the wire protocol differs from x402, see [Q402 docs](https://q402.quackai.ai/docs).
217
219
 
package/dist/index.js CHANGED
@@ -339,7 +339,7 @@ var QUOTE_TOOL = {
339
339
  chain: {
340
340
  type: "string",
341
341
  enum: CHAIN_KEYS,
342
- description: "Optional chain filter; omit to compare all 8."
342
+ description: "Optional chain filter; omit to compare all 9."
343
343
  }
344
344
  },
345
345
  required: ["amount"],
@@ -697,7 +697,7 @@ var PayInputSchema = z2.object({
697
697
  "Stablecoin symbol. USDC / USDT supported on most chains (Injective is USDT-only). RLUSD (Ripple USD, NY DFS regulated, decimals 18) is Ethereum-only."
698
698
  ),
699
699
  keyScope: z2.enum(["auto", "trial", "multichain"]).optional().describe(
700
- '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 8-chain key. Same rule applies to q402_batch_pay.'
700
+ '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 9-chain key. Same rule applies to q402_batch_pay.'
701
701
  ),
702
702
  confirm: z2.literal(true).describe(
703
703
  "MUST be true. Prove the user explicitly approved this exact recipient and amount in the conversation right before this tool was called. Setting this to true on behalf of the user without confirmation is a violation of the tool contract."
@@ -775,7 +775,7 @@ function describeSandboxReason(resolvedKey) {
775
775
  }
776
776
  var PAY_TOOL = {
777
777
  name: "q402_pay",
778
- description: "Send a gasless USDC, USDT, or RLUSD payment via Q402. Auto-routing: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); anything else \u2192 Multichain (paid 9-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 \u2014 USDC/USDT on most chains, RLUSD on Ethereum only, Injective USDT-only. SANDBOX BY DEFAULT \u2014 no funds move unless the resolved key is a live key (q402_live_*), Q402_PRIVATE_KEY is set, and Q402_ENABLE_REAL_PAYMENTS=1. The recipient receives the full amount; the sender pays $0 in gas. ALWAYS get explicit user confirmation of the exact recipient address, amount, chain, and token in conversation immediately before calling this tool.",
778
+ description: "Send a gasless USDC, USDT, or RLUSD payment via Q402. Auto-routing: chain='bnb' + Q402_TRIAL_API_KEY set \u2192 Trial (free sponsored); anything else \u2192 Multichain (paid 9-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 \u2014 USDC/USDT on most chains, RLUSD on Ethereum only, Injective USDT-only. SANDBOX BY DEFAULT \u2014 no funds move unless the resolved key is a live key (q402_live_*), Q402_PRIVATE_KEY is set, and Q402_ENABLE_REAL_PAYMENTS=1. The recipient receives the full amount; the sender pays $0 in gas. Note: the first q402_pay on a chain creates a persistent EIP-7702 delegation on the sender's EOA (set-code TX, Pectra). Subsequent payments on the same chain reuse it (gas-efficient). To remove the delegation later, call q402_clear_delegation. ALWAYS get explicit user confirmation of the exact recipient address, amount, chain, and token in conversation immediately before calling this tool.",
779
779
  inputSchema: {
780
780
  type: "object",
781
781
  properties: {
@@ -800,7 +800,7 @@ var PAY_TOOL = {
800
800
  keyScope: {
801
801
  type: "string",
802
802
  enum: ["auto", "trial", "multichain"],
803
- 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 8-chain key.'
803
+ 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 9-chain key.'
804
804
  },
805
805
  confirm: {
806
806
  type: "boolean",
@@ -833,7 +833,7 @@ var BatchPayInputSchema = z3.object({
833
833
  `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.`
834
834
  ),
835
835
  keyScope: z3.enum(["auto", "trial", "multichain"]).optional().describe(
836
- '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 8-chain key (\u226420 recipients).'
836
+ '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).'
837
837
  ),
838
838
  confirm: z3.literal(true).describe(
839
839
  "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."
@@ -960,7 +960,7 @@ function describeSandboxReason2(resolvedKey) {
960
960
  }
961
961
  var BATCH_PAY_TOOL = {
962
962
  name: "q402_batch_pay",
963
- description: `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 EIP-7702 default 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. 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.`,
963
+ description: `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 EIP-7702 default 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. Note: same EIP-7702 delegation behaviour as q402_pay \u2014 the first call on a chain creates a persistent set-code delegation on the sender's EOA, reused by subsequent calls. Use q402_clear_delegation to remove. 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.`,
964
964
  inputSchema: {
965
965
  type: "object",
966
966
  properties: {
@@ -1052,7 +1052,7 @@ async function runBalance() {
1052
1052
  apiKeyMasked: null,
1053
1053
  scopes: [],
1054
1054
  dashboardUrl: "https://q402.quackai.ai/dashboard",
1055
- setupHint: "Set Q402_TRIAL_API_KEY (BNB-only sponsored, free at /event) and/or Q402_MULTICHAIN_API_KEY (paid 8-chain from /dashboard). Single-env legacy: Q402_API_KEY also works."
1055
+ setupHint: "Set Q402_TRIAL_API_KEY (BNB-only sponsored, free at /event) and/or Q402_MULTICHAIN_API_KEY (paid 9-chain from /dashboard). Single-env legacy: Q402_API_KEY also works."
1056
1056
  };
1057
1057
  }
1058
1058
  const scopes = await Promise.all(
@@ -1249,9 +1249,200 @@ var RECEIPT_TOOL = {
1249
1249
  }
1250
1250
  };
1251
1251
 
1252
+ // src/tools/wallet-status.ts
1253
+ import { z as z6 } from "zod";
1254
+ import { Wallet as Wallet2 } from "ethers";
1255
+ var WalletStatusInputSchema = z6.object({});
1256
+ async function runWalletStatus() {
1257
+ if (!CONFIG.privateKey) {
1258
+ return {
1259
+ error: "MISSING_PRIVATE_KEY",
1260
+ hint: "Set Q402_PRIVATE_KEY in the MCP environment so this tool can derive the EOA to inspect."
1261
+ };
1262
+ }
1263
+ let address;
1264
+ try {
1265
+ address = new Wallet2(CONFIG.privateKey).address;
1266
+ } catch {
1267
+ return {
1268
+ error: "INVALID_PRIVATE_KEY",
1269
+ hint: "Q402_PRIVATE_KEY is set but does not parse as a valid 32-byte hex private key."
1270
+ };
1271
+ }
1272
+ const url = `${CONFIG.relayBaseUrl.replace(/\/$/, "")}/wallet/delegation-status?address=${address}`;
1273
+ let body;
1274
+ try {
1275
+ const res = await fetch(url);
1276
+ body = await res.json();
1277
+ if (!res.ok) {
1278
+ return {
1279
+ address,
1280
+ error: typeof body === "object" && body && "error" in body ? String(body.error) : `HTTP ${res.status}`
1281
+ };
1282
+ }
1283
+ } catch (e) {
1284
+ return {
1285
+ address,
1286
+ error: e instanceof Error ? e.message : String(e)
1287
+ };
1288
+ }
1289
+ const parsed = body;
1290
+ return {
1291
+ address: parsed.address,
1292
+ chains: parsed.chains,
1293
+ summary: parsed.summary
1294
+ };
1295
+ }
1296
+ var WALLET_STATUS_TOOL = {
1297
+ name: "q402_wallet_status",
1298
+ description: "Report the EIP-7702 delegation status of your Q402 wallet (the EOA derived from Q402_PRIVATE_KEY) across all 9 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. Use this before q402_clear_delegation to figure out which chains need a cleanup, or when answering 'why is my wallet showing Smart account?' Requires Q402_PRIVATE_KEY in env (same as q402_pay).",
1299
+ inputSchema: {
1300
+ type: "object",
1301
+ properties: {},
1302
+ additionalProperties: false
1303
+ }
1304
+ };
1305
+
1306
+ // src/tools/clear-delegation.ts
1307
+ import { z as z7 } from "zod";
1308
+ import { Wallet as Wallet3, JsonRpcProvider as JsonRpcProvider2 } from "ethers";
1309
+ var ZERO_ADDRESS = "0x0000000000000000000000000000000000000000";
1310
+ var DEFAULT_RPC2 = {
1311
+ 1: "https://ethereum.publicnode.com",
1312
+ 56: "https://bsc-dataseed1.binance.org/",
1313
+ 143: "https://rpc.monad.xyz",
1314
+ 196: "https://rpc.xlayer.tech",
1315
+ 988: "https://rpc.stable.xyz",
1316
+ 1776: "https://sentry.evm-rpc.injective.network/",
1317
+ 5e3: "https://rpc.mantle.xyz",
1318
+ 43114: "https://api.avax.network/ext/bc/C/rpc",
1319
+ 534352: "https://rpc.scroll.io"
1320
+ };
1321
+ var ClearDelegationInputSchema = z7.object({
1322
+ chain: z7.enum(["avax", "bnb", "eth", "xlayer", "stable", "mantle", "injective", "monad", "scroll"]).describe("Which Q402 chain to clear the delegation on.")
1323
+ });
1324
+ async function runClearDelegation(input) {
1325
+ if (!CONFIG.privateKey) {
1326
+ return {
1327
+ ok: false,
1328
+ error: "MISSING_PRIVATE_KEY",
1329
+ hint: "Set Q402_PRIVATE_KEY in the MCP environment \u2014 same key q402_pay uses. The MCP tool signs locally and never sends the key to Q402."
1330
+ };
1331
+ }
1332
+ const cfg = CHAIN_CONFIG[input.chain];
1333
+ if (!cfg) {
1334
+ return { ok: false, error: "INVALID_CHAIN", hint: `Unknown chain: ${input.chain}` };
1335
+ }
1336
+ let wallet;
1337
+ try {
1338
+ const provider = new JsonRpcProvider2(DEFAULT_RPC2[cfg.chainId]);
1339
+ wallet = new Wallet3(CONFIG.privateKey, provider);
1340
+ } catch {
1341
+ return {
1342
+ ok: false,
1343
+ error: "INVALID_PRIVATE_KEY",
1344
+ hint: "Q402_PRIVATE_KEY is set but does not parse as a valid 32-byte hex private key."
1345
+ };
1346
+ }
1347
+ const address = wallet.address;
1348
+ let nonce;
1349
+ try {
1350
+ nonce = await wallet.provider.getTransactionCount(address);
1351
+ } catch (e) {
1352
+ return {
1353
+ ok: false,
1354
+ address,
1355
+ error: "RPC_FAILED",
1356
+ hint: `Could not read transaction count for ${address} on ${input.chain}: ${e instanceof Error ? e.message : String(e)}`
1357
+ };
1358
+ }
1359
+ let auth;
1360
+ try {
1361
+ auth = await wallet.authorize({
1362
+ chainId: cfg.chainId,
1363
+ address: ZERO_ADDRESS,
1364
+ nonce
1365
+ });
1366
+ } catch (e) {
1367
+ return {
1368
+ ok: false,
1369
+ address,
1370
+ error: "SIGN_FAILED",
1371
+ hint: `Local signing failed: ${e instanceof Error ? e.message : String(e)}`
1372
+ };
1373
+ }
1374
+ const url = `${CONFIG.relayBaseUrl.replace(/\/$/, "")}/wallet/clear-delegation`;
1375
+ const body = {
1376
+ chain: input.chain,
1377
+ address,
1378
+ authorization: {
1379
+ chainId: Number(auth.chainId),
1380
+ address: auth.address,
1381
+ nonce: Number(auth.nonce),
1382
+ yParity: auth.signature.yParity,
1383
+ r: auth.signature.r,
1384
+ s: auth.signature.s
1385
+ }
1386
+ };
1387
+ let res;
1388
+ let json;
1389
+ try {
1390
+ res = await fetch(url, {
1391
+ method: "POST",
1392
+ headers: { "Content-Type": "application/json" },
1393
+ body: JSON.stringify(body)
1394
+ });
1395
+ json = await res.json();
1396
+ } catch (e) {
1397
+ return {
1398
+ ok: false,
1399
+ address,
1400
+ error: "RELAY_UNREACHABLE",
1401
+ hint: `Could not reach Q402 relay at ${url}: ${e instanceof Error ? e.message : String(e)}`
1402
+ };
1403
+ }
1404
+ if (!res.ok) {
1405
+ const errBody = json;
1406
+ return {
1407
+ ok: false,
1408
+ address,
1409
+ chain: input.chain,
1410
+ error: errBody.error ?? `HTTP ${res.status}`,
1411
+ hint: errBody.reason
1412
+ };
1413
+ }
1414
+ const ok = json;
1415
+ return {
1416
+ ok: true,
1417
+ chain: input.chain,
1418
+ address,
1419
+ txHash: ok.txHash,
1420
+ blockNumber: ok.blockNumber,
1421
+ gasUsed: ok.gasUsed,
1422
+ cleared: ok.cleared,
1423
+ explorerUrl: ok.explorerUrl
1424
+ };
1425
+ }
1426
+ var CLEAR_DELEGATION_TOOL = {
1427
+ name: "q402_clear_delegation",
1428
+ description: "Clear the EIP-7702 delegation on a Q402 chain for the configured wallet. After your first q402_pay on a chain, Q402 delegates your EOA to a vetted implementation contract (Pectra set-code transaction) so subsequent payments are gasless without redoing the authorization each time. The delegation persists until explicitly cleared. Call this when: (a) the user wants to receive native gas tokens (BNB/ ETH/etc.) directly to their EOA without revert, (b) the wallet UI is showing a 'Smart account' indicator the user wants to remove, or (c) the user explicitly asks to 'clean up' or 'reset' the delegation. Do NOT call this immediately before another q402_pay on the same chain \u2014 the next payment would just re-create the delegation, wasting one TX. Pair with q402_wallet_status first to see which chains actually have an active delegation. Signing happens locally with Q402_PRIVATE_KEY; the signed authorization is POSTed to Q402 which broadcasts the type-0x04 TX from a sponsor wallet \u2014 the user pays zero gas. Requires Q402_PRIVATE_KEY in env.",
1429
+ inputSchema: {
1430
+ type: "object",
1431
+ properties: {
1432
+ chain: {
1433
+ type: "string",
1434
+ enum: CHAIN_KEYS,
1435
+ description: "Which Q402 chain to clear the delegation on."
1436
+ }
1437
+ },
1438
+ required: ["chain"],
1439
+ additionalProperties: false
1440
+ }
1441
+ };
1442
+
1252
1443
  // src/index.ts
1253
1444
  var PACKAGE_NAME = "@quackai/q402-mcp";
1254
- var PACKAGE_VERSION = "0.5.0";
1445
+ var PACKAGE_VERSION = "0.5.2";
1255
1446
  function jsonText(value) {
1256
1447
  return { type: "text", text: JSON.stringify(value, null, 2) };
1257
1448
  }
@@ -1261,7 +1452,15 @@ async function main() {
1261
1452
  { capabilities: { tools: {} } }
1262
1453
  );
1263
1454
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
1264
- tools: [QUOTE_TOOL, BALANCE_TOOL, PAY_TOOL, BATCH_PAY_TOOL, RECEIPT_TOOL]
1455
+ tools: [
1456
+ QUOTE_TOOL,
1457
+ BALANCE_TOOL,
1458
+ PAY_TOOL,
1459
+ BATCH_PAY_TOOL,
1460
+ RECEIPT_TOOL,
1461
+ WALLET_STATUS_TOOL,
1462
+ CLEAR_DELEGATION_TOOL
1463
+ ]
1265
1464
  }));
1266
1465
  server.setRequestHandler(CallToolRequestSchema, async (req) => {
1267
1466
  const { name, arguments: args } = req.params;
@@ -1287,6 +1486,14 @@ async function main() {
1287
1486
  const parsed = ReceiptInputSchema.parse(args ?? {});
1288
1487
  return { content: [jsonText(await runReceipt(parsed))] };
1289
1488
  }
1489
+ case "q402_wallet_status": {
1490
+ WalletStatusInputSchema.parse(args ?? {});
1491
+ return { content: [jsonText(await runWalletStatus())] };
1492
+ }
1493
+ case "q402_clear_delegation": {
1494
+ const parsed = ClearDelegationInputSchema.parse(args ?? {});
1495
+ return { content: [jsonText(await runClearDelegation(parsed))] };
1496
+ }
1290
1497
  default:
1291
1498
  return {
1292
1499
  isError: true,
package/package.json CHANGED
@@ -1,73 +1,73 @@
1
- {
2
- "name": "@quackai/q402-mcp",
3
- "version": "0.5.0",
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
- "mcpName": "io.github.bitgett/q402-mcp",
6
- "keywords": [
7
- "mcp",
8
- "model-context-protocol",
9
- "claude",
10
- "claude-desktop",
11
- "claude-code",
12
- "codex",
13
- "openai-codex",
14
- "cline",
15
- "q402",
16
- "x402",
17
- "stablecoin",
18
- "usdc",
19
- "usdt",
20
- "rlusd",
21
- "ripple",
22
- "gasless",
23
- "eip-7702",
24
- "payments",
25
- "ai-agents"
26
- ],
27
- "type": "module",
28
- "main": "dist/index.js",
29
- "bin": {
30
- "q402-mcp": "dist/index.js"
31
- },
32
- "files": [
33
- "dist",
34
- "README.md",
35
- "LICENSE"
36
- ],
37
- "engines": {
38
- "node": ">=18.18"
39
- },
40
- "scripts": {
41
- "build": "tsup",
42
- "dev": "tsup --watch",
43
- "lint": "tsc --noEmit",
44
- "prepublishOnly": "npm run lint && npm run build",
45
- "start": "node dist/index.js"
46
- },
47
- "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.29.0",
49
- "ethers": "^6.16.0",
50
- "zod": "^3.23.8"
51
- },
52
- "devDependencies": {
53
- "@types/node": "^20.11.0",
54
- "tsup": "^8.3.0",
55
- "typescript": "^5.5.0"
56
- },
57
- "repository": {
58
- "type": "git",
59
- "url": "git+https://github.com/bitgett/q402-mcp.git"
60
- },
61
- "homepage": "https://q402.quackai.ai/claude",
62
- "bugs": {
63
- "url": "https://github.com/bitgett/q402-mcp/issues"
64
- },
65
- "license": "Apache-2.0",
66
- "author": "David Lee <davidlee@quackai.ai>",
67
- "publishConfig": {
68
- "access": "public"
69
- },
70
- "overrides": {
71
- "ws": "^8.20.1"
72
- }
73
- }
1
+ {
2
+ "name": "@quackai/q402-mcp",
3
+ "version": "0.5.2",
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
+ "mcpName": "io.github.bitgett/q402-mcp",
6
+ "keywords": [
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "claude",
10
+ "claude-desktop",
11
+ "claude-code",
12
+ "codex",
13
+ "openai-codex",
14
+ "cline",
15
+ "q402",
16
+ "x402",
17
+ "stablecoin",
18
+ "usdc",
19
+ "usdt",
20
+ "rlusd",
21
+ "ripple",
22
+ "gasless",
23
+ "eip-7702",
24
+ "payments",
25
+ "ai-agents"
26
+ ],
27
+ "type": "module",
28
+ "main": "dist/index.js",
29
+ "bin": {
30
+ "q402-mcp": "dist/index.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md",
35
+ "LICENSE"
36
+ ],
37
+ "engines": {
38
+ "node": ">=18.18"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "dev": "tsup --watch",
43
+ "lint": "tsc --noEmit",
44
+ "prepublishOnly": "npm run lint && npm run build",
45
+ "start": "node dist/index.js"
46
+ },
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.29.0",
49
+ "ethers": "^6.16.0",
50
+ "zod": "^3.23.8"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^20.11.0",
54
+ "tsup": "^8.3.0",
55
+ "typescript": "^5.5.0"
56
+ },
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/bitgett/q402-mcp.git"
60
+ },
61
+ "homepage": "https://q402.quackai.ai/claude",
62
+ "bugs": {
63
+ "url": "https://github.com/bitgett/q402-mcp/issues"
64
+ },
65
+ "license": "Apache-2.0",
66
+ "author": "David Lee <davidlee@quackai.ai>",
67
+ "publishConfig": {
68
+ "access": "public"
69
+ },
70
+ "overrides": {
71
+ "ws": "^8.20.1"
72
+ }
73
+ }