@agentwonderland/mcp 0.1.51 → 0.1.53

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 (39) hide show
  1. package/dist/core/__tests__/api-client.test.js +6 -2
  2. package/dist/core/__tests__/link-cli.test.d.ts +1 -0
  3. package/dist/core/__tests__/link-cli.test.js +102 -0
  4. package/dist/core/__tests__/principal.test.js +25 -0
  5. package/dist/core/api-client.js +4 -2
  6. package/dist/core/link-cli.d.ts +5 -0
  7. package/dist/core/link-cli.js +25 -25
  8. package/dist/core/principal.d.ts +1 -0
  9. package/dist/core/principal.js +49 -1
  10. package/dist/index.js +3 -0
  11. package/dist/tools/__tests__/rebates.test.d.ts +1 -0
  12. package/dist/tools/__tests__/rebates.test.js +72 -0
  13. package/dist/tools/__tests__/run.test.js +26 -0
  14. package/dist/tools/__tests__/wallet.test.js +1 -0
  15. package/dist/tools/index.d.ts +1 -0
  16. package/dist/tools/index.js +1 -0
  17. package/dist/tools/observability.d.ts +2 -0
  18. package/dist/tools/observability.js +20 -0
  19. package/dist/tools/rebates.d.ts +2 -0
  20. package/dist/tools/rebates.js +51 -0
  21. package/dist/tools/run.js +6 -0
  22. package/dist/tools/solve.js +8 -1
  23. package/dist/tools/wallet.js +4 -4
  24. package/package.json +1 -1
  25. package/src/core/__tests__/api-client.test.ts +8 -1
  26. package/src/core/__tests__/link-cli.test.ts +125 -0
  27. package/src/core/__tests__/principal.test.ts +31 -0
  28. package/src/core/api-client.ts +4 -2
  29. package/src/core/link-cli.ts +25 -27
  30. package/src/core/principal.ts +54 -1
  31. package/src/index.ts +3 -0
  32. package/src/tools/__tests__/rebates.test.ts +91 -0
  33. package/src/tools/__tests__/run.test.ts +33 -0
  34. package/src/tools/__tests__/wallet.test.ts +1 -0
  35. package/src/tools/index.ts +1 -0
  36. package/src/tools/rebates.ts +102 -0
  37. package/src/tools/run.ts +7 -0
  38. package/src/tools/solve.ts +8 -1
  39. package/src/tools/wallet.ts +4 -4
@@ -0,0 +1,102 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { apiGet } from "../core/api-client.js";
3
+
4
+ type RebateStatus = {
5
+ consumer_principal: string;
6
+ principal_type: string;
7
+ principal_value: string;
8
+ payout_address: string | null;
9
+ payout_chain: string;
10
+ auto_payout_threshold_usd: string;
11
+ totals: {
12
+ lifetime_earned_usd: string;
13
+ pending_usd: string;
14
+ paid_usd: string;
15
+ blocked_usd: string;
16
+ total_count: number;
17
+ pending_count: number;
18
+ paid_count: number;
19
+ blocked_count: number;
20
+ };
21
+ by_source: Array<{
22
+ source_type: string;
23
+ status: string;
24
+ count: number;
25
+ rebate_usd: string;
26
+ }>;
27
+ recent_payouts: Array<{
28
+ id: string;
29
+ status: string;
30
+ amount_usd: string;
31
+ earning_count: number;
32
+ tx_hash: string | null;
33
+ processed_at: string | null;
34
+ }>;
35
+ };
36
+
37
+ function text(t: string) {
38
+ return { content: [{ type: "text" as const, text: t }] };
39
+ }
40
+
41
+ function money(value: string | number): string {
42
+ const numeric = Number(value);
43
+ return Number.isFinite(numeric) ? `$${numeric.toFixed(4)}` : `$${value}`;
44
+ }
45
+
46
+ function sourceLabel(value: string): string {
47
+ return value.replace(/_/g, " ");
48
+ }
49
+
50
+ export function registerRebateTools(server: McpServer): void {
51
+ server.tool(
52
+ "rebate_status",
53
+ "Show your Agent Wonderland consumer rebate balance, payout threshold, blocked rebates, and recent payout transactions.",
54
+ {},
55
+ async () => {
56
+ const status = await apiGet<RebateStatus>("/rebates/status", { ensureConsumerPrincipal: true });
57
+ const threshold = Number(status.auto_payout_threshold_usd);
58
+ const pending = Number(status.totals.pending_usd);
59
+ const remaining = Math.max(0, threshold - pending);
60
+
61
+ const lines = [
62
+ "Rebate status",
63
+ `Consumer principal: ${status.consumer_principal}`,
64
+ `Base payout address: ${status.payout_address ?? "not configured"}`,
65
+ "",
66
+ `Lifetime earned: ${money(status.totals.lifetime_earned_usd)} across ${status.totals.total_count} rebate(s)`,
67
+ `Paid out: ${money(status.totals.paid_usd)} across ${status.totals.paid_count} rebate(s)`,
68
+ `Pending: ${money(status.totals.pending_usd)} across ${status.totals.pending_count} rebate(s)`,
69
+ `Blocked: ${money(status.totals.blocked_usd)} across ${status.totals.blocked_count} rebate(s)`,
70
+ ];
71
+
72
+ if (Number.isFinite(threshold) && threshold > 0) {
73
+ lines.push(
74
+ pending >= threshold
75
+ ? `Auto payout: eligible for the next processor run (threshold ${money(threshold)})`
76
+ : `Auto payout: ${money(remaining)} until the ${money(threshold)} threshold`,
77
+ );
78
+ }
79
+
80
+ if (status.by_source.length > 0) {
81
+ lines.push("", "By source:");
82
+ for (const row of status.by_source) {
83
+ lines.push(` ${sourceLabel(row.source_type)} / ${row.status}: ${money(row.rebate_usd)} (${row.count})`);
84
+ }
85
+ }
86
+
87
+ if (status.recent_payouts.length > 0) {
88
+ lines.push("", "Recent payouts:");
89
+ for (const payout of status.recent_payouts.slice(0, 5)) {
90
+ const tx = payout.tx_hash ? ` tx=${payout.tx_hash}` : "";
91
+ lines.push(` ${payout.status}: ${money(payout.amount_usd)} (${payout.earning_count})${tx}`);
92
+ }
93
+ }
94
+
95
+ if (!status.payout_address) {
96
+ lines.push("", "No Base payout address is configured, so new rebates may be blocked.");
97
+ }
98
+
99
+ return text(lines.join("\n"));
100
+ },
101
+ );
102
+ }
package/src/tools/run.ts CHANGED
@@ -220,6 +220,10 @@ export function registerRunTools(server: McpServer): void {
220
220
  ` Payment: ${formatPaymentLabel(method)}`,
221
221
  ];
222
222
 
223
+ if (method === "link") {
224
+ quoteLines.push(" Link: after confirming here, approve the Link spend request and rerun the confirmed call.");
225
+ }
226
+
223
227
  const creditPackLines = buildCreditPackOfferLines(agent);
224
228
  if (creditPackLines.length > 0) {
225
229
  quoteLines.push("", ...creditPackLines);
@@ -299,6 +303,9 @@ export function registerRunTools(server: McpServer): void {
299
303
  );
300
304
  }
301
305
  const msg = apiErr?.message ?? "Failed to run agent";
306
+ if (msg.includes("Link approval required.")) {
307
+ return text(msg);
308
+ }
302
309
  if (msg.includes("Missing required field") || msg.includes("validation failed")) {
303
310
  return text(`Error: ${msg}\n\nUse get_agent("${agent_id}") to see the required input fields.`);
304
311
  }
@@ -292,6 +292,9 @@ export function registerSolveTools(server: McpServer): void {
292
292
  `Best match: ${selected.name}`,
293
293
  `Cost: $${estimatedCost.toFixed(2)}`,
294
294
  `Payment: ${formatPaymentLabel(method)}`,
295
+ ...(method === "link"
296
+ ? ["Link: after confirming here, approve the Link spend request and rerun the confirmed call."]
297
+ : []),
295
298
  ...(() => {
296
299
  const summary = buildCreditPackSummary(selected);
297
300
  return summary.length > 0 ? ["", ...summary] : [];
@@ -361,7 +364,11 @@ export function registerSolveTools(server: McpServer): void {
361
364
  ].join("\n"),
362
365
  );
363
366
  }
364
- return text(`Error: ${apiErr?.message ?? "Failed to run agent"}`);
367
+ const msg = apiErr?.message ?? "Failed to run agent";
368
+ if (msg.includes("Link approval required.")) {
369
+ return text(msg);
370
+ }
371
+ return text(`Error: ${msg}`);
365
372
  }
366
373
 
367
374
  pendingSolves.delete(pendingKey);
@@ -39,7 +39,7 @@ import {
39
39
  installOws,
40
40
  platformSupportsOws,
41
41
  } from "../core/ows-adapter.js";
42
- import { ensureConsumerPrincipal, getConsumerPrincipal } from "../core/principal.js";
42
+ import { ensureConsumerPrincipal, ensureConsumerPrincipalForMethod, getConsumerPrincipal } from "../core/principal.js";
43
43
  import { MCP_PACKAGE_VERSION } from "../core/version.js";
44
44
 
45
45
  function text(t: string) {
@@ -292,7 +292,7 @@ export function registerWalletTools(server: McpServer): void {
292
292
  paymentMethodId: selected.id,
293
293
  label: name ?? selected.label,
294
294
  });
295
- const principal = await ensureConsumerPrincipal();
295
+ const principal = await ensureConsumerPrincipalForMethod("link");
296
296
  return text(
297
297
  [
298
298
  "Link payment method connected.",
@@ -330,7 +330,7 @@ export function registerWalletTools(server: McpServer): void {
330
330
  paymentMethodId: method.id,
331
331
  label: method.label,
332
332
  });
333
- const principal = await ensureConsumerPrincipal();
333
+ const principal = await ensureConsumerPrincipalForMethod("link");
334
334
  return text(
335
335
  [
336
336
  "Link payment method connected.",
@@ -380,7 +380,7 @@ export function registerWalletTools(server: McpServer): void {
380
380
  const result = await pollCardSetup(pendingToken, 250);
381
381
 
382
382
  if (result) {
383
- const principal = await ensureConsumerPrincipal();
383
+ const principal = await ensureConsumerPrincipalForMethod("card");
384
384
  return text(
385
385
  `Connected! ${result.brand} ****${result.last4} is ready for payments.\n\n` +
386
386
  `Consumer principal: ${principal}`,