@quackai/q402-mcp 0.8.1 → 0.8.3
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 +6 -2
- package/dist/index.js +266 -37
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -153,7 +153,7 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
|
|
|
153
153
|
|
|
154
154
|
## Tools exposed
|
|
155
155
|
|
|
156
|
-
**
|
|
156
|
+
**20 tools** — read-only by default; live mode needs an API key + signing path + `Q402_ENABLE_REAL_PAYMENTS=1`.
|
|
157
157
|
|
|
158
158
|
| Tool | Auth | Purpose |
|
|
159
159
|
|---|---|---|
|
|
@@ -173,8 +173,12 @@ Then export the values in `~/.zshrc` / `~/.bashrc`. See the [Codex config refere
|
|
|
173
173
|
| `q402_recurring_resume` | api key | Resume a paused / stopped rule. |
|
|
174
174
|
| `q402_recurring_skip_next` | api key | Skip only the next scheduled fire. |
|
|
175
175
|
| `q402_recurring_cancel` | api key | Permanently stop a rule. |
|
|
176
|
+
| `q402_bridge_quote` | none | Quote a Chainlink CCIP USDC bridge across eth/avax/arbitrum. Returns LINK + native fee. |
|
|
177
|
+
| `q402_bridge_send` | live mode | Execute the bridge. v0.8.2 ships sandbox-only; live execution lands once session-binding ships. |
|
|
178
|
+
| `q402_bridge_history` | api key | Recent CCIP bridges (50 most recent). |
|
|
179
|
+
| `q402_bridge_gas_tank` | api key | Per-chain LINK + native Gas Tank balance for bridge fees. |
|
|
176
180
|
|
|
177
|
-
`q402_pay` + `q402_batch_pay` require explicit in-chat confirmation. Batch confirmation = full batch, not per-row.
|
|
181
|
+
`q402_pay` + `q402_batch_pay` + `q402_bridge_send` require explicit in-chat confirmation. Batch confirmation = full batch, not per-row.
|
|
178
182
|
|
|
179
183
|
> ℹ️ `q402_pay` expects a 0x address — ENS isn't resolved server-side. Resolve client-side first.
|
|
180
184
|
> Per-chain Gas Tank balances + full TX history live in the [dashboard](https://q402.quackai.ai/dashboard) (wallet-signature only).
|
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.8.
|
|
214
|
+
var PACKAGE_VERSION = "0.8.3";
|
|
215
215
|
|
|
216
216
|
// src/tools/quote.ts
|
|
217
217
|
import { z } from "zod";
|
|
@@ -2799,10 +2799,216 @@ async function runAgenticInfo(input = {}) {
|
|
|
2799
2799
|
};
|
|
2800
2800
|
}
|
|
2801
2801
|
|
|
2802
|
-
// src/tools/
|
|
2802
|
+
// src/tools/bridge-quote.ts
|
|
2803
2803
|
import { z as z10 } from "zod";
|
|
2804
|
-
var
|
|
2805
|
-
|
|
2804
|
+
var BridgeQuoteInputSchema = z10.object({
|
|
2805
|
+
src: z10.enum(["eth", "avax", "arbitrum"]).describe("Source chain"),
|
|
2806
|
+
dst: z10.enum(["eth", "avax", "arbitrum"]).describe("Destination chain"),
|
|
2807
|
+
amount: z10.string().regex(/^\d+$/).describe("USDC amount in raw 6-decimal units (e.g. '1000000' = 1 USDC)"),
|
|
2808
|
+
destReceiver: z10.string().regex(/^0x[0-9a-fA-F]{40}$/).describe("Destination receiver address (Agentic Wallet on destination)")
|
|
2809
|
+
});
|
|
2810
|
+
var BRIDGE_QUOTE_TOOL = {
|
|
2811
|
+
name: "q402_bridge_quote",
|
|
2812
|
+
description: "Quote the Chainlink CCIP fee for bridging USDC across the 3-chain triangle (eth/avax/arbitrum). Returns BOTH the LINK fee (~10% cheaper) and the native fee, so the agent can pick the cheaper path or surface both options to the user. Read-only; no auth required.",
|
|
2813
|
+
inputSchema: {
|
|
2814
|
+
type: "object",
|
|
2815
|
+
properties: {
|
|
2816
|
+
src: {
|
|
2817
|
+
type: "string",
|
|
2818
|
+
enum: ["eth", "avax", "arbitrum"],
|
|
2819
|
+
description: "Source chain."
|
|
2820
|
+
},
|
|
2821
|
+
dst: {
|
|
2822
|
+
type: "string",
|
|
2823
|
+
enum: ["eth", "avax", "arbitrum"],
|
|
2824
|
+
description: "Destination chain (MUST differ from src; pool only routes inside the 3-chain triangle)."
|
|
2825
|
+
},
|
|
2826
|
+
amount: {
|
|
2827
|
+
type: "string",
|
|
2828
|
+
pattern: "^[0-9]+$",
|
|
2829
|
+
description: "USDC amount in raw 6-decimal units (e.g. '1000000' = 1 USDC). Integer string only."
|
|
2830
|
+
},
|
|
2831
|
+
destReceiver: {
|
|
2832
|
+
type: "string",
|
|
2833
|
+
pattern: "^0x[0-9a-fA-F]{40}$",
|
|
2834
|
+
description: "Destination receiver (0x 20-byte address). Same EOA on the destination chain."
|
|
2835
|
+
}
|
|
2836
|
+
},
|
|
2837
|
+
required: ["src", "dst", "amount", "destReceiver"]
|
|
2838
|
+
}
|
|
2839
|
+
};
|
|
2840
|
+
async function runBridgeQuote(input) {
|
|
2841
|
+
const url = new URL("/api/ccip/quote", CONFIG.relayBaseUrl);
|
|
2842
|
+
const res = await fetch(url, {
|
|
2843
|
+
method: "POST",
|
|
2844
|
+
headers: { "Content-Type": "application/json" },
|
|
2845
|
+
body: JSON.stringify(input)
|
|
2846
|
+
});
|
|
2847
|
+
const data = await res.json();
|
|
2848
|
+
if (!res.ok) {
|
|
2849
|
+
return { content: [{ type: "text", text: `Quote failed (HTTP ${res.status}): ${JSON.stringify(data)}` }], isError: true };
|
|
2850
|
+
}
|
|
2851
|
+
const recommended = data.recommended;
|
|
2852
|
+
const link = data.fee?.link;
|
|
2853
|
+
const native = data.fee?.native;
|
|
2854
|
+
const otherKey = recommended === "link" ? "native" : "link";
|
|
2855
|
+
const recUsd = recommended ? data.fee?.[recommended]?.usd : void 0;
|
|
2856
|
+
const otherUsd = recommended ? data.fee?.[otherKey]?.usd : void 0;
|
|
2857
|
+
const cheaper = recommended && typeof recUsd === "number" ? `Cheaper: ${recommended.toUpperCase()} (~$${recUsd.toFixed(4)} vs $${(otherUsd ?? 0).toFixed(4)})` : "Quote returned.";
|
|
2858
|
+
return {
|
|
2859
|
+
content: [
|
|
2860
|
+
{ type: "text", text: cheaper },
|
|
2861
|
+
{ type: "text", text: JSON.stringify({ recommended, link, native }, null, 2) }
|
|
2862
|
+
]
|
|
2863
|
+
};
|
|
2864
|
+
}
|
|
2865
|
+
|
|
2866
|
+
// src/tools/bridge-send.ts
|
|
2867
|
+
import { z as z11 } from "zod";
|
|
2868
|
+
var BridgeSendInputSchema = z11.object({
|
|
2869
|
+
src: z11.enum(["eth", "avax", "arbitrum"]).describe("Source chain"),
|
|
2870
|
+
dst: z11.enum(["eth", "avax", "arbitrum"]).describe("Destination chain"),
|
|
2871
|
+
amount: z11.string().regex(/^\d+$/).describe("USDC amount in raw 6-decimal units"),
|
|
2872
|
+
walletId: z11.string().describe("Agentic Wallet ID (from q402_agentic_info)"),
|
|
2873
|
+
feeToken: z11.enum(["LINK", "native", "auto"]).optional().describe("Fee token. 'auto' picks cheaper of the two; defaults to LINK."),
|
|
2874
|
+
sandbox: z11.boolean().optional().describe("Sandbox mode (default true). Set to false for live bridge.")
|
|
2875
|
+
});
|
|
2876
|
+
var BRIDGE_SEND_TOOL = {
|
|
2877
|
+
name: "q402_bridge_send",
|
|
2878
|
+
description: "Execute a Chainlink CCIP USDC bridge between two of the 3 supported chains (eth/avax/arbitrum). The Q402 server signs ccipSend on behalf of the user's Agentic Wallet. Fee is debited from the user's Gas Tank (LINK slot or native, per the feeToken arg). SANDBOX BY DEFAULT: returns a synthetic messageId unless `sandbox: false` is passed AND the server env has Q402_ENABLE_REAL_PAYMENTS=1. ALWAYS confirm the bridge details with the user before setting sandbox: false. Recommended flow: q402_bridge_quote first \u2192 show user the cost \u2192 get user confirmation \u2192 call q402_bridge_send with sandbox: false.",
|
|
2879
|
+
inputSchema: {
|
|
2880
|
+
type: "object",
|
|
2881
|
+
properties: {
|
|
2882
|
+
src: {
|
|
2883
|
+
type: "string",
|
|
2884
|
+
enum: ["eth", "avax", "arbitrum"],
|
|
2885
|
+
description: "Source chain."
|
|
2886
|
+
},
|
|
2887
|
+
dst: {
|
|
2888
|
+
type: "string",
|
|
2889
|
+
enum: ["eth", "avax", "arbitrum"],
|
|
2890
|
+
description: "Destination chain (MUST differ from src)."
|
|
2891
|
+
},
|
|
2892
|
+
amount: {
|
|
2893
|
+
type: "string",
|
|
2894
|
+
pattern: "^[0-9]+$",
|
|
2895
|
+
description: "USDC amount in raw 6-decimal units (e.g. '1000000' = 1 USDC). Integer string only."
|
|
2896
|
+
},
|
|
2897
|
+
walletId: {
|
|
2898
|
+
type: "string",
|
|
2899
|
+
description: "Agentic Wallet ID (from q402_agentic_info)."
|
|
2900
|
+
},
|
|
2901
|
+
feeToken: {
|
|
2902
|
+
type: "string",
|
|
2903
|
+
enum: ["LINK", "native", "auto"],
|
|
2904
|
+
description: "Fee token. Default: LINK (~10% cheaper). 'auto' picks cheaper at quote time."
|
|
2905
|
+
},
|
|
2906
|
+
sandbox: {
|
|
2907
|
+
type: "boolean",
|
|
2908
|
+
description: "Sandbox-only in v0.8.3 (live bridging requires dashboard session-binding). Default true."
|
|
2909
|
+
}
|
|
2910
|
+
},
|
|
2911
|
+
required: ["src", "dst", "amount", "walletId"]
|
|
2912
|
+
}
|
|
2913
|
+
};
|
|
2914
|
+
async function runBridgeSend(input) {
|
|
2915
|
+
const sandbox = input.sandbox !== false;
|
|
2916
|
+
if (sandbox) {
|
|
2917
|
+
return {
|
|
2918
|
+
content: [{
|
|
2919
|
+
type: "text",
|
|
2920
|
+
text: JSON.stringify({
|
|
2921
|
+
sandbox: true,
|
|
2922
|
+
messageId: "0x" + "00".repeat(32),
|
|
2923
|
+
txHash: "0x" + "00".repeat(32),
|
|
2924
|
+
note: "Sandbox response. To execute a real bridge, pass `sandbox: false` AND ensure the server has Q402_ENABLE_REAL_PAYMENTS=1.",
|
|
2925
|
+
src: input.src,
|
|
2926
|
+
dst: input.dst,
|
|
2927
|
+
amount: input.amount
|
|
2928
|
+
}, null, 2)
|
|
2929
|
+
}]
|
|
2930
|
+
};
|
|
2931
|
+
}
|
|
2932
|
+
return {
|
|
2933
|
+
content: [{
|
|
2934
|
+
type: "text",
|
|
2935
|
+
text: "Live CCIP bridge via MCP is not yet wired in v0.8.2 \u2014 agents can quote and plan via q402_bridge_quote and q402_bridge_send (sandbox), but actual execution must happen via https://q402.quackai.ai/dashboard for now. Live MCP execution lands in a follow-up release."
|
|
2936
|
+
}],
|
|
2937
|
+
isError: true
|
|
2938
|
+
};
|
|
2939
|
+
}
|
|
2940
|
+
|
|
2941
|
+
// src/tools/bridge-history.ts
|
|
2942
|
+
import { z as z12 } from "zod";
|
|
2943
|
+
var BridgeHistoryInputSchema = z12.object({
|
|
2944
|
+
ownerAddress: z12.string().regex(/^0x[0-9a-fA-F]{40}$/).optional().describe("Owner EOA. Defaults to the configured Agentic Wallet owner.")
|
|
2945
|
+
});
|
|
2946
|
+
var BRIDGE_HISTORY_TOOL = {
|
|
2947
|
+
name: "q402_bridge_history",
|
|
2948
|
+
description: "List the user's recent Chainlink CCIP bridges (most-recent first, up to 50 records). Each record includes messageId, source/destination chains, USDC amount, fee paid, and CCIP Explorer link. v0.8.2 returns dashboard URL guidance \u2014 full MCP wiring lands in a follow-up.",
|
|
2949
|
+
inputSchema: {
|
|
2950
|
+
type: "object",
|
|
2951
|
+
properties: {
|
|
2952
|
+
ownerAddress: {
|
|
2953
|
+
type: "string",
|
|
2954
|
+
pattern: "^0x[0-9a-fA-F]{40}$",
|
|
2955
|
+
description: "Owner EOA (0x address, optional \u2014 defaults to configured wallet)."
|
|
2956
|
+
}
|
|
2957
|
+
}
|
|
2958
|
+
}
|
|
2959
|
+
};
|
|
2960
|
+
async function runBridgeHistory(_input) {
|
|
2961
|
+
return {
|
|
2962
|
+
content: [{
|
|
2963
|
+
type: "text",
|
|
2964
|
+
text: "Bridge history via MCP requires owner-sig auth, which is dashboard-managed in v0.8.3. View at https://q402.quackai.ai/dashboard \u2192 Agent tab \u2192 Bridge History."
|
|
2965
|
+
}],
|
|
2966
|
+
isError: true
|
|
2967
|
+
};
|
|
2968
|
+
}
|
|
2969
|
+
|
|
2970
|
+
// src/tools/bridge-gas-tank.ts
|
|
2971
|
+
import { z as z13 } from "zod";
|
|
2972
|
+
var BridgeGasTankInputSchema = z13.object({
|
|
2973
|
+
ownerAddress: z13.string().regex(/^0x[0-9a-fA-F]{40}$/).optional().describe("Owner EOA. Defaults to configured wallet.")
|
|
2974
|
+
});
|
|
2975
|
+
var BRIDGE_GAS_TANK_TOOL = {
|
|
2976
|
+
name: "q402_bridge_gas_tank",
|
|
2977
|
+
description: "Report the user's Bridge Gas Tank state \u2014 LINK + native balance per CCIP chain (eth/avax/arbitrum). Q402 charges no markup on bridges; users pay only the actual Chainlink CCIP fee, debited from this Gas Tank. LINK fees are ~10% cheaper than native. Tool returns guidance + dashboard URL in v0.8.3.",
|
|
2978
|
+
inputSchema: {
|
|
2979
|
+
type: "object",
|
|
2980
|
+
properties: {
|
|
2981
|
+
ownerAddress: {
|
|
2982
|
+
type: "string",
|
|
2983
|
+
pattern: "^0x[0-9a-fA-F]{40}$",
|
|
2984
|
+
description: "Owner EOA (0x address, optional \u2014 defaults to configured wallet)."
|
|
2985
|
+
}
|
|
2986
|
+
}
|
|
2987
|
+
}
|
|
2988
|
+
};
|
|
2989
|
+
async function runBridgeGasTank(_input) {
|
|
2990
|
+
return {
|
|
2991
|
+
content: [{
|
|
2992
|
+
type: "text",
|
|
2993
|
+
text: [
|
|
2994
|
+
"Bridge Gas Tank covers Chainlink CCIP fees on the 3-chain triangle (eth/avax/arbitrum).",
|
|
2995
|
+
"",
|
|
2996
|
+
"Two fee tokens supported:",
|
|
2997
|
+
" \u2022 LINK (default, ~10% cheaper)",
|
|
2998
|
+
" \u2022 native (ETH / AVAX / ETH respectively)",
|
|
2999
|
+
"",
|
|
3000
|
+
"Top up by sending LINK or native to the Q402 facilitator address on the source chain. The next deposit-scan cron tick (~5 min) credits your Gas Tank.",
|
|
3001
|
+
"",
|
|
3002
|
+
"Live balance + deposit addresses: https://q402.quackai.ai/dashboard \u2192 Agent tab \u2192 Bridge Gas Tank"
|
|
3003
|
+
].join("\n")
|
|
3004
|
+
}]
|
|
3005
|
+
};
|
|
3006
|
+
}
|
|
3007
|
+
|
|
3008
|
+
// src/tools/recurring-list.ts
|
|
3009
|
+
import { z as z14 } from "zod";
|
|
3010
|
+
var RecurringListInputSchema = z14.object({
|
|
3011
|
+
walletId: z14.string().optional().describe(
|
|
2806
3012
|
"Optional lowercased Agent Wallet address to list rules for when the user holds multiple wallets. Omit to use Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
2807
3013
|
)
|
|
2808
3014
|
});
|
|
@@ -2886,29 +3092,29 @@ async function runRecurringList(input = {}) {
|
|
|
2886
3092
|
}
|
|
2887
3093
|
|
|
2888
3094
|
// src/tools/recurring-create.ts
|
|
2889
|
-
import { z as
|
|
3095
|
+
import { z as z15 } from "zod";
|
|
2890
3096
|
var ADDRESS_RE = /^0x[0-9a-fA-F]{40}$/;
|
|
2891
3097
|
var AMOUNT_RE = /^\d+(\.\d{1,18})?$/;
|
|
2892
|
-
var RecurringCreateInputSchema =
|
|
2893
|
-
confirm:
|
|
3098
|
+
var RecurringCreateInputSchema = z15.object({
|
|
3099
|
+
confirm: z15.literal(true).describe(
|
|
2894
3100
|
'REQUIRED. Must be literally `true`. Authoring a recurring rule schedules future on-chain payments that the user does not click through one-by-one \u2014 the user has to explicitly say yes BEFORE this is called. Echo back the frequency + recipient + amount + chain + token + cancelWindow you intend to create, get a plain-language confirmation from the user (e.g. "yes, create the schedule"), and ONLY then call this with confirm: true. Mirrors the same guard q402_pay / q402_batch_pay use on one-shot sends.'
|
|
2895
3101
|
),
|
|
2896
|
-
frequency:
|
|
3102
|
+
frequency: z15.string().min(1).describe(
|
|
2897
3103
|
'Cadence string. One of: "hourly:N" (N=1..23), "daily", "weekly:{mon|tue|wed|thu|fri|sat|sun}", "monthly:N" (N=1..31), "monthly:last". Examples: "hourly:1" fires every hour, "weekly:fri" fires every Friday, "monthly:1" fires on the 1st of each month.'
|
|
2898
3104
|
),
|
|
2899
|
-
recipient:
|
|
2900
|
-
amount:
|
|
3105
|
+
recipient: z15.string().regex(ADDRESS_RE).describe("0x-prefixed 20-byte recipient address. Required."),
|
|
3106
|
+
amount: z15.string().regex(AMOUNT_RE).describe(
|
|
2901
3107
|
'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).'
|
|
2902
3108
|
),
|
|
2903
|
-
chain:
|
|
3109
|
+
chain: z15.enum(["bnb", "eth", "avax", "xlayer", "mantle", "injective", "monad", "scroll", "stable", "arbitrum"]).default("bnb").describe(
|
|
2904
3110
|
"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."
|
|
2905
3111
|
),
|
|
2906
|
-
token:
|
|
2907
|
-
label:
|
|
2908
|
-
cancelWindowHours:
|
|
3112
|
+
token: z15.enum(["USDC", "USDT"]).default("USDT").describe("Stablecoin to send. USDC or USDT. Both peg to USD-1."),
|
|
3113
|
+
label: z15.string().max(64).optional().describe("Optional human-readable label (\u226464 chars). Shows up in q402_recurring_list and the dashboard."),
|
|
3114
|
+
cancelWindowHours: z15.number().min(0).optional().describe(
|
|
2909
3115
|
"Hours of advance notice before each fire during which the rule can be cancelled. 0 = fire immediately at the next slot, no alert. Capped at the cadence interval (e.g. \u2264 N-0.5h for hourly:N, \u226424 for daily). Defaults to 0."
|
|
2910
3116
|
),
|
|
2911
|
-
walletId:
|
|
3117
|
+
walletId: z15.string().optional().describe(
|
|
2912
3118
|
"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."
|
|
2913
3119
|
)
|
|
2914
3120
|
});
|
|
@@ -3037,12 +3243,12 @@ async function runRecurringCreate(input) {
|
|
|
3037
3243
|
}
|
|
3038
3244
|
|
|
3039
3245
|
// src/tools/recurring-cancel.ts
|
|
3040
|
-
import { z as
|
|
3041
|
-
var RecurringCancelInputSchema =
|
|
3042
|
-
ruleId:
|
|
3246
|
+
import { z as z16 } from "zod";
|
|
3247
|
+
var RecurringCancelInputSchema = z16.object({
|
|
3248
|
+
ruleId: z16.string().min(1).describe(
|
|
3043
3249
|
"Rule id to cancel. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field. Cancelling is immediate."
|
|
3044
3250
|
),
|
|
3045
|
-
walletId:
|
|
3251
|
+
walletId: z16.string().optional().describe(
|
|
3046
3252
|
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3047
3253
|
)
|
|
3048
3254
|
});
|
|
@@ -3130,15 +3336,15 @@ async function runRecurringCancel(input) {
|
|
|
3130
3336
|
}
|
|
3131
3337
|
|
|
3132
3338
|
// src/tools/recurring-fires.ts
|
|
3133
|
-
import { z as
|
|
3134
|
-
var RecurringFiresInputSchema =
|
|
3135
|
-
ruleId:
|
|
3339
|
+
import { z as z17 } from "zod";
|
|
3340
|
+
var RecurringFiresInputSchema = z17.object({
|
|
3341
|
+
ruleId: z17.string().min(1).describe(
|
|
3136
3342
|
"Rule id whose fire history to fetch. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field."
|
|
3137
3343
|
),
|
|
3138
|
-
limit:
|
|
3344
|
+
limit: z17.number().int().min(1).max(50).optional().describe(
|
|
3139
3345
|
"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."
|
|
3140
3346
|
),
|
|
3141
|
-
walletId:
|
|
3347
|
+
walletId: z17.string().optional().describe(
|
|
3142
3348
|
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3143
3349
|
)
|
|
3144
3350
|
});
|
|
@@ -3244,12 +3450,12 @@ async function runRecurringFires(input) {
|
|
|
3244
3450
|
}
|
|
3245
3451
|
|
|
3246
3452
|
// src/tools/recurring-pause.ts
|
|
3247
|
-
import { z as
|
|
3248
|
-
var RecurringPauseInputSchema =
|
|
3249
|
-
ruleId:
|
|
3453
|
+
import { z as z18 } from "zod";
|
|
3454
|
+
var RecurringPauseInputSchema = z18.object({
|
|
3455
|
+
ruleId: z18.string().min(1).describe(
|
|
3250
3456
|
"Rule id to pause. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field. Pausing is immediate and reversible."
|
|
3251
3457
|
),
|
|
3252
|
-
walletId:
|
|
3458
|
+
walletId: z18.string().optional().describe(
|
|
3253
3459
|
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3254
3460
|
)
|
|
3255
3461
|
});
|
|
@@ -3337,12 +3543,12 @@ async function runRecurringPause(input) {
|
|
|
3337
3543
|
}
|
|
3338
3544
|
|
|
3339
3545
|
// src/tools/recurring-resume.ts
|
|
3340
|
-
import { z as
|
|
3341
|
-
var RecurringResumeInputSchema =
|
|
3342
|
-
ruleId:
|
|
3546
|
+
import { z as z19 } from "zod";
|
|
3547
|
+
var RecurringResumeInputSchema = z19.object({
|
|
3548
|
+
ruleId: z19.string().min(1).describe(
|
|
3343
3549
|
"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."
|
|
3344
3550
|
),
|
|
3345
|
-
walletId:
|
|
3551
|
+
walletId: z19.string().optional().describe(
|
|
3346
3552
|
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3347
3553
|
)
|
|
3348
3554
|
});
|
|
@@ -3430,12 +3636,12 @@ async function runRecurringResume(input) {
|
|
|
3430
3636
|
}
|
|
3431
3637
|
|
|
3432
3638
|
// src/tools/recurring-skip-next.ts
|
|
3433
|
-
import { z as
|
|
3434
|
-
var RecurringSkipNextInputSchema =
|
|
3435
|
-
ruleId:
|
|
3639
|
+
import { z as z20 } from "zod";
|
|
3640
|
+
var RecurringSkipNextInputSchema = z20.object({
|
|
3641
|
+
ruleId: z20.string().min(1).describe(
|
|
3436
3642
|
"Rule id whose next scheduled fire to skip. Obtain from q402_recurring_list \u2014 each entry's `ruleId` field."
|
|
3437
3643
|
),
|
|
3438
|
-
walletId:
|
|
3644
|
+
walletId: z20.string().optional().describe(
|
|
3439
3645
|
"Optional lowercased Agent Wallet address when the user holds multiple wallets. Defaults to Q402_AGENT_WALLET_ADDRESS env, then the owner's default wallet."
|
|
3440
3646
|
)
|
|
3441
3647
|
});
|
|
@@ -3550,7 +3756,14 @@ async function main() {
|
|
|
3550
3756
|
RECURRING_RESUME_TOOL,
|
|
3551
3757
|
RECURRING_SKIP_NEXT_TOOL,
|
|
3552
3758
|
RECURRING_CANCEL_TOOL,
|
|
3553
|
-
CLEAR_DELEGATION_TOOL
|
|
3759
|
+
CLEAR_DELEGATION_TOOL,
|
|
3760
|
+
// CCIP bridge surface (v0.8.2) — USDC routing on the eth/avax/arbitrum
|
|
3761
|
+
// triangle. Bridge_send is sandbox-only in v0.8.2; live execution
|
|
3762
|
+
// happens through the dashboard until session-binding ships.
|
|
3763
|
+
BRIDGE_QUOTE_TOOL,
|
|
3764
|
+
BRIDGE_SEND_TOOL,
|
|
3765
|
+
BRIDGE_HISTORY_TOOL,
|
|
3766
|
+
BRIDGE_GAS_TANK_TOOL
|
|
3554
3767
|
]
|
|
3555
3768
|
}));
|
|
3556
3769
|
server.setRequestHandler(CallToolRequestSchema, async (req) => {
|
|
@@ -3621,6 +3834,22 @@ async function main() {
|
|
|
3621
3834
|
const parsed = RecurringSkipNextInputSchema.parse(args ?? {});
|
|
3622
3835
|
return { content: [jsonText(await runRecurringSkipNext(parsed))] };
|
|
3623
3836
|
}
|
|
3837
|
+
case "q402_bridge_quote": {
|
|
3838
|
+
const parsed = BridgeQuoteInputSchema.parse(args ?? {});
|
|
3839
|
+
return await runBridgeQuote(parsed);
|
|
3840
|
+
}
|
|
3841
|
+
case "q402_bridge_send": {
|
|
3842
|
+
const parsed = BridgeSendInputSchema.parse(args ?? {});
|
|
3843
|
+
return await runBridgeSend(parsed);
|
|
3844
|
+
}
|
|
3845
|
+
case "q402_bridge_history": {
|
|
3846
|
+
const parsed = BridgeHistoryInputSchema.parse(args ?? {});
|
|
3847
|
+
return await runBridgeHistory(parsed);
|
|
3848
|
+
}
|
|
3849
|
+
case "q402_bridge_gas_tank": {
|
|
3850
|
+
const parsed = BridgeGasTankInputSchema.parse(args ?? {});
|
|
3851
|
+
return await runBridgeGasTank(parsed);
|
|
3852
|
+
}
|
|
3624
3853
|
default:
|
|
3625
3854
|
return {
|
|
3626
3855
|
isError: true,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quackai/q402-mcp",
|
|
3
|
-
"version": "0.8.
|
|
4
|
-
"description": "MCP server for Q402 — gasless USDC
|
|
3
|
+
"version": "0.8.3",
|
|
4
|
+
"description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments + Chainlink CCIP bridge across 10 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": [
|
|
7
7
|
"mcp",
|