@open-loyalty/mcp-server 1.0.3 → 1.3.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 (142) hide show
  1. package/README.md +180 -177
  2. package/dist/auth/provider.js +2 -14
  3. package/dist/auth/storage.js +22 -0
  4. package/dist/client/http.d.ts +5 -0
  5. package/dist/client/http.js +62 -3
  6. package/dist/config.d.ts +6 -5
  7. package/dist/config.js +15 -11
  8. package/dist/http.js +170 -65
  9. package/dist/instructions.d.ts +5 -0
  10. package/dist/instructions.js +420 -0
  11. package/dist/prompts/fan-engagement-setup.d.ts +107 -0
  12. package/dist/prompts/fan-engagement-setup.js +492 -0
  13. package/dist/server.d.ts +1 -1
  14. package/dist/server.js +68 -278
  15. package/dist/tools/achievement/handlers.d.ts +117 -0
  16. package/dist/tools/achievement/handlers.js +161 -0
  17. package/dist/tools/achievement/index.d.ts +479 -0
  18. package/dist/tools/achievement/index.js +74 -0
  19. package/dist/tools/achievement/schemas.d.ts +433 -0
  20. package/dist/tools/achievement/schemas.js +142 -0
  21. package/dist/tools/achievement.d.ts +155 -121
  22. package/dist/tools/achievement.js +82 -39
  23. package/dist/tools/admin.d.ts +18 -6
  24. package/dist/tools/admin.js +24 -12
  25. package/dist/tools/analytics.d.ts +29 -11
  26. package/dist/tools/analytics.js +58 -48
  27. package/dist/tools/apikey.d.ts +10 -3
  28. package/dist/tools/apikey.js +13 -6
  29. package/dist/tools/audit.d.ts +6 -2
  30. package/dist/tools/audit.js +8 -4
  31. package/dist/tools/badge.d.ts +14 -6
  32. package/dist/tools/badge.js +36 -27
  33. package/dist/tools/campaign/handlers.d.ts +42 -0
  34. package/dist/tools/campaign/handlers.js +223 -0
  35. package/dist/tools/campaign/index.d.ts +783 -0
  36. package/dist/tools/campaign/index.js +112 -0
  37. package/dist/tools/campaign/member-handlers.d.ts +60 -0
  38. package/dist/tools/campaign/member-handlers.js +159 -0
  39. package/dist/tools/campaign/schemas.d.ts +704 -0
  40. package/dist/tools/campaign/schemas.js +259 -0
  41. package/dist/tools/campaign/types.d.ts +161 -0
  42. package/dist/tools/campaign/types.js +2 -0
  43. package/dist/tools/campaign.d.ts +41 -16
  44. package/dist/tools/campaign.js +38 -25
  45. package/dist/tools/custom-event.d.ts +315 -0
  46. package/dist/tools/custom-event.js +270 -0
  47. package/dist/tools/export.d.ts +12 -4
  48. package/dist/tools/export.js +25 -20
  49. package/dist/tools/import.d.ts +9 -3
  50. package/dist/tools/import.js +33 -21
  51. package/dist/tools/index.d.ts +3 -11
  52. package/dist/tools/index.js +17 -475
  53. package/dist/tools/member/handlers.d.ts +111 -0
  54. package/dist/tools/member/handlers.js +206 -0
  55. package/dist/tools/member/index.d.ts +169 -0
  56. package/dist/tools/member/index.js +92 -0
  57. package/dist/tools/member/schemas.d.ts +89 -0
  58. package/dist/tools/member/schemas.js +65 -0
  59. package/dist/tools/member.d.ts +21 -0
  60. package/dist/tools/member.js +56 -62
  61. package/dist/tools/points.d.ts +19 -6
  62. package/dist/tools/points.js +51 -49
  63. package/dist/tools/referral/handlers.d.ts +47 -0
  64. package/dist/tools/referral/handlers.js +115 -0
  65. package/dist/tools/referral/index.d.ts +44 -0
  66. package/dist/tools/referral/index.js +44 -0
  67. package/dist/tools/referral/schemas.d.ts +34 -0
  68. package/dist/tools/referral/schemas.js +52 -0
  69. package/dist/tools/reward/handlers.d.ts +110 -0
  70. package/dist/tools/reward/handlers.js +289 -0
  71. package/dist/tools/reward/index.d.ts +177 -0
  72. package/dist/tools/reward/index.js +90 -0
  73. package/dist/tools/reward/schemas.d.ts +116 -0
  74. package/dist/tools/reward/schemas.js +91 -0
  75. package/dist/tools/reward.d.ts +18 -0
  76. package/dist/tools/reward.js +56 -66
  77. package/dist/tools/role.d.ts +26 -7
  78. package/dist/tools/role.js +25 -12
  79. package/dist/tools/segment/handlers.d.ts +87 -0
  80. package/dist/tools/segment/handlers.js +174 -0
  81. package/dist/tools/segment/index.d.ts +395 -0
  82. package/dist/tools/segment/index.js +87 -0
  83. package/dist/tools/segment/schemas.d.ts +337 -0
  84. package/dist/tools/segment/schemas.js +79 -0
  85. package/dist/tools/segment.d.ts +29 -10
  86. package/dist/tools/segment.js +84 -50
  87. package/dist/tools/store.d.ts +12 -4
  88. package/dist/tools/store.js +16 -8
  89. package/dist/tools/tierset.d.ts +19 -7
  90. package/dist/tools/tierset.js +44 -35
  91. package/dist/tools/transaction.d.ts +16 -8
  92. package/dist/tools/transaction.js +25 -21
  93. package/dist/tools/wallet-type.d.ts +7 -3
  94. package/dist/tools/wallet-type.js +14 -12
  95. package/dist/tools/webhook.d.ts +23 -10
  96. package/dist/tools/webhook.js +135 -33
  97. package/dist/types/schemas/achievement.d.ts +12 -309
  98. package/dist/types/schemas/achievement.js +0 -13
  99. package/dist/types/schemas/admin.d.ts +10 -97
  100. package/dist/types/schemas/admin.js +0 -38
  101. package/dist/types/schemas/badge.d.ts +0 -37
  102. package/dist/types/schemas/badge.js +0 -11
  103. package/dist/types/schemas/campaign.d.ts +64 -832
  104. package/dist/types/schemas/campaign.js +2 -25
  105. package/dist/types/schemas/common.d.ts +5 -0
  106. package/dist/types/schemas/common.js +5 -0
  107. package/dist/types/schemas/export.d.ts +0 -17
  108. package/dist/types/schemas/export.js +0 -7
  109. package/dist/types/schemas/member.d.ts +37 -176
  110. package/dist/types/schemas/member.js +0 -27
  111. package/dist/types/schemas/points.d.ts +0 -63
  112. package/dist/types/schemas/points.js +0 -22
  113. package/dist/types/schemas/reward.d.ts +71 -68
  114. package/dist/types/schemas/reward.js +8 -28
  115. package/dist/types/schemas/role.d.ts +0 -100
  116. package/dist/types/schemas/role.js +0 -29
  117. package/dist/types/schemas/segment.d.ts +0 -58
  118. package/dist/types/schemas/segment.js +0 -17
  119. package/dist/types/schemas/tierset.d.ts +0 -176
  120. package/dist/types/schemas/tierset.js +0 -27
  121. package/dist/types/schemas/transaction.d.ts +23 -254
  122. package/dist/types/schemas/transaction.js +0 -7
  123. package/dist/types/schemas/wallet-type.d.ts +8 -8
  124. package/dist/types/schemas/wallet-type.js +1 -1
  125. package/dist/types/schemas/webhook.d.ts +0 -58
  126. package/dist/types/schemas/webhook.js +0 -12
  127. package/dist/utils/errors.js +30 -3
  128. package/dist/utils/payload.d.ts +12 -0
  129. package/dist/utils/payload.js +14 -0
  130. package/dist/workflows/app-login-streak.d.ts +39 -0
  131. package/dist/workflows/app-login-streak.js +298 -0
  132. package/dist/workflows/early-arrival.d.ts +33 -0
  133. package/dist/workflows/early-arrival.js +148 -0
  134. package/dist/workflows/index.d.ts +101 -0
  135. package/dist/workflows/index.js +208 -0
  136. package/dist/workflows/match-attendance.d.ts +45 -0
  137. package/dist/workflows/match-attendance.js +308 -0
  138. package/dist/workflows/sportsbar-visit.d.ts +41 -0
  139. package/dist/workflows/sportsbar-visit.js +284 -0
  140. package/dist/workflows/vod-watching.d.ts +43 -0
  141. package/dist/workflows/vod-watching.js +326 -0
  142. package/package.json +10 -2
@@ -0,0 +1,42 @@
1
+ import { CampaignListItem } from "../../types/schemas/campaign.js";
2
+ import { SimulatedEffect, CampaignSimulateInput, CampaignCreateInput } from "./types.js";
3
+ export declare function campaignList(input: {
4
+ storeCode?: string;
5
+ page?: number;
6
+ perPage?: number;
7
+ active?: boolean;
8
+ type?: string;
9
+ trigger?: string;
10
+ }): Promise<{
11
+ campaigns: CampaignListItem[];
12
+ total: {
13
+ all?: number;
14
+ filtered?: number;
15
+ };
16
+ }>;
17
+ export declare function campaignGet(input: {
18
+ storeCode?: string;
19
+ campaignId: string;
20
+ }): Promise<Record<string, unknown>>;
21
+ export declare function campaignCreate(input: CampaignCreateInput): Promise<{
22
+ campaignId: string;
23
+ }>;
24
+ export declare function campaignUpdate(input: Record<string, unknown>): Promise<void>;
25
+ export declare function campaignPatch(input: {
26
+ storeCode?: string;
27
+ campaignId: string;
28
+ active?: boolean;
29
+ displayOrder?: number;
30
+ }): Promise<void>;
31
+ export declare function campaignDelete(input: {
32
+ storeCode?: string;
33
+ campaignId: string;
34
+ }): Promise<void>;
35
+ export declare function campaignSimulate(input: CampaignSimulateInput): Promise<{
36
+ simulatedEffects: SimulatedEffect[];
37
+ evaluationWarnings?: Array<{
38
+ campaignId: string;
39
+ message: string;
40
+ }>;
41
+ simulatedMember?: Record<string, unknown>;
42
+ }>;
@@ -0,0 +1,223 @@
1
+ import { apiGet, apiPost, apiPut, apiPatch, apiDelete } from "../../client/http.js";
2
+ import { formatApiError } from "../../utils/errors.js";
3
+ import { getStoreCode } from "../../config.js";
4
+ // Core CRUD handlers
5
+ export async function campaignList(input) {
6
+ const storeCode = getStoreCode(input.storeCode);
7
+ const params = new URLSearchParams();
8
+ if (input.page)
9
+ params.append("_page", String(input.page));
10
+ if (input.perPage)
11
+ params.append("_itemsOnPage", String(input.perPage));
12
+ if (input.active !== undefined)
13
+ params.append("active", String(input.active));
14
+ if (input.type)
15
+ params.append("type", input.type);
16
+ if (input.trigger)
17
+ params.append("trigger", input.trigger);
18
+ const queryString = params.toString();
19
+ const url = `/${storeCode}/campaign${queryString ? `?${queryString}` : ""}`;
20
+ try {
21
+ const response = await apiGet(url);
22
+ const campaigns = (response.items || []).map((item) => {
23
+ const campaign = item;
24
+ const translations = campaign.translations;
25
+ let name = "";
26
+ if (Array.isArray(translations)) {
27
+ const enTranslation = translations.find((t) => t.locale === "en" || t.locale?.startsWith("en"));
28
+ name = enTranslation?.name || translations[0]?.name || campaign.name || "";
29
+ }
30
+ else if (translations && typeof translations === "object") {
31
+ name = translations.en?.name || campaign.name || "";
32
+ }
33
+ else {
34
+ name = campaign.name || "";
35
+ }
36
+ return {
37
+ campaignId: campaign.campaignId,
38
+ name,
39
+ type: campaign.type,
40
+ trigger: campaign.trigger,
41
+ active: (campaign.active ?? false),
42
+ displayOrder: campaign.displayOrder,
43
+ };
44
+ });
45
+ const total = response.total || {};
46
+ return {
47
+ campaigns,
48
+ total: {
49
+ all: typeof total.all === "number" ? total.all : undefined,
50
+ filtered: typeof total.filtered === "number" ? total.filtered : undefined,
51
+ },
52
+ };
53
+ }
54
+ catch (error) {
55
+ throw formatApiError(error, "ol_campaign_list");
56
+ }
57
+ }
58
+ export async function campaignGet(input) {
59
+ const storeCode = getStoreCode(input.storeCode);
60
+ try {
61
+ const response = await apiGet(`/${storeCode}/campaign/${input.campaignId}`);
62
+ return response;
63
+ }
64
+ catch (error) {
65
+ throw formatApiError(error, "ol_campaign_get");
66
+ }
67
+ }
68
+ export async function campaignCreate(input) {
69
+ const storeCode = getStoreCode(input.storeCode);
70
+ const campaignPayload = {
71
+ type: input.type,
72
+ trigger: input.trigger,
73
+ translations: input.translations,
74
+ activity: input.activity,
75
+ rules: input.rules,
76
+ };
77
+ if (input.visibility)
78
+ campaignPayload.visibility = input.visibility;
79
+ if (input.audience)
80
+ campaignPayload.audience = input.audience;
81
+ if (input.limits)
82
+ campaignPayload.limits = input.limits;
83
+ if (input.active !== undefined)
84
+ campaignPayload.active = input.active;
85
+ if (input.displayOrder !== undefined)
86
+ campaignPayload.displayOrder = input.displayOrder;
87
+ if (input.labels)
88
+ campaignPayload.labels = input.labels;
89
+ if (input.event)
90
+ campaignPayload.event = input.event;
91
+ if (input.achievementId)
92
+ campaignPayload.achievementId = input.achievementId;
93
+ try {
94
+ const response = await apiPost(`/${storeCode}/campaign`, { campaign: campaignPayload });
95
+ return { campaignId: response.campaignId };
96
+ }
97
+ catch (error) {
98
+ throw formatApiError(error, "ol_campaign_create");
99
+ }
100
+ }
101
+ export async function campaignUpdate(input) {
102
+ const storeCode = getStoreCode(input.storeCode);
103
+ const campaignId = input.campaignId;
104
+ const { storeCode: _sc, campaignId: _cid, ...campaignPayload } = input;
105
+ try {
106
+ await apiPut(`/${storeCode}/campaign/${campaignId}`, { campaign: campaignPayload });
107
+ }
108
+ catch (error) {
109
+ throw formatApiError(error, "ol_campaign_update");
110
+ }
111
+ }
112
+ export async function campaignPatch(input) {
113
+ const storeCode = getStoreCode(input.storeCode);
114
+ const patchPayload = {};
115
+ if (input.active !== undefined)
116
+ patchPayload.active = input.active;
117
+ if (input.displayOrder !== undefined)
118
+ patchPayload.displayOrder = input.displayOrder;
119
+ try {
120
+ await apiPatch(`/${storeCode}/campaign/${input.campaignId}`, { campaign: patchPayload });
121
+ }
122
+ catch (error) {
123
+ throw formatApiError(error, "ol_campaign_patch");
124
+ }
125
+ }
126
+ export async function campaignDelete(input) {
127
+ const storeCode = getStoreCode(input.storeCode);
128
+ try {
129
+ await apiDelete(`/${storeCode}/campaign/${input.campaignId}`);
130
+ }
131
+ catch (error) {
132
+ throw formatApiError(error, "ol_campaign_delete");
133
+ }
134
+ }
135
+ // Simulation handler
136
+ export async function campaignSimulate(input) {
137
+ const storeCode = getStoreCode(input.storeCode);
138
+ const simulatePayload = {
139
+ trigger: input.trigger,
140
+ customer: {},
141
+ };
142
+ const customer = {};
143
+ if (input.customer.customerId)
144
+ customer.id = input.customer.customerId;
145
+ if (input.customer.id)
146
+ customer.id = input.customer.id;
147
+ if (input.customer.email)
148
+ customer.email = input.customer.email;
149
+ if (input.customer.loyaltyCardNumber)
150
+ customer.loyaltyCardNumber = input.customer.loyaltyCardNumber;
151
+ if (input.customer.phone)
152
+ customer.phone = input.customer.phone;
153
+ if (input.customer.firstName)
154
+ customer.firstName = input.customer.firstName;
155
+ if (input.customer.lastName)
156
+ customer.lastName = input.customer.lastName;
157
+ simulatePayload.customer = customer;
158
+ if (input.transaction) {
159
+ const transaction = {};
160
+ if (input.transaction.grossValue !== undefined)
161
+ transaction.grossValue = input.transaction.grossValue;
162
+ if (input.transaction.documentNumber)
163
+ transaction.documentNumber = input.transaction.documentNumber;
164
+ if (input.transaction.purchasedAt)
165
+ transaction.purchasedAt = input.transaction.purchasedAt;
166
+ if (input.transaction.documentType)
167
+ transaction.documentType = input.transaction.documentType;
168
+ if (input.transaction.purchasePlace)
169
+ transaction.purchasePlace = input.transaction.purchasePlace;
170
+ if (input.transaction.items)
171
+ transaction.items = input.transaction.items;
172
+ if (input.transaction.labels)
173
+ transaction.labels = input.transaction.labels;
174
+ simulatePayload.transaction = transaction;
175
+ }
176
+ if (input.customEvent) {
177
+ simulatePayload.event = input.customEvent.eventCode;
178
+ if (input.customEvent.attributes) {
179
+ simulatePayload.eventAttributes = input.customEvent.attributes;
180
+ }
181
+ }
182
+ if (input.referrer) {
183
+ const referrer = {};
184
+ if (input.referrer.id)
185
+ referrer.id = input.referrer.id;
186
+ if (input.referrer.email)
187
+ referrer.email = input.referrer.email;
188
+ if (input.referrer.loyaltyCardNumber)
189
+ referrer.loyaltyCardNumber = input.referrer.loyaltyCardNumber;
190
+ simulatePayload.referrer = referrer;
191
+ }
192
+ try {
193
+ const response = await apiPost(`/${storeCode}/campaign/simulate`, { simulate: simulatePayload });
194
+ const effectsByCampaign = new Map();
195
+ for (const effect of response.effects || []) {
196
+ const campaignId = effect.campaign?.campaignId || "unknown";
197
+ const campaignName = effect.campaign?.name || undefined;
198
+ if (!effectsByCampaign.has(campaignId)) {
199
+ effectsByCampaign.set(campaignId, {
200
+ campaignId,
201
+ campaignName,
202
+ effects: [],
203
+ });
204
+ }
205
+ const campaignEffect = effectsByCampaign.get(campaignId);
206
+ campaignEffect.effects.push({
207
+ type: effect.type,
208
+ target: effect.target,
209
+ points: effect.points,
210
+ wallet: effect.wallet,
211
+ rewardId: effect.rewardId,
212
+ });
213
+ }
214
+ return {
215
+ simulatedEffects: Array.from(effectsByCampaign.values()),
216
+ evaluationWarnings: response.evaluationWarnings,
217
+ simulatedMember: response.simulatedMember,
218
+ };
219
+ }
220
+ catch (error) {
221
+ throw formatApiError(error, "ol_campaign_simulate");
222
+ }
223
+ }