@capivv/mcp-server 0.1.3 → 0.5.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.
Files changed (141) hide show
  1. package/README.md +73 -2
  2. package/dist/client.d.ts +62 -3
  3. package/dist/client.js +220 -5
  4. package/dist/config.js +1 -1
  5. package/dist/http.d.ts +12 -0
  6. package/dist/http.js +102 -0
  7. package/dist/resources/guides.d.ts +2 -0
  8. package/dist/resources/guides.js +81 -0
  9. package/dist/resources/index.js +4 -0
  10. package/dist/resources/quickstart.d.ts +2 -0
  11. package/dist/resources/quickstart.js +173 -0
  12. package/dist/resources/rules.js +8 -2
  13. package/dist/tools/activate-rule.d.ts +3 -0
  14. package/dist/tools/activate-rule.js +9 -0
  15. package/dist/tools/api-key-usage.d.ts +3 -0
  16. package/dist/tools/api-key-usage.js +70 -0
  17. package/dist/tools/apply-rule.js +54 -13
  18. package/dist/tools/approve-change-request.d.ts +3 -0
  19. package/dist/tools/approve-change-request.js +16 -0
  20. package/dist/tools/archive-app.d.ts +3 -0
  21. package/dist/tools/archive-app.js +9 -0
  22. package/dist/tools/autopilot-status.d.ts +3 -0
  23. package/dist/tools/autopilot-status.js +117 -0
  24. package/dist/tools/check-drift.d.ts +3 -0
  25. package/dist/tools/check-drift.js +21 -0
  26. package/dist/tools/create-app.d.ts +3 -0
  27. package/dist/tools/create-app.js +13 -0
  28. package/dist/tools/create-entitlement.d.ts +3 -0
  29. package/dist/tools/create-entitlement.js +11 -0
  30. package/dist/tools/create-experiment.d.ts +3 -0
  31. package/dist/tools/create-experiment.js +43 -0
  32. package/dist/tools/create-paywall.d.ts +3 -0
  33. package/dist/tools/create-paywall.js +18 -0
  34. package/dist/tools/create-pricing-strategy.d.ts +3 -0
  35. package/dist/tools/create-pricing-strategy.js +49 -0
  36. package/dist/tools/create-product.d.ts +3 -0
  37. package/dist/tools/create-product.js +77 -0
  38. package/dist/tools/create-promotion.d.ts +3 -0
  39. package/dist/tools/create-promotion.js +35 -0
  40. package/dist/tools/create-rescue-flow.d.ts +3 -0
  41. package/dist/tools/create-rescue-flow.js +20 -0
  42. package/dist/tools/delete-app.d.ts +3 -0
  43. package/dist/tools/delete-app.js +9 -0
  44. package/dist/tools/delete-entitlement.d.ts +3 -0
  45. package/dist/tools/delete-entitlement.js +11 -0
  46. package/dist/tools/delete-paywall.d.ts +3 -0
  47. package/dist/tools/delete-paywall.js +16 -0
  48. package/dist/tools/delete-product.d.ts +3 -0
  49. package/dist/tools/delete-product.js +9 -0
  50. package/dist/tools/delete-promotion.d.ts +3 -0
  51. package/dist/tools/delete-promotion.js +11 -0
  52. package/dist/tools/delete-rescue-flow.d.ts +3 -0
  53. package/dist/tools/delete-rescue-flow.js +11 -0
  54. package/dist/tools/delete-rule.d.ts +3 -0
  55. package/dist/tools/delete-rule.js +9 -0
  56. package/dist/tools/get-entitlement.d.ts +3 -0
  57. package/dist/tools/get-entitlement.js +9 -0
  58. package/dist/tools/get-experiment-summary.d.ts +3 -0
  59. package/dist/tools/get-experiment-summary.js +9 -0
  60. package/dist/tools/get-offering.d.ts +3 -0
  61. package/dist/tools/get-offering.js +9 -0
  62. package/dist/tools/get-paywall-stats.d.ts +3 -0
  63. package/dist/tools/get-paywall-stats.js +6 -0
  64. package/dist/tools/get-product.d.ts +3 -0
  65. package/dist/tools/get-product.js +9 -0
  66. package/dist/tools/get-rescue-stats.d.ts +3 -0
  67. package/dist/tools/get-rescue-stats.js +12 -0
  68. package/dist/tools/get-rule.d.ts +3 -0
  69. package/dist/tools/get-rule.js +9 -0
  70. package/dist/tools/import-products.js +7 -5
  71. package/dist/tools/index.js +143 -1
  72. package/dist/tools/list-change-requests.d.ts +3 -0
  73. package/dist/tools/list-change-requests.js +14 -0
  74. package/dist/tools/list-entitlements.d.ts +3 -0
  75. package/dist/tools/list-entitlements.js +6 -0
  76. package/dist/tools/list-paywalls.d.ts +3 -0
  77. package/dist/tools/list-paywalls.js +6 -0
  78. package/dist/tools/list-pricing-strategies.d.ts +3 -0
  79. package/dist/tools/list-pricing-strategies.js +8 -0
  80. package/dist/tools/list-promotions.d.ts +3 -0
  81. package/dist/tools/list-promotions.js +6 -0
  82. package/dist/tools/list-rescue-flows.d.ts +3 -0
  83. package/dist/tools/list-rescue-flows.js +6 -0
  84. package/dist/tools/list-rule-versions.d.ts +3 -0
  85. package/dist/tools/list-rule-versions.js +9 -0
  86. package/dist/tools/list-rules.js +4 -2
  87. package/dist/tools/next-step.d.ts +3 -0
  88. package/dist/tools/next-step.js +123 -0
  89. package/dist/tools/preview-pricing.d.ts +3 -0
  90. package/dist/tools/preview-pricing.js +13 -0
  91. package/dist/tools/push-prices-to-stores.d.ts +3 -0
  92. package/dist/tools/push-prices-to-stores.js +9 -0
  93. package/dist/tools/recompute-prices.d.ts +3 -0
  94. package/dist/tools/recompute-prices.js +24 -0
  95. package/dist/tools/resolve-drift.d.ts +3 -0
  96. package/dist/tools/resolve-drift.js +15 -0
  97. package/dist/tools/restore-app.d.ts +3 -0
  98. package/dist/tools/restore-app.js +9 -0
  99. package/dist/tools/revert-app-autopilot.d.ts +3 -0
  100. package/dist/tools/revert-app-autopilot.js +9 -0
  101. package/dist/tools/rollback-rule.d.ts +3 -0
  102. package/dist/tools/rollback-rule.js +10 -0
  103. package/dist/tools/run-app-autopilot.d.ts +3 -0
  104. package/dist/tools/run-app-autopilot.js +9 -0
  105. package/dist/tools/set-country-price-override.d.ts +3 -0
  106. package/dist/tools/set-country-price-override.js +13 -0
  107. package/dist/tools/setup-wizard.d.ts +3 -0
  108. package/dist/tools/setup-wizard.js +259 -0
  109. package/dist/tools/start-experiment.d.ts +3 -0
  110. package/dist/tools/start-experiment.js +9 -0
  111. package/dist/tools/status.js +25 -1
  112. package/dist/tools/stop-experiment.d.ts +3 -0
  113. package/dist/tools/stop-experiment.js +9 -0
  114. package/dist/tools/sync-suggestions-count.d.ts +3 -0
  115. package/dist/tools/sync-suggestions-count.js +6 -0
  116. package/dist/tools/trigger-sync.d.ts +3 -0
  117. package/dist/tools/trigger-sync.js +6 -0
  118. package/dist/tools/update-app.d.ts +3 -0
  119. package/dist/tools/update-app.js +19 -0
  120. package/dist/tools/update-entitlement.d.ts +3 -0
  121. package/dist/tools/update-entitlement.js +13 -0
  122. package/dist/tools/update-experiment.d.ts +3 -0
  123. package/dist/tools/update-experiment.js +22 -0
  124. package/dist/tools/update-offering.d.ts +3 -0
  125. package/dist/tools/update-offering.js +31 -0
  126. package/dist/tools/update-paywall.d.ts +3 -0
  127. package/dist/tools/update-paywall.js +23 -0
  128. package/dist/tools/update-product.d.ts +3 -0
  129. package/dist/tools/update-product.js +16 -0
  130. package/dist/tools/update-promotion.d.ts +3 -0
  131. package/dist/tools/update-promotion.js +20 -0
  132. package/dist/tools/update-rescue-flow.d.ts +3 -0
  133. package/dist/tools/update-rescue-flow.js +27 -0
  134. package/dist/tools/verify-setup.d.ts +3 -0
  135. package/dist/tools/verify-setup.js +200 -0
  136. package/dist/tools/whoami.d.ts +3 -0
  137. package/dist/tools/whoami.js +31 -0
  138. package/dist/types.d.ts +417 -79
  139. package/dist/types.js +0 -2
  140. package/mcp.json +89 -0
  141. package/package.json +8 -2
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ export function registerCreateExperimentTool(server, client) {
3
+ server.tool('capivv_create_experiment', [
4
+ 'Create an A/B experiment with variants. Variants split traffic by `traffic_percent` (must sum to 100). Exactly one variant should have `is_control: true`.',
5
+ 'Common metrics: "paywall_conversion", "trial_to_paid", "arpu". `entity_type` + `entity_id` scope the experiment to a specific paywall, product, or pricing strategy.',
6
+ 'New experiments start in `draft` status — call capivv_start_experiment to enroll users.',
7
+ ].join(' '), {
8
+ name: z.string().describe('Display name'),
9
+ description: z.string().optional().describe('Optional description'),
10
+ target_metric: z
11
+ .string()
12
+ .describe('Metric to optimize (e.g. "paywall_conversion", "trial_to_paid", "arpu")'),
13
+ entity_type: z
14
+ .string()
15
+ .optional()
16
+ .describe('Scope: "paywall", "product", "pricing_strategy", etc.'),
17
+ entity_id: z.string().optional().describe('ID of the scoped entity'),
18
+ start_date: z.string().optional().describe('ISO 8601 start timestamp'),
19
+ end_date: z.string().optional().describe('ISO 8601 end timestamp'),
20
+ sample_size_target: z
21
+ .number()
22
+ .optional()
23
+ .describe('Target sample size before considering the experiment conclusive'),
24
+ confidence_level: z.number().optional().describe('Confidence level (e.g. 95). Defaults to 95.'),
25
+ metadata: z.record(z.string(), z.unknown()).optional().describe('Free-form metadata'),
26
+ variants: z
27
+ .array(z.object({
28
+ name: z.string().describe('Variant name (e.g. "Control", "Variant A")'),
29
+ is_control: z.boolean().describe('Exactly one variant should be the control.'),
30
+ traffic_percent: z
31
+ .number()
32
+ .describe('Traffic allocation percentage (0-100). Sum across variants must be 100.'),
33
+ config: z
34
+ .record(z.string(), z.unknown())
35
+ .optional()
36
+ .describe('Variant-specific overrides (paywall config, price, etc.)'),
37
+ }))
38
+ .describe('Variants to create with the experiment'),
39
+ }, async (args) => {
40
+ const exp = await client.createExperiment(args);
41
+ return { content: [{ type: 'text', text: JSON.stringify(exp, null, 2) }] };
42
+ });
43
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerCreatePaywallTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ export function registerCreatePaywallTool(server, client) {
3
+ server.tool('capivv_create_paywall', [
4
+ 'Create a new paywall on a Capivv app.',
5
+ 'paywall_type controls behavior: "hard" (block until purchase), "soft" (skippable), "upsell" (offer to existing users), or "promo" (limited-time offer).',
6
+ 'Use capivv_update_paywall after creation to attach a template, configure the layout, or schedule A/B variants — those are not part of the create call.',
7
+ ].join(' '), {
8
+ app_id: z.string().describe('App ID this paywall belongs to'),
9
+ name: z.string().describe('Display name shown in the dashboard (e.g. "Onboarding paywall")'),
10
+ identifier: z
11
+ .string()
12
+ .describe('Stable identifier the SDK uses to fetch this paywall (e.g. "onboarding_v2")'),
13
+ paywall_type: z.string().describe('One of: hard, soft, upsell, promo'),
14
+ }, async (args) => {
15
+ const paywall = await client.createPaywall(args);
16
+ return { content: [{ type: 'text', text: JSON.stringify(paywall, null, 2) }] };
17
+ });
18
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerCreatePricingStrategyTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,49 @@
1
+ import { z } from 'zod';
2
+ export function registerCreatePricingStrategyTool(server, client) {
3
+ server.tool('capivv_create_pricing_strategy', [
4
+ 'Create a localized pricing strategy for an app.',
5
+ 'Combines three signals — Purchasing Power Parity (PPP), Big Mac index, and FX-neutral conversion — using configurable weights to derive a country price.',
6
+ 'Affordability is then clamped per income tier (1–4) so emerging markets don\'t collapse to pennies and rich markets don\'t inflate above the base price.',
7
+ 'Guardrails (`max_auto_change_pct`, `max_auto_decrease_pct`) block changes that exceed the threshold; those go to a change-request queue instead of auto-applying.',
8
+ 'Defaults work fine for most cases — start with just `app_id` and `name`.',
9
+ ].join(' '), {
10
+ app_id: z.string().describe('App ID this strategy applies to'),
11
+ name: z.string().describe('Display name (e.g. "Worldwide PPP-blended pricing")'),
12
+ w_ppp: z.number().optional().describe('PPP weight (0-1). Default 0.6.'),
13
+ w_bigmac: z.number().optional().describe('Big Mac index weight (0-1). Default 0.2.'),
14
+ w_fx_neutral: z
15
+ .number()
16
+ .optional()
17
+ .describe('FX-neutral weight (0-1). Default 0.2. The three weights should sum to ~1.0.'),
18
+ tier1_min_aff: z
19
+ .number()
20
+ .optional()
21
+ .describe('Minimum affordability for tier 1 (lowest income). Default 0.25.'),
22
+ tier1_max_aff: z.number().optional().describe('Maximum affordability for tier 1.'),
23
+ tier2_min_aff: z.number().optional().describe('Minimum affordability for tier 2.'),
24
+ tier2_max_aff: z.number().optional().describe('Maximum affordability for tier 2.'),
25
+ tier3_min_aff: z.number().optional().describe('Minimum affordability for tier 3.'),
26
+ tier3_max_aff: z.number().optional().describe('Maximum affordability for tier 3.'),
27
+ tier4_min_aff: z.number().optional().describe('Minimum affordability for tier 4.'),
28
+ tier4_max_aff: z.number().optional().describe('Maximum affordability for tier 4.'),
29
+ anti_arbitrage_floor_factor: z
30
+ .number()
31
+ .optional()
32
+ .describe('Floor multiplier (e.g. 0.5 means prices can\'t go below 50% of base).'),
33
+ max_auto_change_pct: z
34
+ .number()
35
+ .optional()
36
+ .describe('Max % change auto-applied without approval. Larger changes go to change requests.'),
37
+ max_auto_decrease_pct: z
38
+ .number()
39
+ .optional()
40
+ .describe('Max % decrease auto-applied (prevents accidental fire-sale pricing).'),
41
+ excluded_countries: z
42
+ .array(z.string())
43
+ .optional()
44
+ .describe('ISO country codes to skip (manual pricing only).'),
45
+ }, async (args) => {
46
+ const strategy = await client.createPricingStrategy(args);
47
+ return { content: [{ type: 'text', text: JSON.stringify(strategy, null, 2) }] };
48
+ });
49
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerCreateProductTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod';
2
+ export function registerCreateProductTool(server, client) {
3
+ server.tool('capivv_create_product', [
4
+ 'Create a subscription, consumable, or non-consumable product end-to-end.',
5
+ 'By default this creates the Capivv-side product record AND the matching subscription / IAP in App Store Connect or Google Play (whichever store is connected for the app).',
6
+ 'If the requested price does not match a store tier exactly, Capivv snaps to the nearest valid tier and returns both the requested and the actual price so you can show the customer the delta.',
7
+ 'Pass `skip_store_write: true` to opt out of the store-side write — only useful when migrating an existing store-side product into Capivv (rare).',
8
+ '',
9
+ 'On success the response includes a `store_create` block with the store-side product ID and snapped prices. On store failure the Capivv-side record is rolled back and the verbatim store error is returned.',
10
+ ].join(' '), {
11
+ app_id: z.string().describe('App ID this product belongs to'),
12
+ external_id: z.string().describe('Store product ID (e.g., "com.example.pro_monthly")'),
13
+ product_type: z.string().describe('One of: subscription, consumable, non_consumable'),
14
+ display_name: z.string().describe('Human-readable product name'),
15
+ description: z.string().optional().describe('Optional product description'),
16
+ entitlement_ids: z
17
+ .array(z.string())
18
+ .optional()
19
+ .describe('Entitlement IDs this product grants upon purchase'),
20
+ subscription: z
21
+ .object({
22
+ billing_period: z
23
+ .string()
24
+ .describe('Billing period: week, month, three_months, six_months, or year'),
25
+ grace_period_enabled: z.boolean().optional().describe('Enable grace period for failed renewals'),
26
+ })
27
+ .optional()
28
+ .describe('Subscription configuration (required for subscription products)'),
29
+ prices: z
30
+ .array(z.object({
31
+ currency: z.string().describe('ISO 4217 currency code (e.g., "USD")'),
32
+ amount_cents: z.number().describe('Price in cents (e.g., 1099 for $10.99)'),
33
+ is_default: z.boolean().optional().describe('Whether this is the default price'),
34
+ }))
35
+ .optional()
36
+ .describe('Product prices'),
37
+ skip_store_write: z
38
+ .boolean()
39
+ .optional()
40
+ .describe('When true, only creates the Capivv-side record and skips writing to App Store Connect / Google Play. Use only when migrating an existing store-side product.'),
41
+ default_locale: z
42
+ .string()
43
+ .optional()
44
+ .describe('Locale used for store-side product localization. Defaults to "en-US".'),
45
+ }, async (args) => {
46
+ const { skip_store_write, ...rest } = args;
47
+ const product = await client.createProduct({
48
+ ...rest,
49
+ also_create_in_store: skip_store_write !== true,
50
+ });
51
+ const summary = formatStoreCreateSummary(product);
52
+ const text = summary
53
+ ? `${summary}\n\n${JSON.stringify(product, null, 2)}`
54
+ : JSON.stringify(product, null, 2);
55
+ return { content: [{ type: 'text', text }] };
56
+ });
57
+ }
58
+ function formatStoreCreateSummary(product) {
59
+ const sc = product.store_create;
60
+ if (!sc)
61
+ return null;
62
+ const lines = [];
63
+ lines.push(`Created ${product.display_name} on ${sc.store === 'apple' ? 'App Store Connect' : 'Google Play'} (id: ${sc.store_product_id}).`);
64
+ for (const sp of sc.snapped_prices) {
65
+ if (sp.requested_cents === sp.actual_cents) {
66
+ lines.push(` ${sp.currency}: ${formatCents(sp.actual_cents, sp.currency)} (matches your request exactly).`);
67
+ }
68
+ else {
69
+ lines.push(` ${sp.currency}: used ${formatCents(sp.actual_cents, sp.currency)} — closest store tier to your ${formatCents(sp.requested_cents, sp.currency)} request.`);
70
+ }
71
+ }
72
+ return lines.join('\n');
73
+ }
74
+ function formatCents(cents, currency) {
75
+ const major = (cents / 100).toFixed(2);
76
+ return `${major} ${currency}`;
77
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerCreatePromotionTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,35 @@
1
+ import { z } from 'zod';
2
+ export function registerCreatePromotionTool(server, client) {
3
+ server.tool('capivv_create_promotion', [
4
+ 'Create a promotion (flash sale, bundle, segmented offer, or referral campaign).',
5
+ 'campaign_type controls behavior: "flash_sale" (time-bound discount), "bundle" (multi-product offer), "segment" (target a user segment), "referral" (reward referrers).',
6
+ 'When starts_at / ends_at are omitted, the promotion runs for 30 days starting now.',
7
+ ].join(' '), {
8
+ name: z.string().describe('Display name (e.g. "Summer 20% off")'),
9
+ identifier: z
10
+ .string()
11
+ .optional()
12
+ .describe('Stable identifier the SDK can target (e.g. "summer_2026")'),
13
+ description: z.string().optional().describe('Free-form description'),
14
+ campaign_type: z.string().describe('One of: flash_sale, bundle, segment, referral'),
15
+ discount_percent: z
16
+ .number()
17
+ .optional()
18
+ .describe('Percentage discount (0-100). Omit for non-discount campaigns.'),
19
+ starts_at: z
20
+ .string()
21
+ .optional()
22
+ .describe('ISO 8601 start timestamp. Defaults to now.'),
23
+ ends_at: z
24
+ .string()
25
+ .optional()
26
+ .describe('ISO 8601 end timestamp. Defaults to now + 30 days.'),
27
+ max_redemptions: z
28
+ .number()
29
+ .optional()
30
+ .describe('Redemption cap across the workspace. Omit for unlimited.'),
31
+ }, async (args) => {
32
+ const promotion = await client.createPromotion(args);
33
+ return { content: [{ type: 'text', text: JSON.stringify(promotion, null, 2) }] };
34
+ });
35
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerCreateRescueFlowTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ export function registerCreateRescueFlowTool(server, client) {
3
+ server.tool('capivv_create_rescue_flow', [
4
+ 'Create a cancellation rescue flow. Triggered when a user attempts to cancel; runs the configured steps (reason capture, retention offers, deflection) in priority order.',
5
+ 'After creation, use capivv_update_rescue_flow to attach `conditions` (eligibility filters) and `steps` (the offer ladder) — both default to empty.',
6
+ ].join(' '), {
7
+ name: z.string().describe('Display name (e.g. "Annual rescue ladder")'),
8
+ identifier: z
9
+ .string()
10
+ .describe('Stable identifier the SDK uses to fetch this flow (e.g. "annual_rescue_v1")'),
11
+ description: z.string().optional().describe('Free-form description'),
12
+ priority: z
13
+ .number()
14
+ .optional()
15
+ .describe('Priority (higher runs first when multiple flows match). Defaults to 0.'),
16
+ }, async (args) => {
17
+ const flow = await client.createRescueFlow(args);
18
+ return { content: [{ type: 'text', text: JSON.stringify(flow, null, 2) }] };
19
+ });
20
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeleteAppTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerDeleteAppTool(server, client) {
3
+ server.tool('capivv_delete_app', 'Permanently delete an app and all its products, entitlements, prices, paywalls, etc. (cascades). Prefer capivv_archive_app for reversible removal.', {
4
+ app_id: z.string().describe('App ID to delete'),
5
+ }, async ({ app_id }) => {
6
+ await client.deleteApp(app_id);
7
+ return { content: [{ type: 'text', text: `App ${app_id} permanently deleted.` }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeleteEntitlementTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ export function registerDeleteEntitlementTool(server, client) {
3
+ server.tool('capivv_delete_entitlement', 'Delete an entitlement by ID. Cascades to grants and revocations. Will fail if the entitlement is still referenced by active products — detach them first.', {
4
+ entitlement_id: z.string().describe('Entitlement ID to delete'),
5
+ }, async ({ entitlement_id }) => {
6
+ await client.deleteEntitlement(entitlement_id);
7
+ return {
8
+ content: [{ type: 'text', text: `Entitlement ${entitlement_id} deleted.` }],
9
+ };
10
+ });
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeletePaywallTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export function registerDeletePaywallTool(server, client) {
3
+ server.tool('capivv_delete_paywall', 'Delete a paywall by ID. The paywall is removed from the dashboard and stops being served to clients. Use capivv_list_paywalls to find the paywall_id.', {
4
+ paywall_id: z.string().describe('Paywall ID to delete'),
5
+ }, async ({ paywall_id }) => {
6
+ await client.deletePaywall(paywall_id);
7
+ return {
8
+ content: [
9
+ {
10
+ type: 'text',
11
+ text: `Paywall ${paywall_id} deleted.`,
12
+ },
13
+ ],
14
+ };
15
+ });
16
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeleteProductTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerDeleteProductTool(server, client) {
3
+ server.tool('capivv_delete_product', 'Delete a product by ID. This is irreversible.', {
4
+ product_id: z.string().describe('Product ID to delete'),
5
+ }, async ({ product_id }) => {
6
+ await client.deleteProduct(product_id);
7
+ return { content: [{ type: 'text', text: `Product ${product_id} deleted.` }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeletePromotionTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ export function registerDeletePromotionTool(server, client) {
3
+ server.tool('capivv_delete_promotion', 'Delete a promotion by ID. Stops the promotion immediately and removes it from the dashboard. Active redemptions are preserved in the audit log. Use capivv_list_promotions to find the promotion_id.', {
4
+ promotion_id: z.string().describe('Promotion ID to delete'),
5
+ }, async ({ promotion_id }) => {
6
+ await client.deletePromotion(promotion_id);
7
+ return {
8
+ content: [{ type: 'text', text: `Promotion ${promotion_id} deleted.` }],
9
+ };
10
+ });
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeleteRescueFlowTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,11 @@
1
+ import { z } from 'zod';
2
+ export function registerDeleteRescueFlowTool(server, client) {
3
+ server.tool('capivv_delete_rescue_flow', 'Delete a rescue flow by ID. The flow stops running immediately. Historical rescue events remain in analytics. Use capivv_list_rescue_flows to find the rescue_flow_id.', {
4
+ rescue_flow_id: z.string().describe('Rescue flow ID to delete'),
5
+ }, async ({ rescue_flow_id }) => {
6
+ await client.deleteRescueFlow(rescue_flow_id);
7
+ return {
8
+ content: [{ type: 'text', text: `Rescue flow ${rescue_flow_id} deleted.` }],
9
+ };
10
+ });
11
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerDeleteRuleTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerDeleteRuleTool(server, client) {
3
+ server.tool('capivv_delete_rule', 'Delete a business rule by ID. This is irreversible.', {
4
+ rule_id: z.string().describe('Rule ID to delete'),
5
+ }, async ({ rule_id }) => {
6
+ await client.deleteRule(rule_id);
7
+ return { content: [{ type: 'text', text: `Rule ${rule_id} deleted.` }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetEntitlementTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerGetEntitlementTool(server, client) {
3
+ server.tool('capivv_get_entitlement', 'Get a single entitlement by ID. Use capivv_list_entitlements to find the entitlement_id.', {
4
+ entitlement_id: z.string().describe('Entitlement ID'),
5
+ }, async ({ entitlement_id }) => {
6
+ const ent = await client.getEntitlement(entitlement_id);
7
+ return { content: [{ type: 'text', text: JSON.stringify(ent, null, 2) }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetExperimentSummaryTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerGetExperimentSummaryTool(server, client) {
3
+ server.tool('capivv_get_experiment_summary', 'Get full details for a single experiment: its variants, sample sizes, conversion rates, statistical significance, and recommendations. Use capivv_list_experiments to find the experiment_id.', {
4
+ experiment_id: z.string().describe('Experiment ID'),
5
+ }, async ({ experiment_id }) => {
6
+ const exp = await client.getExperiment(experiment_id);
7
+ return { content: [{ type: 'text', text: JSON.stringify(exp, null, 2) }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetOfferingTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerGetOfferingTool(server, client) {
3
+ server.tool('capivv_get_offering', 'Get a single offering by ID with full package details. Use capivv_list_offerings to find the offering_id.', {
4
+ offering_id: z.string().describe('Offering ID'),
5
+ }, async ({ offering_id }) => {
6
+ const offering = await client.getOffering(offering_id);
7
+ return { content: [{ type: 'text', text: JSON.stringify(offering, null, 2) }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetPaywallStatsTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,6 @@
1
+ export function registerGetPaywallStatsTool(server, client) {
2
+ server.tool('capivv_get_paywall_stats', 'Get aggregated paywall stats for the workspace: total views, total conversions, and average conversion rate (across every paywall in the tenant). Use capivv_list_paywalls for per-paywall numbers.', async () => {
3
+ const stats = await client.getPaywallStats();
4
+ return { content: [{ type: 'text', text: JSON.stringify(stats, null, 2) }] };
5
+ });
6
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetProductTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerGetProductTool(server, client) {
3
+ server.tool('capivv_get_product', 'Get a single product by ID with full metadata, including the store_product_id when the product was created via Phase A end-to-end. Use capivv_list_products to find the product_id.', {
4
+ product_id: z.string().describe('Product ID'),
5
+ }, async ({ product_id }) => {
6
+ const product = await client.getProduct(product_id);
7
+ return { content: [{ type: 'text', text: JSON.stringify(product, null, 2) }] };
8
+ });
9
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetRescueStatsTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,12 @@
1
+ import { z } from 'zod';
2
+ export function registerGetRescueStatsTool(server, client) {
3
+ server.tool('capivv_get_rescue_stats', 'Get aggregated rescue stats for the workspace: total cancellation attempts, successful saves, save rate, and recovered revenue. Defaults to the last 30 days.', {
4
+ days: z
5
+ .number()
6
+ .optional()
7
+ .describe('Lookback window in days. Defaults to 30.'),
8
+ }, async ({ days }) => {
9
+ const stats = await client.getRescueStats(days ?? 30);
10
+ return { content: [{ type: 'text', text: JSON.stringify(stats, null, 2) }] };
11
+ });
12
+ }
@@ -0,0 +1,3 @@
1
+ import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import type { CapivvClient } from '../client.js';
3
+ export declare function registerGetRuleTool(server: McpServer, client: CapivvClient): void;
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ export function registerGetRuleTool(server, client) {
3
+ server.tool('capivv_get_rule', 'Get a single rule (entitlement-grant YAML logic) by ID. Use capivv_list_rules to find the rule_id.', {
4
+ rule_id: z.string().describe('Rule ID'),
5
+ }, async ({ rule_id }) => {
6
+ const rule = await client.getRuleById(rule_id);
7
+ return { content: [{ type: 'text', text: JSON.stringify(rule, null, 2) }] };
8
+ });
9
+ }
@@ -1,17 +1,19 @@
1
1
  import { z } from 'zod';
2
2
  export function registerImportProductsTool(server, client) {
3
3
  server.tool('capivv_import_products', 'Import products from connected App Store Connect or Google Play Console into Capivv. Returns a preview of what will be imported including suggested products, entitlements, and offerings.', { app_id: z.string().describe('App ID to import products for') }, async ({ app_id }) => {
4
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
4
5
  const preview = await client.getImportPreview(app_id);
5
- const newProducts = preview.suggestion.products.filter((p) => !p.already_exists);
6
- const newEntitlements = preview.suggestion.entitlements.filter((e) => !e.already_exists);
6
+ const suggestion = preview.suggestion ?? {};
7
+ const newProducts = (suggestion.products ?? []).filter((p) => !p.already_exists);
8
+ const newEntitlements = (suggestion.entitlements ?? []).filter((e) => !e.already_exists);
7
9
  const summary = {
8
10
  new_products: newProducts.length,
9
11
  new_entitlements: newEntitlements.length,
10
- new_offerings: preview.suggestion.offerings.length,
12
+ new_offerings: (suggestion.offerings ?? []).length,
11
13
  existing_counts: preview.existing_counts,
12
- warnings: preview.suggestion.warnings,
14
+ warnings: suggestion.warnings,
13
15
  store_errors: preview.store_errors,
14
- details: preview.suggestion,
16
+ details: suggestion,
15
17
  };
16
18
  return { content: [{ type: 'text', text: JSON.stringify(summary, null, 2) }] };
17
19
  });