@solvapay/mcp-core 0.4.2 → 0.4.3
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/index.cjs +98 -22
- package/dist/index.d.cts +44 -10
- package/dist/index.d.ts +44 -10
- package/dist/index.js +95 -22
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -38,9 +38,11 @@ __export(index_exports, {
|
|
|
38
38
|
McpBearerAuthError: () => McpBearerAuthError,
|
|
39
39
|
NARRATORS: () => NARRATORS,
|
|
40
40
|
OPEN_TOOL_FOR_VIEW: () => OPEN_TOOL_FOR_VIEW,
|
|
41
|
+
PORTAL_AUTO_RECHARGE_QUERY: () => PORTAL_AUTO_RECHARGE_QUERY,
|
|
41
42
|
SOLVAPAY_BOOTSTRAP_MIME_TYPE: () => SOLVAPAY_BOOTSTRAP_MIME_TYPE,
|
|
42
43
|
SOLVAPAY_BOOTSTRAP_URI: () => SOLVAPAY_BOOTSTRAP_URI,
|
|
43
44
|
SOLVAPAY_DEFAULT_CSP: () => SOLVAPAY_DEFAULT_CSP,
|
|
45
|
+
SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS: () => SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS,
|
|
44
46
|
SOLVAPAY_MCP_VIEW_KINDS: () => SOLVAPAY_MCP_VIEW_KINDS,
|
|
45
47
|
SOLVAPAY_OVERVIEW_MARKDOWN: () => SOLVAPAY_OVERVIEW_MARKDOWN,
|
|
46
48
|
SOLVAPAY_OVERVIEW_MIME_TYPE: () => SOLVAPAY_OVERVIEW_MIME_TYPE,
|
|
@@ -53,6 +55,7 @@ __export(index_exports, {
|
|
|
53
55
|
VIEW_FOR_TOOL: () => VIEW_FOR_TOOL,
|
|
54
56
|
applyHideToolsByAudience: () => applyHideToolsByAudience,
|
|
55
57
|
assertValidProductRef: () => import_core3.assertValidProductRef,
|
|
58
|
+
autoRechargeUrlFrom: () => autoRechargeUrlFrom,
|
|
56
59
|
balanceSummary: () => balanceSummary,
|
|
57
60
|
buildAuthInfoFromBearer: () => buildAuthInfoFromBearer,
|
|
58
61
|
buildPayableHandler: () => buildPayableHandler,
|
|
@@ -120,10 +123,13 @@ var MCP_PROMPT_NAMES = {
|
|
|
120
123
|
};
|
|
121
124
|
|
|
122
125
|
// src/types.ts
|
|
123
|
-
var
|
|
126
|
+
var SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS = [
|
|
124
127
|
"checkout",
|
|
125
128
|
"account",
|
|
126
|
-
"topup"
|
|
129
|
+
"topup"
|
|
130
|
+
];
|
|
131
|
+
var SOLVAPAY_MCP_VIEW_KINDS = [
|
|
132
|
+
...SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS,
|
|
127
133
|
"auto-recharge"
|
|
128
134
|
];
|
|
129
135
|
var TOOL_FOR_VIEW = {
|
|
@@ -756,6 +762,9 @@ function narrateTopup(data) {
|
|
|
756
762
|
lines.push(recoveryLine(["account"]));
|
|
757
763
|
return withCheckout(data, lines);
|
|
758
764
|
}
|
|
765
|
+
function autoRechargePortalUrl(data) {
|
|
766
|
+
return httpsUrl(data.autoRechargeUrl) ?? httpsUrl(data.portalUrl);
|
|
767
|
+
}
|
|
759
768
|
function narrateAutoRecharge(data) {
|
|
760
769
|
const lines = [];
|
|
761
770
|
lines.push(`**Auto-recharge \u2014 ${productName(data)}**`);
|
|
@@ -764,16 +773,27 @@ function narrateAutoRecharge(data) {
|
|
|
764
773
|
const bal = balanceRow(customer);
|
|
765
774
|
if (bal) lines.push(bal);
|
|
766
775
|
const enabled = customer?.autoRecharge?.enabled === true;
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
776
|
+
const failed = customer?.autoRecharge?.status === "failed";
|
|
777
|
+
if (failed) {
|
|
778
|
+
lines.push("Auto-recharge failed \u2014 update your card to resume");
|
|
779
|
+
} else {
|
|
780
|
+
lines.push(
|
|
781
|
+
enabled ? "Auto-recharge is on. It tops your balance up automatically so calls do not fail." : "Auto-recharge is off. Turn it on from the link below \u2014 it stores a card and tops your balance up automatically so calls do not fail."
|
|
782
|
+
);
|
|
783
|
+
}
|
|
784
|
+
const manageUrl = autoRechargePortalUrl(data);
|
|
785
|
+
if (manageUrl) {
|
|
786
|
+
lines.push(`Manage: ${namedManageMarkdown(manageUrl)} (${CHECKOUT_TTL})`);
|
|
787
|
+
}
|
|
772
788
|
lines.push("");
|
|
773
789
|
lines.push(recoveryLine(["account"]));
|
|
774
790
|
const links = [];
|
|
775
|
-
|
|
776
|
-
|
|
791
|
+
if (manageUrl) {
|
|
792
|
+
links.push({
|
|
793
|
+
uri: manageUrl,
|
|
794
|
+
name: enabled ? "Manage auto-recharge" : "Turn on auto-recharge"
|
|
795
|
+
});
|
|
796
|
+
}
|
|
777
797
|
return { text: lines.join("\n"), links };
|
|
778
798
|
}
|
|
779
799
|
var NARRATORS = {
|
|
@@ -1000,7 +1020,8 @@ var BootstrapPayloadSchema = import_zod2.z.object({
|
|
|
1000
1020
|
plans: import_zod2.z.array(import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown())),
|
|
1001
1021
|
customer: import_zod2.z.record(import_zod2.z.string(), import_zod2.z.unknown()).nullable(),
|
|
1002
1022
|
checkoutUrl: import_zod2.z.string().nullable().optional(),
|
|
1003
|
-
portalUrl: import_zod2.z.string().nullable().optional()
|
|
1023
|
+
portalUrl: import_zod2.z.string().nullable().optional(),
|
|
1024
|
+
autoRechargeUrl: import_zod2.z.string().nullable().optional()
|
|
1004
1025
|
}).passthrough();
|
|
1005
1026
|
|
|
1006
1027
|
// src/derive-view.ts
|
|
@@ -1012,7 +1033,7 @@ function isOutOfCredits(customer) {
|
|
|
1012
1033
|
const credits = customer?.balance?.credits;
|
|
1013
1034
|
return credits === 0;
|
|
1014
1035
|
}
|
|
1015
|
-
function deriveDefaultView(data, enabledViews = new Set(
|
|
1036
|
+
function deriveDefaultView(data, enabledViews = new Set(SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS)) {
|
|
1016
1037
|
const customer = data.customer;
|
|
1017
1038
|
const preferred = !hasActivePlan(customer, data.productRef) ? "checkout" : isOutOfCredits(customer) ? "topup" : "account";
|
|
1018
1039
|
if (enabledViews.has(preferred)) return preferred;
|
|
@@ -1181,6 +1202,18 @@ function resetMcpConfigLogForTests() {
|
|
|
1181
1202
|
|
|
1182
1203
|
// src/bootstrap-payload.ts
|
|
1183
1204
|
var import_server3 = require("@solvapay/server");
|
|
1205
|
+
|
|
1206
|
+
// src/portal-links.ts
|
|
1207
|
+
var PORTAL_AUTO_RECHARGE_QUERY = "tab=credits&intent=autorecharge";
|
|
1208
|
+
function autoRechargeUrlFrom(customerUrl) {
|
|
1209
|
+
if (typeof customerUrl !== "string" || !/^https?:\/\//i.test(customerUrl)) {
|
|
1210
|
+
return null;
|
|
1211
|
+
}
|
|
1212
|
+
const separator = customerUrl.includes("?") ? "&" : "?";
|
|
1213
|
+
return `${customerUrl}${separator}${PORTAL_AUTO_RECHARGE_QUERY}`;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
// src/bootstrap-payload.ts
|
|
1184
1217
|
var okOrNull = (result) => (0, import_server3.isErrorResult)(result) ? null : result;
|
|
1185
1218
|
var buildProviderNotFoundMessage = () => [
|
|
1186
1219
|
"Provider account not found on this SolvaPay deployment.",
|
|
@@ -1220,7 +1253,10 @@ function createBuildBootstrapPayload(options) {
|
|
|
1220
1253
|
try {
|
|
1221
1254
|
const platform = await solvaPay.apiClient.getPlatformConfig?.();
|
|
1222
1255
|
return platform?.stripePublishableKey ?? null;
|
|
1223
|
-
} catch {
|
|
1256
|
+
} catch (err) {
|
|
1257
|
+
console.warn("[solvapay] bootstrap: getPlatformConfig failed; stripePublishableKey omitted", {
|
|
1258
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1259
|
+
});
|
|
1224
1260
|
return null;
|
|
1225
1261
|
}
|
|
1226
1262
|
};
|
|
@@ -1286,6 +1322,12 @@ function createBuildBootstrapPayload(options) {
|
|
|
1286
1322
|
if ((0, import_server3.isErrorResult)(productResult)) {
|
|
1287
1323
|
throw createBootstrapProductError(productResult);
|
|
1288
1324
|
}
|
|
1325
|
+
if ((0, import_server3.isErrorResult)(plansResult)) {
|
|
1326
|
+
console.warn("[solvapay] bootstrap: listPlans failed; plans omitted from payload", {
|
|
1327
|
+
error: plansResult.error,
|
|
1328
|
+
status: plansResult.status
|
|
1329
|
+
});
|
|
1330
|
+
}
|
|
1289
1331
|
const plans = (0, import_server3.isErrorResult)(plansResult) ? [] : plansResult.plans;
|
|
1290
1332
|
const purchase = okOrNull(resolvedPurchaseResult);
|
|
1291
1333
|
const enrichedPurchase = purchase ? {
|
|
@@ -1333,7 +1375,8 @@ function createBuildBootstrapPayload(options) {
|
|
|
1333
1375
|
plans,
|
|
1334
1376
|
customer,
|
|
1335
1377
|
checkoutUrl: checkout?.checkoutUrl ?? null,
|
|
1336
|
-
portalUrl: portal?.customerUrl ?? null
|
|
1378
|
+
portalUrl: portal?.customerUrl ?? null,
|
|
1379
|
+
autoRechargeUrl: autoRechargeUrlFrom(portal?.customerUrl)
|
|
1337
1380
|
};
|
|
1338
1381
|
};
|
|
1339
1382
|
}
|
|
@@ -1411,7 +1454,13 @@ var VIEWER_DESCRIPTION = 'Call when the user says "upgrade", "change plan", "buy
|
|
|
1411
1454
|
var INTENT_MODE_SCHEMA = import_zod3.z.enum(["ui", "text", "auto"]).optional().describe(
|
|
1412
1455
|
"Default `mode: 'auto'` returns a self-sufficient text summary (plan, price, https checkout URL) and still opens the iframe on UI hosts. Pass `mode: 'text'` to strip the iframe, or `mode: 'ui'` for a one-line placeholder that still includes the checkout URL."
|
|
1413
1456
|
);
|
|
1414
|
-
var DEFAULT_VIEWS = [...
|
|
1457
|
+
var DEFAULT_VIEWS = [...SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS];
|
|
1458
|
+
function readAutoRechargeArg(value) {
|
|
1459
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
1460
|
+
return void 0;
|
|
1461
|
+
}
|
|
1462
|
+
return value;
|
|
1463
|
+
}
|
|
1415
1464
|
function buildSolvaPayDescriptors(options) {
|
|
1416
1465
|
const {
|
|
1417
1466
|
solvaPay,
|
|
@@ -1505,9 +1554,17 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1505
1554
|
publicBaseUrl,
|
|
1506
1555
|
getCustomerRef
|
|
1507
1556
|
});
|
|
1508
|
-
const
|
|
1509
|
-
|
|
1510
|
-
|
|
1557
|
+
const advertisedViewList = SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS.filter(
|
|
1558
|
+
(view) => enabledViews.has(view)
|
|
1559
|
+
);
|
|
1560
|
+
if (advertisedViewList.length > 0) {
|
|
1561
|
+
const advertisedEnum = import_zod3.z.enum(
|
|
1562
|
+
advertisedViewList
|
|
1563
|
+
);
|
|
1564
|
+
const viewEnum = import_zod3.z.preprocess(
|
|
1565
|
+
(value) => value === "auto-recharge" ? "account" : value,
|
|
1566
|
+
advertisedEnum
|
|
1567
|
+
).optional().describe(VIEW_PARAM_DESCRIPTION);
|
|
1511
1568
|
pushTool({
|
|
1512
1569
|
name: VIEWER_TOOL_NAME,
|
|
1513
1570
|
title: "Account",
|
|
@@ -1518,11 +1575,11 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1518
1575
|
annotations: VIEWER_ANNOTATIONS,
|
|
1519
1576
|
handler: async (args, extra) => trace(VIEWER_TOOL_NAME, args, extra, async () => {
|
|
1520
1577
|
const requested = args.view === "checkout" || args.view === "account" || args.view === "topup" || args.view === "auto-recharge" ? args.view : void 0;
|
|
1521
|
-
if (requested !== void 0 && !enabledViews.has(requested)) {
|
|
1578
|
+
if (requested !== void 0 && requested !== "auto-recharge" && !enabledViews.has(requested)) {
|
|
1522
1579
|
return toolErrorResult({
|
|
1523
1580
|
error: `view '${requested}' is not enabled on this server`,
|
|
1524
1581
|
status: 400,
|
|
1525
|
-
details: `Enabled views: ${
|
|
1582
|
+
details: `Enabled views: ${advertisedViewList.join(", ")}. Pass one of those, or omit view to let the server pick.`
|
|
1526
1583
|
});
|
|
1527
1584
|
}
|
|
1528
1585
|
const mode = parseMode(args.mode);
|
|
@@ -1577,14 +1634,22 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1577
1634
|
});
|
|
1578
1635
|
pushTool({
|
|
1579
1636
|
name: MCP_TOOL_NAMES.createPayment,
|
|
1580
|
-
description: UI_ONLY_PREFIX + 'Create a Stripe payment intent for the authenticated customer. Pass purpose: "plan" to purchase a plan (returns { clientSecret, publishableKey, accountId?, customerRef }) or purpose: "topup" for a credit top-up (credits are recorded by webhook after confirmation).',
|
|
1637
|
+
description: UI_ONLY_PREFIX + 'Create a Stripe payment intent for the authenticated customer. Pass purpose: "plan" to purchase a plan (returns { clientSecret, publishableKey, accountId?, customerRef }) or purpose: "topup" for a credit top-up (credits are recorded by webhook after confirmation). A topup may carry autoRecharge so the card entered for the top-up is saved as the auto-recharge funding source.',
|
|
1581
1638
|
inputSchema: {
|
|
1582
1639
|
purpose: import_zod3.z.enum(["plan", "topup"]).describe('"plan" for plan checkout; "topup" for credit top-up.'),
|
|
1583
1640
|
planRef: import_zod3.z.string().optional(),
|
|
1584
1641
|
productRef: import_zod3.z.string().optional(),
|
|
1585
1642
|
currency: import_zod3.z.string().optional(),
|
|
1586
1643
|
amount: import_zod3.z.number().int().positive().optional(),
|
|
1587
|
-
description: import_zod3.z.string().optional()
|
|
1644
|
+
description: import_zod3.z.string().optional(),
|
|
1645
|
+
autoRecharge: import_zod3.z.object({
|
|
1646
|
+
enabled: import_zod3.z.boolean(),
|
|
1647
|
+
triggerType: import_zod3.z.literal("balance"),
|
|
1648
|
+
thresholdAmountMajor: import_zod3.z.number().positive().optional(),
|
|
1649
|
+
topupAmountMajor: import_zod3.z.number().positive().optional(),
|
|
1650
|
+
maxMonthlySpendMajor: import_zod3.z.number().positive().optional(),
|
|
1651
|
+
currency: import_zod3.z.string().length(3)
|
|
1652
|
+
}).optional()
|
|
1588
1653
|
},
|
|
1589
1654
|
meta: uiToolMeta,
|
|
1590
1655
|
annotations: solvapayTool({ readOnlyHint: false, destructiveHint: false }),
|
|
@@ -1599,6 +1664,14 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1599
1664
|
details: 'Pass purpose: "plan" or purpose: "topup".'
|
|
1600
1665
|
});
|
|
1601
1666
|
}
|
|
1667
|
+
const autoRecharge = readAutoRechargeArg(args.autoRecharge);
|
|
1668
|
+
if (purpose === "plan" && autoRecharge) {
|
|
1669
|
+
return toolErrorResult({
|
|
1670
|
+
error: "create_payment_intent plan does not accept autoRecharge",
|
|
1671
|
+
status: 400,
|
|
1672
|
+
details: 'autoRecharge is only honoured on purpose: "topup".'
|
|
1673
|
+
});
|
|
1674
|
+
}
|
|
1602
1675
|
if (purpose === "topup") {
|
|
1603
1676
|
const amount = typeof args.amount === "number" ? args.amount : 0;
|
|
1604
1677
|
const currency2 = typeof args.currency === "string" ? args.currency : "";
|
|
@@ -1612,7 +1685,7 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1612
1685
|
}
|
|
1613
1686
|
const result2 = await (0, import_server4.createTopupPaymentIntentCore)(
|
|
1614
1687
|
buildRequest(extra, { method: "POST" }),
|
|
1615
|
-
{ amount, currency: currency2, description },
|
|
1688
|
+
{ amount, currency: currency2, description, ...autoRecharge ? { autoRecharge } : {} },
|
|
1616
1689
|
{ solvaPay }
|
|
1617
1690
|
);
|
|
1618
1691
|
if ((0, import_server4.isErrorResult)(result2)) return toolErrorResult(result2);
|
|
@@ -2261,9 +2334,11 @@ function buildAuthInfoFromBearer(authorization, options = {}) {
|
|
|
2261
2334
|
McpBearerAuthError,
|
|
2262
2335
|
NARRATORS,
|
|
2263
2336
|
OPEN_TOOL_FOR_VIEW,
|
|
2337
|
+
PORTAL_AUTO_RECHARGE_QUERY,
|
|
2264
2338
|
SOLVAPAY_BOOTSTRAP_MIME_TYPE,
|
|
2265
2339
|
SOLVAPAY_BOOTSTRAP_URI,
|
|
2266
2340
|
SOLVAPAY_DEFAULT_CSP,
|
|
2341
|
+
SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS,
|
|
2267
2342
|
SOLVAPAY_MCP_VIEW_KINDS,
|
|
2268
2343
|
SOLVAPAY_OVERVIEW_MARKDOWN,
|
|
2269
2344
|
SOLVAPAY_OVERVIEW_MIME_TYPE,
|
|
@@ -2276,6 +2351,7 @@ function buildAuthInfoFromBearer(authorization, options = {}) {
|
|
|
2276
2351
|
VIEW_FOR_TOOL,
|
|
2277
2352
|
applyHideToolsByAudience,
|
|
2278
2353
|
assertValidProductRef,
|
|
2354
|
+
autoRechargeUrlFrom,
|
|
2279
2355
|
balanceSummary,
|
|
2280
2356
|
buildAuthInfoFromBearer,
|
|
2281
2357
|
buildPayableHandler,
|
package/dist/index.d.cts
CHANGED
|
@@ -201,14 +201,14 @@ interface PaywallToolResult {
|
|
|
201
201
|
/**
|
|
202
202
|
* Which view a SolvaPay MCP server knows how to bootstrap.
|
|
203
203
|
*
|
|
204
|
-
*
|
|
205
|
-
* `
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* refactor (merchant paywall /
|
|
210
|
-
* `content[0].text` + `structuredContent =
|
|
211
|
-
* iframe).
|
|
204
|
+
* Advertised landings on the `account` viewer are `checkout`,
|
|
205
|
+
* `account`, and `topup`. `'auto-recharge'` is a deprecated leftover
|
|
206
|
+
* stamp: the tool schema does not offer it, but a leftover argument
|
|
207
|
+
* still opens the account surface (status row + portal link). There is
|
|
208
|
+
* no `paywall` or `nudge` view — those responses are plain text
|
|
209
|
+
* narrations per the text-only paywall refactor (merchant paywall /
|
|
210
|
+
* nudge tool results ship `content[0].text` + `structuredContent =
|
|
211
|
+
* gate` and never open the iframe).
|
|
212
212
|
*
|
|
213
213
|
* The legacy `'about'`, `'activate'`, and `'usage'` surfaces were
|
|
214
214
|
* dropped earlier — About is served by tool descriptions + docs
|
|
@@ -216,7 +216,9 @@ interface PaywallToolResult {
|
|
|
216
216
|
* `PlanActivationDispatcher`, and Usage folds inline into the account
|
|
217
217
|
* view.
|
|
218
218
|
*/
|
|
219
|
-
type
|
|
219
|
+
type SolvaPayMcpAdvertisedViewKind = 'checkout' | 'account' | 'topup';
|
|
220
|
+
type SolvaPayMcpViewKind = SolvaPayMcpAdvertisedViewKind | 'auto-recharge';
|
|
221
|
+
declare const SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS: readonly ["checkout", "account", "topup"];
|
|
220
222
|
declare const SOLVAPAY_MCP_VIEW_KINDS: readonly ["checkout", "account", "topup", "auto-recharge"];
|
|
221
223
|
/**
|
|
222
224
|
* Payload returned by every `open_*` bootstrap tool and consumed by the
|
|
@@ -249,6 +251,12 @@ interface BootstrapPayload {
|
|
|
249
251
|
checkoutUrl?: string | null;
|
|
250
252
|
/** Customer portal URL for the current customer, when one could be minted. */
|
|
251
253
|
portalUrl?: string | null;
|
|
254
|
+
/**
|
|
255
|
+
* Hosted portal URL that opens the auto-recharge form (`tab=credits&intent=autorecharge`).
|
|
256
|
+
* Null when no portal session could be minted. Suffixed in `@solvapay/mcp-core`
|
|
257
|
+
* from the same `customerUrl` as `portalUrl`.
|
|
258
|
+
*/
|
|
259
|
+
autoRechargeUrl?: string | null;
|
|
252
260
|
}
|
|
253
261
|
/**
|
|
254
262
|
* Content Security Policy allow-list inputs merged with the Stripe
|
|
@@ -844,6 +852,7 @@ declare const BootstrapPayloadSchema: z.ZodObject<{
|
|
|
844
852
|
customer: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
845
853
|
checkoutUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
846
854
|
portalUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
855
|
+
autoRechargeUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
847
856
|
}, z.core.$loose>;
|
|
848
857
|
|
|
849
858
|
/**
|
|
@@ -1410,6 +1419,31 @@ declare const SOLVAPAY_OVERVIEW_URI = "docs://solvapay/overview.md";
|
|
|
1410
1419
|
declare const SOLVAPAY_OVERVIEW_MIME_TYPE = "text/markdown";
|
|
1411
1420
|
declare const SOLVAPAY_OVERVIEW_MARKDOWN = "# SolvaPay MCP server \u2014 overview\n\nThis MCP server connects a SolvaPay-protected product to your host so users can\nmanage their plan, usage, and billing **without leaving the chat**. It is\ndual-audience: every tool returns a UI bootstrap for hosts that render MCP UI\nresources (`basic-host`, Claude Desktop, ChatGPT, etc.) and a markdown summary\nwith clickable URLs for text-only hosts.\n\n## What the user can do\n\n- **Account** \u2014 one read-only viewer for every billing surface. Pass `view`:\n `checkout` (upgrade / change plan / buy / subscribe), `account` (current\n plan, cancel, billing), or `topup` (add credits). Omit `view` and the\n server picks (no plan \u2192 checkout, out of credits \u2192 topup, else account).\n Slash commands `/upgrade`, `/manage_account`, and `/topup` remap onto\n this tool. `account`.\n- **Activate plan** \u2014 activate a specific plan by `planRef`. Free plans\n activate immediately, usage-based plans activate when balance covers the\n configured usage, paid plans return checkout. Requires `planRef` \u2014 to list\n plans, call `account` with `view: \"checkout\"`. `/activate_plan`.\n\n## How it fits together\n\nThe viewer returns a full `BootstrapPayload` (merchant + product + plans\n+ customer snapshot) so the embedded UI never fires per-view read calls. When\na paywalled data tool hits the usage limit, its response is plain text: the\n`content[0].text` narration names the recovery tool (`account`, or\n`activate_plan` when a specific planRef is known) and inlines\n`gate.checkoutUrl` for terminal-first hosts. The structured gate rides on\n`structuredContent` for programmatic consumers. No widget iframe opens for a\ngate \u2014 the LLM reads the narration and, if the user agrees, calls the named\ntool which mounts the checkout / topup / account surface.\n\nAuth is handled by the SolvaPay OAuth bridge (see `createMcpOAuthBridge`). The\nbridge injects `customer_ref` onto every authenticated request; tools that\nneed an authenticated caller return `Unauthorized` when it is missing.\n\n## Also see\n\n- `docs://solvapay/overview.md` (this resource) \u2014 agent-facing narration.\n- `ui://<app>/mcp-app.html` \u2014 the embedded UI shell.\n- `tools/list` + `prompts/list` \u2014 programmatic discovery of the intent tools\n and their slash-command shortcuts.\n";
|
|
1412
1421
|
|
|
1422
|
+
/**
|
|
1423
|
+
* Hosted-portal deep links minted from a customer session URL.
|
|
1424
|
+
*
|
|
1425
|
+
* Phase 1 suffixes the already-minted `customerUrl` in the SDK so the
|
|
1426
|
+
* MCP widget can land on the auto-recharge form without a new network
|
|
1427
|
+
* call or a platform deploy. The query params are the same ones the
|
|
1428
|
+
* customer-app manage page already parses (`tab=credits&intent=autorecharge`).
|
|
1429
|
+
*
|
|
1430
|
+
* Keep this constant in lockstep with
|
|
1431
|
+
* `apps/customer-app/src/pages/customer/manage/index.tsx`. A rename
|
|
1432
|
+
* there without a matching change here degrades to the Credits tab
|
|
1433
|
+
* without the form open — not a dead link, but not the intended
|
|
1434
|
+
* destination either.
|
|
1435
|
+
*/
|
|
1436
|
+
declare const PORTAL_AUTO_RECHARGE_QUERY = "tab=credits&intent=autorecharge";
|
|
1437
|
+
/**
|
|
1438
|
+
* Suffix a minted customer-portal URL so it opens the auto-recharge
|
|
1439
|
+
* form (or the Credits summary when auto-recharge is already on).
|
|
1440
|
+
*
|
|
1441
|
+
* Returns `null` for a missing or non-http URL — the same guard
|
|
1442
|
+
* `narrate.ts` uses. No silent default: a missing portal URL yields
|
|
1443
|
+
* `null` and the widget renders status without an action.
|
|
1444
|
+
*/
|
|
1445
|
+
declare function autoRechargeUrlFrom(customerUrl: string | null | undefined): string | null;
|
|
1446
|
+
|
|
1413
1447
|
/**
|
|
1414
1448
|
* `buildPayableHandler(solvaPay, ctx, handler)` — framework-neutral
|
|
1415
1449
|
* wrapper that produces an MCP tool handler enforcing the SolvaPay
|
|
@@ -1607,4 +1641,4 @@ interface BuildAuthInfoFromBearerOptions extends McpBearerCustomerRefOptions {
|
|
|
1607
1641
|
}
|
|
1608
1642
|
declare function buildAuthInfoFromBearer(authorization?: string | null, options?: BuildAuthInfoFromBearerOptions): McpToolExtra['authInfo'] | null;
|
|
1609
1643
|
|
|
1610
|
-
export { type ActivePlanPurchaseLike, type ApplyHideToolsByAudienceContext, type ApplyHideToolsByAudienceExtra, type ApplyHideToolsByAudienceOptions, type BootstrapCustomer, type BootstrapMerchant, type BootstrapPayload, BootstrapPayloadSchema, type BootstrapPlan, type BootstrapProduct, type BuildAuthInfoFromBearerOptions, type BuildBootstrapPayloadFn, type BuildPayableHandlerContext, type BuildSolvaPayDescriptorsOptions, type BuildSolvaPayRequestOptions, type ContentBlock, type CreateBuildBootstrapPayloadOptions, type CustomerSnapshot, DEFAULT_OAUTH_PATHS, type DcrFailureDiagnosticInput, type HideToolsByAudienceBypass, INTENT_TOOL_NAMES, type IntentToolName, MCP_PROMPT_NAMES, MCP_TOOL_NAMES, type McpAdapterOptions, McpBearerAuthError, type McpBearerCustomerRefOptions, type McpConfigLogInput, type McpPromptName, type McpToolExtra, type McpToolName, NARRATORS, type NarratorOutput, type NudgeSpec, type OAuthAuthorizationServerOptions, type OAuthBridgePaths, OPEN_TOOL_FOR_VIEW, type PayableHandler, type PaywallToolResult, type PaywallToolResultContext, type ResponseContext, type ResponseOptions, type ResponseResult, SOLVAPAY_BOOTSTRAP_MIME_TYPE, SOLVAPAY_BOOTSTRAP_URI, SOLVAPAY_DEFAULT_CSP, SOLVAPAY_MCP_VIEW_KINDS, SOLVAPAY_OVERVIEW_MARKDOWN, SOLVAPAY_OVERVIEW_MIME_TYPE, SOLVAPAY_OVERVIEW_URI, type SolvaPayBootstrapResourceDescriptor, type SolvaPayCallToolResult, type SolvaPayDescriptorBundle, type SolvaPayDocsResourceDescriptor, type SolvaPayMcpCsp, type SolvaPayMcpViewKind, type SolvaPayMerchantBranding, type SolvaPayPromptDescriptor, type SolvaPayPromptResult, type SolvaPayResourceDescriptor, type SolvaPayToolAnnotations, type SolvaPayToolDescriptor, type SolvaPayToolIcon, type SolvaPayToolMode, TOOL_FOR_VIEW, ToolErrorEnvelopeSchema, VIEWER_TOOL_NAME, VIEW_FOR_OPEN_TOOL, VIEW_FOR_TOOL, applyHideToolsByAudience, balanceSummary, buildAuthInfoFromBearer, buildPayableHandler, buildSolvaPayDescriptors, buildSolvaPayPrompts, buildSolvaPayRequest, createBuildBootstrapPayload, decodeJwtPayload, defaultGetCustomerRef, defaultIsChatGptRequest, deriveDefaultView, deriveIcons, enrichPurchase, extractBearerToken, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, isPlanPurchase, logDcrFailureDiagnostic, logMcpConfigOnce, mergeCsp, narrateActivatePlan, narrateAlreadyActive, narrateAutoRecharge, narrateManageAccount, narrateTopup, narrateUpgrade, narratedToolResult, parseMode, paywallToolResult, previewJson, resetMcpConfigLogForTests, resolveOAuthPaths, selectActivePlanPurchase, toolErrorResult, toolResult, uiPlaceholder, withoutTrailingSlash };
|
|
1644
|
+
export { type ActivePlanPurchaseLike, type ApplyHideToolsByAudienceContext, type ApplyHideToolsByAudienceExtra, type ApplyHideToolsByAudienceOptions, type BootstrapCustomer, type BootstrapMerchant, type BootstrapPayload, BootstrapPayloadSchema, type BootstrapPlan, type BootstrapProduct, type BuildAuthInfoFromBearerOptions, type BuildBootstrapPayloadFn, type BuildPayableHandlerContext, type BuildSolvaPayDescriptorsOptions, type BuildSolvaPayRequestOptions, type ContentBlock, type CreateBuildBootstrapPayloadOptions, type CustomerSnapshot, DEFAULT_OAUTH_PATHS, type DcrFailureDiagnosticInput, type HideToolsByAudienceBypass, INTENT_TOOL_NAMES, type IntentToolName, MCP_PROMPT_NAMES, MCP_TOOL_NAMES, type McpAdapterOptions, McpBearerAuthError, type McpBearerCustomerRefOptions, type McpConfigLogInput, type McpPromptName, type McpToolExtra, type McpToolName, NARRATORS, type NarratorOutput, type NudgeSpec, type OAuthAuthorizationServerOptions, type OAuthBridgePaths, OPEN_TOOL_FOR_VIEW, PORTAL_AUTO_RECHARGE_QUERY, type PayableHandler, type PaywallToolResult, type PaywallToolResultContext, type ResponseContext, type ResponseOptions, type ResponseResult, SOLVAPAY_BOOTSTRAP_MIME_TYPE, SOLVAPAY_BOOTSTRAP_URI, SOLVAPAY_DEFAULT_CSP, SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS, SOLVAPAY_MCP_VIEW_KINDS, SOLVAPAY_OVERVIEW_MARKDOWN, SOLVAPAY_OVERVIEW_MIME_TYPE, SOLVAPAY_OVERVIEW_URI, type SolvaPayBootstrapResourceDescriptor, type SolvaPayCallToolResult, type SolvaPayDescriptorBundle, type SolvaPayDocsResourceDescriptor, type SolvaPayMcpAdvertisedViewKind, type SolvaPayMcpCsp, type SolvaPayMcpViewKind, type SolvaPayMerchantBranding, type SolvaPayPromptDescriptor, type SolvaPayPromptResult, type SolvaPayResourceDescriptor, type SolvaPayToolAnnotations, type SolvaPayToolDescriptor, type SolvaPayToolIcon, type SolvaPayToolMode, TOOL_FOR_VIEW, ToolErrorEnvelopeSchema, VIEWER_TOOL_NAME, VIEW_FOR_OPEN_TOOL, VIEW_FOR_TOOL, applyHideToolsByAudience, autoRechargeUrlFrom, balanceSummary, buildAuthInfoFromBearer, buildPayableHandler, buildSolvaPayDescriptors, buildSolvaPayPrompts, buildSolvaPayRequest, createBuildBootstrapPayload, decodeJwtPayload, defaultGetCustomerRef, defaultIsChatGptRequest, deriveDefaultView, deriveIcons, enrichPurchase, extractBearerToken, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, isPlanPurchase, logDcrFailureDiagnostic, logMcpConfigOnce, mergeCsp, narrateActivatePlan, narrateAlreadyActive, narrateAutoRecharge, narrateManageAccount, narrateTopup, narrateUpgrade, narratedToolResult, parseMode, paywallToolResult, previewJson, resetMcpConfigLogForTests, resolveOAuthPaths, selectActivePlanPurchase, toolErrorResult, toolResult, uiPlaceholder, withoutTrailingSlash };
|
package/dist/index.d.ts
CHANGED
|
@@ -201,14 +201,14 @@ interface PaywallToolResult {
|
|
|
201
201
|
/**
|
|
202
202
|
* Which view a SolvaPay MCP server knows how to bootstrap.
|
|
203
203
|
*
|
|
204
|
-
*
|
|
205
|
-
* `
|
|
206
|
-
*
|
|
207
|
-
*
|
|
208
|
-
*
|
|
209
|
-
* refactor (merchant paywall /
|
|
210
|
-
* `content[0].text` + `structuredContent =
|
|
211
|
-
* iframe).
|
|
204
|
+
* Advertised landings on the `account` viewer are `checkout`,
|
|
205
|
+
* `account`, and `topup`. `'auto-recharge'` is a deprecated leftover
|
|
206
|
+
* stamp: the tool schema does not offer it, but a leftover argument
|
|
207
|
+
* still opens the account surface (status row + portal link). There is
|
|
208
|
+
* no `paywall` or `nudge` view — those responses are plain text
|
|
209
|
+
* narrations per the text-only paywall refactor (merchant paywall /
|
|
210
|
+
* nudge tool results ship `content[0].text` + `structuredContent =
|
|
211
|
+
* gate` and never open the iframe).
|
|
212
212
|
*
|
|
213
213
|
* The legacy `'about'`, `'activate'`, and `'usage'` surfaces were
|
|
214
214
|
* dropped earlier — About is served by tool descriptions + docs
|
|
@@ -216,7 +216,9 @@ interface PaywallToolResult {
|
|
|
216
216
|
* `PlanActivationDispatcher`, and Usage folds inline into the account
|
|
217
217
|
* view.
|
|
218
218
|
*/
|
|
219
|
-
type
|
|
219
|
+
type SolvaPayMcpAdvertisedViewKind = 'checkout' | 'account' | 'topup';
|
|
220
|
+
type SolvaPayMcpViewKind = SolvaPayMcpAdvertisedViewKind | 'auto-recharge';
|
|
221
|
+
declare const SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS: readonly ["checkout", "account", "topup"];
|
|
220
222
|
declare const SOLVAPAY_MCP_VIEW_KINDS: readonly ["checkout", "account", "topup", "auto-recharge"];
|
|
221
223
|
/**
|
|
222
224
|
* Payload returned by every `open_*` bootstrap tool and consumed by the
|
|
@@ -249,6 +251,12 @@ interface BootstrapPayload {
|
|
|
249
251
|
checkoutUrl?: string | null;
|
|
250
252
|
/** Customer portal URL for the current customer, when one could be minted. */
|
|
251
253
|
portalUrl?: string | null;
|
|
254
|
+
/**
|
|
255
|
+
* Hosted portal URL that opens the auto-recharge form (`tab=credits&intent=autorecharge`).
|
|
256
|
+
* Null when no portal session could be minted. Suffixed in `@solvapay/mcp-core`
|
|
257
|
+
* from the same `customerUrl` as `portalUrl`.
|
|
258
|
+
*/
|
|
259
|
+
autoRechargeUrl?: string | null;
|
|
252
260
|
}
|
|
253
261
|
/**
|
|
254
262
|
* Content Security Policy allow-list inputs merged with the Stripe
|
|
@@ -844,6 +852,7 @@ declare const BootstrapPayloadSchema: z.ZodObject<{
|
|
|
844
852
|
customer: z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
|
|
845
853
|
checkoutUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
846
854
|
portalUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
855
|
+
autoRechargeUrl: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
847
856
|
}, z.core.$loose>;
|
|
848
857
|
|
|
849
858
|
/**
|
|
@@ -1410,6 +1419,31 @@ declare const SOLVAPAY_OVERVIEW_URI = "docs://solvapay/overview.md";
|
|
|
1410
1419
|
declare const SOLVAPAY_OVERVIEW_MIME_TYPE = "text/markdown";
|
|
1411
1420
|
declare const SOLVAPAY_OVERVIEW_MARKDOWN = "# SolvaPay MCP server \u2014 overview\n\nThis MCP server connects a SolvaPay-protected product to your host so users can\nmanage their plan, usage, and billing **without leaving the chat**. It is\ndual-audience: every tool returns a UI bootstrap for hosts that render MCP UI\nresources (`basic-host`, Claude Desktop, ChatGPT, etc.) and a markdown summary\nwith clickable URLs for text-only hosts.\n\n## What the user can do\n\n- **Account** \u2014 one read-only viewer for every billing surface. Pass `view`:\n `checkout` (upgrade / change plan / buy / subscribe), `account` (current\n plan, cancel, billing), or `topup` (add credits). Omit `view` and the\n server picks (no plan \u2192 checkout, out of credits \u2192 topup, else account).\n Slash commands `/upgrade`, `/manage_account`, and `/topup` remap onto\n this tool. `account`.\n- **Activate plan** \u2014 activate a specific plan by `planRef`. Free plans\n activate immediately, usage-based plans activate when balance covers the\n configured usage, paid plans return checkout. Requires `planRef` \u2014 to list\n plans, call `account` with `view: \"checkout\"`. `/activate_plan`.\n\n## How it fits together\n\nThe viewer returns a full `BootstrapPayload` (merchant + product + plans\n+ customer snapshot) so the embedded UI never fires per-view read calls. When\na paywalled data tool hits the usage limit, its response is plain text: the\n`content[0].text` narration names the recovery tool (`account`, or\n`activate_plan` when a specific planRef is known) and inlines\n`gate.checkoutUrl` for terminal-first hosts. The structured gate rides on\n`structuredContent` for programmatic consumers. No widget iframe opens for a\ngate \u2014 the LLM reads the narration and, if the user agrees, calls the named\ntool which mounts the checkout / topup / account surface.\n\nAuth is handled by the SolvaPay OAuth bridge (see `createMcpOAuthBridge`). The\nbridge injects `customer_ref` onto every authenticated request; tools that\nneed an authenticated caller return `Unauthorized` when it is missing.\n\n## Also see\n\n- `docs://solvapay/overview.md` (this resource) \u2014 agent-facing narration.\n- `ui://<app>/mcp-app.html` \u2014 the embedded UI shell.\n- `tools/list` + `prompts/list` \u2014 programmatic discovery of the intent tools\n and their slash-command shortcuts.\n";
|
|
1412
1421
|
|
|
1422
|
+
/**
|
|
1423
|
+
* Hosted-portal deep links minted from a customer session URL.
|
|
1424
|
+
*
|
|
1425
|
+
* Phase 1 suffixes the already-minted `customerUrl` in the SDK so the
|
|
1426
|
+
* MCP widget can land on the auto-recharge form without a new network
|
|
1427
|
+
* call or a platform deploy. The query params are the same ones the
|
|
1428
|
+
* customer-app manage page already parses (`tab=credits&intent=autorecharge`).
|
|
1429
|
+
*
|
|
1430
|
+
* Keep this constant in lockstep with
|
|
1431
|
+
* `apps/customer-app/src/pages/customer/manage/index.tsx`. A rename
|
|
1432
|
+
* there without a matching change here degrades to the Credits tab
|
|
1433
|
+
* without the form open — not a dead link, but not the intended
|
|
1434
|
+
* destination either.
|
|
1435
|
+
*/
|
|
1436
|
+
declare const PORTAL_AUTO_RECHARGE_QUERY = "tab=credits&intent=autorecharge";
|
|
1437
|
+
/**
|
|
1438
|
+
* Suffix a minted customer-portal URL so it opens the auto-recharge
|
|
1439
|
+
* form (or the Credits summary when auto-recharge is already on).
|
|
1440
|
+
*
|
|
1441
|
+
* Returns `null` for a missing or non-http URL — the same guard
|
|
1442
|
+
* `narrate.ts` uses. No silent default: a missing portal URL yields
|
|
1443
|
+
* `null` and the widget renders status without an action.
|
|
1444
|
+
*/
|
|
1445
|
+
declare function autoRechargeUrlFrom(customerUrl: string | null | undefined): string | null;
|
|
1446
|
+
|
|
1413
1447
|
/**
|
|
1414
1448
|
* `buildPayableHandler(solvaPay, ctx, handler)` — framework-neutral
|
|
1415
1449
|
* wrapper that produces an MCP tool handler enforcing the SolvaPay
|
|
@@ -1607,4 +1641,4 @@ interface BuildAuthInfoFromBearerOptions extends McpBearerCustomerRefOptions {
|
|
|
1607
1641
|
}
|
|
1608
1642
|
declare function buildAuthInfoFromBearer(authorization?: string | null, options?: BuildAuthInfoFromBearerOptions): McpToolExtra['authInfo'] | null;
|
|
1609
1643
|
|
|
1610
|
-
export { type ActivePlanPurchaseLike, type ApplyHideToolsByAudienceContext, type ApplyHideToolsByAudienceExtra, type ApplyHideToolsByAudienceOptions, type BootstrapCustomer, type BootstrapMerchant, type BootstrapPayload, BootstrapPayloadSchema, type BootstrapPlan, type BootstrapProduct, type BuildAuthInfoFromBearerOptions, type BuildBootstrapPayloadFn, type BuildPayableHandlerContext, type BuildSolvaPayDescriptorsOptions, type BuildSolvaPayRequestOptions, type ContentBlock, type CreateBuildBootstrapPayloadOptions, type CustomerSnapshot, DEFAULT_OAUTH_PATHS, type DcrFailureDiagnosticInput, type HideToolsByAudienceBypass, INTENT_TOOL_NAMES, type IntentToolName, MCP_PROMPT_NAMES, MCP_TOOL_NAMES, type McpAdapterOptions, McpBearerAuthError, type McpBearerCustomerRefOptions, type McpConfigLogInput, type McpPromptName, type McpToolExtra, type McpToolName, NARRATORS, type NarratorOutput, type NudgeSpec, type OAuthAuthorizationServerOptions, type OAuthBridgePaths, OPEN_TOOL_FOR_VIEW, type PayableHandler, type PaywallToolResult, type PaywallToolResultContext, type ResponseContext, type ResponseOptions, type ResponseResult, SOLVAPAY_BOOTSTRAP_MIME_TYPE, SOLVAPAY_BOOTSTRAP_URI, SOLVAPAY_DEFAULT_CSP, SOLVAPAY_MCP_VIEW_KINDS, SOLVAPAY_OVERVIEW_MARKDOWN, SOLVAPAY_OVERVIEW_MIME_TYPE, SOLVAPAY_OVERVIEW_URI, type SolvaPayBootstrapResourceDescriptor, type SolvaPayCallToolResult, type SolvaPayDescriptorBundle, type SolvaPayDocsResourceDescriptor, type SolvaPayMcpCsp, type SolvaPayMcpViewKind, type SolvaPayMerchantBranding, type SolvaPayPromptDescriptor, type SolvaPayPromptResult, type SolvaPayResourceDescriptor, type SolvaPayToolAnnotations, type SolvaPayToolDescriptor, type SolvaPayToolIcon, type SolvaPayToolMode, TOOL_FOR_VIEW, ToolErrorEnvelopeSchema, VIEWER_TOOL_NAME, VIEW_FOR_OPEN_TOOL, VIEW_FOR_TOOL, applyHideToolsByAudience, balanceSummary, buildAuthInfoFromBearer, buildPayableHandler, buildSolvaPayDescriptors, buildSolvaPayPrompts, buildSolvaPayRequest, createBuildBootstrapPayload, decodeJwtPayload, defaultGetCustomerRef, defaultIsChatGptRequest, deriveDefaultView, deriveIcons, enrichPurchase, extractBearerToken, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, isPlanPurchase, logDcrFailureDiagnostic, logMcpConfigOnce, mergeCsp, narrateActivatePlan, narrateAlreadyActive, narrateAutoRecharge, narrateManageAccount, narrateTopup, narrateUpgrade, narratedToolResult, parseMode, paywallToolResult, previewJson, resetMcpConfigLogForTests, resolveOAuthPaths, selectActivePlanPurchase, toolErrorResult, toolResult, uiPlaceholder, withoutTrailingSlash };
|
|
1644
|
+
export { type ActivePlanPurchaseLike, type ApplyHideToolsByAudienceContext, type ApplyHideToolsByAudienceExtra, type ApplyHideToolsByAudienceOptions, type BootstrapCustomer, type BootstrapMerchant, type BootstrapPayload, BootstrapPayloadSchema, type BootstrapPlan, type BootstrapProduct, type BuildAuthInfoFromBearerOptions, type BuildBootstrapPayloadFn, type BuildPayableHandlerContext, type BuildSolvaPayDescriptorsOptions, type BuildSolvaPayRequestOptions, type ContentBlock, type CreateBuildBootstrapPayloadOptions, type CustomerSnapshot, DEFAULT_OAUTH_PATHS, type DcrFailureDiagnosticInput, type HideToolsByAudienceBypass, INTENT_TOOL_NAMES, type IntentToolName, MCP_PROMPT_NAMES, MCP_TOOL_NAMES, type McpAdapterOptions, McpBearerAuthError, type McpBearerCustomerRefOptions, type McpConfigLogInput, type McpPromptName, type McpToolExtra, type McpToolName, NARRATORS, type NarratorOutput, type NudgeSpec, type OAuthAuthorizationServerOptions, type OAuthBridgePaths, OPEN_TOOL_FOR_VIEW, PORTAL_AUTO_RECHARGE_QUERY, type PayableHandler, type PaywallToolResult, type PaywallToolResultContext, type ResponseContext, type ResponseOptions, type ResponseResult, SOLVAPAY_BOOTSTRAP_MIME_TYPE, SOLVAPAY_BOOTSTRAP_URI, SOLVAPAY_DEFAULT_CSP, SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS, SOLVAPAY_MCP_VIEW_KINDS, SOLVAPAY_OVERVIEW_MARKDOWN, SOLVAPAY_OVERVIEW_MIME_TYPE, SOLVAPAY_OVERVIEW_URI, type SolvaPayBootstrapResourceDescriptor, type SolvaPayCallToolResult, type SolvaPayDescriptorBundle, type SolvaPayDocsResourceDescriptor, type SolvaPayMcpAdvertisedViewKind, type SolvaPayMcpCsp, type SolvaPayMcpViewKind, type SolvaPayMerchantBranding, type SolvaPayPromptDescriptor, type SolvaPayPromptResult, type SolvaPayResourceDescriptor, type SolvaPayToolAnnotations, type SolvaPayToolDescriptor, type SolvaPayToolIcon, type SolvaPayToolMode, TOOL_FOR_VIEW, ToolErrorEnvelopeSchema, VIEWER_TOOL_NAME, VIEW_FOR_OPEN_TOOL, VIEW_FOR_TOOL, applyHideToolsByAudience, autoRechargeUrlFrom, balanceSummary, buildAuthInfoFromBearer, buildPayableHandler, buildSolvaPayDescriptors, buildSolvaPayPrompts, buildSolvaPayRequest, createBuildBootstrapPayload, decodeJwtPayload, defaultGetCustomerRef, defaultIsChatGptRequest, deriveDefaultView, deriveIcons, enrichPurchase, extractBearerToken, getCustomerRefFromBearerAuthHeader, getCustomerRefFromJwtPayload, getOAuthAuthorizationServerResponse, getOAuthProtectedResourceResponse, isPlanPurchase, logDcrFailureDiagnostic, logMcpConfigOnce, mergeCsp, narrateActivatePlan, narrateAlreadyActive, narrateAutoRecharge, narrateManageAccount, narrateTopup, narrateUpgrade, narratedToolResult, parseMode, paywallToolResult, previewJson, resetMcpConfigLogForTests, resolveOAuthPaths, selectActivePlanPurchase, toolErrorResult, toolResult, uiPlaceholder, withoutTrailingSlash };
|
package/dist/index.js
CHANGED
|
@@ -19,10 +19,13 @@ var MCP_PROMPT_NAMES = {
|
|
|
19
19
|
};
|
|
20
20
|
|
|
21
21
|
// src/types.ts
|
|
22
|
-
var
|
|
22
|
+
var SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS = [
|
|
23
23
|
"checkout",
|
|
24
24
|
"account",
|
|
25
|
-
"topup"
|
|
25
|
+
"topup"
|
|
26
|
+
];
|
|
27
|
+
var SOLVAPAY_MCP_VIEW_KINDS = [
|
|
28
|
+
...SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS,
|
|
26
29
|
"auto-recharge"
|
|
27
30
|
];
|
|
28
31
|
var TOOL_FOR_VIEW = {
|
|
@@ -668,6 +671,9 @@ function narrateTopup(data) {
|
|
|
668
671
|
lines.push(recoveryLine(["account"]));
|
|
669
672
|
return withCheckout(data, lines);
|
|
670
673
|
}
|
|
674
|
+
function autoRechargePortalUrl(data) {
|
|
675
|
+
return httpsUrl(data.autoRechargeUrl) ?? httpsUrl(data.portalUrl);
|
|
676
|
+
}
|
|
671
677
|
function narrateAutoRecharge(data) {
|
|
672
678
|
const lines = [];
|
|
673
679
|
lines.push(`**Auto-recharge \u2014 ${productName(data)}**`);
|
|
@@ -676,16 +682,27 @@ function narrateAutoRecharge(data) {
|
|
|
676
682
|
const bal = balanceRow(customer);
|
|
677
683
|
if (bal) lines.push(bal);
|
|
678
684
|
const enabled = customer?.autoRecharge?.enabled === true;
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
685
|
+
const failed = customer?.autoRecharge?.status === "failed";
|
|
686
|
+
if (failed) {
|
|
687
|
+
lines.push("Auto-recharge failed \u2014 update your card to resume");
|
|
688
|
+
} else {
|
|
689
|
+
lines.push(
|
|
690
|
+
enabled ? "Auto-recharge is on. It tops your balance up automatically so calls do not fail." : "Auto-recharge is off. Turn it on from the link below \u2014 it stores a card and tops your balance up automatically so calls do not fail."
|
|
691
|
+
);
|
|
692
|
+
}
|
|
693
|
+
const manageUrl = autoRechargePortalUrl(data);
|
|
694
|
+
if (manageUrl) {
|
|
695
|
+
lines.push(`Manage: ${namedManageMarkdown(manageUrl)} (${CHECKOUT_TTL})`);
|
|
696
|
+
}
|
|
684
697
|
lines.push("");
|
|
685
698
|
lines.push(recoveryLine(["account"]));
|
|
686
699
|
const links = [];
|
|
687
|
-
|
|
688
|
-
|
|
700
|
+
if (manageUrl) {
|
|
701
|
+
links.push({
|
|
702
|
+
uri: manageUrl,
|
|
703
|
+
name: enabled ? "Manage auto-recharge" : "Turn on auto-recharge"
|
|
704
|
+
});
|
|
705
|
+
}
|
|
689
706
|
return { text: lines.join("\n"), links };
|
|
690
707
|
}
|
|
691
708
|
var NARRATORS = {
|
|
@@ -919,7 +936,8 @@ var BootstrapPayloadSchema = z2.object({
|
|
|
919
936
|
plans: z2.array(z2.record(z2.string(), z2.unknown())),
|
|
920
937
|
customer: z2.record(z2.string(), z2.unknown()).nullable(),
|
|
921
938
|
checkoutUrl: z2.string().nullable().optional(),
|
|
922
|
-
portalUrl: z2.string().nullable().optional()
|
|
939
|
+
portalUrl: z2.string().nullable().optional(),
|
|
940
|
+
autoRechargeUrl: z2.string().nullable().optional()
|
|
923
941
|
}).passthrough();
|
|
924
942
|
|
|
925
943
|
// src/derive-view.ts
|
|
@@ -931,7 +949,7 @@ function isOutOfCredits(customer) {
|
|
|
931
949
|
const credits = customer?.balance?.credits;
|
|
932
950
|
return credits === 0;
|
|
933
951
|
}
|
|
934
|
-
function deriveDefaultView(data, enabledViews = new Set(
|
|
952
|
+
function deriveDefaultView(data, enabledViews = new Set(SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS)) {
|
|
935
953
|
const customer = data.customer;
|
|
936
954
|
const preferred = !hasActivePlan(customer, data.productRef) ? "checkout" : isOutOfCredits(customer) ? "topup" : "account";
|
|
937
955
|
if (enabledViews.has(preferred)) return preferred;
|
|
@@ -1128,6 +1146,18 @@ import {
|
|
|
1128
1146
|
listPlansCore,
|
|
1129
1147
|
nextActionFor
|
|
1130
1148
|
} from "@solvapay/server";
|
|
1149
|
+
|
|
1150
|
+
// src/portal-links.ts
|
|
1151
|
+
var PORTAL_AUTO_RECHARGE_QUERY = "tab=credits&intent=autorecharge";
|
|
1152
|
+
function autoRechargeUrlFrom(customerUrl) {
|
|
1153
|
+
if (typeof customerUrl !== "string" || !/^https?:\/\//i.test(customerUrl)) {
|
|
1154
|
+
return null;
|
|
1155
|
+
}
|
|
1156
|
+
const separator = customerUrl.includes("?") ? "&" : "?";
|
|
1157
|
+
return `${customerUrl}${separator}${PORTAL_AUTO_RECHARGE_QUERY}`;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
// src/bootstrap-payload.ts
|
|
1131
1161
|
var okOrNull = (result) => isErrorResult(result) ? null : result;
|
|
1132
1162
|
var buildProviderNotFoundMessage = () => [
|
|
1133
1163
|
"Provider account not found on this SolvaPay deployment.",
|
|
@@ -1167,7 +1197,10 @@ function createBuildBootstrapPayload(options) {
|
|
|
1167
1197
|
try {
|
|
1168
1198
|
const platform = await solvaPay.apiClient.getPlatformConfig?.();
|
|
1169
1199
|
return platform?.stripePublishableKey ?? null;
|
|
1170
|
-
} catch {
|
|
1200
|
+
} catch (err) {
|
|
1201
|
+
console.warn("[solvapay] bootstrap: getPlatformConfig failed; stripePublishableKey omitted", {
|
|
1202
|
+
error: err instanceof Error ? err.message : String(err)
|
|
1203
|
+
});
|
|
1171
1204
|
return null;
|
|
1172
1205
|
}
|
|
1173
1206
|
};
|
|
@@ -1233,6 +1266,12 @@ function createBuildBootstrapPayload(options) {
|
|
|
1233
1266
|
if (isErrorResult(productResult)) {
|
|
1234
1267
|
throw createBootstrapProductError(productResult);
|
|
1235
1268
|
}
|
|
1269
|
+
if (isErrorResult(plansResult)) {
|
|
1270
|
+
console.warn("[solvapay] bootstrap: listPlans failed; plans omitted from payload", {
|
|
1271
|
+
error: plansResult.error,
|
|
1272
|
+
status: plansResult.status
|
|
1273
|
+
});
|
|
1274
|
+
}
|
|
1236
1275
|
const plans = isErrorResult(plansResult) ? [] : plansResult.plans;
|
|
1237
1276
|
const purchase = okOrNull(resolvedPurchaseResult);
|
|
1238
1277
|
const enrichedPurchase = purchase ? {
|
|
@@ -1280,7 +1319,8 @@ function createBuildBootstrapPayload(options) {
|
|
|
1280
1319
|
plans,
|
|
1281
1320
|
customer,
|
|
1282
1321
|
checkoutUrl: checkout?.checkoutUrl ?? null,
|
|
1283
|
-
portalUrl: portal?.customerUrl ?? null
|
|
1322
|
+
portalUrl: portal?.customerUrl ?? null,
|
|
1323
|
+
autoRechargeUrl: autoRechargeUrlFrom(portal?.customerUrl)
|
|
1284
1324
|
};
|
|
1285
1325
|
};
|
|
1286
1326
|
}
|
|
@@ -1358,7 +1398,13 @@ var VIEWER_DESCRIPTION = 'Call when the user says "upgrade", "change plan", "buy
|
|
|
1358
1398
|
var INTENT_MODE_SCHEMA = z3.enum(["ui", "text", "auto"]).optional().describe(
|
|
1359
1399
|
"Default `mode: 'auto'` returns a self-sufficient text summary (plan, price, https checkout URL) and still opens the iframe on UI hosts. Pass `mode: 'text'` to strip the iframe, or `mode: 'ui'` for a one-line placeholder that still includes the checkout URL."
|
|
1360
1400
|
);
|
|
1361
|
-
var DEFAULT_VIEWS = [...
|
|
1401
|
+
var DEFAULT_VIEWS = [...SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS];
|
|
1402
|
+
function readAutoRechargeArg(value) {
|
|
1403
|
+
if (value == null || typeof value !== "object" || Array.isArray(value)) {
|
|
1404
|
+
return void 0;
|
|
1405
|
+
}
|
|
1406
|
+
return value;
|
|
1407
|
+
}
|
|
1362
1408
|
function buildSolvaPayDescriptors(options) {
|
|
1363
1409
|
const {
|
|
1364
1410
|
solvaPay,
|
|
@@ -1452,9 +1498,17 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1452
1498
|
publicBaseUrl,
|
|
1453
1499
|
getCustomerRef
|
|
1454
1500
|
});
|
|
1455
|
-
const
|
|
1456
|
-
|
|
1457
|
-
|
|
1501
|
+
const advertisedViewList = SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS.filter(
|
|
1502
|
+
(view) => enabledViews.has(view)
|
|
1503
|
+
);
|
|
1504
|
+
if (advertisedViewList.length > 0) {
|
|
1505
|
+
const advertisedEnum = z3.enum(
|
|
1506
|
+
advertisedViewList
|
|
1507
|
+
);
|
|
1508
|
+
const viewEnum = z3.preprocess(
|
|
1509
|
+
(value) => value === "auto-recharge" ? "account" : value,
|
|
1510
|
+
advertisedEnum
|
|
1511
|
+
).optional().describe(VIEW_PARAM_DESCRIPTION);
|
|
1458
1512
|
pushTool({
|
|
1459
1513
|
name: VIEWER_TOOL_NAME,
|
|
1460
1514
|
title: "Account",
|
|
@@ -1465,11 +1519,11 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1465
1519
|
annotations: VIEWER_ANNOTATIONS,
|
|
1466
1520
|
handler: async (args, extra) => trace(VIEWER_TOOL_NAME, args, extra, async () => {
|
|
1467
1521
|
const requested = args.view === "checkout" || args.view === "account" || args.view === "topup" || args.view === "auto-recharge" ? args.view : void 0;
|
|
1468
|
-
if (requested !== void 0 && !enabledViews.has(requested)) {
|
|
1522
|
+
if (requested !== void 0 && requested !== "auto-recharge" && !enabledViews.has(requested)) {
|
|
1469
1523
|
return toolErrorResult({
|
|
1470
1524
|
error: `view '${requested}' is not enabled on this server`,
|
|
1471
1525
|
status: 400,
|
|
1472
|
-
details: `Enabled views: ${
|
|
1526
|
+
details: `Enabled views: ${advertisedViewList.join(", ")}. Pass one of those, or omit view to let the server pick.`
|
|
1473
1527
|
});
|
|
1474
1528
|
}
|
|
1475
1529
|
const mode = parseMode(args.mode);
|
|
@@ -1524,14 +1578,22 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1524
1578
|
});
|
|
1525
1579
|
pushTool({
|
|
1526
1580
|
name: MCP_TOOL_NAMES.createPayment,
|
|
1527
|
-
description: UI_ONLY_PREFIX + 'Create a Stripe payment intent for the authenticated customer. Pass purpose: "plan" to purchase a plan (returns { clientSecret, publishableKey, accountId?, customerRef }) or purpose: "topup" for a credit top-up (credits are recorded by webhook after confirmation).',
|
|
1581
|
+
description: UI_ONLY_PREFIX + 'Create a Stripe payment intent for the authenticated customer. Pass purpose: "plan" to purchase a plan (returns { clientSecret, publishableKey, accountId?, customerRef }) or purpose: "topup" for a credit top-up (credits are recorded by webhook after confirmation). A topup may carry autoRecharge so the card entered for the top-up is saved as the auto-recharge funding source.',
|
|
1528
1582
|
inputSchema: {
|
|
1529
1583
|
purpose: z3.enum(["plan", "topup"]).describe('"plan" for plan checkout; "topup" for credit top-up.'),
|
|
1530
1584
|
planRef: z3.string().optional(),
|
|
1531
1585
|
productRef: z3.string().optional(),
|
|
1532
1586
|
currency: z3.string().optional(),
|
|
1533
1587
|
amount: z3.number().int().positive().optional(),
|
|
1534
|
-
description: z3.string().optional()
|
|
1588
|
+
description: z3.string().optional(),
|
|
1589
|
+
autoRecharge: z3.object({
|
|
1590
|
+
enabled: z3.boolean(),
|
|
1591
|
+
triggerType: z3.literal("balance"),
|
|
1592
|
+
thresholdAmountMajor: z3.number().positive().optional(),
|
|
1593
|
+
topupAmountMajor: z3.number().positive().optional(),
|
|
1594
|
+
maxMonthlySpendMajor: z3.number().positive().optional(),
|
|
1595
|
+
currency: z3.string().length(3)
|
|
1596
|
+
}).optional()
|
|
1535
1597
|
},
|
|
1536
1598
|
meta: uiToolMeta,
|
|
1537
1599
|
annotations: solvapayTool({ readOnlyHint: false, destructiveHint: false }),
|
|
@@ -1546,6 +1608,14 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1546
1608
|
details: 'Pass purpose: "plan" or purpose: "topup".'
|
|
1547
1609
|
});
|
|
1548
1610
|
}
|
|
1611
|
+
const autoRecharge = readAutoRechargeArg(args.autoRecharge);
|
|
1612
|
+
if (purpose === "plan" && autoRecharge) {
|
|
1613
|
+
return toolErrorResult({
|
|
1614
|
+
error: "create_payment_intent plan does not accept autoRecharge",
|
|
1615
|
+
status: 400,
|
|
1616
|
+
details: 'autoRecharge is only honoured on purpose: "topup".'
|
|
1617
|
+
});
|
|
1618
|
+
}
|
|
1549
1619
|
if (purpose === "topup") {
|
|
1550
1620
|
const amount = typeof args.amount === "number" ? args.amount : 0;
|
|
1551
1621
|
const currency2 = typeof args.currency === "string" ? args.currency : "";
|
|
@@ -1559,7 +1629,7 @@ function buildSolvaPayDescriptors(options) {
|
|
|
1559
1629
|
}
|
|
1560
1630
|
const result2 = await createTopupPaymentIntentCore(
|
|
1561
1631
|
buildRequest(extra, { method: "POST" }),
|
|
1562
|
-
{ amount, currency: currency2, description },
|
|
1632
|
+
{ amount, currency: currency2, description, ...autoRecharge ? { autoRecharge } : {} },
|
|
1563
1633
|
{ solvaPay }
|
|
1564
1634
|
);
|
|
1565
1635
|
if (isErrorResult2(result2)) return toolErrorResult(result2);
|
|
@@ -2207,9 +2277,11 @@ export {
|
|
|
2207
2277
|
McpBearerAuthError,
|
|
2208
2278
|
NARRATORS,
|
|
2209
2279
|
OPEN_TOOL_FOR_VIEW,
|
|
2280
|
+
PORTAL_AUTO_RECHARGE_QUERY,
|
|
2210
2281
|
SOLVAPAY_BOOTSTRAP_MIME_TYPE,
|
|
2211
2282
|
SOLVAPAY_BOOTSTRAP_URI,
|
|
2212
2283
|
SOLVAPAY_DEFAULT_CSP,
|
|
2284
|
+
SOLVAPAY_MCP_ADVERTISED_VIEW_KINDS,
|
|
2213
2285
|
SOLVAPAY_MCP_VIEW_KINDS,
|
|
2214
2286
|
SOLVAPAY_OVERVIEW_MARKDOWN,
|
|
2215
2287
|
SOLVAPAY_OVERVIEW_MIME_TYPE,
|
|
@@ -2222,6 +2294,7 @@ export {
|
|
|
2222
2294
|
VIEW_FOR_TOOL,
|
|
2223
2295
|
applyHideToolsByAudience,
|
|
2224
2296
|
assertValidProductRef2 as assertValidProductRef,
|
|
2297
|
+
autoRechargeUrlFrom,
|
|
2225
2298
|
balanceSummary,
|
|
2226
2299
|
buildAuthInfoFromBearer,
|
|
2227
2300
|
buildPayableHandler,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@solvapay/mcp-core",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Framework-neutral MCP contracts for the SolvaPay SDK (tool names, descriptors, payable handler, paywall meta, CSP, bootstrap payload, OAuth discovery JSON builders, bearer/JWT helpers).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"typescript": "^5.9.3",
|
|
42
42
|
"vitest": "^4.1.2",
|
|
43
43
|
"zod": "^4.3.6",
|
|
44
|
-
"@solvapay/server": "2.
|
|
44
|
+
"@solvapay/server": "2.7.0",
|
|
45
45
|
"@solvapay/test-utils": "^0.0.0"
|
|
46
46
|
},
|
|
47
47
|
"scripts": {
|