@open-loyalty/mcp-server 1.0.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 (99) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +654 -0
  3. package/dist/client/http.d.ts +8 -0
  4. package/dist/client/http.js +69 -0
  5. package/dist/config.d.ts +17 -0
  6. package/dist/config.js +40 -0
  7. package/dist/index.d.ts +2 -0
  8. package/dist/index.js +20 -0
  9. package/dist/server.d.ts +4 -0
  10. package/dist/server.js +334 -0
  11. package/dist/tools/achievement.d.ts +983 -0
  12. package/dist/tools/achievement.js +311 -0
  13. package/dist/tools/admin.d.ts +153 -0
  14. package/dist/tools/admin.js +193 -0
  15. package/dist/tools/analytics.d.ts +162 -0
  16. package/dist/tools/analytics.js +245 -0
  17. package/dist/tools/apikey.d.ts +72 -0
  18. package/dist/tools/apikey.js +78 -0
  19. package/dist/tools/audit.d.ts +107 -0
  20. package/dist/tools/audit.js +90 -0
  21. package/dist/tools/badge.d.ts +135 -0
  22. package/dist/tools/badge.js +165 -0
  23. package/dist/tools/campaign.d.ts +1775 -0
  24. package/dist/tools/campaign.js +724 -0
  25. package/dist/tools/export.d.ts +110 -0
  26. package/dist/tools/export.js +147 -0
  27. package/dist/tools/import.d.ts +110 -0
  28. package/dist/tools/import.js +126 -0
  29. package/dist/tools/index.d.ts +22 -0
  30. package/dist/tools/index.js +527 -0
  31. package/dist/tools/member.d.ts +345 -0
  32. package/dist/tools/member.js +358 -0
  33. package/dist/tools/member.test.d.ts +1 -0
  34. package/dist/tools/member.test.js +213 -0
  35. package/dist/tools/points.d.ts +188 -0
  36. package/dist/tools/points.js +306 -0
  37. package/dist/tools/points.test.d.ts +1 -0
  38. package/dist/tools/points.test.js +292 -0
  39. package/dist/tools/reward.d.ts +261 -0
  40. package/dist/tools/reward.js +371 -0
  41. package/dist/tools/reward.test.d.ts +1 -0
  42. package/dist/tools/reward.test.js +240 -0
  43. package/dist/tools/role.d.ts +161 -0
  44. package/dist/tools/role.js +160 -0
  45. package/dist/tools/segment.d.ts +797 -0
  46. package/dist/tools/segment.js +299 -0
  47. package/dist/tools/store.d.ts +101 -0
  48. package/dist/tools/store.js +117 -0
  49. package/dist/tools/tierset.d.ts +288 -0
  50. package/dist/tools/tierset.js +244 -0
  51. package/dist/tools/transaction.d.ts +357 -0
  52. package/dist/tools/transaction.js +242 -0
  53. package/dist/tools/transaction.test.d.ts +1 -0
  54. package/dist/tools/transaction.test.js +235 -0
  55. package/dist/tools/wallet-type.d.ts +32 -0
  56. package/dist/tools/wallet-type.js +58 -0
  57. package/dist/tools/webhook.d.ts +179 -0
  58. package/dist/tools/webhook.js +171 -0
  59. package/dist/types/schemas/achievement.d.ts +1116 -0
  60. package/dist/types/schemas/achievement.js +172 -0
  61. package/dist/types/schemas/admin.d.ts +263 -0
  62. package/dist/types/schemas/admin.js +99 -0
  63. package/dist/types/schemas/analytics.d.ts +542 -0
  64. package/dist/types/schemas/analytics.js +130 -0
  65. package/dist/types/schemas/badge.d.ts +131 -0
  66. package/dist/types/schemas/badge.js +48 -0
  67. package/dist/types/schemas/campaign.d.ts +2005 -0
  68. package/dist/types/schemas/campaign.js +189 -0
  69. package/dist/types/schemas/common.d.ts +52 -0
  70. package/dist/types/schemas/common.js +26 -0
  71. package/dist/types/schemas/export.d.ts +127 -0
  72. package/dist/types/schemas/export.js +43 -0
  73. package/dist/types/schemas/import.d.ts +344 -0
  74. package/dist/types/schemas/import.js +68 -0
  75. package/dist/types/schemas/member.d.ts +443 -0
  76. package/dist/types/schemas/member.js +92 -0
  77. package/dist/types/schemas/points.d.ts +188 -0
  78. package/dist/types/schemas/points.js +54 -0
  79. package/dist/types/schemas/reward.d.ts +278 -0
  80. package/dist/types/schemas/reward.js +69 -0
  81. package/dist/types/schemas/role.d.ts +260 -0
  82. package/dist/types/schemas/role.js +75 -0
  83. package/dist/types/schemas/segment.d.ts +592 -0
  84. package/dist/types/schemas/segment.js +114 -0
  85. package/dist/types/schemas/tierset.d.ts +552 -0
  86. package/dist/types/schemas/tierset.js +87 -0
  87. package/dist/types/schemas/transaction.d.ts +1022 -0
  88. package/dist/types/schemas/transaction.js +63 -0
  89. package/dist/types/schemas/wallet-type.d.ts +99 -0
  90. package/dist/types/schemas/wallet-type.js +17 -0
  91. package/dist/types/schemas/webhook.d.ts +195 -0
  92. package/dist/types/schemas/webhook.js +39 -0
  93. package/dist/utils/cursor.d.ts +84 -0
  94. package/dist/utils/cursor.js +117 -0
  95. package/dist/utils/errors.d.ts +12 -0
  96. package/dist/utils/errors.js +69 -0
  97. package/dist/utils/pagination.d.ts +39 -0
  98. package/dist/utils/pagination.js +77 -0
  99. package/package.json +65 -0
@@ -0,0 +1,90 @@
1
+ import { z } from "zod";
2
+ import { apiGet, apiPost } from "../client/http.js";
3
+ import { formatApiError } from "../utils/errors.js";
4
+ // Input Schemas
5
+ export const AuditListInputSchema = {
6
+ page: z.number().optional().describe("Page number (default: 1)."),
7
+ perPage: z.number().optional().describe("Items per page (default: 25)."),
8
+ eventType: z.string().optional().describe("Filter by event type."),
9
+ entityId: z.string().optional().describe("Filter by entity ID."),
10
+ entityType: z.string().optional().describe("Filter by entity type (e.g., MEMBER, CAMPAIGN)."),
11
+ username: z.string().optional().describe("Filter by username who performed the action."),
12
+ dateFrom: z.string().optional().describe("Filter by creation date from (ISO format)."),
13
+ dateTo: z.string().optional().describe("Filter by creation date to (ISO format)."),
14
+ store: z.string().optional().describe("Filter by store code."),
15
+ };
16
+ export const AuditExportInputSchema = {
17
+ dateFrom: z.string().optional().describe("Export logs from this date (ISO format)."),
18
+ dateTo: z.string().optional().describe("Export logs to this date (ISO format)."),
19
+ page: z.number().optional().describe("Page number for export."),
20
+ perPage: z.number().optional().describe("Items per page for export."),
21
+ };
22
+ // Handler functions
23
+ export async function auditList(input) {
24
+ const params = new URLSearchParams();
25
+ if (input.page)
26
+ params.append("_page", String(input.page));
27
+ if (input.perPage)
28
+ params.append("_itemsOnPage", String(input.perPage));
29
+ if (input.eventType)
30
+ params.append("eventType", input.eventType);
31
+ if (input.entityId)
32
+ params.append("entityId", input.entityId);
33
+ if (input.entityType)
34
+ params.append("entityType", input.entityType);
35
+ if (input.username)
36
+ params.append("username", input.username);
37
+ if (input.dateFrom)
38
+ params.append("createdAt[gte]", input.dateFrom);
39
+ if (input.dateTo)
40
+ params.append("createdAt[lte]", input.dateTo);
41
+ if (input.store)
42
+ params.append("store", input.store);
43
+ const queryString = params.toString();
44
+ const url = `/audit/log${queryString ? `?${queryString}` : ""}`;
45
+ try {
46
+ const response = await apiGet(url);
47
+ return response;
48
+ }
49
+ catch (error) {
50
+ throw formatApiError(error, "openloyalty_audit_list");
51
+ }
52
+ }
53
+ export async function auditExport(input) {
54
+ const payload = {};
55
+ const systemLogPayload = {};
56
+ if (input.dateFrom || input.dateTo) {
57
+ systemLogPayload.createdAt = {};
58
+ if (input.dateFrom)
59
+ systemLogPayload.createdAt.gte = input.dateFrom;
60
+ if (input.dateTo)
61
+ systemLogPayload.createdAt.lte = input.dateTo;
62
+ }
63
+ if (input.page)
64
+ systemLogPayload._page = input.page;
65
+ if (input.perPage)
66
+ systemLogPayload._itemsOnPage = input.perPage;
67
+ payload.systemLog = systemLogPayload;
68
+ try {
69
+ const response = await apiPost("/system-log/export", payload);
70
+ return response;
71
+ }
72
+ catch (error) {
73
+ throw formatApiError(error, "openloyalty_audit_export");
74
+ }
75
+ }
76
+ // Tool definitions
77
+ export const auditToolDefinitions = [
78
+ {
79
+ name: "openloyalty_audit_list",
80
+ description: "List audit log entries with optional filtering. Returns paginated list of audit entries with auditLogId, eventType, entityType, entityId, username, timestamp, and details. Audit logs track all administrative actions. Use for compliance and troubleshooting.",
81
+ inputSchema: AuditListInputSchema,
82
+ handler: auditList,
83
+ },
84
+ {
85
+ name: "openloyalty_audit_export",
86
+ description: "Create an export of system logs. Returns exportId that can be used to track export status. The export will be processed asynchronously. Use date filters to scope the export range.",
87
+ inputSchema: AuditExportInputSchema,
88
+ handler: auditExport,
89
+ },
90
+ ];
@@ -0,0 +1,135 @@
1
+ import { z } from "zod";
2
+ import { BadgeTypeListItem, MemberBadge } from "../types/schemas/badge.js";
3
+ export declare const BadgeListInputSchema: {
4
+ storeCode: z.ZodOptional<z.ZodString>;
5
+ page: z.ZodOptional<z.ZodNumber>;
6
+ perPage: z.ZodOptional<z.ZodNumber>;
7
+ name: z.ZodOptional<z.ZodString>;
8
+ badgeTypeId: z.ZodOptional<z.ZodString>;
9
+ };
10
+ export declare const BadgeGetInputSchema: {
11
+ storeCode: z.ZodOptional<z.ZodString>;
12
+ badgeTypeId: z.ZodString;
13
+ };
14
+ export declare const BadgeUpdateInputSchema: {
15
+ storeCode: z.ZodOptional<z.ZodString>;
16
+ badgeTypeId: z.ZodString;
17
+ name: z.ZodOptional<z.ZodString>;
18
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
19
+ name: z.ZodString;
20
+ description: z.ZodOptional<z.ZodString>;
21
+ }, "strip", z.ZodTypeAny, {
22
+ name: string;
23
+ description?: string | undefined;
24
+ }, {
25
+ name: string;
26
+ description?: string | undefined;
27
+ }>>>;
28
+ imageUrl: z.ZodOptional<z.ZodString>;
29
+ active: z.ZodOptional<z.ZodBoolean>;
30
+ };
31
+ export declare const BadgeGetMemberBadgesInputSchema: {
32
+ storeCode: z.ZodOptional<z.ZodString>;
33
+ memberId: z.ZodString;
34
+ page: z.ZodOptional<z.ZodNumber>;
35
+ perPage: z.ZodOptional<z.ZodNumber>;
36
+ name: z.ZodOptional<z.ZodString>;
37
+ badgeTypeId: z.ZodOptional<z.ZodString>;
38
+ };
39
+ export declare function badgeList(input: {
40
+ storeCode?: string;
41
+ page?: number;
42
+ perPage?: number;
43
+ name?: string;
44
+ badgeTypeId?: string;
45
+ }): Promise<{
46
+ badges: BadgeTypeListItem[];
47
+ total: {
48
+ all?: number;
49
+ filtered?: number;
50
+ };
51
+ }>;
52
+ export declare function badgeGet(input: {
53
+ storeCode?: string;
54
+ badgeTypeId: string;
55
+ }): Promise<Record<string, unknown>>;
56
+ interface BadgeUpdateInput {
57
+ storeCode?: string;
58
+ badgeTypeId: string;
59
+ name?: string;
60
+ translations?: Record<string, {
61
+ name: string;
62
+ description?: string;
63
+ }>;
64
+ imageUrl?: string;
65
+ active?: boolean;
66
+ }
67
+ export declare function badgeUpdate(input: BadgeUpdateInput): Promise<void>;
68
+ export declare function badgeGetMemberBadges(input: {
69
+ storeCode?: string;
70
+ memberId: string;
71
+ page?: number;
72
+ perPage?: number;
73
+ name?: string;
74
+ badgeTypeId?: string;
75
+ }): Promise<{
76
+ badges: MemberBadge[];
77
+ total: {
78
+ all?: number;
79
+ filtered?: number;
80
+ };
81
+ }>;
82
+ export declare const badgeToolDefinitions: readonly [{
83
+ readonly name: "openloyalty_badge_list";
84
+ readonly 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.";
85
+ readonly inputSchema: {
86
+ storeCode: z.ZodOptional<z.ZodString>;
87
+ page: z.ZodOptional<z.ZodNumber>;
88
+ perPage: z.ZodOptional<z.ZodNumber>;
89
+ name: z.ZodOptional<z.ZodString>;
90
+ badgeTypeId: z.ZodOptional<z.ZodString>;
91
+ };
92
+ readonly handler: typeof badgeList;
93
+ }, {
94
+ readonly name: "openloyalty_badge_get";
95
+ readonly description: "Get badge type details including name, image URL, and linked achievements count.";
96
+ readonly inputSchema: {
97
+ storeCode: z.ZodOptional<z.ZodString>;
98
+ badgeTypeId: z.ZodString;
99
+ };
100
+ readonly handler: typeof badgeGet;
101
+ }, {
102
+ readonly name: "openloyalty_badge_update";
103
+ readonly description: "Update badge type configuration. Badge types are created automatically when referenced by achievements. Use this to update name, image, or translations.";
104
+ readonly inputSchema: {
105
+ storeCode: z.ZodOptional<z.ZodString>;
106
+ badgeTypeId: z.ZodString;
107
+ name: z.ZodOptional<z.ZodString>;
108
+ translations: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
109
+ name: z.ZodString;
110
+ description: z.ZodOptional<z.ZodString>;
111
+ }, "strip", z.ZodTypeAny, {
112
+ name: string;
113
+ description?: string | undefined;
114
+ }, {
115
+ name: string;
116
+ description?: string | undefined;
117
+ }>>>;
118
+ imageUrl: z.ZodOptional<z.ZodString>;
119
+ active: z.ZodOptional<z.ZodBoolean>;
120
+ };
121
+ readonly handler: typeof badgeUpdate;
122
+ }, {
123
+ readonly name: "openloyalty_badge_get_member_badges";
124
+ readonly 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.";
125
+ readonly inputSchema: {
126
+ storeCode: z.ZodOptional<z.ZodString>;
127
+ memberId: z.ZodString;
128
+ page: z.ZodOptional<z.ZodNumber>;
129
+ perPage: z.ZodOptional<z.ZodNumber>;
130
+ name: z.ZodOptional<z.ZodString>;
131
+ badgeTypeId: z.ZodOptional<z.ZodString>;
132
+ };
133
+ readonly handler: typeof badgeGetMemberBadges;
134
+ }];
135
+ export {};
@@ -0,0 +1,165 @@
1
+ import { z } from "zod";
2
+ import { apiGet, apiPut } from "../client/http.js";
3
+ import { formatApiError } from "../utils/errors.js";
4
+ import { getConfig } from "../config.js";
5
+ // Input Schemas
6
+ export const BadgeListInputSchema = {
7
+ storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
8
+ page: z.number().optional().describe("Page number (default: 1)."),
9
+ perPage: z.number().optional().describe("Items per page (default: 10)."),
10
+ name: z.string().optional().describe("Filter by badge name."),
11
+ badgeTypeId: z.string().optional().describe("Filter by specific badge type ID."),
12
+ };
13
+ export const BadgeGetInputSchema = {
14
+ storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
15
+ badgeTypeId: z.string().describe("The badge type ID (UUID) to retrieve."),
16
+ };
17
+ export const BadgeUpdateInputSchema = {
18
+ storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
19
+ badgeTypeId: z.string().describe("The badge type ID (UUID) to update."),
20
+ name: z.string().optional().describe("Badge name."),
21
+ translations: z.record(z.string(), z.object({
22
+ name: z.string(),
23
+ description: z.string().optional(),
24
+ })).optional().describe("Badge translations."),
25
+ imageUrl: z.string().optional().describe("URL to badge image."),
26
+ active: z.boolean().optional().describe("Whether badge type is active."),
27
+ };
28
+ export const BadgeGetMemberBadgesInputSchema = {
29
+ storeCode: z.string().optional().describe("Store code. If not provided, uses the default store code from configuration."),
30
+ memberId: z.string().describe("The member ID (UUID)."),
31
+ page: z.number().optional().describe("Page number (default: 1)."),
32
+ perPage: z.number().optional().describe("Items per page (default: 10)."),
33
+ name: z.string().optional().describe("Filter by badge name."),
34
+ badgeTypeId: z.string().optional().describe("Filter by specific badge type ID."),
35
+ };
36
+ // Handler functions
37
+ export async function badgeList(input) {
38
+ const config = getConfig();
39
+ const storeCode = input.storeCode || config.defaultStoreCode;
40
+ const params = new URLSearchParams();
41
+ if (input.page)
42
+ params.append("_page", String(input.page));
43
+ if (input.perPage)
44
+ params.append("_itemsOnPage", String(input.perPage));
45
+ if (input.name)
46
+ params.append("name", input.name);
47
+ if (input.badgeTypeId)
48
+ params.append("badgeTypeId", input.badgeTypeId);
49
+ const queryString = params.toString();
50
+ const url = `/${storeCode}/badge-type${queryString ? `?${queryString}` : ""}`;
51
+ try {
52
+ const response = await apiGet(url);
53
+ const badges = (response.items || []).map((item) => ({
54
+ badgeTypeId: item.badgeTypeId,
55
+ name: item.name,
56
+ createdAt: item.createdAt,
57
+ updatedAt: item.updatedAt,
58
+ }));
59
+ const total = response.total || {};
60
+ return {
61
+ badges,
62
+ total: {
63
+ all: typeof total.all === "number" ? total.all : undefined,
64
+ filtered: typeof total.filtered === "number" ? total.filtered : undefined,
65
+ },
66
+ };
67
+ }
68
+ catch (error) {
69
+ throw formatApiError(error, "openloyalty_badge_list");
70
+ }
71
+ }
72
+ export async function badgeGet(input) {
73
+ const config = getConfig();
74
+ const storeCode = input.storeCode || config.defaultStoreCode;
75
+ try {
76
+ const response = await apiGet(`/${storeCode}/badge-type/${input.badgeTypeId}`);
77
+ return response;
78
+ }
79
+ catch (error) {
80
+ throw formatApiError(error, "openloyalty_badge_get");
81
+ }
82
+ }
83
+ export async function badgeUpdate(input) {
84
+ const config = getConfig();
85
+ const storeCode = input.storeCode || config.defaultStoreCode;
86
+ const badgePayload = {};
87
+ if (input.name !== undefined)
88
+ badgePayload.name = input.name;
89
+ if (input.translations)
90
+ badgePayload.translations = input.translations;
91
+ if (input.imageUrl !== undefined)
92
+ badgePayload.imageUrl = input.imageUrl;
93
+ if (input.active !== undefined)
94
+ badgePayload.active = input.active;
95
+ try {
96
+ // CRITICAL: Wrap body as { badgeType: {...} }
97
+ await apiPut(`/${storeCode}/badge-type/${input.badgeTypeId}`, { badgeType: badgePayload });
98
+ }
99
+ catch (error) {
100
+ throw formatApiError(error, "openloyalty_badge_update");
101
+ }
102
+ }
103
+ export async function badgeGetMemberBadges(input) {
104
+ const config = getConfig();
105
+ const storeCode = input.storeCode || config.defaultStoreCode;
106
+ const params = new URLSearchParams();
107
+ if (input.page)
108
+ params.append("_page", String(input.page));
109
+ if (input.perPage)
110
+ params.append("_itemsOnPage", String(input.perPage));
111
+ if (input.name)
112
+ params.append("name", input.name);
113
+ if (input.badgeTypeId)
114
+ params.append("badgeTypeId", input.badgeTypeId);
115
+ const queryString = params.toString();
116
+ const url = `/${storeCode}/member/${input.memberId}/badge${queryString ? `?${queryString}` : ""}`;
117
+ try {
118
+ const response = await apiGet(url);
119
+ const badges = (response.items || []).map((item) => ({
120
+ badgeTypeId: item.badgeTypeId,
121
+ name: item.name,
122
+ completedCount: item.completedCount,
123
+ createdAt: item.createdAt,
124
+ updatedAt: item.updatedAt,
125
+ }));
126
+ const total = response.total || {};
127
+ return {
128
+ badges,
129
+ total: {
130
+ all: typeof total.all === "number" ? total.all : undefined,
131
+ filtered: typeof total.filtered === "number" ? total.filtered : undefined,
132
+ },
133
+ };
134
+ }
135
+ catch (error) {
136
+ throw formatApiError(error, "openloyalty_badge_get_member_badges");
137
+ }
138
+ }
139
+ // Tool definitions
140
+ export const badgeToolDefinitions = [
141
+ {
142
+ name: "openloyalty_badge_list",
143
+ 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.",
144
+ inputSchema: BadgeListInputSchema,
145
+ handler: badgeList,
146
+ },
147
+ {
148
+ name: "openloyalty_badge_get",
149
+ description: "Get badge type details including name, image URL, and linked achievements count.",
150
+ inputSchema: BadgeGetInputSchema,
151
+ handler: badgeGet,
152
+ },
153
+ {
154
+ name: "openloyalty_badge_update",
155
+ description: "Update badge type configuration. Badge types are created automatically when referenced by achievements. Use this to update name, image, or translations.",
156
+ inputSchema: BadgeUpdateInputSchema,
157
+ handler: badgeUpdate,
158
+ },
159
+ {
160
+ name: "openloyalty_badge_get_member_badges",
161
+ 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.",
162
+ inputSchema: BadgeGetMemberBadgesInputSchema,
163
+ handler: badgeGetMemberBadges,
164
+ },
165
+ ];