@akoskomuves/appstoreconnect-mcp 0.1.1

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.
Files changed (73) hide show
  1. package/CHANGELOG.md +74 -0
  2. package/LICENSE +21 -0
  3. package/README.md +158 -0
  4. package/data/apple-music-prices.json +78 -0
  5. package/dist/auth.d.ts +9 -0
  6. package/dist/auth.d.ts.map +1 -0
  7. package/dist/auth.js +33 -0
  8. package/dist/auth.js.map +1 -0
  9. package/dist/client.d.ts +6 -0
  10. package/dist/client.d.ts.map +1 -0
  11. package/dist/client.js +75 -0
  12. package/dist/client.js.map +1 -0
  13. package/dist/clients.d.ts +31 -0
  14. package/dist/clients.d.ts.map +1 -0
  15. package/dist/clients.js +88 -0
  16. package/dist/clients.js.map +1 -0
  17. package/dist/config.d.ts +7 -0
  18. package/dist/config.d.ts.map +1 -0
  19. package/dist/config.js +29 -0
  20. package/dist/config.js.map +1 -0
  21. package/dist/digest.d.ts +13 -0
  22. package/dist/digest.d.ts.map +1 -0
  23. package/dist/digest.js +154 -0
  24. package/dist/digest.js.map +1 -0
  25. package/dist/doctor.d.ts +2 -0
  26. package/dist/doctor.d.ts.map +1 -0
  27. package/dist/doctor.js +139 -0
  28. package/dist/doctor.js.map +1 -0
  29. package/dist/domains/apps.d.ts +4 -0
  30. package/dist/domains/apps.d.ts.map +1 -0
  31. package/dist/domains/apps.js +40 -0
  32. package/dist/domains/apps.js.map +1 -0
  33. package/dist/domains/ppp.d.ts +6 -0
  34. package/dist/domains/ppp.d.ts.map +1 -0
  35. package/dist/domains/ppp.js +539 -0
  36. package/dist/domains/ppp.js.map +1 -0
  37. package/dist/domains/pricing.d.ts +4 -0
  38. package/dist/domains/pricing.d.ts.map +1 -0
  39. package/dist/domains/pricing.js +55 -0
  40. package/dist/domains/pricing.js.map +1 -0
  41. package/dist/domains/subscriptions.d.ts +4 -0
  42. package/dist/domains/subscriptions.d.ts.map +1 -0
  43. package/dist/domains/subscriptions.js +84 -0
  44. package/dist/domains/subscriptions.js.map +1 -0
  45. package/dist/domains/territories.d.ts +4 -0
  46. package/dist/domains/territories.d.ts.map +1 -0
  47. package/dist/domains/territories.js +21 -0
  48. package/dist/domains/territories.js.map +1 -0
  49. package/dist/errors.d.ts +6 -0
  50. package/dist/errors.d.ts.map +1 -0
  51. package/dist/errors.js +11 -0
  52. package/dist/errors.js.map +1 -0
  53. package/dist/index.d.ts +3 -0
  54. package/dist/index.d.ts.map +1 -0
  55. package/dist/index.js +98 -0
  56. package/dist/index.js.map +1 -0
  57. package/dist/init.d.ts +6 -0
  58. package/dist/init.d.ts.map +1 -0
  59. package/dist/init.js +316 -0
  60. package/dist/init.js.map +1 -0
  61. package/dist/jsonapi.d.ts +62 -0
  62. package/dist/jsonapi.d.ts.map +1 -0
  63. package/dist/jsonapi.js +78 -0
  64. package/dist/jsonapi.js.map +1 -0
  65. package/dist/ppp/index.d.ts +40 -0
  66. package/dist/ppp/index.d.ts.map +1 -0
  67. package/dist/ppp/index.js +85 -0
  68. package/dist/ppp/index.js.map +1 -0
  69. package/dist/schemas.d.ts +10 -0
  70. package/dist/schemas.d.ts.map +1 -0
  71. package/dist/schemas.js +34 -0
  72. package/dist/schemas.js.map +1 -0
  73. package/package.json +79 -0
@@ -0,0 +1,539 @@
1
+ import { z } from 'zod';
2
+ import { buildIncludedIndex, formatTable, lookupIncluded, paginate, } from '../jsonapi.js';
3
+ import { applyFloor, computeFactor, computeTarget, indexAsMap, loadIndex, parseDecimal, percentChange, snapToTier, } from '../ppp/index.js';
4
+ import { SubscriptionIdSchema } from '../schemas.js';
5
+ function fmtMoney(n) {
6
+ if (n === undefined)
7
+ return '';
8
+ if (Number.isInteger(n))
9
+ return n.toString();
10
+ return n.toFixed(2);
11
+ }
12
+ function fmtPct(n) {
13
+ if (n === undefined)
14
+ return '';
15
+ const sign = n > 0 ? '+' : '';
16
+ return `${sign}${n.toFixed(0)}%`;
17
+ }
18
+ function todayPlusDaysISO(days) {
19
+ const d = new Date();
20
+ d.setUTCDate(d.getUTCDate() + days);
21
+ return d.toISOString().slice(0, 10);
22
+ }
23
+ async function fetchCurrentPriceMap(client, subscriptionId) {
24
+ const path = `/v1/subscriptions/${encodeURIComponent(subscriptionId)}/prices?include=subscriptionPricePoint,territory`;
25
+ const pages = await paginate(client, path, 2000);
26
+ const index = buildIncludedIndex(pages.included);
27
+ const out = new Map();
28
+ for (const price of pages.data) {
29
+ const territoryRel = price.relationships?.['territory']?.data;
30
+ const pointRel = price.relationships?.['subscriptionPricePoint']?.data;
31
+ const territoryId = territoryRel && !Array.isArray(territoryRel) ? territoryRel.id : undefined;
32
+ const pointId = pointRel && !Array.isArray(pointRel) ? pointRel.id : undefined;
33
+ if (!territoryId || !pointId)
34
+ continue;
35
+ const point = lookupIncluded(index, 'subscriptionPricePoints', pointId);
36
+ const territory = lookupIncluded(index, 'territories', territoryId);
37
+ const amount = parseDecimal(point?.attributes?.['customerPrice']);
38
+ const currency = territory?.attributes?.['currency'] ?? '';
39
+ if (amount === undefined)
40
+ continue;
41
+ out.set(territoryId, { amount, territory: territoryId, currency });
42
+ }
43
+ return out;
44
+ }
45
+ async function fetchPricePointsForTerritory(client, subscriptionId, territoryId) {
46
+ const params = new URLSearchParams();
47
+ params.set('filter[territory]', territoryId);
48
+ params.set('limit', '200');
49
+ const pages = await paginate(client, `/v1/subscriptions/${encodeURIComponent(subscriptionId)}/pricePoints?${params.toString()}`, 5000);
50
+ const out = [];
51
+ for (const p of pages.data) {
52
+ const amt = parseDecimal(p.attributes?.['customerPrice']);
53
+ if (amt === undefined)
54
+ continue;
55
+ out.push({ id: p.id, amount: amt });
56
+ }
57
+ return out;
58
+ }
59
+ async function computeProposal(client, args) {
60
+ const index = loadIndex();
61
+ const indexMap = indexAsMap(index);
62
+ const anchorEntry = indexMap.get(args.anchorTerritory);
63
+ if (!anchorEntry) {
64
+ throw new Error(`Anchor territory ${args.anchorTerritory} is not in the Apple Music index. Add it to data/apple-music-prices.json.`);
65
+ }
66
+ const currentPriceMap = await fetchCurrentPriceMap(client, args.subscriptionId);
67
+ const targetTerritories = args.territories
68
+ ? args.territories.map((t) => t.toUpperCase())
69
+ : Array.from(currentPriceMap.keys());
70
+ const pending = [];
71
+ const rows = [];
72
+ for (const territoryId of targetTerritories) {
73
+ const current = currentPriceMap.get(territoryId);
74
+ if (!current) {
75
+ rows.push({
76
+ territory: territoryId,
77
+ currency: '',
78
+ currentLocal: undefined,
79
+ factor: undefined,
80
+ targetLocal: undefined,
81
+ snappedAmount: undefined,
82
+ snappedPointId: undefined,
83
+ changePct: undefined,
84
+ reason: 'no-current-price',
85
+ });
86
+ continue;
87
+ }
88
+ const indexEntry = indexMap.get(territoryId);
89
+ if (!indexEntry) {
90
+ if (args.skipMissingIndex)
91
+ continue;
92
+ rows.push({
93
+ territory: territoryId,
94
+ currency: current.currency,
95
+ currentLocal: current.amount,
96
+ factor: undefined,
97
+ targetLocal: undefined,
98
+ snappedAmount: undefined,
99
+ snappedPointId: undefined,
100
+ changePct: undefined,
101
+ reason: 'no-index',
102
+ });
103
+ continue;
104
+ }
105
+ // Currency-mismatch guard. The Apple Music ratio is only a valid
106
+ // PPP-FX signal when its denominator and the ASC billing currency
107
+ // are the same — otherwise we'd multiply $X by a (foreign-currency
108
+ // / USD) ratio and write the result back as USD, which is
109
+ // dimensionally wrong. (Hit by USD-billed Gulf markets where Apple
110
+ // Music is sold in BHD/KWD/OMR.)
111
+ if (current.currency && indexEntry.currency && current.currency !== indexEntry.currency) {
112
+ rows.push({
113
+ territory: territoryId,
114
+ currency: current.currency,
115
+ currentLocal: current.amount,
116
+ factor: undefined,
117
+ targetLocal: undefined,
118
+ snappedAmount: undefined,
119
+ snappedPointId: undefined,
120
+ changePct: undefined,
121
+ reason: `currency-mismatch (asc=${current.currency}, am=${indexEntry.currency})`,
122
+ });
123
+ continue;
124
+ }
125
+ const factor = computeFactor(indexEntry.individualPrice, anchorEntry.individualPrice);
126
+ const target = computeTarget(args.basePriceAnchor, factor);
127
+ const flooredTarget = applyFloor(target, current.amount, args.floorFactor);
128
+ pending.push({
129
+ territoryId,
130
+ targetLocal: flooredTarget,
131
+ current: current.amount,
132
+ currency: current.currency,
133
+ factor,
134
+ });
135
+ }
136
+ const pricePointResults = await Promise.allSettled(pending.map((p) => fetchPricePointsForTerritory(client, args.subscriptionId, p.territoryId).then((pts) => ({
137
+ territoryId: p.territoryId,
138
+ points: pts,
139
+ }))));
140
+ const pointsByTerritory = new Map();
141
+ for (const result of pricePointResults) {
142
+ if (result.status === 'fulfilled') {
143
+ pointsByTerritory.set(result.value.territoryId, result.value.points);
144
+ }
145
+ }
146
+ for (const p of pending) {
147
+ const points = pointsByTerritory.get(p.territoryId) ?? [];
148
+ if (points.length === 0) {
149
+ rows.push({
150
+ territory: p.territoryId,
151
+ currency: p.currency,
152
+ currentLocal: p.current,
153
+ factor: p.factor,
154
+ targetLocal: p.targetLocal,
155
+ snappedAmount: undefined,
156
+ snappedPointId: undefined,
157
+ changePct: undefined,
158
+ reason: 'no-price-points',
159
+ });
160
+ continue;
161
+ }
162
+ const snapped = snapToTier(p.targetLocal, points.map((pt) => pt.amount), args.roundStrategy);
163
+ if (snapped === undefined) {
164
+ rows.push({
165
+ territory: p.territoryId,
166
+ currency: p.currency,
167
+ currentLocal: p.current,
168
+ factor: p.factor,
169
+ targetLocal: p.targetLocal,
170
+ snappedAmount: undefined,
171
+ snappedPointId: undefined,
172
+ changePct: undefined,
173
+ reason: 'snap-failed',
174
+ });
175
+ continue;
176
+ }
177
+ const snappedPoint = points.find((pt) => pt.amount === snapped);
178
+ const changePct = percentChange(p.current, snapped);
179
+ const unchanged = snapped === p.current;
180
+ if (unchanged && args.skipUnchanged)
181
+ continue;
182
+ rows.push({
183
+ territory: p.territoryId,
184
+ currency: p.currency,
185
+ currentLocal: p.current,
186
+ factor: p.factor,
187
+ targetLocal: p.targetLocal,
188
+ snappedAmount: snapped,
189
+ snappedPointId: snappedPoint?.id,
190
+ changePct,
191
+ reason: unchanged ? 'unchanged' : 'change',
192
+ });
193
+ }
194
+ rows.sort((a, b) => {
195
+ const ai = a.changePct ?? 0;
196
+ const bi = b.changePct ?? 0;
197
+ return ai - bi;
198
+ });
199
+ return {
200
+ rows,
201
+ snapshot: index.snapshot,
202
+ anchorTerritory: args.anchorTerritory,
203
+ basePriceAnchor: args.basePriceAnchor,
204
+ roundStrategy: args.roundStrategy,
205
+ floorFactor: args.floorFactor,
206
+ };
207
+ }
208
+ function shortPointId(id) {
209
+ if (!id)
210
+ return '';
211
+ return id.length <= 10 ? id : `…${id.slice(-8)}`;
212
+ }
213
+ function renderProposalTable(ctx, subscriptionId, options = {}) {
214
+ const pointIdMode = options.pointIdMode ?? 'short';
215
+ const showPointId = pointIdMode !== 'none';
216
+ const columns = [
217
+ { header: 'TERR' },
218
+ { header: 'CCY' },
219
+ { header: 'CURRENT', align: 'right' },
220
+ { header: 'TARGET', align: 'right' },
221
+ { header: 'SNAPPED', align: 'right' },
222
+ { header: 'Δ', align: 'right' },
223
+ { header: 'FACTOR', align: 'right' },
224
+ ...(showPointId ? [{ header: 'POINT_ID' }] : []),
225
+ { header: 'NOTE' },
226
+ ];
227
+ const tableRows = ctx.rows.map((r) => {
228
+ const pointIdCell = pointIdMode === 'full' ? (r.snappedPointId ?? '') : shortPointId(r.snappedPointId);
229
+ return [
230
+ r.territory,
231
+ r.currency,
232
+ fmtMoney(r.currentLocal),
233
+ fmtMoney(r.targetLocal),
234
+ fmtMoney(r.snappedAmount),
235
+ fmtPct(r.changePct),
236
+ r.factor !== undefined ? r.factor.toFixed(3) : '',
237
+ ...(showPointId ? [pointIdCell] : []),
238
+ r.reason === 'change' ? '' : r.reason,
239
+ ];
240
+ });
241
+ const changes = ctx.rows.filter((r) => r.reason === 'change').length;
242
+ const drops = ctx.rows.filter((r) => (r.changePct ?? 0) < 0).length;
243
+ const lifts = ctx.rows.filter((r) => (r.changePct ?? 0) > 0).length;
244
+ const summary = `Proposal for subscription ${subscriptionId}: ${changes} change${changes === 1 ? '' : 's'} (${drops} drops, ${lifts} lifts), anchor ${ctx.anchorTerritory}=${ctx.basePriceAnchor}, round=${ctx.roundStrategy}, floor=${ctx.floorFactor}, snapshot=${ctx.snapshot}`;
245
+ return `${summary}\n\n${formatTable(columns, tableRows)}`;
246
+ }
247
+ /** Run async tasks with a fixed concurrency limit. Returns results in order. */
248
+ export async function concurrentMap(items, concurrency, worker) {
249
+ const results = new Array(items.length);
250
+ let cursor = 0;
251
+ async function runWorker() {
252
+ while (true) {
253
+ const i = cursor++;
254
+ if (i >= items.length)
255
+ return;
256
+ const item = items[i];
257
+ results[i] = await worker(item, i);
258
+ }
259
+ }
260
+ const workers = Array.from({ length: Math.min(concurrency, items.length) }, runWorker);
261
+ await Promise.all(workers);
262
+ return results;
263
+ }
264
+ async function postSubscriptionPrice(client, args) {
265
+ const body = {
266
+ data: {
267
+ type: 'subscriptionPrices',
268
+ attributes: {
269
+ startDate: args.startDate,
270
+ preserveCurrentPrice: args.preserveCurrentPrice,
271
+ },
272
+ relationships: {
273
+ subscription: { data: { type: 'subscriptions', id: args.subscriptionId } },
274
+ subscriptionPricePoint: {
275
+ data: { type: 'subscriptionPricePoints', id: args.pricePointId },
276
+ },
277
+ territory: { data: { type: 'territories', id: args.territoryId } },
278
+ },
279
+ },
280
+ };
281
+ try {
282
+ const res = await client.request('/v1/subscriptionPrices', {
283
+ method: 'POST',
284
+ body: JSON.stringify(body),
285
+ });
286
+ return res?.data?.id ? { ok: true, id: res.data.id } : { ok: true };
287
+ }
288
+ catch (err) {
289
+ const e = err;
290
+ return { ok: false, error: e.message ?? String(err) };
291
+ }
292
+ }
293
+ export function registerPpp(server, client) {
294
+ server.registerTool('ppp_load_index', {
295
+ title: 'Load Apple Music PPP index',
296
+ description: 'Returns the bundled Apple Music Individual plan price snapshot used by the ppp_* tools. Refresh by editing data/apple-music-prices.json upstream.',
297
+ inputSchema: {
298
+ raw: z.boolean().default(false),
299
+ },
300
+ }, async ({ raw }) => {
301
+ const index = loadIndex();
302
+ if (raw) {
303
+ return { content: [{ type: 'text', text: JSON.stringify(index, null, 2) }] };
304
+ }
305
+ const columns = [
306
+ { header: 'TERR' },
307
+ { header: 'CCY' },
308
+ { header: 'AM_PRICE', align: 'right' },
309
+ ];
310
+ const rows = [...index.prices]
311
+ .sort((a, b) => a.territory.localeCompare(b.territory))
312
+ .map((p) => [p.territory, p.currency, fmtMoney(p.individualPrice)]);
313
+ const text = `Apple Music index — snapshot ${index.snapshot}, anchor ${index.anchor}, ${index.prices.length} territories\n\n${formatTable(columns, rows)}`;
314
+ return { content: [{ type: 'text', text }] };
315
+ });
316
+ server.registerTool('ppp_compute_proposal', {
317
+ title: 'Compute PPP rebalance proposal',
318
+ description: 'Compute a proposed per-territory price schedule for a subscription, using the bundled Apple Music index as the PPP signal. Read-only — does not write to App Store Connect. Pair with ppp_apply_proposal to schedule the changes.',
319
+ inputSchema: {
320
+ subscriptionId: SubscriptionIdSchema,
321
+ basePriceAnchor: z
322
+ .number()
323
+ .positive()
324
+ .describe('Anchor-territory base price (e.g. 29.99 USD).'),
325
+ anchorTerritory: z.string().length(3).default('USA'),
326
+ roundStrategy: z.enum(['nearest', 'down', 'up']).default('nearest'),
327
+ floorFactor: z
328
+ .number()
329
+ .min(0)
330
+ .max(1)
331
+ .default(0.15)
332
+ .describe('Lower bound on the proposed price as a fraction of current. 0 disables.'),
333
+ skipUnchanged: z
334
+ .boolean()
335
+ .default(true)
336
+ .describe('Hide rows where the snapped target equals the current price.'),
337
+ territories: z
338
+ .array(z.string().length(3))
339
+ .optional()
340
+ .describe('Restrict the proposal to a subset of territories. Omit to compute all.'),
341
+ skipMissingIndex: z
342
+ .boolean()
343
+ .default(true)
344
+ .describe('Skip territories for which Apple Music data is not in the bundled index. Set false to surface them as `no-index`.'),
345
+ raw: z.boolean().default(false),
346
+ },
347
+ }, async (args) => {
348
+ const ctx = await computeProposal(client, {
349
+ subscriptionId: args.subscriptionId,
350
+ basePriceAnchor: args.basePriceAnchor,
351
+ anchorTerritory: args.anchorTerritory,
352
+ roundStrategy: args.roundStrategy,
353
+ floorFactor: args.floorFactor,
354
+ skipUnchanged: args.skipUnchanged,
355
+ ...(args.territories ? { territories: args.territories } : {}),
356
+ skipMissingIndex: args.skipMissingIndex,
357
+ });
358
+ if (args.raw) {
359
+ return {
360
+ content: [{ type: 'text', text: JSON.stringify(ctx, null, 2) }],
361
+ };
362
+ }
363
+ const table = renderProposalTable(ctx, args.subscriptionId);
364
+ const footer = '\n\nDry-run only. To apply: call ppp_apply_proposal with the same args, or call asc_post_subscription_price per row using the POINT_IDs above.';
365
+ return { content: [{ type: 'text', text: `${table}${footer}` }] };
366
+ });
367
+ server.registerTool('ppp_apply_proposal', {
368
+ title: 'Apply PPP rebalance proposal',
369
+ description: 'Compute a PPP rebalance proposal, then schedule the price changes against App Store Connect. By default, asks the user to confirm via MCP elicitation before any write. Pass confirm:true to bypass elicitation (useful when running under automation, or when the client does not support elicitation).',
370
+ inputSchema: {
371
+ subscriptionId: SubscriptionIdSchema,
372
+ basePriceAnchor: z.number().positive(),
373
+ anchorTerritory: z.string().length(3).default('USA'),
374
+ roundStrategy: z.enum(['nearest', 'down', 'up']).default('nearest'),
375
+ floorFactor: z.number().min(0).max(1).default(0.15),
376
+ territories: z.array(z.string().length(3)).optional(),
377
+ skipMissingIndex: z.boolean().default(true),
378
+ startDate: z
379
+ .string()
380
+ .regex(/^\d{4}-\d{2}-\d{2}$/, 'Must be YYYY-MM-DD')
381
+ .optional()
382
+ .describe('Start date YYYY-MM-DD. Defaults to today + 7 days.'),
383
+ preserveCurrentPrice: z
384
+ .boolean()
385
+ .default(true)
386
+ .describe('Grandfather existing subscribers. Strongly recommended.'),
387
+ maxConcurrency: z
388
+ .number()
389
+ .int()
390
+ .min(1)
391
+ .max(20)
392
+ .default(2)
393
+ .describe('Parallel POSTs. Apple throttles writes globally (~50/min); the client retries on 429 with exponential backoff, so a low value avoids piling up retries.'),
394
+ maxDropPct: z
395
+ .number()
396
+ .min(0)
397
+ .max(100)
398
+ .default(90)
399
+ .describe('Refuse to apply if any row drops by more than this percentage. Sanity guard against bad index data.'),
400
+ confirm: z
401
+ .boolean()
402
+ .default(false)
403
+ .describe('Skip MCP elicitation and apply directly. Use only when the client lacks elicitation support, or in automation.'),
404
+ },
405
+ }, async (args) => {
406
+ const startDate = args.startDate ?? todayPlusDaysISO(7);
407
+ const ctx = await computeProposal(client, {
408
+ subscriptionId: args.subscriptionId,
409
+ basePriceAnchor: args.basePriceAnchor,
410
+ anchorTerritory: args.anchorTerritory,
411
+ roundStrategy: args.roundStrategy,
412
+ floorFactor: args.floorFactor,
413
+ skipUnchanged: true,
414
+ ...(args.territories ? { territories: args.territories } : {}),
415
+ skipMissingIndex: args.skipMissingIndex,
416
+ });
417
+ const writable = ctx.rows.filter((r) => r.reason === 'change' && r.snappedPointId !== undefined);
418
+ if (writable.length === 0) {
419
+ return {
420
+ content: [
421
+ {
422
+ type: 'text',
423
+ text: `${renderProposalTable(ctx, args.subscriptionId)}\n\nNothing to apply — no eligible rows. (Skipped: no-current-price, no-index, no-price-points, snap-failed, unchanged.)`,
424
+ },
425
+ ],
426
+ };
427
+ }
428
+ const maxDropRow = writable.reduce((acc, r) => {
429
+ if ((r.changePct ?? 0) >= 0)
430
+ return acc;
431
+ if (!acc || (r.changePct ?? 0) < (acc.changePct ?? 0))
432
+ return r;
433
+ return acc;
434
+ }, undefined);
435
+ if (maxDropRow && Math.abs(maxDropRow.changePct ?? 0) > args.maxDropPct) {
436
+ return {
437
+ content: [
438
+ {
439
+ type: 'text',
440
+ text: `${renderProposalTable(ctx, args.subscriptionId)}\n\nRefused to apply: ${maxDropRow.territory} drops by ${fmtPct(maxDropRow.changePct)}, which exceeds maxDropPct=${args.maxDropPct}. Either raise maxDropPct, restrict the run to specific territories, or refresh the Apple Music snapshot.`,
441
+ },
442
+ ],
443
+ };
444
+ }
445
+ const changes = writable.length;
446
+ const drops = writable.filter((r) => (r.changePct ?? 0) < 0).length;
447
+ const lifts = writable.filter((r) => (r.changePct ?? 0) > 0).length;
448
+ // Confirmation: try MCP elicitation first; if it fails or returns
449
+ // !accept, honour the user's choice. confirm:true bypasses entirely.
450
+ let confirmed = args.confirm;
451
+ let confirmationSource = args.confirm
452
+ ? 'arg'
453
+ : 'auto-fallback';
454
+ if (!confirmed) {
455
+ try {
456
+ const elicit = await server.server.elicitInput({
457
+ message: `Apply ${changes} subscription price change${changes === 1 ? '' : 's'} (${drops} drop${drops === 1 ? '' : 's'}, ${lifts} lift${lifts === 1 ? '' : 's'})?\n\nSubscription: ${args.subscriptionId}\nStart date: ${startDate}\nPreserve: ${args.preserveCurrentPrice}\nLargest drop: ${maxDropRow ? `${maxDropRow.territory} ${fmtPct(maxDropRow.changePct)}` : 'none'}\n\n${renderProposalTable(ctx, args.subscriptionId, { pointIdMode: 'none' })}`,
458
+ requestedSchema: {
459
+ type: 'object',
460
+ properties: {
461
+ acknowledge: {
462
+ type: 'boolean',
463
+ title: 'I have reviewed the proposal above',
464
+ description: 'Tick to enable Apply.',
465
+ },
466
+ },
467
+ required: ['acknowledge'],
468
+ },
469
+ });
470
+ if (elicit.action === 'accept' && elicit.content?.['acknowledge'] === true) {
471
+ confirmed = true;
472
+ confirmationSource = 'elicitation';
473
+ }
474
+ else {
475
+ return {
476
+ content: [
477
+ {
478
+ type: 'text',
479
+ text: `${renderProposalTable(ctx, args.subscriptionId)}\n\nCancelled by user (${elicit.action}). No writes performed.`,
480
+ },
481
+ ],
482
+ };
483
+ }
484
+ }
485
+ catch {
486
+ // Client doesn't support elicitation — surface the proposal and
487
+ // tell the caller to re-run with confirm:true.
488
+ return {
489
+ content: [
490
+ {
491
+ type: 'text',
492
+ text: `${renderProposalTable(ctx, args.subscriptionId)}\n\nClient does not support MCP elicitation. To apply, re-run with confirm: true (and the same args) — only after a human has reviewed the table above.`,
493
+ },
494
+ ],
495
+ };
496
+ }
497
+ }
498
+ // Apply.
499
+ const applyResults = await concurrentMap(writable, args.maxConcurrency, async (row) => {
500
+ const result = await postSubscriptionPrice(client, {
501
+ subscriptionId: args.subscriptionId,
502
+ territoryId: row.territory,
503
+ pricePointId: row.snappedPointId,
504
+ startDate,
505
+ preserveCurrentPrice: args.preserveCurrentPrice,
506
+ });
507
+ if (result.ok) {
508
+ return {
509
+ territory: row.territory,
510
+ pricePointId: row.snappedPointId,
511
+ status: 'applied',
512
+ ...(result.id ? { newPriceId: result.id } : {}),
513
+ };
514
+ }
515
+ return {
516
+ territory: row.territory,
517
+ pricePointId: row.snappedPointId,
518
+ status: 'failed',
519
+ error: result.error,
520
+ };
521
+ });
522
+ const succeeded = applyResults.filter((r) => r.status === 'applied');
523
+ const failed = applyResults.filter((r) => r.status === 'failed');
524
+ const resultColumns = [
525
+ { header: 'TERR' },
526
+ { header: 'STATUS' },
527
+ { header: 'PRICE_ID_OR_ERROR' },
528
+ ];
529
+ const resultRows = applyResults.map((r) => [
530
+ r.territory,
531
+ r.status,
532
+ r.status === 'applied' ? (r.newPriceId ?? '') : (r.error ?? ''),
533
+ ]);
534
+ const summary = `Applied ${succeeded.length}/${changes} (failed ${failed.length}). Subscription ${args.subscriptionId}, start ${startDate}, confirmation via ${confirmationSource}.`;
535
+ const text = `${summary}\n\n${formatTable(resultColumns, resultRows)}\n\nVerify with asc_list_subscription_prices — pending entries will have a non-null START_DATE.`;
536
+ return { content: [{ type: 'text', text }] };
537
+ });
538
+ }
539
+ //# sourceMappingURL=ppp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ppp.js","sourceRoot":"","sources":["../../src/domains/ppp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ASCClient } from '../client.js';
3
+ export declare function registerPricing(server: McpServer, client: ASCClient): void;
4
+ //# sourceMappingURL=pricing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.d.ts","sourceRoot":"","sources":["../../src/domains/pricing.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAS9C,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CAmE1E"}
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ import { PricePointIdSchema, StartDateSchema, SubscriptionIdSchema, SubscriptionPriceIdSchema, TerritoryIdSchema, } from '../schemas.js';
3
+ export function registerPricing(server, client) {
4
+ server.registerTool('asc_post_subscription_price', {
5
+ title: 'Schedule a subscription price change',
6
+ description: 'Schedule a price change for a single (subscription, territory) on a future date. ' +
7
+ 'Always pass preserveCurrentPrice=true unless you intend to re-price existing subscribers. ' +
8
+ 'Apple requires startDate ≥ today + 24h; this server defaults to ≥7 days for safety.',
9
+ inputSchema: {
10
+ subscriptionId: SubscriptionIdSchema,
11
+ territoryId: TerritoryIdSchema,
12
+ pricePointId: PricePointIdSchema,
13
+ startDate: StartDateSchema,
14
+ preserveCurrentPrice: z
15
+ .boolean()
16
+ .default(true)
17
+ .describe('Grandfather existing subscribers at their current price. Strongly recommended.'),
18
+ },
19
+ }, async ({ subscriptionId, territoryId, pricePointId, startDate, preserveCurrentPrice }) => {
20
+ const body = {
21
+ data: {
22
+ type: 'subscriptionPrices',
23
+ attributes: {
24
+ startDate,
25
+ preserveCurrentPrice,
26
+ },
27
+ relationships: {
28
+ subscription: { data: { type: 'subscriptions', id: subscriptionId } },
29
+ subscriptionPricePoint: {
30
+ data: { type: 'subscriptionPricePoints', id: pricePointId },
31
+ },
32
+ territory: { data: { type: 'territories', id: territoryId } },
33
+ },
34
+ },
35
+ };
36
+ const data = await client.request('/v1/subscriptionPrices', {
37
+ method: 'POST',
38
+ body: JSON.stringify(body),
39
+ });
40
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
41
+ });
42
+ server.registerTool('asc_delete_subscription_price', {
43
+ title: 'Cancel a pending subscription price change',
44
+ description: 'Delete a pending scheduled subscription price by ID. Use this to roll back a change that has not yet activated.',
45
+ inputSchema: {
46
+ subscriptionPriceId: SubscriptionPriceIdSchema,
47
+ },
48
+ }, async ({ subscriptionPriceId }) => {
49
+ await client.request(`/v1/subscriptionPrices/${encodeURIComponent(subscriptionPriceId)}`, { method: 'DELETE' });
50
+ return {
51
+ content: [{ type: 'text', text: `Deleted scheduled price ${subscriptionPriceId}.` }],
52
+ };
53
+ });
54
+ }
55
+ //# sourceMappingURL=pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pricing.js","sourceRoot":"","sources":["../../src/domains/pricing.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,yBAAyB,EACzB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAEvB,MAAM,UAAU,eAAe,CAAC,MAAiB,EAAE,MAAiB;IAClE,MAAM,CAAC,YAAY,CACjB,6BAA6B,EAC7B;QACE,KAAK,EAAE,sCAAsC;QAC7C,WAAW,EACT,mFAAmF;YACnF,4FAA4F;YAC5F,qFAAqF;QACvF,WAAW,EAAE;YACX,cAAc,EAAE,oBAAoB;YACpC,WAAW,EAAE,iBAAiB;YAC9B,YAAY,EAAE,kBAAkB;YAChC,SAAS,EAAE,eAAe;YAC1B,oBAAoB,EAAE,CAAC;iBACpB,OAAO,EAAE;iBACT,OAAO,CAAC,IAAI,CAAC;iBACb,QAAQ,CACP,gFAAgF,CACjF;SACJ;KACF,EACD,KAAK,EAAE,EAAE,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,SAAS,EAAE,oBAAoB,EAAE,EAAE,EAAE;QACvF,MAAM,IAAI,GAAG;YACX,IAAI,EAAE;gBACJ,IAAI,EAAE,oBAAoB;gBAC1B,UAAU,EAAE;oBACV,SAAS;oBACT,oBAAoB;iBACrB;gBACD,aAAa,EAAE;oBACb,YAAY,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,EAAE,cAAc,EAAE,EAAE;oBACrE,sBAAsB,EAAE;wBACtB,IAAI,EAAE,EAAE,IAAI,EAAE,yBAAyB,EAAE,EAAE,EAAE,YAAY,EAAE;qBAC5D;oBACD,SAAS,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE;iBAC9D;aACF;SACF,CAAC;QACF,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,OAAO,CAAU,wBAAwB,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;SAC3B,CAAC,CAAC;QACH,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IAC9E,CAAC,CACF,CAAC;IAEF,MAAM,CAAC,YAAY,CACjB,+BAA+B,EAC/B;QACE,KAAK,EAAE,4CAA4C;QACnD,WAAW,EACT,iHAAiH;QACnH,WAAW,EAAE;YACX,mBAAmB,EAAE,yBAAyB;SAC/C;KACF,EACD,KAAK,EAAE,EAAE,mBAAmB,EAAE,EAAE,EAAE;QAChC,MAAM,MAAM,CAAC,OAAO,CAClB,0BAA0B,kBAAkB,CAAC,mBAAmB,CAAC,EAAE,EACnE,EAAE,MAAM,EAAE,QAAQ,EAAE,CACrB,CAAC;QACF,OAAO;YACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,mBAAmB,GAAG,EAAE,CAAC;SACrF,CAAC;IACJ,CAAC,CACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { ASCClient } from '../client.js';
3
+ export declare function registerSubscriptions(server: McpServer, client: ASCClient): void;
4
+ //# sourceMappingURL=subscriptions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subscriptions.d.ts","sourceRoot":"","sources":["../../src/domains/subscriptions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAuB9C,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,GAAG,IAAI,CA0GhF"}