@blanketbyte/wise-mcp 1.0.4 → 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.
- package/dist/auth/pages.js +2 -2
- package/dist/tools.js +30 -1
- package/package.json +1 -1
package/dist/auth/pages.js
CHANGED
|
@@ -183,7 +183,7 @@ function layout(title, body) {
|
|
|
183
183
|
footer .ic { width:14px; height:14px; }
|
|
184
184
|
footer a { color:var(--muted); }
|
|
185
185
|
footer a.gh { display:inline-flex; align-items:center; gap:4px; }
|
|
186
|
-
footer a.ver { color:var(--faint); text-decoration:none; font-variant-numeric:tabular-nums; }
|
|
186
|
+
footer a.ver { flex-basis:100%; text-align:center; margin-top:-2px; color:var(--faint); font-size:12px; text-decoration:none; font-variant-numeric:tabular-nums; }
|
|
187
187
|
footer a.ver:hover { text-decoration:underline; }
|
|
188
188
|
.dot { opacity:.5; }
|
|
189
189
|
</style>
|
|
@@ -204,7 +204,7 @@ function card(inner, opts) {
|
|
|
204
204
|
</div>
|
|
205
205
|
${inner}
|
|
206
206
|
</div>
|
|
207
|
-
<footer>${icon("lock")}<span>Token encrypted at rest</span><span class="dot">·</span><a href="/sessions">Manage sessions</a><span class="dot">·</span><a class="gh" href="${REPO_URL}" target="_blank" rel="noopener">${icon("github")}Source</a><
|
|
207
|
+
<footer>${icon("lock")}<span>Token encrypted at rest</span><span class="dot">·</span><a href="/sessions">Manage sessions</a><span class="dot">·</span><a class="gh" href="${REPO_URL}" target="_blank" rel="noopener">${icon("github")}Source</a><a class="ver" href="${REPO_URL}/releases/tag/v${VERSION}" target="_blank" rel="noopener" title="Release notes">v${VERSION}</a></footer>
|
|
208
208
|
</main>`;
|
|
209
209
|
}
|
|
210
210
|
/** Red banner shown on every page served over plain HTTP (except localhost). */
|
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, {
|
|
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.
|
|
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": [
|