@blanketbyte/wise-mcp 1.0.5 → 1.0.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.
Files changed (2) hide show
  1. package/dist/tools.js +30 -1
  2. package/package.json +1 -1
package/dist/tools.js CHANGED
@@ -274,7 +274,15 @@ function registerWriteTools(server, wise, { sessionKey, connectionId }, safe) {
274
274
  (sourceCurrency !== recipient.currency ? `, rate ${quote.rate}` : "") +
275
275
  (details.reference ? `, reference "${details.reference}"` : "") +
276
276
  (quote.delivery ? `, ${stripHtml(quote.delivery)}` : "");
277
- const { code, expiresAt } = storePending(sessionKey, { kind: "transfer", profileId: profile.id, quoteId: quote.id, targetAccount: recipient.id, customerTransactionId: randomUUID(), details }, summary);
277
+ const { code, expiresAt } = storePending(sessionKey, {
278
+ kind: "transfer",
279
+ profileId: profile.id,
280
+ quoteId: quote.id,
281
+ targetAccount: recipient.id,
282
+ customerTransactionId: randomUUID(),
283
+ details,
284
+ expected: { amount: quote.source.amount, currency: sourceCurrency },
285
+ }, summary);
278
286
  await log("transfer_prepared", { code, summary });
279
287
  return ok({
280
288
  status: "awaiting_user_confirmation",
@@ -319,6 +327,27 @@ function registerWriteTools(server, wise, { sessionKey, connectionId }, safe) {
319
327
  try {
320
328
  if (a.kind === "transfer") {
321
329
  const t = await wise.createTransfer({ targetAccount: a.targetAccount, quoteId: a.quoteId, customerTransactionId: a.customerTransactionId, details: a.details });
330
+ // Wise has been seen creating a transfer for a different amount than its own quote. Never leave the
331
+ // user with a transfer they didn't approve: it's still unpaid, so cancel it and say what happened.
332
+ const got = { amount: Number(t.source.amount), currency: String(t.source.currency ?? "").toUpperCase() };
333
+ if (Math.abs(got.amount - a.expected.amount) > 0.005 || got.currency !== a.expected.currency.toUpperCase()) {
334
+ const cancelled = await wise.cancelTransfer(t.id).then((c) => c.status, (err) => `cancel failed: ${err instanceof Error ? err.message : err}`);
335
+ await log("transfer_amount_mismatch", {
336
+ code: confirmation_code,
337
+ summary: p.summary,
338
+ transfer_id: t.id,
339
+ quote_id: a.quoteId,
340
+ expected: a.expected,
341
+ got,
342
+ cancelled,
343
+ });
344
+ return fail(`Wise created transfer ${t.id} for ${money(got.amount, got.currency)} instead of the approved ` +
345
+ `${money(a.expected.amount, a.expected.currency)} (quote ${a.quoteId}). ` +
346
+ (cancelled === "cancelled"
347
+ ? "It was cancelled automatically, so nothing will be paid. "
348
+ : `Automatic cancellation didn't succeed (${cancelled}): tell the user to cancel it in the Wise app and NOT pay it. `) +
349
+ "Don't retry; tell the user this is a Wise-side mismatch.");
350
+ }
322
351
  await log("transfer_created", { code: confirmation_code, summary: p.summary, transfer_id: t.id, status: t.status });
323
352
  return ok({
324
353
  status: "created_awaiting_payment",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blanketbyte/wise-mcp",
3
- "version": "1.0.5",
3
+ "version": "1.0.6",
4
4
  "description": "MCP server for Wise: read balances, card payments, transfers and recipients, and prepare transfers you approve twice. Runs locally (npx, for Claude, Codex, Cursor…) or as a remote connector for Claude and ChatGPT.",
5
5
  "mcpName": "io.github.BlanketByte/wise-mcp",
6
6
  "keywords": [