@quackai/q402-mcp 0.6.5 → 0.7.0
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.
- package/README.md +2 -2
- package/dist/index.js +269 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -70,7 +70,7 @@ Q402 supports three signing modes — pick ONE:
|
|
|
70
70
|
|---|---|---|---|
|
|
71
71
|
| **A** | `Q402_PRIVATE_KEY` | your MetaMask EOA, local | Simplest. After the first payment that EOA shows "Smart account" in MetaMask (EIP-7702 delegation, reversible via `q402_clear_delegation`). |
|
|
72
72
|
| **B** | `Q402_AGENTIC_PRIVATE_KEY` | dedicated Agent Wallet, local | Export the PK from the [dashboard](https://q402.quackai.ai/dashboard) Agent tab → Export. Signs locally just like Mode A, but the signer is your Agent Wallet — MetaMask is never touched. Recommended for AI-agent automation. |
|
|
73
|
-
| **C** | (just
|
|
73
|
+
| **C** | (just an API key) | dedicated Agent Wallet, server-managed | The encrypted Agent Wallet key lives on the Q402 server and signs on your behalf. No private key on the client. Optionally set `Q402_AGENT_WALLET_ADDRESS` to pick among multiple wallets (max 10 per owner). **One-shot pays** work with either `Q402_TRIAL_API_KEY` (BNB-only sponsored) or `Q402_MULTICHAIN_API_KEY` (paid, all 9 chains). **Recurring** (`q402_recurring_create`) requires the paid Multichain key on every chain, including BNB. |
|
|
74
74
|
|
|
75
75
|
When more than one signing mode is set at once, `q402_pay` asks the user which to use rather than picking silently. The picker lives in the `walletMode` argument: `"agentic-server"` (Mode C), `"agentic-local"` (Mode B), `"eoa"` (Mode A).
|
|
76
76
|
|
|
@@ -163,7 +163,7 @@ Three signing paths. Pick one when `q402_doctor` asks on first install. You can
|
|
|
163
163
|
|
|
164
164
|
| Mode | Best for | Env to set | Private key in env? |
|
|
165
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** |
|
|
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. One-shot pays accept either key; **recurring schedules require the paid Multichain key on every chain (BNB included)**. | `Q402_MULTICHAIN_API_KEY` (paid, full surface) **or** `Q402_TRIAL_API_KEY` (free BNB, one-shot only) | **No** |
|
|
167
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
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
169
|
|
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.
|
|
214
|
+
var PACKAGE_VERSION = "0.7.0";
|
|
215
215
|
|
|
216
216
|
// src/tools/quote.ts
|
|
217
217
|
import { z } from "zod";
|
|
@@ -2268,8 +2268,8 @@ async function runDoctor() {
|
|
|
2268
2268
|
{
|
|
2269
2269
|
pick: "C",
|
|
2270
2270
|
title: "Q402 server signs for me (recommended, simplest)",
|
|
2271
|
-
description: "Q402 holds an encrypted Agent Wallet for you. You only set an API key \u2014 no private key in your env, no MetaMask popup, no Smart-account marker on your wallet. Best for AI agents, automations, and anyone who just wants payments to work.",
|
|
2272
|
-
env: ["Q402_MULTICHAIN_API_KEY (paid)", "or Q402_TRIAL_API_KEY (free BNB)"],
|
|
2271
|
+
description: "Q402 holds an encrypted Agent Wallet for you. You only set an API key \u2014 no private key in your env, no MetaMask popup, no Smart-account marker on your wallet. Best for AI agents, automations, and anyone who just wants payments to work. One-shot pays accept either key below; recurring schedules require the paid Multichain key on every chain (BNB included).",
|
|
2272
|
+
env: ["Q402_MULTICHAIN_API_KEY (paid \u2014 required for recurring)", "or Q402_TRIAL_API_KEY (free BNB, one-shot pays only)"],
|
|
2273
2273
|
privateKeyRequired: false
|
|
2274
2274
|
},
|
|
2275
2275
|
{
|
|
@@ -2407,7 +2407,7 @@ async function runDoctor() {
|
|
|
2407
2407
|
primary: modes.primary,
|
|
2408
2408
|
/** Plain-English picker that the AI should echo when the user asks
|
|
2409
2409
|
* "which mode do I use?" or "do I need a private key?". */
|
|
2410
|
-
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." : 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 (
|
|
2410
|
+
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 9 chains. Q402_TRIAL_API_KEY alone unlocks one-shot pays on BNB only; recurring requires the paid key.",
|
|
2411
2411
|
/** All three modes documented so the AI can answer "what are my
|
|
2412
2412
|
* options?" without re-deriving from envState. */
|
|
2413
2413
|
catalog: [
|
|
@@ -2661,7 +2661,7 @@ var RecurringCreateInputSchema = z11.object({
|
|
|
2661
2661
|
'Amount per fire, as a decimal string (e.g. "1.5", "0.0001"). Counted in the same unit as `token` (USDC or USDT, both 1:1 USD).'
|
|
2662
2662
|
),
|
|
2663
2663
|
chain: z11.enum(["bnb", "eth", "avax", "xlayer", "mantle", "injective", "monad", "scroll", "stable"]).default("bnb").describe(
|
|
2664
|
-
"Chain to fire the recurring TX on. Defaults to bnb
|
|
2664
|
+
"Chain to fire the recurring TX on. Defaults to bnb. Recurring requires the paid Multichain subscription on EVERY chain, including bnb \u2014 Trial keys are rejected at create time with MULTICHAIN_REQUIRED. Trial keys can still pay one-shot via q402_pay on BNB."
|
|
2665
2665
|
),
|
|
2666
2666
|
token: z11.enum(["USDC", "USDT"]).default("USDT").describe("Stablecoin to send. USDC or USDT. Both peg to USD-1."),
|
|
2667
2667
|
label: z11.string().max(64).optional().describe("Optional human-readable label (\u226464 chars). Shows up in q402_recurring_list and the dashboard."),
|
|
@@ -2971,6 +2971,255 @@ async function runRecurringFires(input) {
|
|
|
2971
2971
|
}
|
|
2972
2972
|
}
|
|
2973
2973
|
|
|
2974
|
+
// src/tools/recurring-pause.ts
|
|
2975
|
+
import { z as z14 } from "zod";
|
|
2976
|
+
var RecurringPauseInputSchema = z14.object({
|
|
2977
|
+
ruleId: z14.string().min(1).describe(
|
|
2978
|
+
"Rule id to pause. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field. Pausing is immediate and reversible."
|
|
2979
|
+
),
|
|
2980
|
+
walletId: z14.string().optional().describe(
|
|
2981
|
+
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
2982
|
+
)
|
|
2983
|
+
});
|
|
2984
|
+
var RECURRING_PAUSE_TOOL = {
|
|
2985
|
+
name: "q402_recurring_pause",
|
|
2986
|
+
description: `Pause an active recurring-payment rule. Takes a ruleId (from q402_recurring_list). The rule transitions to status "paused" \u2014 the cron skips it on every tick until you resume. Fully reversible via q402_recurring_resume. Use this when the user says 'pause my Friday payout' or 'hold on, stop my recurring rule for now' \u2014 gentler than cancel, no re-authoring required. Authenticated by the paid Multichain API key (same gate as create/cancel). Read q402_recurring_list first to find the matching ruleId.`,
|
|
2987
|
+
inputSchema: {
|
|
2988
|
+
type: "object",
|
|
2989
|
+
properties: {
|
|
2990
|
+
ruleId: {
|
|
2991
|
+
type: "string",
|
|
2992
|
+
description: "Rule id from q402_recurring_list. Required."
|
|
2993
|
+
},
|
|
2994
|
+
walletId: {
|
|
2995
|
+
type: "string",
|
|
2996
|
+
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."
|
|
2997
|
+
}
|
|
2998
|
+
},
|
|
2999
|
+
required: ["ruleId"],
|
|
3000
|
+
additionalProperties: false
|
|
3001
|
+
}
|
|
3002
|
+
};
|
|
3003
|
+
async function runRecurringPause(input) {
|
|
3004
|
+
const base = CONFIG.relayBaseUrl;
|
|
3005
|
+
const dashboardUrl = base.replace(/\/api$/, "") + "/dashboard?tab=agent";
|
|
3006
|
+
if (!CONFIG.apiKey || !CONFIG.apiKey.startsWith("q402_live_")) {
|
|
3007
|
+
return {
|
|
3008
|
+
ok: false,
|
|
3009
|
+
walletId: null,
|
|
3010
|
+
rule: null,
|
|
3011
|
+
error: "API_KEY_REQUIRED",
|
|
3012
|
+
message: "No live Q402 API key configured. Run q402_doctor to set one up.",
|
|
3013
|
+
dashboardUrl
|
|
3014
|
+
};
|
|
3015
|
+
}
|
|
3016
|
+
const explicitWalletId = typeof input.walletId === "string" && input.walletId.length > 0 ? input.walletId.toLowerCase() : CONFIG.walletId;
|
|
3017
|
+
try {
|
|
3018
|
+
const res = await fetch(`${base}/wallet/agentic/recurring-by-key`, {
|
|
3019
|
+
method: "POST",
|
|
3020
|
+
headers: { "Content-Type": "application/json" },
|
|
3021
|
+
body: JSON.stringify({
|
|
3022
|
+
apiKey: CONFIG.apiKey,
|
|
3023
|
+
action: "pause",
|
|
3024
|
+
ruleId: input.ruleId,
|
|
3025
|
+
...explicitWalletId ? { walletId: explicitWalletId } : {}
|
|
3026
|
+
})
|
|
3027
|
+
});
|
|
3028
|
+
const data = await res.json().catch(() => ({}));
|
|
3029
|
+
if (!res.ok) {
|
|
3030
|
+
return {
|
|
3031
|
+
ok: false,
|
|
3032
|
+
walletId: explicitWalletId,
|
|
3033
|
+
rule: null,
|
|
3034
|
+
error: data.error ?? `HTTP_${res.status}`,
|
|
3035
|
+
message: data.message ?? `Pause failed with HTTP ${res.status}.`,
|
|
3036
|
+
dashboardUrl
|
|
3037
|
+
};
|
|
3038
|
+
}
|
|
3039
|
+
return {
|
|
3040
|
+
ok: true,
|
|
3041
|
+
walletId: data.walletId ?? explicitWalletId,
|
|
3042
|
+
rule: data.rule ?? null,
|
|
3043
|
+
dashboardUrl
|
|
3044
|
+
};
|
|
3045
|
+
} catch (e) {
|
|
3046
|
+
return {
|
|
3047
|
+
ok: false,
|
|
3048
|
+
walletId: explicitWalletId,
|
|
3049
|
+
rule: null,
|
|
3050
|
+
error: "NETWORK_ERROR",
|
|
3051
|
+
message: e instanceof Error ? e.message : String(e),
|
|
3052
|
+
dashboardUrl
|
|
3053
|
+
};
|
|
3054
|
+
}
|
|
3055
|
+
}
|
|
3056
|
+
|
|
3057
|
+
// src/tools/recurring-resume.ts
|
|
3058
|
+
import { z as z15 } from "zod";
|
|
3059
|
+
var RecurringResumeInputSchema = z15.object({
|
|
3060
|
+
ruleId: z15.string().min(1).describe(
|
|
3061
|
+
"Rule id to resume. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field. Resume is immediate; nextRunAt advances to the next valid slot."
|
|
3062
|
+
),
|
|
3063
|
+
walletId: z15.string().optional().describe(
|
|
3064
|
+
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3065
|
+
)
|
|
3066
|
+
});
|
|
3067
|
+
var RECURRING_RESUME_TOOL = {
|
|
3068
|
+
name: "q402_recurring_resume",
|
|
3069
|
+
description: "Resume a paused or stopped recurring-payment rule. Takes a ruleId (from q402_recurring_list). Supported transitions: paused \u2192 active, paused-by-archive \u2192 active (after restoring the wallet), and fired-cap-exceeded \u2192 active (after raising the per-tx cap or re-subscribing). nextRunAt is advanced to the next valid slot so the rule doesn't immediately fire on a stale schedule. Cancelled rules cannot be resumed \u2014 re-author via q402_recurring_create. Authenticated by the paid Multichain API key.",
|
|
3070
|
+
inputSchema: {
|
|
3071
|
+
type: "object",
|
|
3072
|
+
properties: {
|
|
3073
|
+
ruleId: {
|
|
3074
|
+
type: "string",
|
|
3075
|
+
description: "Rule id from q402_recurring_list. Required."
|
|
3076
|
+
},
|
|
3077
|
+
walletId: {
|
|
3078
|
+
type: "string",
|
|
3079
|
+
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."
|
|
3080
|
+
}
|
|
3081
|
+
},
|
|
3082
|
+
required: ["ruleId"],
|
|
3083
|
+
additionalProperties: false
|
|
3084
|
+
}
|
|
3085
|
+
};
|
|
3086
|
+
async function runRecurringResume(input) {
|
|
3087
|
+
const base = CONFIG.relayBaseUrl;
|
|
3088
|
+
const dashboardUrl = base.replace(/\/api$/, "") + "/dashboard?tab=agent";
|
|
3089
|
+
if (!CONFIG.apiKey || !CONFIG.apiKey.startsWith("q402_live_")) {
|
|
3090
|
+
return {
|
|
3091
|
+
ok: false,
|
|
3092
|
+
walletId: null,
|
|
3093
|
+
rule: null,
|
|
3094
|
+
error: "API_KEY_REQUIRED",
|
|
3095
|
+
message: "No live Q402 API key configured. Run q402_doctor to set one up.",
|
|
3096
|
+
dashboardUrl
|
|
3097
|
+
};
|
|
3098
|
+
}
|
|
3099
|
+
const explicitWalletId = typeof input.walletId === "string" && input.walletId.length > 0 ? input.walletId.toLowerCase() : CONFIG.walletId;
|
|
3100
|
+
try {
|
|
3101
|
+
const res = await fetch(`${base}/wallet/agentic/recurring-by-key`, {
|
|
3102
|
+
method: "POST",
|
|
3103
|
+
headers: { "Content-Type": "application/json" },
|
|
3104
|
+
body: JSON.stringify({
|
|
3105
|
+
apiKey: CONFIG.apiKey,
|
|
3106
|
+
action: "resume",
|
|
3107
|
+
ruleId: input.ruleId,
|
|
3108
|
+
...explicitWalletId ? { walletId: explicitWalletId } : {}
|
|
3109
|
+
})
|
|
3110
|
+
});
|
|
3111
|
+
const data = await res.json().catch(() => ({}));
|
|
3112
|
+
if (!res.ok) {
|
|
3113
|
+
return {
|
|
3114
|
+
ok: false,
|
|
3115
|
+
walletId: explicitWalletId,
|
|
3116
|
+
rule: null,
|
|
3117
|
+
error: data.error ?? `HTTP_${res.status}`,
|
|
3118
|
+
message: data.message ?? `Resume failed with HTTP ${res.status}.`,
|
|
3119
|
+
dashboardUrl
|
|
3120
|
+
};
|
|
3121
|
+
}
|
|
3122
|
+
return {
|
|
3123
|
+
ok: true,
|
|
3124
|
+
walletId: data.walletId ?? explicitWalletId,
|
|
3125
|
+
rule: data.rule ?? null,
|
|
3126
|
+
dashboardUrl
|
|
3127
|
+
};
|
|
3128
|
+
} catch (e) {
|
|
3129
|
+
return {
|
|
3130
|
+
ok: false,
|
|
3131
|
+
walletId: explicitWalletId,
|
|
3132
|
+
rule: null,
|
|
3133
|
+
error: "NETWORK_ERROR",
|
|
3134
|
+
message: e instanceof Error ? e.message : String(e),
|
|
3135
|
+
dashboardUrl
|
|
3136
|
+
};
|
|
3137
|
+
}
|
|
3138
|
+
}
|
|
3139
|
+
|
|
3140
|
+
// src/tools/recurring-skip-next.ts
|
|
3141
|
+
import { z as z16 } from "zod";
|
|
3142
|
+
var RecurringSkipNextInputSchema = z16.object({
|
|
3143
|
+
ruleId: z16.string().min(1).describe(
|
|
3144
|
+
"Rule id whose next scheduled fire to skip. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field."
|
|
3145
|
+
),
|
|
3146
|
+
walletId: z16.string().optional().describe(
|
|
3147
|
+
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3148
|
+
)
|
|
3149
|
+
});
|
|
3150
|
+
var RECURRING_SKIP_NEXT_TOOL = {
|
|
3151
|
+
name: "q402_recurring_skip_next",
|
|
3152
|
+
description: "Skip ONLY the next scheduled fire of a recurring-payment rule. Cadence is preserved \u2014 the fire after the skipped one runs normally. Use this when the user says 'skip the next Friday payout, Alice is on holiday' or 'don't fire this month's subscription, charge it next month'. The rule must be in active status; paused / cancelled rules must be resumed first. Authenticated by the paid Multichain API key. Call q402_recurring_list first to confirm the ruleId and current schedule.",
|
|
3153
|
+
inputSchema: {
|
|
3154
|
+
type: "object",
|
|
3155
|
+
properties: {
|
|
3156
|
+
ruleId: {
|
|
3157
|
+
type: "string",
|
|
3158
|
+
description: "Rule id from q402_recurring_list. Required."
|
|
3159
|
+
},
|
|
3160
|
+
walletId: {
|
|
3161
|
+
type: "string",
|
|
3162
|
+
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."
|
|
3163
|
+
}
|
|
3164
|
+
},
|
|
3165
|
+
required: ["ruleId"],
|
|
3166
|
+
additionalProperties: false
|
|
3167
|
+
}
|
|
3168
|
+
};
|
|
3169
|
+
async function runRecurringSkipNext(input) {
|
|
3170
|
+
const base = CONFIG.relayBaseUrl;
|
|
3171
|
+
const dashboardUrl = base.replace(/\/api$/, "") + "/dashboard?tab=agent";
|
|
3172
|
+
if (!CONFIG.apiKey || !CONFIG.apiKey.startsWith("q402_live_")) {
|
|
3173
|
+
return {
|
|
3174
|
+
ok: false,
|
|
3175
|
+
walletId: null,
|
|
3176
|
+
rule: null,
|
|
3177
|
+
error: "API_KEY_REQUIRED",
|
|
3178
|
+
message: "No live Q402 API key configured. Run q402_doctor to set one up.",
|
|
3179
|
+
dashboardUrl
|
|
3180
|
+
};
|
|
3181
|
+
}
|
|
3182
|
+
const explicitWalletId = typeof input.walletId === "string" && input.walletId.length > 0 ? input.walletId.toLowerCase() : CONFIG.walletId;
|
|
3183
|
+
try {
|
|
3184
|
+
const res = await fetch(`${base}/wallet/agentic/recurring-by-key`, {
|
|
3185
|
+
method: "POST",
|
|
3186
|
+
headers: { "Content-Type": "application/json" },
|
|
3187
|
+
body: JSON.stringify({
|
|
3188
|
+
apiKey: CONFIG.apiKey,
|
|
3189
|
+
action: "skip-next",
|
|
3190
|
+
ruleId: input.ruleId,
|
|
3191
|
+
...explicitWalletId ? { walletId: explicitWalletId } : {}
|
|
3192
|
+
})
|
|
3193
|
+
});
|
|
3194
|
+
const data = await res.json().catch(() => ({}));
|
|
3195
|
+
if (!res.ok) {
|
|
3196
|
+
return {
|
|
3197
|
+
ok: false,
|
|
3198
|
+
walletId: explicitWalletId,
|
|
3199
|
+
rule: null,
|
|
3200
|
+
error: data.error ?? `HTTP_${res.status}`,
|
|
3201
|
+
message: data.message ?? `Skip-next failed with HTTP ${res.status}.`,
|
|
3202
|
+
dashboardUrl
|
|
3203
|
+
};
|
|
3204
|
+
}
|
|
3205
|
+
return {
|
|
3206
|
+
ok: true,
|
|
3207
|
+
walletId: data.walletId ?? explicitWalletId,
|
|
3208
|
+
rule: data.rule ?? null,
|
|
3209
|
+
dashboardUrl
|
|
3210
|
+
};
|
|
3211
|
+
} catch (e) {
|
|
3212
|
+
return {
|
|
3213
|
+
ok: false,
|
|
3214
|
+
walletId: explicitWalletId,
|
|
3215
|
+
rule: null,
|
|
3216
|
+
error: "NETWORK_ERROR",
|
|
3217
|
+
message: e instanceof Error ? e.message : String(e),
|
|
3218
|
+
dashboardUrl
|
|
3219
|
+
};
|
|
3220
|
+
}
|
|
3221
|
+
}
|
|
3222
|
+
|
|
2974
3223
|
// src/index.ts
|
|
2975
3224
|
function jsonText(value) {
|
|
2976
3225
|
return { type: "text", text: JSON.stringify(value, null, 2) };
|
|
@@ -2995,6 +3244,9 @@ async function main() {
|
|
|
2995
3244
|
RECURRING_LIST_TOOL,
|
|
2996
3245
|
RECURRING_CREATE_TOOL,
|
|
2997
3246
|
RECURRING_FIRES_TOOL,
|
|
3247
|
+
RECURRING_PAUSE_TOOL,
|
|
3248
|
+
RECURRING_RESUME_TOOL,
|
|
3249
|
+
RECURRING_SKIP_NEXT_TOOL,
|
|
2998
3250
|
RECURRING_CANCEL_TOOL,
|
|
2999
3251
|
CLEAR_DELEGATION_TOOL
|
|
3000
3252
|
]
|
|
@@ -3055,6 +3307,18 @@ async function main() {
|
|
|
3055
3307
|
const parsed = RecurringFiresInputSchema.parse(args ?? {});
|
|
3056
3308
|
return { content: [jsonText(await runRecurringFires(parsed))] };
|
|
3057
3309
|
}
|
|
3310
|
+
case "q402_recurring_pause": {
|
|
3311
|
+
const parsed = RecurringPauseInputSchema.parse(args ?? {});
|
|
3312
|
+
return { content: [jsonText(await runRecurringPause(parsed))] };
|
|
3313
|
+
}
|
|
3314
|
+
case "q402_recurring_resume": {
|
|
3315
|
+
const parsed = RecurringResumeInputSchema.parse(args ?? {});
|
|
3316
|
+
return { content: [jsonText(await runRecurringResume(parsed))] };
|
|
3317
|
+
}
|
|
3318
|
+
case "q402_recurring_skip_next": {
|
|
3319
|
+
const parsed = RecurringSkipNextInputSchema.parse(args ?? {});
|
|
3320
|
+
return { content: [jsonText(await runRecurringSkipNext(parsed))] };
|
|
3321
|
+
}
|
|
3058
3322
|
default:
|
|
3059
3323
|
return {
|
|
3060
3324
|
isError: true,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quackai/q402-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
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": [
|