@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/mcp.js CHANGED
@@ -194,6 +194,8 @@ add("Customers", "customers", ["read", "write"], { read: "View customers", write
194
194
  add("Customers", "customer_pii", ["read"], { read: "View customer PII" }, { sensitive: true });
195
195
  add("Customers", "customer_addresses", ["read", "write"], { read: "View addresses", write: "Manage addresses" });
196
196
  add("Customers", "customer_payment_methods", ["read", "write"], { read: "View stored cards", write: "Manage stored cards" }, { sensitive: true });
197
+ add("Customers", "customer_tokens", ["read"], { read: "Check shoppers' sign-in tokens" });
198
+ add("Customers", "customer_directory", ["read"], { read: "Find customers by name or email" }, { sensitive: true });
197
199
  add(
198
200
  "Customer accounts",
199
201
  "customer_accounts",
@@ -326,6 +328,7 @@ var EVENT_SCOPE_OVERRIDES = {
326
328
  "subscription.invoice_refunded": "payment_refunds:read",
327
329
  "payment.disputed": "payment_disputes:read",
328
330
  "payment.dispute_cleared": "payment_disputes:read",
331
+ "payment.dispute_lost": "payment_disputes:read",
329
332
  "fulfillment.digital.delivered": "fulfillment_digital:read"
330
333
  };
331
334
  var PREFIX_RULES = [
@@ -444,6 +447,29 @@ function redactShopperPii(value) {
444
447
  return walk(value, null, 0);
445
448
  }
446
449
 
450
+ // ../core-scopes/src/public-payment.ts
451
+ var RAW_PROCESSOR_KEYS = ["processorResponse", "gr4vy_payment_method"];
452
+ var RAW = new Set(RAW_PROCESSOR_KEYS);
453
+ function isPlainObject2(value) {
454
+ if (value === null || typeof value !== "object") return false;
455
+ const proto = Object.getPrototypeOf(value);
456
+ return proto === Object.prototype || proto === null;
457
+ }
458
+ function strip(value, depth) {
459
+ if (depth > 32) return value;
460
+ if (Array.isArray(value)) return value.map((v) => strip(v, depth + 1));
461
+ if (!isPlainObject2(value)) return value;
462
+ const out = {};
463
+ for (const [key, child] of Object.entries(value)) {
464
+ if (RAW.has(key)) continue;
465
+ out[key] = strip(child, depth + 1);
466
+ }
467
+ return out;
468
+ }
469
+ function stripRawProcessorData(value) {
470
+ return strip(value, 0);
471
+ }
472
+
447
473
  // ../action-catalog/src/actions.ts
448
474
  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.";
449
475
  var ACTIONS = [
@@ -1456,7 +1482,7 @@ var ACTIONS = [
1456
1482
  {
1457
1483
  id: "create_customer",
1458
1484
  title: "Create a customer",
1459
- description: "Create a customer record. Use search_customers first if the buyer may already exist \u2014 this does not de-duplicate by email.",
1485
+ 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.",
1460
1486
  kind: "write",
1461
1487
  scopes: ["customers:write"],
1462
1488
  input: [
@@ -1688,6 +1714,29 @@ var ACTIONS = [
1688
1714
  channels: ["mcp", "zapier", "make", "n8n"],
1689
1715
  idempotent: true
1690
1716
  },
1717
+ {
1718
+ id: "set_subscription_payment_method",
1719
+ title: "Change a subscription's card",
1720
+ 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.",
1721
+ kind: "write",
1722
+ scopes: ["subscriptions:write"],
1723
+ input: [
1724
+ { name: "id", type: "string", required: true, description: "Subscription id." },
1725
+ {
1726
+ name: "paymentMethodId",
1727
+ type: "string",
1728
+ required: true,
1729
+ description: "One of the subscription customer's saved cards (GET /api/v1/customers/:id/payment-methods): active and in date."
1730
+ }
1731
+ ],
1732
+ requests: [{ method: "PATCH", path: "/api/v1/subscriptions/:id/payment-method" }],
1733
+ channels: ["mcp", "zapier", "make", "n8n"],
1734
+ idempotent: true,
1735
+ guardrails: [
1736
+ "Changes which card future renewals charge. Confirm the subscription and the card (brand, last four) with the user first.",
1737
+ "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."
1738
+ ]
1739
+ },
1691
1740
  {
1692
1741
  id: "cancel_subscription",
1693
1742
  title: "Cancel a subscription",
@@ -2399,6 +2448,14 @@ var HANDLERS = {
2399
2448
  idempotencyKey: `mcp-manage-subscription-${id}-${action}-${Date.now()}`
2400
2449
  });
2401
2450
  },
2451
+ set_subscription_payment_method: async (ctx, args) => {
2452
+ const id = String(args.id);
2453
+ return ctx.client.patch(`/api/v1/subscriptions/${id}/payment-method`, {
2454
+ // `id` is the path parameter; the body is `.strict()`.
2455
+ body: { paymentMethodId: args.paymentMethodId },
2456
+ idempotencyKey: `mcp-set-subscription-card-${id}-${String(args.paymentMethodId)}-${Date.now()}`
2457
+ });
2458
+ },
2402
2459
  create_quote: async (ctx, args) => {
2403
2460
  const items = Array.isArray(args.items) ? args.items : [];
2404
2461
  if (args.netN !== void 0 && items.some((item) => item && item.recurring)) {
@@ -2663,6 +2720,7 @@ var DISPLAY_QUALIFIERS = [
2663
2720
  "Payment processing",
2664
2721
  "Disputed",
2665
2722
  "Authorization expired",
2723
+ "Chargeback lost",
2666
2724
  "Returned",
2667
2725
  "Partially returned",
2668
2726
  "Delivered",
@@ -2740,6 +2798,8 @@ var PAYMENT = {
2740
2798
  cardBrand: S,
2741
2799
  disputed: S,
2742
2800
  disputeOpenedAt: S,
2801
+ disputeOutcome: S,
2802
+ disputeClosedAt: S,
2743
2803
  errorCode: S,
2744
2804
  netN: S,
2745
2805
  netNSource: S,
@@ -2802,6 +2862,10 @@ var SUBSCRIPTION = {
2802
2862
  pendingIntervalCount: S,
2803
2863
  scheduleTotal: S,
2804
2864
  nextPaymentAmount: S,
2865
+ // A physical subscription (0236): the method is an enum, and the ship-to is
2866
+ // kept to its country like every other address here.
2867
+ deliveryMethod: S,
2868
+ shippingAddress: ADDRESS,
2805
2869
  paymentSchedule: [{
2806
2870
  index: S,
2807
2871
  amount: S,
@@ -3178,7 +3242,7 @@ var OAUTH_PROJECTIONS = {
3178
3242
  };
3179
3243
 
3180
3244
  // src/server.ts
3181
- var VERSION = true ? "0.4.0" : "0.0.0-dev";
3245
+ var VERSION = true ? "0.4.2" : "0.0.0-dev";
3182
3246
  function registerableActions(policy) {
3183
3247
  const isProduction = policy.identity.environment.providerEnvironment === "production";
3184
3248
  return actionsForChannel("mcp").filter((action) => {
@@ -3291,7 +3355,7 @@ function createServer(options) {
3291
3355
  isError: true
3292
3356
  };
3293
3357
  }
3294
- const result = await handler(ctx, args ?? {});
3358
+ const result = stripRawProcessorData(await handler(ctx, args ?? {}));
3295
3359
  const shown = redactPii ? redactShopperPii(project(result, OAUTH_PROJECTIONS[action.id])) : result;
3296
3360
  return { content: [{ type: "text", text: formatResult(shown) }] };
3297
3361
  } catch (error) {