@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
@@ -2,8 +2,9 @@ import { z } from "zod";
2
2
  import { apiGet, apiPost, apiPut, apiDelete } from "../client/http.js";
3
3
  import { MemberSchema, } from "../types/schemas/member.js";
4
4
  import { formatApiError } from "../utils/errors.js";
5
- import { getConfig } from "../config.js";
5
+ import { getStoreCode } from "../config.js";
6
6
  import { buildPaginationParams } from "../utils/pagination.js";
7
+ import { omitUndefined } from "../utils/payload.js";
7
8
  // Input Schemas
8
9
  export const MemberCreateInputSchema = {
9
10
  storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
@@ -71,31 +72,20 @@ export const MemberAssignTierInputSchema = {
71
72
  };
72
73
  // Handler functions
73
74
  export async function memberCreate(input) {
74
- const config = getConfig();
75
- const storeCode = input.storeCode || config.defaultStoreCode;
76
- const payload = {
75
+ const storeCode = getStoreCode(input.storeCode);
76
+ const payload = omitUndefined({
77
77
  email: input.email,
78
- };
79
- if (input.firstName)
80
- payload.firstName = input.firstName;
81
- if (input.lastName)
82
- payload.lastName = input.lastName;
83
- if (input.phone)
84
- payload.phone = input.phone;
85
- if (input.birthDate)
86
- payload.birthDate = input.birthDate;
87
- if (input.gender)
88
- payload.gender = input.gender;
89
- if (input.loyaltyCardNumber)
90
- payload.loyaltyCardNumber = input.loyaltyCardNumber;
91
- if (input.agreement1 !== undefined)
92
- payload.agreement1 = input.agreement1;
93
- if (input.agreement2 !== undefined)
94
- payload.agreement2 = input.agreement2;
95
- if (input.agreement3 !== undefined)
96
- payload.agreement3 = input.agreement3;
97
- if (input.address)
98
- payload.address = input.address;
78
+ firstName: input.firstName,
79
+ lastName: input.lastName,
80
+ phone: input.phone,
81
+ birthDate: input.birthDate,
82
+ gender: input.gender,
83
+ loyaltyCardNumber: input.loyaltyCardNumber,
84
+ agreement1: input.agreement1,
85
+ agreement2: input.agreement2,
86
+ agreement3: input.agreement3,
87
+ address: input.address,
88
+ });
99
89
  try {
100
90
  const response = await apiPost(`/${storeCode}/member`, { customer: payload });
101
91
  return {
@@ -109,8 +99,7 @@ export async function memberCreate(input) {
109
99
  }
110
100
  }
111
101
  export async function memberGet(input) {
112
- const config = getConfig();
113
- const storeCode = input.storeCode || config.defaultStoreCode;
102
+ const storeCode = getStoreCode(input.storeCode);
114
103
  try {
115
104
  const response = await apiGet(`/${storeCode}/member/${input.memberId}`);
116
105
  // Map API response to our schema
@@ -141,8 +130,7 @@ export async function memberGet(input) {
141
130
  }
142
131
  }
143
132
  export async function memberList(input) {
144
- const config = getConfig();
145
- const storeCode = input.storeCode || config.defaultStoreCode;
133
+ const storeCode = getStoreCode(input.storeCode);
146
134
  const params = new URLSearchParams();
147
135
  // Use buildPaginationParams for cursor/page handling
148
136
  buildPaginationParams({ cursor: input.cursor, page: input.page, perPage: input.perPage }, params);
@@ -188,27 +176,18 @@ export async function memberList(input) {
188
176
  }
189
177
  }
190
178
  export async function memberUpdate(input) {
191
- const config = getConfig();
192
- const storeCode = input.storeCode || config.defaultStoreCode;
193
- const payload = {};
194
- if (input.firstName)
195
- payload.firstName = input.firstName;
196
- if (input.lastName)
197
- payload.lastName = input.lastName;
198
- if (input.phone)
199
- payload.phone = input.phone;
200
- if (input.birthDate)
201
- payload.birthDate = input.birthDate;
202
- if (input.gender)
203
- payload.gender = input.gender;
204
- if (input.address)
205
- payload.address = input.address;
206
- if (input.agreement1 !== undefined)
207
- payload.agreement1 = input.agreement1;
208
- if (input.agreement2 !== undefined)
209
- payload.agreement2 = input.agreement2;
210
- if (input.agreement3 !== undefined)
211
- payload.agreement3 = input.agreement3;
179
+ const storeCode = getStoreCode(input.storeCode);
180
+ const payload = omitUndefined({
181
+ firstName: input.firstName,
182
+ lastName: input.lastName,
183
+ phone: input.phone,
184
+ birthDate: input.birthDate,
185
+ gender: input.gender,
186
+ address: input.address,
187
+ agreement1: input.agreement1,
188
+ agreement2: input.agreement2,
189
+ agreement3: input.agreement3,
190
+ });
212
191
  try {
213
192
  await apiPut(`/${storeCode}/member/${input.memberId}`, { customer: payload });
214
193
  }
@@ -217,8 +196,7 @@ export async function memberUpdate(input) {
217
196
  }
218
197
  }
219
198
  export async function memberActivate(input) {
220
- const config = getConfig();
221
- const storeCode = input.storeCode || config.defaultStoreCode;
199
+ const storeCode = getStoreCode(input.storeCode);
222
200
  try {
223
201
  await apiPost(`/${storeCode}/member/${input.memberId}/activate`);
224
202
  }
@@ -227,8 +205,7 @@ export async function memberActivate(input) {
227
205
  }
228
206
  }
229
207
  export async function memberDeactivate(input) {
230
- const config = getConfig();
231
- const storeCode = input.storeCode || config.defaultStoreCode;
208
+ const storeCode = getStoreCode(input.storeCode);
232
209
  try {
233
210
  await apiPost(`/${storeCode}/member/${input.memberId}/deactivate`);
234
211
  }
@@ -237,8 +214,7 @@ export async function memberDeactivate(input) {
237
214
  }
238
215
  }
239
216
  export async function memberDelete(input) {
240
- const config = getConfig();
241
- const storeCode = input.storeCode || config.defaultStoreCode;
217
+ const storeCode = getStoreCode(input.storeCode);
242
218
  try {
243
219
  await apiDelete(`/${storeCode}/member/${input.memberId}`);
244
220
  }
@@ -247,8 +223,7 @@ export async function memberDelete(input) {
247
223
  }
248
224
  }
249
225
  export async function memberGetTierProgress(input) {
250
- const config = getConfig();
251
- const storeCode = input.storeCode || config.defaultStoreCode;
226
+ const storeCode = getStoreCode(input.storeCode);
252
227
  try {
253
228
  const response = await apiGet(`/${storeCode}/member/${input.memberId}/tier`);
254
229
  const currentLevel = response.currentLevel;
@@ -272,8 +247,7 @@ export async function memberGetTierProgress(input) {
272
247
  }
273
248
  }
274
249
  export async function memberAssignTier(input) {
275
- const config = getConfig();
276
- const storeCode = input.storeCode || config.defaultStoreCode;
250
+ const storeCode = getStoreCode(input.storeCode);
277
251
  try {
278
252
  await apiPost(`/${storeCode}/member/${input.memberId}/tier`, { levelId: input.levelId });
279
253
  }
@@ -282,8 +256,7 @@ export async function memberAssignTier(input) {
282
256
  }
283
257
  }
284
258
  export async function memberRemoveManualTier(input) {
285
- const config = getConfig();
286
- const storeCode = input.storeCode || config.defaultStoreCode;
259
+ const storeCode = getStoreCode(input.storeCode);
287
260
  try {
288
261
  // API uses POST to /remove-manually-level, not DELETE to /tier
289
262
  await apiPost(`/${storeCode}/member/${input.memberId}/remove-manually-level`);
@@ -296,62 +269,83 @@ export async function memberRemoveManualTier(input) {
296
269
  export const memberToolDefinitions = [
297
270
  {
298
271
  name: "openloyalty_member_create",
272
+ title: "Register New Member",
299
273
  description: "Register a new loyalty program member. Returns memberId for subsequent operations like points_add or member_get. Email must be unique within the store.",
274
+ readOnly: false,
300
275
  inputSchema: MemberCreateInputSchema,
301
276
  handler: memberCreate,
302
277
  },
303
278
  {
304
279
  name: "openloyalty_member_get",
280
+ title: "Get Member Profile",
305
281
  description: "Get member details including profile, points balance, and tier status. Use memberId from member_create or member_list.",
282
+ readOnly: true,
306
283
  inputSchema: MemberGetInputSchema,
307
284
  handler: memberGet,
308
285
  },
309
286
  {
310
287
  name: "openloyalty_member_list",
288
+ title: "Search Members",
311
289
  description: "Search and list members with optional filters. Use member_get for full details of a specific member. " +
312
290
  "Supports cursor pagination: provide 'cursor' from previous response to get next page.",
291
+ readOnly: true,
313
292
  inputSchema: MemberListInputSchema,
314
293
  handler: memberList,
315
294
  },
316
295
  {
317
296
  name: "openloyalty_member_update",
297
+ title: "Update Member Profile",
318
298
  description: "Update member profile fields. Cannot change email. Use member_get first to see current values.",
299
+ readOnly: false,
319
300
  inputSchema: MemberUpdateInputSchema,
320
301
  handler: memberUpdate,
321
302
  },
322
303
  {
323
304
  name: "openloyalty_member_activate",
305
+ title: "Activate Member Account",
324
306
  description: "Activate a member account. Inactive members cannot earn or spend points.",
307
+ readOnly: false,
325
308
  inputSchema: MemberIdInputSchema,
326
309
  handler: memberActivate,
327
310
  },
328
311
  {
329
312
  name: "openloyalty_member_deactivate",
313
+ title: "Deactivate Member Account",
330
314
  description: "Deactivate a member account. Deactivated members cannot earn or spend points but retain their balance.",
315
+ readOnly: false,
331
316
  inputSchema: MemberIdInputSchema,
332
317
  handler: memberDeactivate,
333
318
  },
334
319
  {
335
320
  name: "openloyalty_member_delete",
321
+ title: "Delete Member (Permanent)",
336
322
  description: "Permanently removes member and all associated data. Cannot be undone. Use for GDPR compliance or member requests.",
323
+ readOnly: false,
324
+ destructive: true,
337
325
  inputSchema: MemberIdInputSchema,
338
326
  handler: memberDelete,
339
327
  },
340
328
  {
341
329
  name: "openloyalty_member_get_tier_progress",
330
+ title: "Check Tier Progress",
342
331
  description: "Get member tier progression status showing current tier and progress to next. Returns currentValue, requiredValue, and progressPercent.",
332
+ readOnly: true,
343
333
  inputSchema: MemberIdInputSchema,
344
334
  handler: memberGetTierProgress,
345
335
  },
346
336
  {
347
337
  name: "openloyalty_member_assign_tier",
338
+ title: "Assign Tier to Member",
348
339
  description: "Manually assign a tier level to a member, overriding automatic tier calculation. Use tierset_get_tiers to find available levelId values.",
340
+ readOnly: false,
349
341
  inputSchema: MemberAssignTierInputSchema,
350
342
  handler: memberAssignTier,
351
343
  },
352
344
  {
353
345
  name: "openloyalty_member_remove_manual_tier",
346
+ title: "Remove Manual Tier Assignment",
354
347
  description: "Remove manually assigned tier from member, restoring automatic tier calculation based on conditions.",
348
+ readOnly: false,
355
349
  inputSchema: MemberIdInputSchema,
356
350
  handler: memberRemoveManualTier,
357
351
  },
@@ -119,7 +119,9 @@ export declare function pointsGetHistogram(input: {
119
119
  }>>;
120
120
  export declare const pointsToolDefinitions: readonly [{
121
121
  readonly name: "openloyalty_points_add";
122
+ readonly title: "Add Points to Member";
122
123
  readonly description: string;
124
+ readonly readOnly: false;
123
125
  readonly inputSchema: {
124
126
  storeCode: z.ZodOptional<z.ZodString>;
125
127
  memberId: z.ZodString;
@@ -132,7 +134,9 @@ export declare const pointsToolDefinitions: readonly [{
132
134
  readonly handler: typeof pointsAdd;
133
135
  }, {
134
136
  readonly name: "openloyalty_points_spend";
137
+ readonly title: "Spend Member Points";
135
138
  readonly description: string;
139
+ readonly readOnly: false;
136
140
  readonly inputSchema: {
137
141
  storeCode: z.ZodOptional<z.ZodString>;
138
142
  memberId: z.ZodString;
@@ -143,7 +147,9 @@ export declare const pointsToolDefinitions: readonly [{
143
147
  readonly handler: typeof pointsSpend;
144
148
  }, {
145
149
  readonly name: "openloyalty_points_transfer";
150
+ readonly title: "Transfer Points Between Members";
146
151
  readonly description: string;
152
+ readonly readOnly: false;
147
153
  readonly inputSchema: {
148
154
  storeCode: z.ZodOptional<z.ZodString>;
149
155
  senderId: z.ZodString;
@@ -153,7 +159,9 @@ export declare const pointsToolDefinitions: readonly [{
153
159
  readonly handler: typeof pointsTransfer;
154
160
  }, {
155
161
  readonly name: "openloyalty_points_get_balance";
162
+ readonly title: "Check Points Balance";
156
163
  readonly description: string;
164
+ readonly readOnly: true;
157
165
  readonly inputSchema: {
158
166
  storeCode: z.ZodOptional<z.ZodString>;
159
167
  memberId: z.ZodString;
@@ -162,7 +170,9 @@ export declare const pointsToolDefinitions: readonly [{
162
170
  readonly handler: typeof pointsGetBalance;
163
171
  }, {
164
172
  readonly name: "openloyalty_points_get_history";
173
+ readonly title: "View Points History";
165
174
  readonly description: string;
175
+ readonly readOnly: true;
166
176
  readonly inputSchema: {
167
177
  storeCode: z.ZodOptional<z.ZodString>;
168
178
  memberId: z.ZodString;
@@ -174,7 +184,9 @@ export declare const pointsToolDefinitions: readonly [{
174
184
  readonly handler: typeof pointsGetHistory;
175
185
  }, {
176
186
  readonly name: "openloyalty_points_get_histogram";
187
+ readonly title: "View Points Trends";
177
188
  readonly description: string;
189
+ readonly readOnly: true;
178
190
  readonly inputSchema: {
179
191
  storeCode: z.ZodOptional<z.ZodString>;
180
192
  memberId: z.ZodString;
@@ -1,8 +1,9 @@
1
1
  import { z } from "zod";
2
2
  import { apiGet, apiPost } from "../client/http.js";
3
3
  import { formatApiError, OpenLoyaltyError } from "../utils/errors.js";
4
- import { getConfig } from "../config.js";
4
+ import { getStoreCode } from "../config.js";
5
5
  import { buildPaginationParams } from "../utils/pagination.js";
6
+ import { omitUndefined } from "../utils/payload.js";
6
7
  // Input Schemas
7
8
  export const PointsAddInputSchema = {
8
9
  storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
@@ -50,19 +51,14 @@ export const PointsHistogramInputSchema = {
50
51
  };
51
52
  // Handler functions
52
53
  export async function pointsAdd(input) {
53
- const config = getConfig();
54
- const storeCode = input.storeCode || config.defaultStoreCode;
55
- const payload = {
54
+ const storeCode = getStoreCode(input.storeCode);
55
+ const payload = omitUndefined({
56
56
  points: input.points,
57
- };
58
- if (input.walletCode)
59
- payload.walletCode = input.walletCode;
60
- if (input.comment)
61
- payload.comment = input.comment;
62
- if (input.expiresInDays)
63
- payload.expiresInDays = input.expiresInDays;
64
- if (input.lockedUntilDays)
65
- payload.lockedUntilDays = input.lockedUntilDays;
57
+ walletCode: input.walletCode,
58
+ comment: input.comment,
59
+ expiresInDays: input.expiresInDays,
60
+ lockedUntilDays: input.lockedUntilDays,
61
+ });
66
62
  try {
67
63
  const response = await apiPost(`/${storeCode}/points/add`, { transfer: { customer: input.memberId, ...payload } });
68
64
  return { transferId: response.transferId };
@@ -72,15 +68,12 @@ export async function pointsAdd(input) {
72
68
  }
73
69
  }
74
70
  export async function pointsSpend(input) {
75
- const config = getConfig();
76
- const storeCode = input.storeCode || config.defaultStoreCode;
77
- const payload = {
71
+ const storeCode = getStoreCode(input.storeCode);
72
+ const payload = omitUndefined({
78
73
  points: input.points,
79
- };
80
- if (input.walletCode)
81
- payload.walletCode = input.walletCode;
82
- if (input.comment)
83
- payload.comment = input.comment;
74
+ walletCode: input.walletCode,
75
+ comment: input.comment,
76
+ });
84
77
  try {
85
78
  const response = await apiPost(`/${storeCode}/points/spend`, { transfer: { customer: input.memberId, ...payload } });
86
79
  return { transferId: response.transferId };
@@ -100,8 +93,7 @@ export async function pointsSpend(input) {
100
93
  }
101
94
  }
102
95
  export async function pointsTransfer(input) {
103
- const config = getConfig();
104
- const storeCode = input.storeCode || config.defaultStoreCode;
96
+ const storeCode = getStoreCode(input.storeCode);
105
97
  if (input.senderId === input.receiverId) {
106
98
  throw new Error("Cannot transfer points to yourself. senderId and receiverId must be different.");
107
99
  }
@@ -130,8 +122,7 @@ export async function pointsTransfer(input) {
130
122
  }
131
123
  }
132
124
  export async function pointsGetBalance(input) {
133
- const config = getConfig();
134
- const storeCode = input.storeCode || config.defaultStoreCode;
125
+ const storeCode = getStoreCode(input.storeCode);
135
126
  const params = new URLSearchParams();
136
127
  if (input.walletCode)
137
128
  params.append("walletType:code", input.walletCode);
@@ -180,8 +171,7 @@ export async function pointsGetBalance(input) {
180
171
  }
181
172
  }
182
173
  export async function pointsGetHistory(input) {
183
- const config = getConfig();
184
- const storeCode = input.storeCode || config.defaultStoreCode;
174
+ const storeCode = getStoreCode(input.storeCode);
185
175
  const params = new URLSearchParams();
186
176
  params.append("member:id", input.memberId);
187
177
  // Use buildPaginationParams for cursor/page handling
@@ -218,8 +208,7 @@ export async function pointsGetHistory(input) {
218
208
  }
219
209
  }
220
210
  export async function pointsGetHistogram(input) {
221
- const config = getConfig();
222
- const storeCode = input.storeCode || config.defaultStoreCode;
211
+ const storeCode = getStoreCode(input.storeCode);
223
212
  const params = new URLSearchParams();
224
213
  params.append("member:id", input.memberId);
225
214
  // pointType is required by the API: spent|earned|expired|pending
@@ -262,44 +251,56 @@ export async function pointsGetHistogram(input) {
262
251
  export const pointsToolDefinitions = [
263
252
  {
264
253
  name: "openloyalty_points_add",
254
+ title: "Add Points to Member",
265
255
  description: "Add points to member wallet. Points can have optional expiration and lock period. " +
266
256
  "Use for welcome bonuses, manual adjustments, or custom rewards. Returns transferId.",
257
+ readOnly: false,
267
258
  inputSchema: PointsAddInputSchema,
268
259
  handler: pointsAdd,
269
260
  },
270
261
  {
271
262
  name: "openloyalty_points_spend",
263
+ title: "Spend Member Points",
272
264
  description: "Deduct points from member wallet. Fails if insufficient balance. " +
273
265
  "Use points_get_balance first to verify available points. Returns transferId.",
266
+ readOnly: false,
274
267
  inputSchema: PointsSpendInputSchema,
275
268
  handler: pointsSpend,
276
269
  },
277
270
  {
278
271
  name: "openloyalty_points_transfer",
272
+ title: "Transfer Points Between Members",
279
273
  description: "Transfer points from one member to another (P2P transfer). " +
280
274
  "Sender must have sufficient balance. Returns transferId.",
275
+ readOnly: false,
281
276
  inputSchema: PointsTransferInputSchema,
282
277
  handler: pointsTransfer,
283
278
  },
284
279
  {
285
280
  name: "openloyalty_points_get_balance",
281
+ title: "Check Points Balance",
286
282
  description: "Get member points balance breakdown. activeUnits is available for spending. " +
287
283
  "earnedUnits shows lifetime earnings, lockedUnits shows pending points.",
284
+ readOnly: true,
288
285
  inputSchema: PointsBalanceInputSchema,
289
286
  handler: pointsGetBalance,
290
287
  },
291
288
  {
292
289
  name: "openloyalty_points_get_history",
290
+ title: "View Points History",
293
291
  description: "Get points transaction history for a member. Filter by type: adding, spending, " +
294
292
  "p2p_spending, p2p_adding, blocked, expired. Returns paginated list of transfers. " +
295
293
  "Supports cursor pagination: provide 'cursor' from previous response to get next page.",
294
+ readOnly: true,
296
295
  inputSchema: PointsHistoryInputSchema,
297
296
  handler: pointsGetHistory,
298
297
  },
299
298
  {
300
299
  name: "openloyalty_points_get_histogram",
300
+ title: "View Points Trends",
301
301
  description: "Get points histogram data for visualization. Shows earning and spending patterns over time. " +
302
302
  "Use interval (day/week/month) to aggregate data and dateFrom/dateTo to filter range.",
303
+ readOnly: true,
303
304
  inputSchema: PointsHistogramInputSchema,
304
305
  handler: pointsGetHistogram,
305
306
  },
@@ -158,7 +158,9 @@ export declare function rewardCategoryList(input: {
158
158
  }>;
159
159
  export declare const rewardToolDefinitions: readonly [{
160
160
  readonly name: "openloyalty_reward_list";
161
+ readonly title: "Browse Rewards";
161
162
  readonly description: string;
163
+ readonly readOnly: true;
162
164
  readonly inputSchema: {
163
165
  storeCode: z.ZodOptional<z.ZodString>;
164
166
  page: z.ZodOptional<z.ZodNumber>;
@@ -170,7 +172,9 @@ export declare const rewardToolDefinitions: readonly [{
170
172
  readonly handler: typeof rewardList;
171
173
  }, {
172
174
  readonly name: "openloyalty_reward_create";
175
+ readonly title: "Create New Reward";
173
176
  readonly description: string;
177
+ readonly readOnly: false;
174
178
  readonly inputSchema: {
175
179
  storeCode: z.ZodOptional<z.ZodString>;
176
180
  name: z.ZodString;
@@ -190,7 +194,9 @@ export declare const rewardToolDefinitions: readonly [{
190
194
  readonly handler: typeof rewardCreate;
191
195
  }, {
192
196
  readonly name: "openloyalty_reward_get";
197
+ readonly title: "Get Reward Details";
193
198
  readonly description: "Get full reward details including configuration, targeting, and coupon settings.";
199
+ readonly readOnly: true;
194
200
  readonly inputSchema: {
195
201
  storeCode: z.ZodOptional<z.ZodString>;
196
202
  rewardId: z.ZodString;
@@ -198,7 +204,9 @@ export declare const rewardToolDefinitions: readonly [{
198
204
  readonly handler: typeof rewardGet;
199
205
  }, {
200
206
  readonly name: "openloyalty_reward_update";
207
+ readonly title: "Update Reward";
201
208
  readonly description: "Update reward configuration. Cannot change reward type after creation.";
209
+ readonly readOnly: false;
202
210
  readonly inputSchema: {
203
211
  storeCode: z.ZodOptional<z.ZodString>;
204
212
  rewardId: z.ZodString;
@@ -213,7 +221,9 @@ export declare const rewardToolDefinitions: readonly [{
213
221
  readonly handler: typeof rewardUpdate;
214
222
  }, {
215
223
  readonly name: "openloyalty_reward_activate";
224
+ readonly title: "Activate Reward";
216
225
  readonly description: "Activate a reward, making it available for members to redeem.";
226
+ readonly readOnly: false;
217
227
  readonly inputSchema: {
218
228
  storeCode: z.ZodOptional<z.ZodString>;
219
229
  rewardId: z.ZodString;
@@ -221,7 +231,9 @@ export declare const rewardToolDefinitions: readonly [{
221
231
  readonly handler: typeof rewardActivate;
222
232
  }, {
223
233
  readonly name: "openloyalty_reward_deactivate";
234
+ readonly title: "Deactivate Reward";
224
235
  readonly description: "Deactivate a reward, hiding it from members. Already purchased rewards remain valid.";
236
+ readonly readOnly: false;
225
237
  readonly inputSchema: {
226
238
  storeCode: z.ZodOptional<z.ZodString>;
227
239
  rewardId: z.ZodString;
@@ -229,7 +241,9 @@ export declare const rewardToolDefinitions: readonly [{
229
241
  readonly handler: typeof rewardDeactivate;
230
242
  }, {
231
243
  readonly name: "openloyalty_reward_buy";
244
+ readonly title: "Redeem Reward for Member";
232
245
  readonly description: string;
246
+ readonly readOnly: false;
233
247
  readonly inputSchema: {
234
248
  storeCode: z.ZodOptional<z.ZodString>;
235
249
  rewardId: z.ZodString;
@@ -241,7 +255,9 @@ export declare const rewardToolDefinitions: readonly [{
241
255
  readonly handler: typeof rewardBuy;
242
256
  }, {
243
257
  readonly name: "openloyalty_reward_redeem";
258
+ readonly title: "Use Coupon Code";
244
259
  readonly description: string;
260
+ readonly readOnly: false;
245
261
  readonly inputSchema: {
246
262
  storeCode: z.ZodOptional<z.ZodString>;
247
263
  memberId: z.ZodString;
@@ -250,7 +266,9 @@ export declare const rewardToolDefinitions: readonly [{
250
266
  readonly handler: typeof rewardRedeem;
251
267
  }, {
252
268
  readonly name: "openloyalty_reward_category_list";
269
+ readonly title: "List Reward Categories";
253
270
  readonly description: "List reward categories. Use categoryId when creating or filtering rewards.";
271
+ readonly readOnly: true;
254
272
  readonly inputSchema: {
255
273
  storeCode: z.ZodOptional<z.ZodString>;
256
274
  page: z.ZodOptional<z.ZodNumber>;