@open-loyalty/mcp-server 1.0.2 → 1.1.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 (75) hide show
  1. package/dist/client/http.d.ts +5 -0
  2. package/dist/client/http.js +52 -3
  3. package/dist/config.d.ts +16 -2
  4. package/dist/config.js +28 -10
  5. package/dist/http.js +135 -62
  6. package/dist/server.js +8 -5
  7. package/dist/tools/achievement.d.ts +14 -0
  8. package/dist/tools/achievement.js +22 -15
  9. package/dist/tools/admin.d.ts +12 -0
  10. package/dist/tools/admin.js +12 -0
  11. package/dist/tools/analytics.d.ts +18 -0
  12. package/dist/tools/analytics.js +28 -19
  13. package/dist/tools/apikey.d.ts +7 -0
  14. package/dist/tools/apikey.js +7 -0
  15. package/dist/tools/audit.d.ts +4 -0
  16. package/dist/tools/audit.js +4 -0
  17. package/dist/tools/badge.d.ts +8 -0
  18. package/dist/tools/badge.js +13 -9
  19. package/dist/tools/campaign.d.ts +41 -16
  20. package/dist/tools/campaign.js +38 -25
  21. package/dist/tools/export.d.ts +8 -0
  22. package/dist/tools/export.js +13 -8
  23. package/dist/tools/import.d.ts +6 -0
  24. package/dist/tools/import.js +10 -6
  25. package/dist/tools/index.d.ts +3 -11
  26. package/dist/tools/index.js +4 -470
  27. package/dist/tools/member.d.ts +21 -0
  28. package/dist/tools/member.js +56 -62
  29. package/dist/tools/points.d.ts +12 -0
  30. package/dist/tools/points.js +30 -29
  31. package/dist/tools/reward.d.ts +18 -0
  32. package/dist/tools/reward.js +56 -66
  33. package/dist/tools/role.d.ts +20 -1
  34. package/dist/tools/role.js +13 -0
  35. package/dist/tools/segment.d.ts +19 -0
  36. package/dist/tools/segment.js +29 -19
  37. package/dist/tools/store.d.ts +8 -0
  38. package/dist/tools/store.js +8 -0
  39. package/dist/tools/tierset.d.ts +12 -0
  40. package/dist/tools/tierset.js +19 -13
  41. package/dist/tools/transaction.d.ts +12 -4
  42. package/dist/tools/transaction.js +13 -9
  43. package/dist/tools/wallet-type.d.ts +4 -0
  44. package/dist/tools/wallet-type.js +7 -5
  45. package/dist/tools/webhook.d.ts +17 -4
  46. package/dist/tools/webhook.js +58 -15
  47. package/dist/types/schemas/achievement.d.ts +0 -297
  48. package/dist/types/schemas/achievement.js +0 -13
  49. package/dist/types/schemas/admin.d.ts +10 -97
  50. package/dist/types/schemas/admin.js +0 -38
  51. package/dist/types/schemas/badge.d.ts +0 -37
  52. package/dist/types/schemas/badge.js +0 -11
  53. package/dist/types/schemas/campaign.d.ts +0 -648
  54. package/dist/types/schemas/campaign.js +0 -18
  55. package/dist/types/schemas/export.d.ts +0 -17
  56. package/dist/types/schemas/export.js +0 -7
  57. package/dist/types/schemas/member.d.ts +37 -176
  58. package/dist/types/schemas/member.js +0 -27
  59. package/dist/types/schemas/points.d.ts +0 -63
  60. package/dist/types/schemas/points.js +0 -22
  61. package/dist/types/schemas/reward.d.ts +0 -73
  62. package/dist/types/schemas/reward.js +0 -25
  63. package/dist/types/schemas/role.d.ts +0 -100
  64. package/dist/types/schemas/role.js +0 -29
  65. package/dist/types/schemas/segment.d.ts +0 -58
  66. package/dist/types/schemas/segment.js +0 -17
  67. package/dist/types/schemas/tierset.d.ts +0 -176
  68. package/dist/types/schemas/tierset.js +0 -27
  69. package/dist/types/schemas/transaction.d.ts +23 -254
  70. package/dist/types/schemas/transaction.js +0 -7
  71. package/dist/types/schemas/webhook.d.ts +0 -58
  72. package/dist/types/schemas/webhook.js +0 -12
  73. package/dist/utils/payload.d.ts +12 -0
  74. package/dist/utils/payload.js +14 -0
  75. package/package.json +3 -1
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { apiGet, apiPut } from "../client/http.js";
3
3
  import { formatApiError } from "../utils/errors.js";
4
- import { getConfig } from "../config.js";
4
+ import { getStoreCode } from "../config.js";
5
5
  // Input Schemas
6
6
  export const BadgeListInputSchema = {
7
7
  storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
@@ -35,8 +35,7 @@ export const BadgeGetMemberBadgesInputSchema = {
35
35
  };
36
36
  // Handler functions
37
37
  export async function badgeList(input) {
38
- const config = getConfig();
39
- const storeCode = input.storeCode || config.defaultStoreCode;
38
+ const storeCode = getStoreCode(input.storeCode);
40
39
  const params = new URLSearchParams();
41
40
  if (input.page)
42
41
  params.append("_page", String(input.page));
@@ -70,8 +69,7 @@ export async function badgeList(input) {
70
69
  }
71
70
  }
72
71
  export async function badgeGet(input) {
73
- const config = getConfig();
74
- const storeCode = input.storeCode || config.defaultStoreCode;
72
+ const storeCode = getStoreCode(input.storeCode);
75
73
  try {
76
74
  const response = await apiGet(`/${storeCode}/badge-type/${input.badgeTypeId}`);
77
75
  return response;
@@ -81,8 +79,7 @@ export async function badgeGet(input) {
81
79
  }
82
80
  }
83
81
  export async function badgeUpdate(input) {
84
- const config = getConfig();
85
- const storeCode = input.storeCode || config.defaultStoreCode;
82
+ const storeCode = getStoreCode(input.storeCode);
86
83
  const badgePayload = {};
87
84
  if (input.name !== undefined)
88
85
  badgePayload.name = input.name;
@@ -101,8 +98,7 @@ export async function badgeUpdate(input) {
101
98
  }
102
99
  }
103
100
  export async function badgeGetMemberBadges(input) {
104
- const config = getConfig();
105
- const storeCode = input.storeCode || config.defaultStoreCode;
101
+ const storeCode = getStoreCode(input.storeCode);
106
102
  const params = new URLSearchParams();
107
103
  if (input.page)
108
104
  params.append("_page", String(input.page));
@@ -140,25 +136,33 @@ export async function badgeGetMemberBadges(input) {
140
136
  export const badgeToolDefinitions = [
141
137
  {
142
138
  name: "openloyalty_badge_list",
139
+ title: "List Badges",
143
140
  description: "List badge types. Badges are visual rewards linked to achievements. When a member completes an achievement with a badgeTypeId, they earn that badge. Use for displaying available badges.",
141
+ readOnly: true,
144
142
  inputSchema: BadgeListInputSchema,
145
143
  handler: badgeList,
146
144
  },
147
145
  {
148
146
  name: "openloyalty_badge_get",
147
+ title: "Get Badge Details",
149
148
  description: "Get badge type details including name, image URL, and linked achievements count.",
149
+ readOnly: true,
150
150
  inputSchema: BadgeGetInputSchema,
151
151
  handler: badgeGet,
152
152
  },
153
153
  {
154
154
  name: "openloyalty_badge_update",
155
+ title: "Update Badge",
155
156
  description: "Update badge type configuration. Badge types are created automatically when referenced by achievements. Use this to update name, image, or translations.",
157
+ readOnly: false,
156
158
  inputSchema: BadgeUpdateInputSchema,
157
159
  handler: badgeUpdate,
158
160
  },
159
161
  {
160
162
  name: "openloyalty_badge_get_member_badges",
163
+ title: "Get Member Badges",
161
164
  description: "Get badges earned by a member. Returns each badge with completedCount showing how many times it was earned. Use for displaying member's badge collection.",
165
+ readOnly: true,
162
166
  inputSchema: BadgeGetMemberBadgesInputSchema,
163
167
  handler: badgeGetMemberBadges,
164
168
  },
@@ -356,20 +356,20 @@ export declare const CampaignSimulateInputSchema: {
356
356
  firstName: z.ZodOptional<z.ZodString>;
357
357
  lastName: z.ZodOptional<z.ZodString>;
358
358
  }, "strip", z.ZodTypeAny, {
359
- id?: string | undefined;
360
359
  email?: string | undefined;
361
- firstName?: string | undefined;
362
- lastName?: string | undefined;
363
360
  phone?: string | undefined;
364
361
  loyaltyCardNumber?: string | undefined;
362
+ firstName?: string | undefined;
363
+ lastName?: string | undefined;
364
+ id?: string | undefined;
365
365
  customerId?: string | undefined;
366
366
  }, {
367
- id?: string | undefined;
368
367
  email?: string | undefined;
369
- firstName?: string | undefined;
370
- lastName?: string | undefined;
371
368
  phone?: string | undefined;
372
369
  loyaltyCardNumber?: string | undefined;
370
+ firstName?: string | undefined;
371
+ lastName?: string | undefined;
372
+ id?: string | undefined;
373
373
  customerId?: string | undefined;
374
374
  }>;
375
375
  referrer: z.ZodOptional<z.ZodObject<{
@@ -377,13 +377,13 @@ export declare const CampaignSimulateInputSchema: {
377
377
  email: z.ZodOptional<z.ZodString>;
378
378
  loyaltyCardNumber: z.ZodOptional<z.ZodString>;
379
379
  }, "strip", z.ZodTypeAny, {
380
- id?: string | undefined;
381
380
  email?: string | undefined;
382
381
  loyaltyCardNumber?: string | undefined;
383
- }, {
384
382
  id?: string | undefined;
383
+ }, {
385
384
  email?: string | undefined;
386
385
  loyaltyCardNumber?: string | undefined;
386
+ id?: string | undefined;
387
387
  }>>;
388
388
  };
389
389
  export declare const CampaignGenerateCodesInputSchema: {
@@ -995,7 +995,9 @@ export declare function campaignCreate(input: CampaignCreateInput): Promise<{
995
995
  }>;
996
996
  export declare const campaignToolDefinitions: readonly [{
997
997
  readonly name: "openloyalty_campaign_list";
998
+ readonly title: "List Campaigns";
998
999
  readonly description: "List all campaigns. Filter by type (direct/referral) or trigger (transaction/custom_event/time/etc). Use campaign_get for full configuration including rules and effects.";
1000
+ readonly readOnly: true;
999
1001
  readonly inputSchema: {
1000
1002
  storeCode: z.ZodOptional<z.ZodString>;
1001
1003
  page: z.ZodOptional<z.ZodNumber>;
@@ -1007,7 +1009,9 @@ export declare const campaignToolDefinitions: readonly [{
1007
1009
  readonly handler: typeof campaignList;
1008
1010
  }, {
1009
1011
  readonly name: "openloyalty_campaign_create";
1012
+ readonly title: "Create Campaign";
1010
1013
  readonly description: "Create campaign to automate engagement. Triggers: transaction (purchase-based), custom_event (for custom actions), time (scheduled). Effects: give_points, give_reward, deduct_unit. Rules define when/what happens. Example - Double points: trigger=transaction, effect=give_points with pointsRule containing multiplier:2.";
1014
+ readonly readOnly: false;
1011
1015
  readonly inputSchema: {
1012
1016
  storeCode: z.ZodOptional<z.ZodString>;
1013
1017
  type: z.ZodEnum<["direct", "referral"]>;
@@ -1322,7 +1326,9 @@ export declare const campaignToolDefinitions: readonly [{
1322
1326
  readonly handler: typeof campaignCreate;
1323
1327
  }, {
1324
1328
  readonly name: "openloyalty_campaign_get";
1329
+ readonly title: "Get Campaign Details";
1325
1330
  readonly description: "Get full campaign configuration including all rules, conditions, effects, and targeting.";
1331
+ readonly readOnly: true;
1326
1332
  readonly inputSchema: {
1327
1333
  storeCode: z.ZodOptional<z.ZodString>;
1328
1334
  campaignId: z.ZodString;
@@ -1330,7 +1336,9 @@ export declare const campaignToolDefinitions: readonly [{
1330
1336
  readonly handler: typeof campaignGet;
1331
1337
  }, {
1332
1338
  readonly name: "openloyalty_campaign_update";
1339
+ readonly title: "Update Campaign";
1333
1340
  readonly description: "Full update of campaign configuration. Requires all campaign fields. Use campaign_get first to retrieve current configuration, modify it, then send the complete object.";
1341
+ readonly readOnly: false;
1334
1342
  readonly inputSchema: {
1335
1343
  storeCode: z.ZodOptional<z.ZodString>;
1336
1344
  campaignId: z.ZodString;
@@ -1545,7 +1553,9 @@ export declare const campaignToolDefinitions: readonly [{
1545
1553
  readonly handler: typeof campaignUpdate;
1546
1554
  }, {
1547
1555
  readonly name: "openloyalty_campaign_patch";
1556
+ readonly title: "Patch Campaign";
1548
1557
  readonly description: "Partial update of campaign - only active status and displayOrder can be patched. For full updates, use campaign_update.";
1558
+ readonly readOnly: false;
1549
1559
  readonly inputSchema: {
1550
1560
  storeCode: z.ZodOptional<z.ZodString>;
1551
1561
  campaignId: z.ZodString;
@@ -1555,7 +1565,10 @@ export declare const campaignToolDefinitions: readonly [{
1555
1565
  readonly handler: typeof campaignPatch;
1556
1566
  }, {
1557
1567
  readonly name: "openloyalty_campaign_delete";
1568
+ readonly title: "Delete Campaign (Permanent)";
1558
1569
  readonly description: "Permanently delete a campaign. This cannot be undone. Consider deactivating instead if you may need the campaign later.";
1570
+ readonly readOnly: false;
1571
+ readonly destructive: true;
1559
1572
  readonly inputSchema: {
1560
1573
  storeCode: z.ZodOptional<z.ZodString>;
1561
1574
  campaignId: z.ZodString;
@@ -1563,7 +1576,9 @@ export declare const campaignToolDefinitions: readonly [{
1563
1576
  readonly handler: typeof campaignDelete;
1564
1577
  }, {
1565
1578
  readonly name: "openloyalty_campaign_simulate";
1579
+ readonly title: "Simulate Campaign Effects";
1566
1580
  readonly description: "Simulate campaign effects without executing them. Use to preview what points/rewards a transaction would earn. Provide trigger type, transaction/event data, and customer. Returns simulated effects grouped by campaign.";
1581
+ readonly readOnly: true;
1567
1582
  readonly inputSchema: {
1568
1583
  storeCode: z.ZodOptional<z.ZodString>;
1569
1584
  trigger: z.ZodEnum<["transaction", "custom_event", "time", "achievement", "custom_event_unique_code", "leaderboard", "internal_event", "return_transaction", "challenge", "fortune_wheel"]>;
@@ -1687,20 +1702,20 @@ export declare const campaignToolDefinitions: readonly [{
1687
1702
  firstName: z.ZodOptional<z.ZodString>;
1688
1703
  lastName: z.ZodOptional<z.ZodString>;
1689
1704
  }, "strip", z.ZodTypeAny, {
1690
- id?: string | undefined;
1691
1705
  email?: string | undefined;
1692
- firstName?: string | undefined;
1693
- lastName?: string | undefined;
1694
1706
  phone?: string | undefined;
1695
1707
  loyaltyCardNumber?: string | undefined;
1708
+ firstName?: string | undefined;
1709
+ lastName?: string | undefined;
1710
+ id?: string | undefined;
1696
1711
  customerId?: string | undefined;
1697
1712
  }, {
1698
- id?: string | undefined;
1699
1713
  email?: string | undefined;
1700
- firstName?: string | undefined;
1701
- lastName?: string | undefined;
1702
1714
  phone?: string | undefined;
1703
1715
  loyaltyCardNumber?: string | undefined;
1716
+ firstName?: string | undefined;
1717
+ lastName?: string | undefined;
1718
+ id?: string | undefined;
1704
1719
  customerId?: string | undefined;
1705
1720
  }>;
1706
1721
  referrer: z.ZodOptional<z.ZodObject<{
@@ -1708,19 +1723,21 @@ export declare const campaignToolDefinitions: readonly [{
1708
1723
  email: z.ZodOptional<z.ZodString>;
1709
1724
  loyaltyCardNumber: z.ZodOptional<z.ZodString>;
1710
1725
  }, "strip", z.ZodTypeAny, {
1711
- id?: string | undefined;
1712
1726
  email?: string | undefined;
1713
1727
  loyaltyCardNumber?: string | undefined;
1714
- }, {
1715
1728
  id?: string | undefined;
1729
+ }, {
1716
1730
  email?: string | undefined;
1717
1731
  loyaltyCardNumber?: string | undefined;
1732
+ id?: string | undefined;
1718
1733
  }>>;
1719
1734
  };
1720
1735
  readonly handler: typeof campaignSimulate;
1721
1736
  }, {
1722
1737
  readonly name: "openloyalty_campaign_generate_codes";
1738
+ readonly title: "Generate Campaign Codes";
1723
1739
  readonly description: "Generate unique redemption codes for a campaign. Use for promotions requiring unique codes. Codes are auto-generated and can be retrieved with campaign_list_codes.";
1740
+ readonly readOnly: false;
1724
1741
  readonly inputSchema: {
1725
1742
  storeCode: z.ZodOptional<z.ZodString>;
1726
1743
  campaignId: z.ZodString;
@@ -1729,7 +1746,9 @@ export declare const campaignToolDefinitions: readonly [{
1729
1746
  readonly handler: typeof campaignGenerateCodes;
1730
1747
  }, {
1731
1748
  readonly name: "openloyalty_campaign_list_codes";
1749
+ readonly title: "List Campaign Codes";
1732
1750
  readonly description: "List redemption codes for a campaign. Filter by status (active/used) or specific code. Returns code details including usage status.";
1751
+ readonly readOnly: true;
1733
1752
  readonly inputSchema: {
1734
1753
  storeCode: z.ZodOptional<z.ZodString>;
1735
1754
  campaignId: z.ZodString;
@@ -1741,7 +1760,9 @@ export declare const campaignToolDefinitions: readonly [{
1741
1760
  readonly handler: typeof campaignListCodes;
1742
1761
  }, {
1743
1762
  readonly name: "openloyalty_campaign_get_available";
1763
+ readonly title: "Get Available Campaigns for Member";
1744
1764
  readonly description: "Get campaigns available to a specific member. Returns campaigns the member can participate in based on their tier, segments, and campaign targeting rules. Includes limitReached indicator.";
1765
+ readonly readOnly: true;
1745
1766
  readonly inputSchema: {
1746
1767
  storeCode: z.ZodOptional<z.ZodString>;
1747
1768
  memberId: z.ZodString;
@@ -1753,7 +1774,9 @@ export declare const campaignToolDefinitions: readonly [{
1753
1774
  readonly handler: typeof campaignGetAvailable;
1754
1775
  }, {
1755
1776
  readonly name: "openloyalty_campaign_get_visible";
1777
+ readonly title: "Get Visible Campaigns for Member";
1756
1778
  readonly description: "Get campaigns visible to a specific member. May include campaigns not yet available (e.g., upcoming campaigns or those requiring certain conditions). Use get_available for campaigns the member can currently participate in.";
1779
+ readonly readOnly: true;
1757
1780
  readonly inputSchema: {
1758
1781
  storeCode: z.ZodOptional<z.ZodString>;
1759
1782
  memberId: z.ZodString;
@@ -1764,7 +1787,9 @@ export declare const campaignToolDefinitions: readonly [{
1764
1787
  readonly handler: typeof campaignGetVisible;
1765
1788
  }, {
1766
1789
  readonly name: "openloyalty_campaign_get_leaderboard";
1790
+ readonly title: "Get Campaign Leaderboard";
1767
1791
  readonly description: "Get leaderboard rankings for a campaign. Returns ranked list of members with scores and positions. Use for leaderboard-type campaigns to show competition standings.";
1792
+ readonly readOnly: true;
1768
1793
  readonly inputSchema: {
1769
1794
  storeCode: z.ZodOptional<z.ZodString>;
1770
1795
  campaignId: z.ZodString;
@@ -2,7 +2,7 @@ import { z } from "zod";
2
2
  import { apiGet, apiPost, apiPut, apiPatch, apiDelete } from "../client/http.js";
3
3
  import { CampaignTypeEnum, CampaignTriggerEnum, } from "../types/schemas/campaign.js";
4
4
  import { formatApiError } from "../utils/errors.js";
5
- import { getConfig } from "../config.js";
5
+ import { getStoreCode } from "../config.js";
6
6
  // Input Schemas
7
7
  export const CampaignListInputSchema = {
8
8
  storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
@@ -252,8 +252,7 @@ export const CampaignCreateInputSchema = {
252
252
  };
253
253
  // Handler functions
254
254
  export async function campaignList(input) {
255
- const config = getConfig();
256
- const storeCode = input.storeCode || config.defaultStoreCode;
255
+ const storeCode = getStoreCode(input.storeCode);
257
256
  const params = new URLSearchParams();
258
257
  if (input.page)
259
258
  params.append("_page", String(input.page));
@@ -307,8 +306,7 @@ export async function campaignList(input) {
307
306
  }
308
307
  }
309
308
  export async function campaignGet(input) {
310
- const config = getConfig();
311
- const storeCode = input.storeCode || config.defaultStoreCode;
309
+ const storeCode = getStoreCode(input.storeCode);
312
310
  try {
313
311
  const response = await apiGet(`/${storeCode}/campaign/${input.campaignId}`);
314
312
  return response;
@@ -318,8 +316,7 @@ export async function campaignGet(input) {
318
316
  }
319
317
  }
320
318
  export async function campaignUpdate(input) {
321
- const config = getConfig();
322
- const storeCode = input.storeCode || config.defaultStoreCode;
319
+ const storeCode = getStoreCode(input.storeCode);
323
320
  const campaignId = input.campaignId;
324
321
  // Build campaign payload excluding storeCode and campaignId
325
322
  const { storeCode: _sc, campaignId: _cid, ...campaignPayload } = input;
@@ -332,8 +329,7 @@ export async function campaignUpdate(input) {
332
329
  }
333
330
  }
334
331
  export async function campaignPatch(input) {
335
- const config = getConfig();
336
- const storeCode = input.storeCode || config.defaultStoreCode;
332
+ const storeCode = getStoreCode(input.storeCode);
337
333
  const patchPayload = {};
338
334
  if (input.active !== undefined)
339
335
  patchPayload.active = input.active;
@@ -347,8 +343,7 @@ export async function campaignPatch(input) {
347
343
  }
348
344
  }
349
345
  export async function campaignDelete(input) {
350
- const config = getConfig();
351
- const storeCode = input.storeCode || config.defaultStoreCode;
346
+ const storeCode = getStoreCode(input.storeCode);
352
347
  try {
353
348
  await apiDelete(`/${storeCode}/campaign/${input.campaignId}`);
354
349
  }
@@ -357,8 +352,7 @@ export async function campaignDelete(input) {
357
352
  }
358
353
  }
359
354
  export async function campaignSimulate(input) {
360
- const config = getConfig();
361
- const storeCode = input.storeCode || config.defaultStoreCode;
355
+ const storeCode = getStoreCode(input.storeCode);
362
356
  // Build the simulate payload
363
357
  const simulatePayload = {
364
358
  trigger: input.trigger,
@@ -453,8 +447,7 @@ export async function campaignSimulate(input) {
453
447
  }
454
448
  }
455
449
  export async function campaignGenerateCodes(input) {
456
- const config = getConfig();
457
- const storeCode = input.storeCode || config.defaultStoreCode;
450
+ const storeCode = getStoreCode(input.storeCode);
458
451
  try {
459
452
  // Body wrapped as { generate: { numberOfCodes } }
460
453
  await apiPost(`/${storeCode}/campaign/${input.campaignId}/codes/generate`, { generate: { numberOfCodes: input.quantity } });
@@ -466,8 +459,7 @@ export async function campaignGenerateCodes(input) {
466
459
  }
467
460
  }
468
461
  export async function campaignListCodes(input) {
469
- const config = getConfig();
470
- const storeCode = input.storeCode || config.defaultStoreCode;
462
+ const storeCode = getStoreCode(input.storeCode);
471
463
  const params = new URLSearchParams();
472
464
  if (input.page)
473
465
  params.append("_page", String(input.page));
@@ -503,8 +495,7 @@ export async function campaignListCodes(input) {
503
495
  }
504
496
  }
505
497
  export async function campaignGetAvailable(input) {
506
- const config = getConfig();
507
- const storeCode = input.storeCode || config.defaultStoreCode;
498
+ const storeCode = getStoreCode(input.storeCode);
508
499
  const params = new URLSearchParams();
509
500
  if (input.page)
510
501
  params.append("_page", String(input.page));
@@ -541,8 +532,7 @@ export async function campaignGetAvailable(input) {
541
532
  }
542
533
  }
543
534
  export async function campaignGetVisible(input) {
544
- const config = getConfig();
545
- const storeCode = input.storeCode || config.defaultStoreCode;
535
+ const storeCode = getStoreCode(input.storeCode);
546
536
  const params = new URLSearchParams();
547
537
  if (input.page)
548
538
  params.append("_page", String(input.page));
@@ -576,8 +566,7 @@ export async function campaignGetVisible(input) {
576
566
  }
577
567
  }
578
568
  export async function campaignGetLeaderboard(input) {
579
- const config = getConfig();
580
- const storeCode = input.storeCode || config.defaultStoreCode;
569
+ const storeCode = getStoreCode(input.storeCode);
581
570
  const params = new URLSearchParams();
582
571
  if (input.type)
583
572
  params.append("type", input.type);
@@ -614,8 +603,7 @@ export async function campaignGetLeaderboard(input) {
614
603
  }
615
604
  }
616
605
  export async function campaignCreate(input) {
617
- const config = getConfig();
618
- const storeCode = input.storeCode || config.defaultStoreCode;
606
+ const storeCode = getStoreCode(input.storeCode);
619
607
  // Build the campaign payload
620
608
  const campaignPayload = {
621
609
  type: input.type,
@@ -651,73 +639,98 @@ export async function campaignCreate(input) {
651
639
  export const campaignToolDefinitions = [
652
640
  {
653
641
  name: "openloyalty_campaign_list",
642
+ title: "List Campaigns",
654
643
  description: "List all campaigns. Filter by type (direct/referral) or trigger (transaction/custom_event/time/etc). Use campaign_get for full configuration including rules and effects.",
644
+ readOnly: true,
655
645
  inputSchema: CampaignListInputSchema,
656
646
  handler: campaignList,
657
647
  },
658
648
  {
659
649
  name: "openloyalty_campaign_create",
650
+ title: "Create Campaign",
660
651
  description: "Create campaign to automate engagement. Triggers: transaction (purchase-based), custom_event (for custom actions), time (scheduled). Effects: give_points, give_reward, deduct_unit. Rules define when/what happens. Example - Double points: trigger=transaction, effect=give_points with pointsRule containing multiplier:2.",
652
+ readOnly: false,
661
653
  inputSchema: CampaignCreateInputSchema,
662
654
  handler: campaignCreate,
663
655
  },
664
656
  {
665
657
  name: "openloyalty_campaign_get",
658
+ title: "Get Campaign Details",
666
659
  description: "Get full campaign configuration including all rules, conditions, effects, and targeting.",
660
+ readOnly: true,
667
661
  inputSchema: CampaignGetInputSchema,
668
662
  handler: campaignGet,
669
663
  },
670
664
  {
671
665
  name: "openloyalty_campaign_update",
666
+ title: "Update Campaign",
672
667
  description: "Full update of campaign configuration. Requires all campaign fields. Use campaign_get first to retrieve current configuration, modify it, then send the complete object.",
668
+ readOnly: false,
673
669
  inputSchema: CampaignUpdateInputSchema,
674
670
  handler: campaignUpdate,
675
671
  },
676
672
  {
677
673
  name: "openloyalty_campaign_patch",
674
+ title: "Patch Campaign",
678
675
  description: "Partial update of campaign - only active status and displayOrder can be patched. For full updates, use campaign_update.",
676
+ readOnly: false,
679
677
  inputSchema: CampaignPatchInputSchema,
680
678
  handler: campaignPatch,
681
679
  },
682
680
  {
683
681
  name: "openloyalty_campaign_delete",
682
+ title: "Delete Campaign (Permanent)",
684
683
  description: "Permanently delete a campaign. This cannot be undone. Consider deactivating instead if you may need the campaign later.",
684
+ readOnly: false,
685
+ destructive: true,
685
686
  inputSchema: CampaignDeleteInputSchema,
686
687
  handler: campaignDelete,
687
688
  },
688
689
  {
689
690
  name: "openloyalty_campaign_simulate",
691
+ title: "Simulate Campaign Effects",
690
692
  description: "Simulate campaign effects without executing them. Use to preview what points/rewards a transaction would earn. Provide trigger type, transaction/event data, and customer. Returns simulated effects grouped by campaign.",
693
+ readOnly: true,
691
694
  inputSchema: CampaignSimulateInputSchema,
692
695
  handler: campaignSimulate,
693
696
  },
694
697
  {
695
698
  name: "openloyalty_campaign_generate_codes",
699
+ title: "Generate Campaign Codes",
696
700
  description: "Generate unique redemption codes for a campaign. Use for promotions requiring unique codes. Codes are auto-generated and can be retrieved with campaign_list_codes.",
701
+ readOnly: false,
697
702
  inputSchema: CampaignGenerateCodesInputSchema,
698
703
  handler: campaignGenerateCodes,
699
704
  },
700
705
  {
701
706
  name: "openloyalty_campaign_list_codes",
707
+ title: "List Campaign Codes",
702
708
  description: "List redemption codes for a campaign. Filter by status (active/used) or specific code. Returns code details including usage status.",
709
+ readOnly: true,
703
710
  inputSchema: CampaignListCodesInputSchema,
704
711
  handler: campaignListCodes,
705
712
  },
706
713
  {
707
714
  name: "openloyalty_campaign_get_available",
715
+ title: "Get Available Campaigns for Member",
708
716
  description: "Get campaigns available to a specific member. Returns campaigns the member can participate in based on their tier, segments, and campaign targeting rules. Includes limitReached indicator.",
717
+ readOnly: true,
709
718
  inputSchema: CampaignGetAvailableInputSchema,
710
719
  handler: campaignGetAvailable,
711
720
  },
712
721
  {
713
722
  name: "openloyalty_campaign_get_visible",
723
+ title: "Get Visible Campaigns for Member",
714
724
  description: "Get campaigns visible to a specific member. May include campaigns not yet available (e.g., upcoming campaigns or those requiring certain conditions). Use get_available for campaigns the member can currently participate in.",
725
+ readOnly: true,
715
726
  inputSchema: CampaignGetVisibleInputSchema,
716
727
  handler: campaignGetVisible,
717
728
  },
718
729
  {
719
730
  name: "openloyalty_campaign_get_leaderboard",
731
+ title: "Get Campaign Leaderboard",
720
732
  description: "Get leaderboard rankings for a campaign. Returns ranked list of members with scores and positions. Use for leaderboard-type campaigns to show competition standings.",
733
+ readOnly: true,
721
734
  inputSchema: CampaignGetLeaderboardInputSchema,
722
735
  handler: campaignGetLeaderboard,
723
736
  },
@@ -70,7 +70,9 @@ export declare function exportDownload(input: {
70
70
  }>;
71
71
  export declare const exportToolDefinitions: readonly [{
72
72
  readonly name: "openloyalty_export_create";
73
+ readonly title: "Create Data Export";
73
74
  readonly description: "Create a new data export. Returns exportId for async tracking. Export types: campaignCode (campaign redemption codes), member (member data), memberTier (member tier assignments), memberSegment (member segment membership), rewardFulfillment (reward fulfillment records). The export runs asynchronously - use export_get to check status and export_download when status is 'done'.";
75
+ readonly readOnly: false;
74
76
  readonly inputSchema: {
75
77
  storeCode: z.ZodOptional<z.ZodString>;
76
78
  type: z.ZodEnum<["campaignCode", "member", "memberTier", "memberSegment", "rewardFulfillment"]>;
@@ -81,7 +83,9 @@ export declare const exportToolDefinitions: readonly [{
81
83
  readonly handler: typeof exportCreate;
82
84
  }, {
83
85
  readonly name: "openloyalty_export_list";
86
+ readonly title: "List Exports";
84
87
  readonly description: "List exports with optional filtering. Returns paginated list of exports with exportId, type, status, createdAt, and finishedAt. Status values: pending, done, failed, error.";
88
+ readonly readOnly: true;
85
89
  readonly inputSchema: {
86
90
  storeCode: z.ZodOptional<z.ZodString>;
87
91
  page: z.ZodOptional<z.ZodNumber>;
@@ -93,7 +97,9 @@ export declare const exportToolDefinitions: readonly [{
93
97
  readonly handler: typeof exportList;
94
98
  }, {
95
99
  readonly name: "openloyalty_export_get";
100
+ readonly title: "Get Export Details";
96
101
  readonly description: "Get export details and status. Returns exportId, type, status, createdAt, finishedAt, exportedRows, and message. Check status before downloading - export must have status 'done'.";
102
+ readonly readOnly: true;
97
103
  readonly inputSchema: {
98
104
  storeCode: z.ZodOptional<z.ZodString>;
99
105
  exportId: z.ZodString;
@@ -101,7 +107,9 @@ export declare const exportToolDefinitions: readonly [{
101
107
  readonly handler: typeof exportGet;
102
108
  }, {
103
109
  readonly name: "openloyalty_export_download";
110
+ readonly title: "Download Export File";
104
111
  readonly description: "Download export file content. Returns CSV content. IMPORTANT: Only available when export status is 'done'. Check status with export_get first.";
112
+ readonly readOnly: true;
105
113
  readonly inputSchema: {
106
114
  storeCode: z.ZodOptional<z.ZodString>;
107
115
  exportId: z.ZodString;
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  import { apiGet, apiPost } from "../client/http.js";
3
3
  import { formatApiError } from "../utils/errors.js";
4
- import { getConfig } from "../config.js";
4
+ import { getConfig, getStoreCode } from "../config.js";
5
5
  import axios from "axios";
6
6
  // Input Schemas
7
7
  export const ExportCreateInputSchema = {
@@ -41,8 +41,7 @@ export const ExportDownloadInputSchema = {
41
41
  };
42
42
  // Handler functions
43
43
  export async function exportCreate(input) {
44
- const config = getConfig();
45
- const storeCode = input.storeCode || config.defaultStoreCode;
44
+ const storeCode = getStoreCode(input.storeCode);
46
45
  // Build the payload with type-specific wrapper
47
46
  // The API expects { [type]: { ...filters, _page?, _itemsOnPage? } }
48
47
  const innerPayload = {
@@ -64,8 +63,7 @@ export async function exportCreate(input) {
64
63
  }
65
64
  }
66
65
  export async function exportList(input) {
67
- const config = getConfig();
68
- const storeCode = input.storeCode || config.defaultStoreCode;
66
+ const storeCode = getStoreCode(input.storeCode);
69
67
  const params = new URLSearchParams();
70
68
  if (input.page)
71
69
  params.append("_page", String(input.page));
@@ -88,8 +86,7 @@ export async function exportList(input) {
88
86
  }
89
87
  }
90
88
  export async function exportGet(input) {
91
- const config = getConfig();
92
- const storeCode = input.storeCode || config.defaultStoreCode;
89
+ const storeCode = getStoreCode(input.storeCode);
93
90
  try {
94
91
  const response = await apiGet(`/${storeCode}/export/${input.exportId}`);
95
92
  return response;
@@ -100,7 +97,7 @@ export async function exportGet(input) {
100
97
  }
101
98
  export async function exportDownload(input) {
102
99
  const config = getConfig();
103
- const storeCode = input.storeCode || config.defaultStoreCode;
100
+ const storeCode = getStoreCode(input.storeCode);
104
101
  try {
105
102
  const response = await axios.get(`${config.apiUrl}/${storeCode}/export/${input.exportId}/download`, {
106
103
  headers: {
@@ -122,25 +119,33 @@ export async function exportDownload(input) {
122
119
  export const exportToolDefinitions = [
123
120
  {
124
121
  name: "openloyalty_export_create",
122
+ title: "Create Data Export",
125
123
  description: "Create a new data export. Returns exportId for async tracking. Export types: campaignCode (campaign redemption codes), member (member data), memberTier (member tier assignments), memberSegment (member segment membership), rewardFulfillment (reward fulfillment records). The export runs asynchronously - use export_get to check status and export_download when status is 'done'.",
124
+ readOnly: false,
126
125
  inputSchema: ExportCreateInputSchema,
127
126
  handler: exportCreate,
128
127
  },
129
128
  {
130
129
  name: "openloyalty_export_list",
130
+ title: "List Exports",
131
131
  description: "List exports with optional filtering. Returns paginated list of exports with exportId, type, status, createdAt, and finishedAt. Status values: pending, done, failed, error.",
132
+ readOnly: true,
132
133
  inputSchema: ExportListInputSchema,
133
134
  handler: exportList,
134
135
  },
135
136
  {
136
137
  name: "openloyalty_export_get",
138
+ title: "Get Export Details",
137
139
  description: "Get export details and status. Returns exportId, type, status, createdAt, finishedAt, exportedRows, and message. Check status before downloading - export must have status 'done'.",
140
+ readOnly: true,
138
141
  inputSchema: ExportGetInputSchema,
139
142
  handler: exportGet,
140
143
  },
141
144
  {
142
145
  name: "openloyalty_export_download",
146
+ title: "Download Export File",
143
147
  description: "Download export file content. Returns CSV content. IMPORTANT: Only available when export status is 'done'. Check status with export_get first.",
148
+ readOnly: true,
144
149
  inputSchema: ExportDownloadInputSchema,
145
150
  handler: exportDownload,
146
151
  },
@@ -78,7 +78,9 @@ export declare function importGet(input: {
78
78
  }): Promise<ImportDetailsResponse>;
79
79
  export declare const importToolDefinitions: readonly [{
80
80
  readonly name: "openloyalty_import_create";
81
+ readonly title: "Create Bulk Import";
81
82
  readonly description: "Create a new bulk import from CSV content. Returns importId for async tracking. Import types: member (member data), groupValue (group values), segmentMembers (segment membership), unitTransferAdding (add points), unitTransferSpending (spend points), transaction (transactions), campaignCode (campaign codes), rewardCoupon (reward coupons). CSV format required - provide plain text CSV content.";
83
+ readonly readOnly: false;
82
84
  readonly inputSchema: {
83
85
  storeCode: z.ZodOptional<z.ZodString>;
84
86
  type: z.ZodEnum<["member", "groupValue", "segmentMembers", "unitTransferAdding", "unitTransferSpending", "transaction", "campaignCode", "rewardCoupon"]>;
@@ -88,7 +90,9 @@ export declare const importToolDefinitions: readonly [{
88
90
  readonly handler: typeof importCreate;
89
91
  }, {
90
92
  readonly name: "openloyalty_import_list";
93
+ readonly title: "List Imports";
91
94
  readonly description: "List imports with optional filtering. Returns paginated list of imports with importId, type, uploadedDate, fileName, and status information.";
95
+ readonly readOnly: true;
92
96
  readonly inputSchema: {
93
97
  storeCode: z.ZodOptional<z.ZodString>;
94
98
  page: z.ZodOptional<z.ZodNumber>;
@@ -99,7 +103,9 @@ export declare const importToolDefinitions: readonly [{
99
103
  readonly handler: typeof importList;
100
104
  }, {
101
105
  readonly name: "openloyalty_import_get";
106
+ readonly title: "Get Import Details";
102
107
  readonly description: "Get import details and individual item statuses. Returns paginated list of import items with their success/failure status and error messages.";
108
+ readonly readOnly: true;
103
109
  readonly inputSchema: {
104
110
  storeCode: z.ZodOptional<z.ZodString>;
105
111
  importId: z.ZodString;