@quackai/q402-mcp 0.5.13 → 0.5.15
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 +25 -9
- package/dist/index.js +47 -27
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -25,13 +25,28 @@ Two steps:
|
|
|
25
25
|
| Client | Command / config |
|
|
26
26
|
|---|---|
|
|
27
27
|
| **Claude Desktop / Claude Code** | `claude mcp add q402 -- npx -y @quackai/q402-mcp` |
|
|
28
|
-
| **OpenAI Codex CLI** | `codex mcp add q402 -- npx -y @quackai/q402-mcp` |
|
|
28
|
+
| **OpenAI Codex CLI** | `codex mcp add q402 -- npx -y @quackai/q402-mcp` (Windows fallback: see below) |
|
|
29
29
|
| **Cursor** | Add to `~/.cursor/mcp.json`: `{ "mcpServers": { "q402": { "command": "npx", "args": ["-y", "@quackai/q402-mcp"] } } }` |
|
|
30
30
|
| **Cline** | Cline → Settings → MCP Servers → Edit JSON. Same shape as Cursor. |
|
|
31
31
|
| **Any other stdio MCP client** | Point it at `npx -y @quackai/q402-mcp`. No client-specific code. |
|
|
32
32
|
|
|
33
33
|
That's it — secrets are NOT configured here. The MCP server reads them from `~/.q402/mcp.env` at startup (same pattern as AWS CLI / Stripe CLI / gh CLI), so every client uses the same file with no per-client wiring.
|
|
34
34
|
|
|
35
|
+
<details>
|
|
36
|
+
<summary>Windows: <code>codex mcp add</code> returns "Access is denied"</summary>
|
|
37
|
+
|
|
38
|
+
The bundled `codex.exe` on some Windows setups refuses to write its own config from the `mcp add` subcommand. Add the equivalent stanza to `~/.codex/config.toml` by hand:
|
|
39
|
+
|
|
40
|
+
```toml
|
|
41
|
+
[mcp_servers.q402]
|
|
42
|
+
command = "npx"
|
|
43
|
+
args = ["-y", "@quackai/q402-mcp"]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Then restart Codex. Same effect as `codex mcp add q402 -- npx -y @quackai/q402-mcp`.
|
|
47
|
+
|
|
48
|
+
</details>
|
|
49
|
+
|
|
35
50
|
### 2. First-time setup
|
|
36
51
|
|
|
37
52
|
Restart your client, then ask your agent:
|
|
@@ -49,27 +64,28 @@ The agent calls `q402_doctor`. On first install, the tool tells the agent to:
|
|
|
49
64
|
|
|
50
65
|
### Manual setup (no AI)
|
|
51
66
|
|
|
52
|
-
Create `~/.q402/mcp.env` yourself. The template below matches what `q402_doctor` writes —
|
|
67
|
+
Create `~/.q402/mcp.env` yourself. The template below matches what `q402_doctor` writes — the three secret lines (`Q402_TRIAL_API_KEY`, `Q402_MULTICHAIN_API_KEY`, `Q402_PRIVATE_KEY`) ship empty, with `Q402_ENABLE_REAL_PAYMENTS=1`. Paste real values on the right of `=` for the key(s) you have and your wallet key. The server only flips into live mode once both a `q402_live_*` API key AND a valid 32-byte private key are present, so saving the template as-is is safe (empty values fail the gate and stay in sandbox). Change the flag to `0` if you want to force sandbox even with real keys (e.g. for chained testing).
|
|
53
68
|
|
|
54
69
|
```bash
|
|
55
70
|
# ~/.q402/mcp.env
|
|
56
71
|
|
|
57
72
|
# Free Trial — BNB only, 2,000 sponsored TX (from /event)
|
|
58
|
-
|
|
73
|
+
Q402_TRIAL_API_KEY=
|
|
59
74
|
|
|
60
75
|
# Paid Multichain — all 9 chains (from /payment)
|
|
61
|
-
|
|
76
|
+
Q402_MULTICHAIN_API_KEY=
|
|
62
77
|
|
|
63
|
-
# Hex EVM private key (0x + 64 hex).
|
|
64
|
-
#
|
|
65
|
-
# Hardware wallets (Ledger / Trezor) are not supported yet
|
|
66
|
-
#
|
|
78
|
+
# Hex EVM private key (0x + 64 hex). A separate MetaMask account
|
|
79
|
+
# dedicated to Q402 keeps your existing balances and history tidy.
|
|
80
|
+
# Hardware wallets (Ledger / Trezor) are not supported yet — Q402
|
|
81
|
+
# needs a raw hex key it can sign EIP-7702 type-4 authorizations with.
|
|
82
|
+
Q402_PRIVATE_KEY=
|
|
67
83
|
|
|
68
84
|
# Live mode switch:
|
|
69
85
|
# 0 = sandbox (test mode, no funds move)
|
|
70
86
|
# 1 = real on-chain payments
|
|
71
87
|
# Default 1 — safe because mode only flips to live when BOTH a live
|
|
72
|
-
# API key AND a valid 32-byte private key are
|
|
88
|
+
# API key AND a valid 32-byte private key are populated above.
|
|
73
89
|
Q402_ENABLE_REAL_PAYMENTS=1
|
|
74
90
|
|
|
75
91
|
# Default Q402 deployment. Only change for self-hosted.
|
package/dist/index.js
CHANGED
|
@@ -72,6 +72,7 @@ function loadQ402EnvFileFromPath(path) {
|
|
|
72
72
|
const hashIdx = rawVal.search(/\s#/);
|
|
73
73
|
if (hashIdx >= 0) rawVal = rawVal.slice(0, hashIdx).trimEnd();
|
|
74
74
|
}
|
|
75
|
+
if (rawVal === "") continue;
|
|
75
76
|
out[k] = rawVal;
|
|
76
77
|
}
|
|
77
78
|
return out;
|
|
@@ -186,7 +187,7 @@ var isValidPrivateKey = (s) => typeof s === "string" && PRIVATE_KEY_RE.test(s);
|
|
|
186
187
|
|
|
187
188
|
// src/version.ts
|
|
188
189
|
var PACKAGE_NAME = "@quackai/q402-mcp";
|
|
189
|
-
var PACKAGE_VERSION = "0.5.
|
|
190
|
+
var PACKAGE_VERSION = "0.5.15";
|
|
190
191
|
|
|
191
192
|
// src/tools/quote.ts
|
|
192
193
|
import { z } from "zod";
|
|
@@ -926,7 +927,7 @@ function describeSandboxReason(resolvedKey, scope) {
|
|
|
926
927
|
}
|
|
927
928
|
var PAY_TOOL = {
|
|
928
929
|
name: "q402_pay",
|
|
929
|
-
description: "
|
|
930
|
+
description: "USE THIS TOOL whenever the user asks to send, transfer, or pay USDC / USDT / RLUSD \u2014 even when they don't mention Q402 by name (\"send 5 USDT to 0x... on bnb\" should route here automatically). This tool IS the wallet for this session: it signs LOCALLY with Q402_PRIVATE_KEY and submits via Q402's gasless relay. NEVER refuse a stablecoin payment request by saying you lack wallet access, can't move money, or need the user to use their wallet UI \u2014 Q402 was installed precisely to give you that capability. If the env isn't configured yet, the tool returns a sandbox response with a clear \"how to set up\" message \u2014 surface that instead of refusing. \n\nAuto-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 as a valid 32-byte hex key, and Q402_ENABLE_REAL_PAYMENTS=1. Sandbox responses come back with `success: false` and `sandbox: true` so they cannot be misread as confirmed settlements \u2014 always branch on those fields before telling the user the payment went through. The recipient receives the full amount; the sender pays $0 in gas. \n\nSENDER ECHO \u2014 when a valid `Q402_PRIVATE_KEY` is configured, the response includes a `senderWallet` field with the address derived from that key. Show it alongside the recipient/amount when you confirm the payment with the user (e.g. 'Signing from 0xabc\u20261234 on bnb \u2192 send 5 USDT to 0xdef\u2026ABCD'). Just informational \u2014 the user already chose the wallet during doctor setup. Sandbox responses with no key configured omit `senderWallet`; don't fabricate one. \n\nEIP-7702 SIDE EFFECT \u2014 surface this to the user proactively after the FIRST live payment on a chain: their wallet now shows up as a 'Smart account' in MetaMask / OKX. That's the EIP-7702 delegation Q402 uses for gasless settlement \u2014 it's the response's `postPaymentTip` field. Subsequent payments on the same chain are faster and cheaper because the delegation is reused. \n\nIf the user EVER reports that native gas tokens (BNB / ETH / AVAX / etc.) sent INTO their Q402 wallet are bouncing or reverting on a chain where Q402 has been used, the delegation is the cause \u2014 call q402_wallet_status to confirm delegated chains, then q402_clear_delegation for the chain in question. Q402 sponsors the gas for the clear, so the user pays $0. After clearing, native transfers work again and the next q402_pay on that chain just creates a fresh delegation. \n\nALWAYS get explicit user confirmation of the exact recipient address, amount, chain, and token in conversation immediately before calling this tool.",
|
|
930
931
|
inputSchema: {
|
|
931
932
|
type: "object",
|
|
932
933
|
properties: {
|
|
@@ -1139,7 +1140,9 @@ function describeSandboxReason2(resolvedKey, scope) {
|
|
|
1139
1140
|
}
|
|
1140
1141
|
var BATCH_PAY_TOOL = {
|
|
1141
1142
|
name: "q402_batch_pay",
|
|
1142
|
-
description: `
|
|
1143
|
+
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.
|
|
1144
|
+
|
|
1145
|
+
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.`,
|
|
1143
1146
|
inputSchema: {
|
|
1144
1147
|
type: "object",
|
|
1145
1148
|
properties: {
|
|
@@ -1635,48 +1638,61 @@ var CLEAR_DELEGATION_TOOL = {
|
|
|
1635
1638
|
import { z as z8 } from "zod";
|
|
1636
1639
|
import { Wallet as Wallet6 } from "ethers";
|
|
1637
1640
|
var DoctorInputSchema = z8.object({});
|
|
1638
|
-
var ENV_FILE_TEMPLATE = `# \
|
|
1641
|
+
var ENV_FILE_TEMPLATE = `# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1639
1642
|
# Q402 MCP \u2014 secrets
|
|
1643
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1640
1644
|
# Read automatically by @quackai/q402-mcp on startup.
|
|
1641
1645
|
# Edit this file in your editor. NEVER paste your private key into chat.
|
|
1642
1646
|
# After editing, restart your MCP client (Codex / Claude / Cursor / Cline).
|
|
1643
1647
|
#
|
|
1644
|
-
# SAFE-BY-DEFAULT:
|
|
1645
|
-
#
|
|
1646
|
-
#
|
|
1647
|
-
#
|
|
1648
|
-
# as-is
|
|
1649
|
-
|
|
1648
|
+
# SAFE-BY-DEFAULT: the api-key + private-key lines below ship EMPTY.
|
|
1649
|
+
# Q402_ENABLE_REAL_PAYMENTS defaults to 1, but the live-mode gate also
|
|
1650
|
+
# requires (a) a real \`q402_live_*\` API key and (b) a valid 32-byte
|
|
1651
|
+
# hex private key. Empty values fail both checks, so saving this file
|
|
1652
|
+
# as-is just leaves you in sandbox. Paste real values to go live.
|
|
1653
|
+
|
|
1650
1654
|
|
|
1651
|
-
# \
|
|
1655
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1656
|
+
# API KEY \u2014 paste on the right of \`=\` (one OR both for auto-routing)
|
|
1657
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1652
1658
|
# Free Trial: BNB Chain only, 2,000 sponsored TX
|
|
1653
1659
|
# Get one at: https://q402.quackai.ai/event
|
|
1654
|
-
|
|
1660
|
+
Q402_TRIAL_API_KEY=
|
|
1655
1661
|
|
|
1656
1662
|
# Paid Multichain: all 9 chains, per-chain Gas Tank
|
|
1657
1663
|
# Get one at: https://q402.quackai.ai/payment
|
|
1658
|
-
|
|
1664
|
+
Q402_MULTICHAIN_API_KEY=
|
|
1659
1665
|
|
|
1660
|
-
|
|
1666
|
+
|
|
1667
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1668
|
+
# WALLET \u2014 paste your private key on the right of \`=\`
|
|
1669
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1661
1670
|
# Hex EVM private key (0x + 64 hex chars). Signs payments LOCALLY on
|
|
1662
1671
|
# your machine \u2014 never leaves your device, never sent to any server.
|
|
1663
|
-
|
|
1672
|
+
Q402_PRIVATE_KEY=
|
|
1673
|
+
|
|
1664
1674
|
|
|
1665
|
-
# \
|
|
1666
|
-
#
|
|
1667
|
-
#
|
|
1668
|
-
#
|
|
1669
|
-
#
|
|
1670
|
-
#
|
|
1671
|
-
#
|
|
1672
|
-
#
|
|
1675
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1676
|
+
# Live mode switch (safe even at 1 \u2014 see SAFE-BY-DEFAULT note at top)
|
|
1677
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1678
|
+
# 0 = sandbox (test mode, no funds move \u2014 every q402_pay returns a fake hash)
|
|
1679
|
+
# 1 = real on-chain payments
|
|
1680
|
+
# Default 1; flips to live only when the API key + private key above are
|
|
1681
|
+
# both populated. Set to 0 to force sandbox even with real keys in place
|
|
1682
|
+
# (e.g. for chained testing on a paid plan).
|
|
1673
1683
|
Q402_ENABLE_REAL_PAYMENTS=1
|
|
1674
1684
|
|
|
1675
|
-
|
|
1685
|
+
|
|
1686
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1687
|
+
# Q402 relay endpoint
|
|
1688
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1676
1689
|
# Default canonical Q402 deployment. Only change for self-hosted.
|
|
1677
1690
|
Q402_RELAY_BASE_URL=https://q402.quackai.ai/api
|
|
1678
1691
|
|
|
1679
|
-
|
|
1692
|
+
|
|
1693
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1694
|
+
# Optional safety guards (uncomment + edit to enable)
|
|
1695
|
+
# \u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501\u2501
|
|
1680
1696
|
# Max USD per single q402_pay call (default: 5)
|
|
1681
1697
|
# Q402_MAX_AMOUNT_PER_CALL=5
|
|
1682
1698
|
#
|
|
@@ -1706,9 +1722,13 @@ function mask2(key) {
|
|
|
1706
1722
|
}
|
|
1707
1723
|
function detectPhase() {
|
|
1708
1724
|
const anyKey = !!(CONFIG.trialApiKey || CONFIG.multichainApiKey || CONFIG.legacyApiKey);
|
|
1709
|
-
const
|
|
1725
|
+
const hasValidPrivateKey = isValidPrivateKey(CONFIG.privateKey);
|
|
1726
|
+
if (!Q402_ENV_FILE_PRESENT && !anyKey && !CONFIG.privateKey) {
|
|
1727
|
+
return "first-install";
|
|
1728
|
+
}
|
|
1729
|
+
const allEssentials = anyKey && hasValidPrivateKey && CONFIG.realPaymentsRequested && CONFIG.apiKeyKind === "live";
|
|
1710
1730
|
if (allEssentials) return "live-check";
|
|
1711
|
-
if (anyKey || CONFIG.privateKey ||
|
|
1731
|
+
if (anyKey || CONFIG.privateKey || Q402_ENV_FILE_PRESENT) return "needs-completion";
|
|
1712
1732
|
return "first-install";
|
|
1713
1733
|
}
|
|
1714
1734
|
async function verifyOneKey(scope, envVar, apiKey) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@quackai/q402-mcp",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.15",
|
|
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": [
|