@usethrottle/mcp 0.4.0 → 0.4.2

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/lib.js CHANGED
@@ -62,6 +62,8 @@ add("Customers", "customers", ["read", "write"], { read: "View customers", write
62
62
  add("Customers", "customer_pii", ["read"], { read: "View customer PII" }, { sensitive: true });
63
63
  add("Customers", "customer_addresses", ["read", "write"], { read: "View addresses", write: "Manage addresses" });
64
64
  add("Customers", "customer_payment_methods", ["read", "write"], { read: "View stored cards", write: "Manage stored cards" }, { sensitive: true });
65
+ add("Customers", "customer_tokens", ["read"], { read: "Check shoppers' sign-in tokens" });
66
+ add("Customers", "customer_directory", ["read"], { read: "Find customers by name or email" }, { sensitive: true });
65
67
  add(
66
68
  "Customer accounts",
67
69
  "customer_accounts",
@@ -194,6 +196,7 @@ var EVENT_SCOPE_OVERRIDES = {
194
196
  "subscription.invoice_refunded": "payment_refunds:read",
195
197
  "payment.disputed": "payment_disputes:read",
196
198
  "payment.dispute_cleared": "payment_disputes:read",
199
+ "payment.dispute_lost": "payment_disputes:read",
197
200
  "fulfillment.digital.delivered": "fulfillment_digital:read"
198
201
  };
199
202
  var PREFIX_RULES = [
@@ -312,6 +315,29 @@ function redactShopperPii(value) {
312
315
  return walk(value, null, 0);
313
316
  }
314
317
 
318
+ // ../core-scopes/src/public-payment.ts
319
+ var RAW_PROCESSOR_KEYS = ["processorResponse", "gr4vy_payment_method"];
320
+ var RAW = new Set(RAW_PROCESSOR_KEYS);
321
+ function isPlainObject2(value) {
322
+ if (value === null || typeof value !== "object") return false;
323
+ const proto = Object.getPrototypeOf(value);
324
+ return proto === Object.prototype || proto === null;
325
+ }
326
+ function strip(value, depth) {
327
+ if (depth > 32) return value;
328
+ if (Array.isArray(value)) return value.map((v) => strip(v, depth + 1));
329
+ if (!isPlainObject2(value)) return value;
330
+ const out = {};
331
+ for (const [key, child] of Object.entries(value)) {
332
+ if (RAW.has(key)) continue;
333
+ out[key] = strip(child, depth + 1);
334
+ }
335
+ return out;
336
+ }
337
+ function stripRawProcessorData(value) {
338
+ return strip(value, 0);
339
+ }
340
+
315
341
  // ../action-catalog/src/actions.ts
316
342
  var OAUTH_WITHHELD = "Over an OAuth connection (ChatGPT, Claude) these are withheld, because a buyer can type them: line-item and quote-item names, SKUs and reference ids; company; every address line except the country; the merchant's external ids; notes, messages, reasons and metadata. Describe items by quantity and amount, and say the rest is withheld rather than missing.";
317
343
  var ACTIONS = [
@@ -1324,7 +1350,7 @@ var ACTIONS = [
1324
1350
  {
1325
1351
  id: "create_customer",
1326
1352
  title: "Create a customer",
1327
- description: "Create a customer record. Use search_customers first if the buyer may already exist \u2014 this does not de-duplicate by email.",
1353
+ description: "Create a customer record. Email and externalId are each unique per application: a value that already belongs to a customer fails with 409 customer_already_exists rather than returning the existing record, so use search_customers first if the buyer may already exist.",
1328
1354
  kind: "write",
1329
1355
  scopes: ["customers:write"],
1330
1356
  input: [
@@ -1556,6 +1582,29 @@ var ACTIONS = [
1556
1582
  channels: ["mcp", "zapier", "make", "n8n"],
1557
1583
  idempotent: true
1558
1584
  },
1585
+ {
1586
+ id: "set_subscription_payment_method",
1587
+ title: "Change a subscription's card",
1588
+ description: "Set the saved card one subscription renews on. Only that subscription moves; the customer's default card and their other subscriptions stay as they are. Nothing is charged now.",
1589
+ kind: "write",
1590
+ scopes: ["subscriptions:write"],
1591
+ input: [
1592
+ { name: "id", type: "string", required: true, description: "Subscription id." },
1593
+ {
1594
+ name: "paymentMethodId",
1595
+ type: "string",
1596
+ required: true,
1597
+ description: "One of the subscription customer's saved cards (GET /api/v1/customers/:id/payment-methods): active and in date."
1598
+ }
1599
+ ],
1600
+ requests: [{ method: "PATCH", path: "/api/v1/subscriptions/:id/payment-method" }],
1601
+ channels: ["mcp", "zapier", "make", "n8n"],
1602
+ idempotent: true,
1603
+ guardrails: [
1604
+ "Changes which card future renewals charge. Confirm the subscription and the card (brand, last four) with the user first.",
1605
+ "409 payment_method_unusable: the card is not this customer's active, in-date saved card. 409 invalid_state: the subscription is cancelled or completed."
1606
+ ]
1607
+ },
1559
1608
  {
1560
1609
  id: "cancel_subscription",
1561
1610
  title: "Cancel a subscription",
@@ -2394,6 +2443,14 @@ var HANDLERS = {
2394
2443
  idempotencyKey: `mcp-manage-subscription-${id}-${action}-${Date.now()}`
2395
2444
  });
2396
2445
  },
2446
+ set_subscription_payment_method: async (ctx, args) => {
2447
+ const id = String(args.id);
2448
+ return ctx.client.patch(`/api/v1/subscriptions/${id}/payment-method`, {
2449
+ // `id` is the path parameter; the body is `.strict()`.
2450
+ body: { paymentMethodId: args.paymentMethodId },
2451
+ idempotencyKey: `mcp-set-subscription-card-${id}-${String(args.paymentMethodId)}-${Date.now()}`
2452
+ });
2453
+ },
2397
2454
  create_quote: async (ctx, args) => {
2398
2455
  const items = Array.isArray(args.items) ? args.items : [];
2399
2456
  if (args.netN !== void 0 && items.some((item) => item && item.recurring)) {
@@ -2658,6 +2715,7 @@ var DISPLAY_QUALIFIERS = [
2658
2715
  "Payment processing",
2659
2716
  "Disputed",
2660
2717
  "Authorization expired",
2718
+ "Chargeback lost",
2661
2719
  "Returned",
2662
2720
  "Partially returned",
2663
2721
  "Delivered",
@@ -2735,6 +2793,8 @@ var PAYMENT = {
2735
2793
  cardBrand: S,
2736
2794
  disputed: S,
2737
2795
  disputeOpenedAt: S,
2796
+ disputeOutcome: S,
2797
+ disputeClosedAt: S,
2738
2798
  errorCode: S,
2739
2799
  netN: S,
2740
2800
  netNSource: S,
@@ -2797,6 +2857,10 @@ var SUBSCRIPTION = {
2797
2857
  pendingIntervalCount: S,
2798
2858
  scheduleTotal: S,
2799
2859
  nextPaymentAmount: S,
2860
+ // A physical subscription (0236): the method is an enum, and the ship-to is
2861
+ // kept to its country like every other address here.
2862
+ deliveryMethod: S,
2863
+ shippingAddress: ADDRESS,
2800
2864
  paymentSchedule: [{
2801
2865
  index: S,
2802
2866
  amount: S,
@@ -3173,7 +3237,7 @@ var OAUTH_PROJECTIONS = {
3173
3237
  };
3174
3238
 
3175
3239
  // src/server.ts
3176
- var VERSION = true ? "0.4.0" : "0.0.0-dev";
3240
+ var VERSION = true ? "0.4.2" : "0.0.0-dev";
3177
3241
  function registerableActions(policy) {
3178
3242
  const isProduction = policy.identity.environment.providerEnvironment === "production";
3179
3243
  return actionsForChannel("mcp").filter((action) => {
@@ -3286,7 +3350,7 @@ function createServer(options) {
3286
3350
  isError: true
3287
3351
  };
3288
3352
  }
3289
- const result = await handler(ctx, args ?? {});
3353
+ const result = stripRawProcessorData(await handler(ctx, args ?? {}));
3290
3354
  const shown = redactPii ? redactShopperPii(project(result, OAUTH_PROJECTIONS[action.id])) : result;
3291
3355
  return { content: [{ type: "text", text: formatResult(shown) }] };
3292
3356
  } catch (error) {