@quackai/q402-mcp 0.8.10 → 0.8.12

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 +8 -0
  2. package/dist/index.js +49 -4
  3. package/package.json +75 -75
package/README.md CHANGED
@@ -288,6 +288,14 @@ Single transfers and multi-recipient batches ship today. The next layer — recu
288
288
 
289
289
  ---
290
290
 
291
+ ## Hooks — programmable payment policies
292
+
293
+ Q402 Hooks 1.0 is a policy engine that attaches rules to the payment lifecycle: OFAC compliance screening, spend caps + recipient allowlists, ERC-8004 reputation gating, Chainlink-oracle conditional settlement ("only when BTC ≥ $80k"), and automatic multi-payee splits — plus human-in-the-loop approval holds. Uniswap v4 brought programmable hooks to DEX liquidity; Q402 brings them to AI-agent payments.
294
+
295
+ **Developer reference: [docs/HOOKS.md](docs/HOOKS.md)** — lifecycle, the Hook contract, every shipped hook with config + examples.
296
+
297
+ ---
298
+
291
299
  ## Repository
292
300
 
293
301
  Source code: https://github.com/bitgett/q402-mcp
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.10";
214
+ var PACKAGE_VERSION = "0.8.12";
215
215
 
216
216
  // src/tools/quote.ts
217
217
  import { z } from "zod";
@@ -874,6 +874,18 @@ When MORE THAN ONE wallet is configured in the user's environment, you MUST ask
874
874
  ),
875
875
  confirm: z2.literal(true).describe(
876
876
  "MUST be true. Prove the user explicitly approved this exact recipient and amount in the conversation right before this tool was called. Setting this to true on behalf of the user without confirmation is a violation of the tool contract."
877
+ ),
878
+ hookParams: z2.object({
879
+ recipientAgentId: z2.string().optional().describe("ReputationGate: the recipient's ERC-8004 agent id."),
880
+ condition: z2.object({
881
+ kind: z2.enum(["price", "timestamp"]),
882
+ feed: z2.string().optional().describe('Chainlink feed pair for kind="price", e.g. "BTC/USD".'),
883
+ op: z2.enum([">=", "<=", ">", "<", "after", "before"]),
884
+ value: z2.number().describe('USD price (kind="price") or unix seconds (kind="timestamp").')
885
+ }).optional().describe('ConditionalOracle: settle only when this condition holds, e.g. { kind:"price", feed:"BTC/USD", op:">=", value:80000 }.'),
886
+ splits: z2.array(z2.object({ recipient: z2.string(), bps: z2.number() })).optional().describe("MultiPayeeSplit: per-payment N-way split; bps must sum to 10000.")
887
+ }).optional().describe(
888
+ 'Q402 Hook parameters (server-managed Agent Wallet path only). Attaches per-payment hook conditions: a ConditionalOracle price/time gate, a MultiPayeeSplit fan-out, or a ReputationGate recipient agent id. Honoured only on walletMode="agentic-server".'
877
889
  )
878
890
  });
879
891
  function maxAmountGuard(amount, cap) {
@@ -1050,7 +1062,12 @@ async function runPay(input) {
1050
1062
  token: input.token,
1051
1063
  to: input.to,
1052
1064
  amount: input.amount,
1053
- ...explicitWalletId ? { walletId: explicitWalletId } : {}
1065
+ ...explicitWalletId ? { walletId: explicitWalletId } : {},
1066
+ // Q402 Hook params — only the Mode C (agentic-server) path runs
1067
+ // the per-wallet hook dispatch, so forwarding here is the only
1068
+ // place hookParams take effect. The landing route ignores them
1069
+ // for owner-sig calls (trust boundary), so this is safe.
1070
+ ...input.hookParams ? { hookParams: input.hookParams } : {}
1054
1071
  }),
1055
1072
  signal: AbortSignal.timeout(6e4)
1056
1073
  });
@@ -1220,6 +1237,31 @@ var PAY_TOOL = {
1220
1237
  type: "boolean",
1221
1238
  const: true,
1222
1239
  description: "MUST be true and only set after the user has confirmed recipient + amount in chat."
1240
+ },
1241
+ hookParams: {
1242
+ type: "object",
1243
+ description: "Q402 Hook params (server-managed Agent Wallet only). recipientAgentId (ReputationGate), condition (ConditionalOracle price/time gate), or splits (MultiPayeeSplit fan-out, bps sum 10000).",
1244
+ properties: {
1245
+ recipientAgentId: { type: "string" },
1246
+ condition: {
1247
+ type: "object",
1248
+ properties: {
1249
+ kind: { type: "string", enum: ["price", "timestamp"] },
1250
+ feed: { type: "string" },
1251
+ op: { type: "string", enum: [">=", "<=", ">", "<", "after", "before"] },
1252
+ value: { type: "number" }
1253
+ },
1254
+ required: ["kind", "op", "value"]
1255
+ },
1256
+ splits: {
1257
+ type: "array",
1258
+ items: {
1259
+ type: "object",
1260
+ properties: { recipient: { type: "string" }, bps: { type: "number" } },
1261
+ required: ["recipient", "bps"]
1262
+ }
1263
+ }
1264
+ }
1223
1265
  }
1224
1266
  },
1225
1267
  required: ["chain", "to", "amount", "token", "confirm"],
@@ -3900,8 +3942,11 @@ async function main() {
3900
3942
  RECURRING_CANCEL_TOOL,
3901
3943
  CLEAR_DELEGATION_TOOL,
3902
3944
  // CCIP bridge surface — USDC routing on the eth/avax/arbitrum
3903
- // triangle. Bridge_send is sandbox-only; live execution happens
3904
- // through the dashboard until session-binding ships.
3945
+ // triangle. Bridge_send goes LIVE on Mode C since 0.8.10 (Mode A/B
3946
+ // still fall through to sandbox since the route's API-key auth
3947
+ // path only exists for the server-managed Agent Wallet). History
3948
+ // + Gas Tank tools remain dashboard-pointer until session-binding
3949
+ // exposes owner-sig auth from MCP.
3905
3950
  BRIDGE_QUOTE_TOOL,
3906
3951
  BRIDGE_SEND_TOOL,
3907
3952
  BRIDGE_HISTORY_TOOL,
package/package.json CHANGED
@@ -1,75 +1,75 @@
1
- {
2
- "name": "@quackai/q402-mcp",
3
- "version": "0.8.10",
4
- "description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
5
- "mcpName": "io.github.bitgett/q402-mcp",
6
- "keywords": [
7
- "mcp",
8
- "model-context-protocol",
9
- "claude",
10
- "claude-desktop",
11
- "claude-code",
12
- "codex",
13
- "openai-codex",
14
- "cline",
15
- "q402",
16
- "x402",
17
- "stablecoin",
18
- "usdc",
19
- "usdt",
20
- "rlusd",
21
- "ripple",
22
- "gasless",
23
- "eip-7702",
24
- "payments",
25
- "ai-agents"
26
- ],
27
- "type": "module",
28
- "main": "dist/index.js",
29
- "bin": {
30
- "q402-mcp": "dist/index.js"
31
- },
32
- "files": [
33
- "dist",
34
- "README.md",
35
- "LICENSE"
36
- ],
37
- "engines": {
38
- "node": ">=18.18"
39
- },
40
- "scripts": {
41
- "build": "tsup",
42
- "dev": "tsup --watch",
43
- "lint": "tsc --noEmit",
44
- "prepublishOnly": "npm run lint && npm run build",
45
- "start": "node dist/index.js"
46
- },
47
- "dependencies": {
48
- "@modelcontextprotocol/sdk": "^1.29.0",
49
- "ethers": "^6.16.0",
50
- "zod": "^3.23.8"
51
- },
52
- "devDependencies": {
53
- "@types/node": "^20.11.0",
54
- "tsup": "^8.3.0",
55
- "typescript": "^5.5.0"
56
- },
57
- "repository": {
58
- "type": "git",
59
- "url": "git+https://github.com/bitgett/q402-mcp.git"
60
- },
61
- "homepage": "https://q402.quackai.ai/claude",
62
- "bugs": {
63
- "url": "https://github.com/bitgett/q402-mcp/issues"
64
- },
65
- "license": "Apache-2.0",
66
- "author": "David Lee <davidlee@quackai.ai>",
67
- "publishConfig": {
68
- "access": "public"
69
- },
70
- "overrides": {
71
- "ws": "^8.20.1",
72
- "qs": "^6.15.2",
73
- "hono": "^4.12.21"
74
- }
75
- }
1
+ {
2
+ "name": "@quackai/q402-mcp",
3
+ "version": "0.8.12",
4
+ "description": "MCP server for Q402 — gasless USDC/USDT/RLUSD payments on 10 EVM chains + Chainlink CCIP USDC bridge on the eth/avax/arbitrum triangle, callable from Claude (Desktop / Code), OpenAI Codex CLI, and any other Model Context Protocol client.",
5
+ "mcpName": "io.github.bitgett/q402-mcp",
6
+ "keywords": [
7
+ "mcp",
8
+ "model-context-protocol",
9
+ "claude",
10
+ "claude-desktop",
11
+ "claude-code",
12
+ "codex",
13
+ "openai-codex",
14
+ "cline",
15
+ "q402",
16
+ "x402",
17
+ "stablecoin",
18
+ "usdc",
19
+ "usdt",
20
+ "rlusd",
21
+ "ripple",
22
+ "gasless",
23
+ "eip-7702",
24
+ "payments",
25
+ "ai-agents"
26
+ ],
27
+ "type": "module",
28
+ "main": "dist/index.js",
29
+ "bin": {
30
+ "q402-mcp": "dist/index.js"
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "README.md",
35
+ "LICENSE"
36
+ ],
37
+ "engines": {
38
+ "node": ">=18.18"
39
+ },
40
+ "scripts": {
41
+ "build": "tsup",
42
+ "dev": "tsup --watch",
43
+ "lint": "tsc --noEmit",
44
+ "prepublishOnly": "npm run lint && npm run build",
45
+ "start": "node dist/index.js"
46
+ },
47
+ "dependencies": {
48
+ "@modelcontextprotocol/sdk": "^1.29.0",
49
+ "ethers": "^6.16.0",
50
+ "zod": "^3.23.8"
51
+ },
52
+ "devDependencies": {
53
+ "@types/node": "^20.11.0",
54
+ "tsup": "^8.3.0",
55
+ "typescript": "^5.5.0"
56
+ },
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "git+https://github.com/bitgett/q402-mcp.git"
60
+ },
61
+ "homepage": "https://q402.quackai.ai/claude",
62
+ "bugs": {
63
+ "url": "https://github.com/bitgett/q402-mcp/issues"
64
+ },
65
+ "license": "Apache-2.0",
66
+ "author": "David Lee <davidlee@quackai.ai>",
67
+ "publishConfig": {
68
+ "access": "public"
69
+ },
70
+ "overrides": {
71
+ "ws": "^8.20.1",
72
+ "qs": "^6.15.2",
73
+ "hono": "^4.12.21"
74
+ }
75
+ }