askell-mcp 0.4.12 → 0.4.13
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/README.md +3 -2
- package/package.json +1 -1
- package/spec/openapi-v2.json +1491 -373
- package/src/client/response-formatter.ts +8 -0
- package/src/resources/register.ts +4 -4
- package/src/server.ts +7 -5
|
@@ -67,6 +67,10 @@ function summarizeListItem(item: unknown): unknown {
|
|
|
67
67
|
'currency',
|
|
68
68
|
'amount',
|
|
69
69
|
'total_amount',
|
|
70
|
+
'code',
|
|
71
|
+
'valid',
|
|
72
|
+
'duration',
|
|
73
|
+
'coupon',
|
|
70
74
|
] as const;
|
|
71
75
|
|
|
72
76
|
for (const key of scalarKeys) {
|
|
@@ -127,6 +131,10 @@ function indexListItem(item: unknown): unknown {
|
|
|
127
131
|
out.name = obj.name;
|
|
128
132
|
}
|
|
129
133
|
|
|
134
|
+
if (typeof obj.code === 'string') {
|
|
135
|
+
out.code = obj.code;
|
|
136
|
+
}
|
|
137
|
+
|
|
130
138
|
const customerRef =
|
|
131
139
|
obj.customer_reference ??
|
|
132
140
|
(obj.customer && typeof obj.customer === 'object'
|
|
@@ -2,7 +2,7 @@ import type { McpServer } from '@modelcontextprotocol/server';
|
|
|
2
2
|
|
|
3
3
|
import { getBundledSpec } from '../openapi/registry.ts';
|
|
4
4
|
|
|
5
|
-
const WEBHOOK_EVENTS_DOC = `# Askell webhook events (reference)
|
|
5
|
+
export const WEBHOOK_EVENTS_DOC = `# Askell webhook events (reference)
|
|
6
6
|
|
|
7
7
|
Askell POSTs signed JSON to each URL you register. Verify \`Hook-HMAC\` before parsing.
|
|
8
8
|
|
|
@@ -63,11 +63,11 @@ V2 migration: \`subscription.*\` is **not** aliased onto the new contract (paylo
|
|
|
63
63
|
\`created\`, \`changed\` — \`token\`, \`checkout_url\`, \`status\`.
|
|
64
64
|
|
|
65
65
|
### fulfillment_order.* (v2)
|
|
66
|
-
Family wildcard \`fulfillment_order.*\`.
|
|
66
|
+
Family wildcard \`fulfillment_order.*\`. Bundled swagger names \`fulfillment_order.fulfilled\` (\`POST .../fulfill/\` or dashboard ship) and \`fulfillment_order.cancelled\` (\`POST .../cancel/\`). Do not invent \`created\`/\`changed\`. Live https://docs.askell.is/en/api/webhooks.html still omits this family.
|
|
67
67
|
|
|
68
|
-
Body = \`V2FulfillmentOrder\` = \`GET /v2/fulfillment-orders/{fulfillmentOrderId}/\` (list items are the same object). Physical order from a paid billing run (\`billing_run_id\`; at most one order per run). \`delivery_address\` is a snapshot (later contract address edits do not change it). \`shipping_selection\` is the checkout snapshot. \`fulfillments[]\` are booked shipments (empty until booked / if no shipping providers). Status: \`open\` | \`partially_fulfilled\` | \`fulfilled\` | \`cancelled\`.
|
|
68
|
+
Body = \`V2FulfillmentOrder\` = \`GET /v2/fulfillment-orders/{fulfillmentOrderId}/\` (list items are the same object). Physical order from a paid billing run (\`billing_run_id\`; at most one order per run). \`delivery_address\` is a snapshot (later contract address edits do not change it). \`shipping_selection\` is the checkout snapshot. \`fulfillments[]\` are booked shipments (empty until booked / if no shipping providers). Status: \`open\` | \`partially_fulfilled\` | \`fulfilled\` | \`cancelled\`. External carrier with no Askell integration: shipment \`handler\` is \`""\` — read \`carrier\`.
|
|
69
69
|
|
|
70
|
-
Register \`fulfillment_order.*\` on \`POST /webhooks/\`. REST backfill: \`GET /v2/fulfillment-orders/?updated_since=\` (secret; newest first; \`403\` if the account has no subscription contracts or shipping is disabled).
|
|
70
|
+
Register \`fulfillment_order.*\` on \`POST /webhooks/\`. REST backfill: \`GET /v2/fulfillment-orders/?updated_since=\` (secret; newest first; \`403\` if the account has no subscription contracts or shipping is disabled). Mutate via \`askell_mutate\`: \`POST /v2/fulfillment-orders/{id}/fulfill/\` (optional body) and \`POST .../cancel/\` (no body). Both idempotent \`200\` if already in that state (webhook/email not replayed). \`409\` codes: \`order_cancelled\`, \`order_fulfilled\`, \`booking_in_progress\`.
|
|
71
71
|
`;
|
|
72
72
|
|
|
73
73
|
export function registerResources(server: McpServer): void {
|
package/src/server.ts
CHANGED
|
@@ -37,7 +37,7 @@ Workflow:
|
|
|
37
37
|
|
|
38
38
|
API models:
|
|
39
39
|
- v1 (legacy): PlanVariant + Subscription at paths like /subscriptions/, /customers/. Still supported for existing integrations.
|
|
40
|
-
- v2 (current): Catalog, bundles, quotes, checkouts, subscription contracts, billing runs, fulfillment orders under /v2/. Prefer v2 for new integrations.
|
|
40
|
+
- v2 (current): Catalog, bundles, quotes, checkouts, subscription contracts, billing runs, coupons/promotion codes, fulfillment orders under /v2/. Prefer v2 for new integrations.
|
|
41
41
|
- Prose docs at https://docs.askell.is/api/ may describe flows (embedded checkout, 3D Secure, wallet passes) not fully listed in OpenAPI.
|
|
42
42
|
|
|
43
43
|
API layout:
|
|
@@ -47,8 +47,9 @@ API layout:
|
|
|
47
47
|
- V2 list endpoints paginate only when page_size is provided (default 10, max 1000).
|
|
48
48
|
- GET /v2/customer-entitlements/ requires customer_reference query param.
|
|
49
49
|
|
|
50
|
-
V2 discounts —
|
|
51
|
-
-
|
|
50
|
+
V2 discounts — not v1 Subscription.discount (0-100 on a PlanVariant; never send that to v2). Coupon = discount definition; promotion code = customer-facing code:
|
|
51
|
+
- Catalog (secret): CRUD /v2/coupons/ and /v2/promotion-codes/. Create coupon: exactly one of amount_off+currency or percent_off; duration_in_months required iff duration=repeating (omit otherwise); redeem_by must be future. PATCH type switch: send the old field as null. Redeemed coupon/code cannot DELETE — retire coupon with redeem_by/max_redemptions, promo with active=false (frees code for reuse). List/get hide soft-deletes. Promo code is uppercased and generated if omitted; unique among active; restrict with customer xor customer_reference.
|
|
52
|
+
- Contract: one active discount. GET /v2/subscription-contracts/{id}/discount/ (also nested as contract.discount). Apply with POST .../apply-code/ {promotion_code}. Remove with POST .../remove-discount/.
|
|
52
53
|
- Quotes (POST /v2/subscription-offer-quotes/): pass promotion_code for coupons. When quoting an existing customer, pass customer (numeric id) or combo discounts from their other active contracts and promo-code customer restrictions are skipped. First-period subtotal/tax/total already include coupon + combo. quote.recurring_* include combo, not the coupon — renewal-with-coupon is discount.recurring_final_amount, and only while duration still applies (once → after first payment use recurring_*). combo_discounts[] and discount.recurring_* are on the quote response (askell_describe_operation omits response schemas). Combo is automatic, not apply-code.
|
|
53
54
|
|
|
54
55
|
V2 checkout notes:
|
|
@@ -59,8 +60,9 @@ V2 checkout notes:
|
|
|
59
60
|
- Hosted iframe (not askell.js): POST /v2/checkouts/ and POST .../payment-method-registrations/ take allowed_origin (one origin, no path; http only localhost/loopback). Replaces account-level frame-ancestors; GET empty string = account-level. Rejected on /v2/checkout-sessions/ (sales-channel allowed_origins[]).
|
|
60
61
|
- Embedded checkout uses POST /v2/checkout-sessions/ plus browser session-token sub-paths (widget collects address/shipping; see docs, not all in OpenAPI).
|
|
61
62
|
|
|
62
|
-
V2 fulfillment (warehouse
|
|
63
|
-
- GET /v2/fulfillment-orders/ and GET /v2/fulfillment-orders/{id}/. Same body as fulfillment_order.* webhooks (V2FulfillmentOrder). Secret key. 403 if
|
|
63
|
+
V2 fulfillment (warehouse):
|
|
64
|
+
- GET /v2/fulfillment-orders/ and GET /v2/fulfillment-orders/{id}/. Same body as fulfillment_order.* webhooks (V2FulfillmentOrder). Secret key. 403 if contracts/shipping off. Poll updated_since after a missed webhook (newest first).
|
|
65
|
+
- POST .../{id}/fulfill/ marks shipped (body optional: tracking_number, tracking_url, provider_order_id, carrier, weight_grams). POST .../{id}/cancel/ (no body). Both idempotent 200 if already in that state (no second webhook/email). 409: order_cancelled | order_fulfilled | booking_in_progress (retry shortly). 403 if fulfillment is switched off. External carrier with no Askell integration: shipment.handler is "" — read carrier.
|
|
64
66
|
|
|
65
67
|
Auth:
|
|
66
68
|
- Most endpoints need the secret API key.
|