@usethrottle/mcp 0.2.1 → 0.3.0

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
@@ -9,6 +9,7 @@ var ThrottleError = class extends Error {
9
9
  statusCode;
10
10
  details;
11
11
  body;
12
+ requestId;
12
13
  constructor(args) {
13
14
  super(args.message);
14
15
  this.name = "ThrottleError";
@@ -16,14 +17,17 @@ var ThrottleError = class extends Error {
16
17
  this.statusCode = args.statusCode;
17
18
  this.details = args.details;
18
19
  this.body = args.body;
20
+ const fromBody = args.body?.meta?.requestId;
21
+ const fromHeader = typeof args.responseHeaders?.get === "function" ? args.responseHeaders.get("x-request-id") : args.responseHeaders?.["x-request-id"];
22
+ this.requestId = args.requestId ?? (typeof fromBody === "string" ? fromBody : void 0) ?? (typeof fromHeader === "string" ? fromHeader : void 0);
19
23
  Object.setPrototypeOf(this, new.target.prototype);
20
24
  }
21
25
  };
22
26
 
23
27
  // src/client.ts
24
28
  var ThrottleApiError = class extends ThrottleError {
25
- constructor(code, message, statusCode, details) {
26
- super({ code, message, statusCode, details });
29
+ constructor(code, message, statusCode, details, responseHeaders) {
30
+ super({ code, message, statusCode, details, responseHeaders });
27
31
  this.name = "ThrottleApiError";
28
32
  }
29
33
  };
@@ -89,7 +93,8 @@ var ThrottleClient = class {
89
93
  err?.code ?? `http_${res.status}`,
90
94
  err?.message ?? `Request failed (${res.status}): ${text.slice(0, 200)}`,
91
95
  res.status,
92
- err?.details
96
+ err?.details,
97
+ res.headers
93
98
  );
94
99
  }
95
100
  return parsed;
@@ -1598,14 +1603,22 @@ var ACTIONS = [
1598
1603
  scopes: ["quotes:write"],
1599
1604
  input: [
1600
1605
  { name: "customerId", type: "string", required: true, description: "Customer the quote is for." },
1601
- { name: "items", type: "array", required: true, description: "Quote line items: { name, unitPrice, quantity }." },
1606
+ {
1607
+ name: "items",
1608
+ type: "array",
1609
+ required: true,
1610
+ description: "Quote line items: { name, unitPrice, quantity }. Add `recurring: { plan, interval | intervalUnit + intervalCount, totalPayments?, trialDays? }` to make a line a subscription (one per line when the quote is paid, quantity = seats; at most 10). unitPrice is then the per-period price; a free-trial line is charged nothing at acceptance."
1611
+ },
1602
1612
  { name: "expiresAt", type: "string", required: false, description: "ISO 8601 expiry." },
1603
- { name: "netN", type: "number", required: false, description: "Payment terms in days. Omit for pay-in-full." },
1613
+ { name: "netN", type: "number", required: false, description: "Payment terms in days. Omit for pay-in-full. Not allowed when any item is recurring." },
1604
1614
  { name: "notes", type: "string", required: false, description: "Buyer-visible notes." }
1605
1615
  ],
1606
1616
  requests: [{ method: "POST", path: "/api/v1/quotes" }],
1607
1617
  channels: ["mcp", "zapier", "make", "n8n"],
1608
- idempotent: true
1618
+ idempotent: true,
1619
+ guardrails: [
1620
+ "A quote with a recurring item must be pay-in-full: issuing it with net terms or a deposit fails with 422 recurring_terms_unsupported."
1621
+ ]
1609
1622
  },
1610
1623
  {
1611
1624
  id: "send_quote",
@@ -1712,12 +1725,12 @@ var ACTIONS = [
1712
1725
  {
1713
1726
  id: "send_test_webhook",
1714
1727
  title: "Send a test webhook",
1715
- description: "Send a synthetic signed event to a webhook endpoint to verify signature handling and reachability.",
1728
+ description: "Send a synthetic signed event to a webhook endpoint to verify signature handling and reachability. The event type must be one the endpoint is subscribed to (an endpoint subscribed to all events accepts any); otherwise the call fails with 400 validation_error naming the allowed types.",
1716
1729
  kind: "write",
1717
1730
  scopes: ["webhooks:write"],
1718
1731
  input: [
1719
1732
  { name: "id", type: "string", required: true, description: "Endpoint id." },
1720
- { name: "eventType", type: "string", required: false, description: "Event type to simulate." }
1733
+ { name: "eventType", type: "string", required: false, description: "Event type to simulate. Must be in the endpoint's subscribed events unless it subscribes to all." }
1721
1734
  ],
1722
1735
  requests: [{ method: "POST", path: "/api/v1/webhook-endpoints/:id/test" }],
1723
1736
  channels: ["mcp", "n8n"],
@@ -2386,14 +2399,14 @@ var HANDLERS = {
2386
2399
  idempotencyKey: `mcp-manage-subscription-${id}-${action}-${Date.now()}`
2387
2400
  });
2388
2401
  },
2389
- create_quote: async (ctx, args) => (
2390
- // The real route's body shape differs from this tool's flatter,
2391
- // model-facing input: line items are "items" (not "lineItems"), Net-N
2392
- // terms are nested under paymentTerms.netN with an explicit mode (not a
2393
- // flat "netN"), and the buyer-visible note field is "buyerNote" (not
2394
- // "notes"). Confirmed against packages/platform-api/src/validation/quotes.ts's
2395
- // actual zod schema after a live call 400'd with unrecognized_keys.
2396
- ctx.client.post("/api/v1/quotes", {
2402
+ create_quote: async (ctx, args) => {
2403
+ const items = Array.isArray(args.items) ? args.items : [];
2404
+ if (args.netN !== void 0 && items.some((item) => item && item.recurring)) {
2405
+ throw new Error(
2406
+ "create_quote: items with `recurring` need pay-in-full terms \u2014 omit netN. Net terms cannot start a subscription."
2407
+ );
2408
+ }
2409
+ return ctx.client.post("/api/v1/quotes", {
2397
2410
  body: {
2398
2411
  customerId: args.customerId,
2399
2412
  items: args.items,
@@ -2402,8 +2415,8 @@ var HANDLERS = {
2402
2415
  buyerNote: args.notes
2403
2416
  },
2404
2417
  idempotencyKey: `mcp-create-quote-${String(args.customerId)}-${Date.now()}`
2405
- })
2406
- ),
2418
+ });
2419
+ },
2407
2420
  get_sales_timeseries: async (ctx, args) => ctx.client.get(
2408
2421
  "/api/v1/analytics/orders-timeseries",
2409
2422
  {
@@ -2660,6 +2673,14 @@ var ORDER_DISPLAY_STATUSES = new Set(
2660
2673
  );
2661
2674
  var DISPLAY_STATUS = oneOf(ORDER_DISPLAY_STATUSES);
2662
2675
  var RANGE = { from: S, to: S, timezone: S, groupBy: S };
2676
+ var LINE_RECURRING = {
2677
+ plan: S,
2678
+ interval: S,
2679
+ intervalUnit: S,
2680
+ intervalCount: S,
2681
+ totalPayments: S,
2682
+ trialDays: S
2683
+ };
2663
2684
  var LINE_ITEM = {
2664
2685
  id: S,
2665
2686
  type: S,
@@ -2669,7 +2690,9 @@ var LINE_ITEM = {
2669
2690
  discountAmount: S,
2670
2691
  taxAmount: S,
2671
2692
  total: S,
2672
- recurring: S
2693
+ // amount = renewal price on a trial line (whose unitPrice is 0); count = the old display mirror.
2694
+ recurring: { ...LINE_RECURRING, amount: S, count: S },
2695
+ subscriptionId: S
2673
2696
  };
2674
2697
  var ORDER = {
2675
2698
  id: S,
@@ -2693,6 +2716,7 @@ var ORDER = {
2693
2716
  customerId: S,
2694
2717
  customer: CUSTOMER_REF,
2695
2718
  subscriptionId: S,
2719
+ subscriptionIds: [S],
2696
2720
  shippingAddress: ADDRESS,
2697
2721
  billingAddress: ADDRESS,
2698
2722
  fulfillmentSummary: { itemsFulfilled: S, itemsRemaining: S, itemsTotal: S },
@@ -2815,7 +2839,8 @@ var QUOTE = {
2815
2839
  taxAmount: S,
2816
2840
  total: S,
2817
2841
  optional: S,
2818
- optionalSelected: S
2842
+ optionalSelected: S,
2843
+ recurring: LINE_RECURRING
2819
2844
  }]
2820
2845
  }],
2821
2846
  // Who commented and when, never what they wrote.
@@ -2981,7 +3006,22 @@ var OAUTH_PROJECTIONS = {
2981
3006
  trialDays: S,
2982
3007
  currency: S,
2983
3008
  firstChargeAmountMinor: S
2984
- }
3009
+ },
3010
+ hasSubscriptions: S,
3011
+ // One entry per subscription line. No `name`: it is the line's name.
3012
+ subscriptions: [{
3013
+ lineItemId: S,
3014
+ amount: S,
3015
+ quantity: S,
3016
+ interval: S,
3017
+ intervalUnit: S,
3018
+ intervalCount: S,
3019
+ totalPayments: S,
3020
+ trialDays: S,
3021
+ trialEndsAt: S,
3022
+ planChargedToday: S,
3023
+ taxApplies: S
3024
+ }]
2985
3025
  },
2986
3026
  cart: section({
2987
3027
  id: S,
@@ -3122,7 +3162,7 @@ var OAUTH_PROJECTIONS = {
3122
3162
  };
3123
3163
 
3124
3164
  // src/server.ts
3125
- var VERSION = true ? "0.2.1" : "0.0.0-dev";
3165
+ var VERSION = true ? "0.3.0" : "0.0.0-dev";
3126
3166
  function registerableActions(policy) {
3127
3167
  const isProduction = policy.identity.environment.providerEnvironment === "production";
3128
3168
  return actionsForChannel("mcp").filter((action) => {