@quackai/q402-mcp 0.6.3 → 0.6.5

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 +14 -0
  2. package/dist/index.js +108 -1
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -157,6 +157,20 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
157
157
 
158
158
  ---
159
159
 
160
+ ## Wallet modes — which signing path?
161
+
162
+ Three signing paths. Pick one when `q402_doctor` asks on first install. You can change later by editing `~/.q402/mcp.env` and restarting your client.
163
+
164
+ | Mode | Best for | Env to set | Private key in env? |
165
+ |---|---|---|---|
166
+ | **C — Server-managed** (recommended) | Most users. AI agents, automations, anyone who wants payments to "just work". Q402 holds an encrypted Agent Wallet for you; no MetaMask popup, no Smart-account marker. | `Q402_MULTICHAIN_API_KEY` (paid) **or** `Q402_TRIAL_API_KEY` (free BNB) | **No** |
167
+ | **B — Local Agent Wallet PK** | You want Agent Wallet automation but prefer to hold the PK yourself. Export from the dashboard once. MCP signs locally — key never leaves your machine. Your MetaMask is never touched. | `Q402_AGENTIC_PRIVATE_KEY` + an API key | Yes (Agent Wallet's exported PK) |
168
+ | **A — Your own EOA** | Power users who want their existing MetaMask address to be the on-chain payer. Your EOA signs directly via EIP-7702; the "Smart account" marker after first use is normal + reversible with `q402_clear_delegation`. **Use a fresh wallet.** | `Q402_PRIVATE_KEY` + an API key | Yes (your EOA's PK) |
169
+
170
+ `q402_doctor` on first install reads your env and recommends one of these based on what's already configured. The default for an empty install is Mode C — simplest path. If multiple modes are configured at once (e.g. both `Q402_PRIVATE_KEY` and `Q402_AGENTIC_PRIVATE_KEY` set), `q402_pay` will ask which one to use before sending so the agent never silently picks the wrong wallet.
171
+
172
+ ---
173
+
160
174
  ## Tools exposed
161
175
 
162
176
  | Tool | Auth | Purpose |
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.6.3";
214
+ var PACKAGE_VERSION = "0.6.5";
215
215
 
216
216
  // src/tools/quote.ts
217
217
  import { z } from "zod";
@@ -2869,6 +2869,108 @@ async function runRecurringCancel(input) {
2869
2869
  }
2870
2870
  }
2871
2871
 
2872
+ // src/tools/recurring-fires.ts
2873
+ import { z as z13 } from "zod";
2874
+ var RecurringFiresInputSchema = z13.object({
2875
+ ruleId: z13.string().min(1).describe(
2876
+ "Rule id whose fire history to fetch. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field."
2877
+ ),
2878
+ limit: z13.number().int().min(1).max(50).optional().describe(
2879
+ "Max number of fires to return (newest first). Defaults to 50 (the server cap). Pass a smaller number when you only need the most recent few."
2880
+ ),
2881
+ walletId: z13.string().optional().describe(
2882
+ "Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
2883
+ )
2884
+ });
2885
+ var RECURRING_FIRES_TOOL = {
2886
+ name: "q402_recurring_fires",
2887
+ description: "Read the past-fire history of a specific recurring-payment rule. Returns up to 50 entries (newest first), each with the timestamp, scheduled slot, total USD amount that settled, on-chain tx hashes, and a partial-failure flag if some recipient rows didn't make it. Use this when the user asks 'when was the last fire?', 'did Friday's payout go out?', 'how much has rule X spent?', or before claiming a fire is missing. Authenticated by the configured Multichain API key. Read-only \u2014 does not trigger or modify anything. Call q402_recurring_list first to find the ruleId.",
2888
+ inputSchema: {
2889
+ type: "object",
2890
+ properties: {
2891
+ ruleId: {
2892
+ type: "string",
2893
+ description: "Rule id from q402_recurring_list. Required."
2894
+ },
2895
+ limit: {
2896
+ type: "number",
2897
+ description: "Max number of fires to return (1-50, newest first). Defaults to 50."
2898
+ },
2899
+ walletId: {
2900
+ type: "string",
2901
+ description: "Optional. Lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet on the server."
2902
+ }
2903
+ },
2904
+ required: ["ruleId"],
2905
+ additionalProperties: false
2906
+ }
2907
+ };
2908
+ async function runRecurringFires(input) {
2909
+ const base = CONFIG.relayBaseUrl;
2910
+ const dashboardUrl = base.replace(/\/api$/, "") + "/dashboard?tab=agent";
2911
+ if (!CONFIG.apiKey || !CONFIG.apiKey.startsWith("q402_live_")) {
2912
+ return {
2913
+ configured: false,
2914
+ walletId: null,
2915
+ ruleId: input.ruleId,
2916
+ rule: null,
2917
+ fires: [],
2918
+ count: 0,
2919
+ dashboardUrl,
2920
+ setupHint: "No live Q402 API key configured. Run q402_doctor to set one up, or open the dashboard to view fire history from the UI."
2921
+ };
2922
+ }
2923
+ const explicitWalletId = typeof input.walletId === "string" && input.walletId.length > 0 ? input.walletId.toLowerCase() : CONFIG.walletId;
2924
+ try {
2925
+ const res = await fetch(`${base}/wallet/agentic/recurring-by-key`, {
2926
+ method: "POST",
2927
+ headers: { "Content-Type": "application/json" },
2928
+ body: JSON.stringify({
2929
+ apiKey: CONFIG.apiKey,
2930
+ action: "fires",
2931
+ ruleId: input.ruleId,
2932
+ ...typeof input.limit === "number" ? { limit: input.limit } : {},
2933
+ ...explicitWalletId ? { walletId: explicitWalletId } : {}
2934
+ })
2935
+ });
2936
+ const data = await res.json().catch(() => ({}));
2937
+ if (!res.ok) {
2938
+ return {
2939
+ configured: true,
2940
+ walletId: explicitWalletId,
2941
+ ruleId: input.ruleId,
2942
+ rule: null,
2943
+ fires: [],
2944
+ count: 0,
2945
+ dashboardUrl,
2946
+ error: data.error ?? `HTTP_${res.status}`,
2947
+ message: data.message ?? `Fires fetch failed with HTTP ${res.status}.`
2948
+ };
2949
+ }
2950
+ return {
2951
+ configured: true,
2952
+ walletId: data.walletId ?? explicitWalletId,
2953
+ ruleId: data.ruleId ?? input.ruleId,
2954
+ rule: data.rule ?? null,
2955
+ fires: Array.isArray(data.fires) ? data.fires : [],
2956
+ count: typeof data.count === "number" ? data.count : data.fires?.length ?? 0,
2957
+ dashboardUrl
2958
+ };
2959
+ } catch (e) {
2960
+ return {
2961
+ configured: true,
2962
+ walletId: explicitWalletId,
2963
+ ruleId: input.ruleId,
2964
+ rule: null,
2965
+ fires: [],
2966
+ count: 0,
2967
+ dashboardUrl,
2968
+ error: "NETWORK_ERROR",
2969
+ message: e instanceof Error ? e.message : String(e)
2970
+ };
2971
+ }
2972
+ }
2973
+
2872
2974
  // src/index.ts
2873
2975
  function jsonText(value) {
2874
2976
  return { type: "text", text: JSON.stringify(value, null, 2) };
@@ -2892,6 +2994,7 @@ async function main() {
2892
2994
  AGENTIC_INFO_TOOL,
2893
2995
  RECURRING_LIST_TOOL,
2894
2996
  RECURRING_CREATE_TOOL,
2997
+ RECURRING_FIRES_TOOL,
2895
2998
  RECURRING_CANCEL_TOOL,
2896
2999
  CLEAR_DELEGATION_TOOL
2897
3000
  ]
@@ -2948,6 +3051,10 @@ async function main() {
2948
3051
  const parsed = RecurringCancelInputSchema.parse(args ?? {});
2949
3052
  return { content: [jsonText(await runRecurringCancel(parsed))] };
2950
3053
  }
3054
+ case "q402_recurring_fires": {
3055
+ const parsed = RecurringFiresInputSchema.parse(args ?? {});
3056
+ return { content: [jsonText(await runRecurringFires(parsed))] };
3057
+ }
2951
3058
  default:
2952
3059
  return {
2953
3060
  isError: true,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quackai/q402-mcp",
3
- "version": "0.6.3",
3
+ "version": "0.6.5",
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": [