@quackai/q402-mcp 0.4.5 → 0.4.6

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 CHANGED
@@ -76,8 +76,11 @@ command = "npx"
76
76
  args = ["-y", "@quackai/q402-mcp"]
77
77
  startup_timeout_sec = 20.0
78
78
  env = {
79
- # Two-key model (v0.4.5+): set whichever applies — both is best.
80
- # The server auto-routes by chain: BNB → trial key, else multichain key.
79
+ # Two-key model (v0.4.6+): set whichever applies — both is best.
80
+ # Auto-routing:
81
+ # q402_pay (single) → BNB + trial key set ⇒ trial; else multichain.
82
+ # q402_batch_pay → ALWAYS multichain (trial cap=5 silently breaks
83
+ # 6+ row batches; pass keyScope="trial" to force).
81
84
  # Both keys use the same q402_live_ prefix — the env var name is what
82
85
  # carries the scope, not the key string. Get the values from the
83
86
  # dashboard (each key has its own copy button per view).
@@ -128,19 +131,21 @@ The server has no client-specific code. If your client speaks stdio MCP, point i
128
131
 
129
132
  ## Sandbox vs live mode
130
133
 
131
- By default the MCP server operates in **sandbox mode**: `q402_pay` returns a deterministic-looking fake transaction hash, no funds move, no gas-tank credit is consumed. That makes it safe to plug into any MCP client without worrying about an LLM hallucinating a payment.
134
+ By default the MCP server operates in **sandbox mode**: `q402_pay` returns a random fake transaction hash (32-byte hex, no on-chain broadcast), no funds move, no gas-tank credit is consumed. That makes it safe to plug into any MCP client without worrying about an LLM hallucinating a payment.
132
135
 
133
136
  To enable real on-chain transactions, the resolved API key must be live (`q402_live_*`), `Q402_PRIVATE_KEY` must be set, and `Q402_ENABLE_REAL_PAYMENTS=1`:
134
137
 
135
138
  ```bash
136
- # Two-key model (v0.4.5+) — set whichever applies. Both is best.
137
- # Auto-routing: chain="bnb" → trial key (if set), otherwise multichain key.
139
+ # Two-key model (v0.4.6+) — set whichever applies. Both is best.
140
+ # Auto-routing:
141
+ # q402_pay (single) → BNB + Q402_TRIAL_API_KEY set ⇒ Trial; else Multichain.
142
+ # q402_batch_pay → always Multichain (Trial cap=5 silently breaks 6+ row batches).
138
143
  # Override per call with keyScope: "auto" | "trial" | "multichain".
139
144
  Q402_TRIAL_API_KEY=q402_live_... # BNB-only sponsored Trial key (from /event)
140
145
  Q402_MULTICHAIN_API_KEY=q402_live_... # paid 8-chain key (per-chain Gas Tank)
141
146
 
142
147
  # Legacy fallback. Used for both scopes when the two above are unset —
143
- # pre-v0.4.5 users keep working without any config change.
148
+ # pre-v0.4.6 users keep working without any config change.
144
149
  Q402_API_KEY=q402_live_...
145
150
 
146
151
  Q402_PRIVATE_KEY=0xabc... # signer for the payer EOA
@@ -151,7 +156,7 @@ Anything missing for the resolved scope → automatic sandbox fallback with a hi
151
156
 
152
157
  > ⚠️ **Sandbox returns a deterministic-looking fake `txHash` and a synthetic success result.** A user who *expected* a live transfer (e.g. forgot to set `Q402_ENABLE_REAL_PAYMENTS=1`, mis-typed a scoped env var, or hit an impossible chain×scope combination like `keyScope: "trial"` + `chain: "monad"`) gets a "success" back and may believe funds actually moved.
153
158
  >
154
- > Two-layer mitigation: every sandbox response carries a `setupHint` field on the tool result describing **exactly why** sandbox was selected, and the `q402_balance` tool's `apiKeyKind: "missing"` makes the same diagnosis explicit. Always check `setupHint` on the first call from a new install. The deterministic `txHash` pattern (`0x` + 64 hex derived from `keccak256(chain, to, amount, token, "sandbox")`) is intentional so the agent can recognise it post-hoc, but the safer habit is to inspect `setupHint` before showing the user a success message.
159
+ > Two-layer mitigation: every sandbox response carries a `setupHint` field on the tool result describing **exactly why** sandbox was selected, and a `method: "sandbox"` field that makes the mode explicit independent of hash inspection. The `txHash` itself is a 32-byte random hex string — visually indistinguishable from a real hash but emitted only when no on-chain TX is broadcast so don't rely on hash forensics. Always check `setupHint` (or `method`) before showing the user a success message.
155
160
 
156
161
  ### Hard caps
157
162
 
@@ -172,7 +177,7 @@ Combined with the `confirm: true` argument the tool requires, this means the mod
172
177
  |---|---|---|
173
178
  | `Q402_TRIAL_API_KEY` | live-pay (BNB) | BNB-only sponsored Trial key. Free at https://q402.quackai.ai/event. Used automatically for `chain="bnb"` when set. |
174
179
  | `Q402_MULTICHAIN_API_KEY` | live-pay (8-chain) | Paid 8-chain key. Get one at https://q402.quackai.ai/payment. Used for all non-BNB chains and for BNB when no Trial key is set. |
175
- | `Q402_API_KEY` | legacy fallback | Pre-v0.4.5 single-env path. Used for both scopes when the two above are unset. Keep set if you only have one key. |
180
+ | `Q402_API_KEY` | legacy fallback | Pre-v0.4.6 single-env path. Used for both scopes when the two above are unset. Keep set if you only have one key. |
176
181
  | `Q402_PRIVATE_KEY` | live-pay | Signer for the payer EOA. **Never share. Never paste in chat.** |
177
182
  | `Q402_ENABLE_REAL_PAYMENTS` | live-pay | Set to `1` to opt in. Any other value (or unset) → sandbox. |
178
183
  | `Q402_MAX_AMOUNT_PER_CALL` | optional | USD-equivalent cap. Defaults to `5`. |
package/dist/index.js CHANGED
@@ -816,7 +816,7 @@ var BatchPayInputSchema = z3.object({
816
816
  `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.`
817
817
  ),
818
818
  keyScope: z3.enum(["auto", "trial", "multichain"]).optional().describe(
819
- '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.'
819
+ 'Which API key to use. "auto" (default) ALWAYS routes batches to the Multichain key, even on BNB \u2014 the Trial cap of 5 recipients would silently break any 6+ row batch. Use keyScope="trial" to force the BNB-only sponsored Trial key (max 5 recipients). keyScope="multichain" is the same as auto for batches.'
820
820
  ),
821
821
  confirm: z3.literal(true).describe(
822
822
  "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."
@@ -930,7 +930,7 @@ function describeSandboxReason2(resolvedKey) {
930
930
  }
931
931
  var BATCH_PAY_TOOL = {
932
932
  name: "q402_batch_pay",
933
- description: `Send gasless payments to MULTIPLE recipients on a single chain \xD7 token in one call. Uses Q402_TRIAL_API_KEY for chain='bnb' when the Trial env is set, Q402_MULTICHAIN_API_KEY otherwise. Set keyScope='trial' or 'multichain' to force one. Trial keys: max ${RECIPIENT_LIMIT_TRIAL} recipients per call, BNB Chain + USDC/USDT only. Multichain keys: max ${RECIPIENT_LIMIT_PAID} recipients per call across 6 EIP-7702 default chains (avax, bnb, eth, mantle, injective, monad). xlayer + stable are NOT batchable \u2014 use q402_pay in a loop. 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.`,
933
+ description: `Send gasless payments to MULTIPLE recipients on a single chain \xD7 token in one call. Auto-routing ALWAYS picks the Multichain key (even on BNB) \u2014 the Trial cap of ${RECIPIENT_LIMIT_TRIAL} recipients would silently break 6+ row batches. Set keyScope='trial' to force the BNB-only sponsored Trial key (\u22645 recipients); keyScope='multichain' is the auto default. Trial keys: max ${RECIPIENT_LIMIT_TRIAL} recipients per call, BNB Chain + USDC/USDT only. Multichain keys: max ${RECIPIENT_LIMIT_PAID} recipients per call across 6 EIP-7702 default chains (avax, bnb, eth, mantle, injective, monad). xlayer + stable are NOT batchable \u2014 use q402_pay in a loop. 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.`,
934
934
  inputSchema: {
935
935
  type: "object",
936
936
  properties: {
@@ -971,7 +971,7 @@ var BATCH_PAY_TOOL = {
971
971
  keyScope: {
972
972
  type: "string",
973
973
  enum: ["auto", "trial", "multichain"],
974
- description: 'Which API key to use. "auto" (default) picks Trial for BNB when Q402_TRIAL_API_KEY is set, Multichain otherwise.'
974
+ description: 'Which API key to use. "auto" (default) ALWAYS picks Multichain for batches \u2014 Trial cap=5 would silently break 6+ row batches. Use keyScope="trial" to force the BNB-only sponsored key (\u22645 rows).'
975
975
  },
976
976
  confirm: {
977
977
  type: "boolean",
@@ -1221,7 +1221,7 @@ var RECEIPT_TOOL = {
1221
1221
 
1222
1222
  // src/index.ts
1223
1223
  var PACKAGE_NAME = "@quackai/q402-mcp";
1224
- var PACKAGE_VERSION = "0.4.5";
1224
+ var PACKAGE_VERSION = "0.4.6";
1225
1225
  function jsonText(value) {
1226
1226
  return { type: "text", text: JSON.stringify(value, null, 2) };
1227
1227
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quackai/q402-mcp",
3
- "version": "0.4.5",
3
+ "version": "0.4.6",
4
4
  "description": "MCP server for Q402 — gasless USDC, USDT, and RLUSD payments across 8 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": [