@wilnertech/halopsa-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 (76) hide show
  1. package/.env.example +19 -0
  2. package/LICENSE +21 -0
  3. package/README.md +270 -0
  4. package/dist/api/client.d.ts +85 -0
  5. package/dist/api/client.d.ts.map +1 -0
  6. package/dist/api/client.js +297 -0
  7. package/dist/api/client.js.map +1 -0
  8. package/dist/api/errors.d.ts +60 -0
  9. package/dist/api/errors.d.ts.map +1 -0
  10. package/dist/api/errors.js +188 -0
  11. package/dist/api/errors.js.map +1 -0
  12. package/dist/cache/memory-cache.d.ts +89 -0
  13. package/dist/cache/memory-cache.d.ts.map +1 -0
  14. package/dist/cache/memory-cache.js +175 -0
  15. package/dist/cache/memory-cache.js.map +1 -0
  16. package/dist/cache/prewarm.d.ts +12 -0
  17. package/dist/cache/prewarm.d.ts.map +1 -0
  18. package/dist/cache/prewarm.js +55 -0
  19. package/dist/cache/prewarm.js.map +1 -0
  20. package/dist/index.d.ts +12 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +141 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/schemas/common.d.ts +212 -0
  25. package/dist/schemas/common.d.ts.map +1 -0
  26. package/dist/schemas/common.js +127 -0
  27. package/dist/schemas/common.js.map +1 -0
  28. package/dist/tools/assets.d.ts +482 -0
  29. package/dist/tools/assets.d.ts.map +1 -0
  30. package/dist/tools/assets.js +732 -0
  31. package/dist/tools/assets.js.map +1 -0
  32. package/dist/tools/batch-operations.d.ts +125 -0
  33. package/dist/tools/batch-operations.d.ts.map +1 -0
  34. package/dist/tools/batch-operations.js +207 -0
  35. package/dist/tools/batch-operations.js.map +1 -0
  36. package/dist/tools/clients.d.ts +145 -0
  37. package/dist/tools/clients.d.ts.map +1 -0
  38. package/dist/tools/clients.js +148 -0
  39. package/dist/tools/clients.js.map +1 -0
  40. package/dist/tools/reference-data.d.ts +118 -0
  41. package/dist/tools/reference-data.d.ts.map +1 -0
  42. package/dist/tools/reference-data.js +103 -0
  43. package/dist/tools/reference-data.js.map +1 -0
  44. package/dist/tools/registrations.d.ts +7 -0
  45. package/dist/tools/registrations.d.ts.map +1 -0
  46. package/dist/tools/registrations.js +61 -0
  47. package/dist/tools/registrations.js.map +1 -0
  48. package/dist/tools/registry.d.ts +67 -0
  49. package/dist/tools/registry.d.ts.map +1 -0
  50. package/dist/tools/registry.js +71 -0
  51. package/dist/tools/registry.js.map +1 -0
  52. package/dist/tools/sites.d.ts +188 -0
  53. package/dist/tools/sites.d.ts.map +1 -0
  54. package/dist/tools/sites.js +258 -0
  55. package/dist/tools/sites.js.map +1 -0
  56. package/dist/tools/users.d.ts +317 -0
  57. package/dist/tools/users.d.ts.map +1 -0
  58. package/dist/tools/users.js +489 -0
  59. package/dist/tools/users.js.map +1 -0
  60. package/dist/types/halopsa.d.ts +212 -0
  61. package/dist/types/halopsa.d.ts.map +1 -0
  62. package/dist/types/halopsa.js +8 -0
  63. package/dist/types/halopsa.js.map +1 -0
  64. package/dist/utils/formatter.d.ts +18 -0
  65. package/dist/utils/formatter.d.ts.map +1 -0
  66. package/dist/utils/formatter.js +178 -0
  67. package/dist/utils/formatter.js.map +1 -0
  68. package/dist/utils/similarity.d.ts +25 -0
  69. package/dist/utils/similarity.d.ts.map +1 -0
  70. package/dist/utils/similarity.js +90 -0
  71. package/dist/utils/similarity.js.map +1 -0
  72. package/dist/utils/zod-to-schema.d.ts +29 -0
  73. package/dist/utils/zod-to-schema.d.ts.map +1 -0
  74. package/dist/utils/zod-to-schema.js +182 -0
  75. package/dist/utils/zod-to-schema.js.map +1 -0
  76. package/package.json +61 -0
@@ -0,0 +1,489 @@
1
+ /**
2
+ * HaloPSA User tools with token optimization
3
+ * Provides CRUD operations for users with caching and deduplication
4
+ *
5
+ * CRITICAL: Users are a secondary billing entity
6
+ * - Only ACTIVE users (inactive=false) count toward billing
7
+ * - Duplicates cause billing errors = revenue loss
8
+ */
9
+ import { z } from 'zod';
10
+ import { formatResponse } from '../utils/formatter.js';
11
+ import { TTL } from '../cache/memory-cache.js';
12
+ import { FormatOptionsSchema, ConfidenceThresholds } from '../schemas/common.js';
13
+ // =============================================================================
14
+ // Zod Schemas for Input Validation
15
+ // =============================================================================
16
+ /**
17
+ * List users schema
18
+ */
19
+ export const ListUsersArgsSchema = z.object({
20
+ client_id: z.number().int().optional()
21
+ .describe('Filter by client ID (REQUIRED for multi-tenant environments)'),
22
+ site_id: z.number().int().optional()
23
+ .describe('Filter by site/location ID'),
24
+ search: z.string().optional()
25
+ .describe('Search term'),
26
+ count: z.number().int().min(1).max(100).optional()
27
+ .describe('Number of results per page (max 100, default 50)'),
28
+ page_no: z.number().int().min(1).optional()
29
+ .describe('Page number (1-indexed, default 1)'),
30
+ includeactive: z.boolean().optional()
31
+ .describe('Include active users (default true)'),
32
+ includeinactive: z.boolean().optional()
33
+ .describe('Include inactive users (default false)'),
34
+ format_options: FormatOptionsSchema,
35
+ });
36
+ /**
37
+ * Get single user schema
38
+ */
39
+ export const GetUserArgsSchema = z.object({
40
+ user_id: z.number().int()
41
+ .describe('HaloPSA user ID'),
42
+ format_options: FormatOptionsSchema,
43
+ });
44
+ /**
45
+ * Search users by email schema
46
+ */
47
+ export const SearchUsersByEmailArgsSchema = z.object({
48
+ email: z.string().email()
49
+ .describe('Email address to search for (primary match field)'),
50
+ client_id: z.number().int().optional()
51
+ .describe('Limit search to specific client'),
52
+ format_options: FormatOptionsSchema,
53
+ });
54
+ /**
55
+ * Create user schema
56
+ */
57
+ export const CreateUserArgsSchema = z.object({
58
+ client_id: z.number().int()
59
+ .describe('Client ID to create user under'),
60
+ site_id: z.number().int().optional()
61
+ .describe('Site/location ID'),
62
+ name: z.string().min(1)
63
+ .describe('Full name'),
64
+ emailaddress: z.string().email().optional()
65
+ .describe('Email address (PRIMARY deduplication field)'),
66
+ username: z.string().optional()
67
+ .describe('Windows username'),
68
+ inactive: z.boolean().optional()
69
+ .describe('Inactive status (false=Active, counts for billing)'),
70
+ user_customfields: z.array(z.object({
71
+ id: z.number().int(),
72
+ value: z.string(),
73
+ })).optional()
74
+ .describe('Custom fields array (e.g., UPN)'),
75
+ });
76
+ /**
77
+ * Update user schema
78
+ */
79
+ export const UpdateUserArgsSchema = z.object({
80
+ user_id: z.number().int()
81
+ .describe('HaloPSA user ID to update'),
82
+ site_id: z.number().int().optional()
83
+ .describe('Site/location ID'),
84
+ name: z.string().min(1).optional()
85
+ .describe('Full name'),
86
+ emailaddress: z.string().email().optional()
87
+ .describe('Email address'),
88
+ username: z.string().optional()
89
+ .describe('Windows username'),
90
+ inactive: z.boolean().optional()
91
+ .describe('Inactive status'),
92
+ user_customfields: z.array(z.object({
93
+ id: z.number().int(),
94
+ value: z.string(),
95
+ })).optional()
96
+ .describe('Custom fields array'),
97
+ });
98
+ /**
99
+ * Find user match schema (deduplication)
100
+ */
101
+ export const FindUserMatchArgsSchema = z.object({
102
+ email: z.string().email().optional()
103
+ .describe('Email address (primary match field)'),
104
+ upn: z.string().optional()
105
+ .describe('User Principal Name from Entra (secondary match field)'),
106
+ username: z.string().optional()
107
+ .describe('Windows username (tertiary match field)'),
108
+ client_id: z.number().int()
109
+ .describe('Client ID to scope search'),
110
+ });
111
+ /**
112
+ * Scan user duplicates schema
113
+ */
114
+ export const ScanUserDuplicatesArgsSchema = z.object({
115
+ client_id: z.number().int().optional()
116
+ .describe('Limit scan to specific client'),
117
+ format_options: FormatOptionsSchema,
118
+ });
119
+ // =============================================================================
120
+ // Tool Implementations
121
+ // =============================================================================
122
+ /**
123
+ * List users with optional filtering and token optimization
124
+ * Uses 1-minute cache TTL (billing-critical data)
125
+ */
126
+ export async function listUsers(client, args) {
127
+ const params = {};
128
+ // Build query parameters
129
+ if (args.client_id !== undefined) {
130
+ params.client_id = args.client_id;
131
+ }
132
+ if (args.site_id !== undefined) {
133
+ params.site_id = args.site_id;
134
+ }
135
+ if (args.search !== undefined) {
136
+ params.search = args.search;
137
+ }
138
+ if (args.count !== undefined) {
139
+ params.count = args.count;
140
+ }
141
+ if (args.page_no !== undefined) {
142
+ params.page_no = args.page_no;
143
+ }
144
+ if (args.includeactive !== undefined) {
145
+ params.includeactive = args.includeactive;
146
+ }
147
+ if (args.includeinactive !== undefined) {
148
+ params.includeinactive = args.includeinactive;
149
+ }
150
+ const formatOptions = args.format_options || {};
151
+ // Generate cache key based on filters
152
+ const cacheKey = `users:client_${args.client_id || 'all'}:site_${args.site_id || 'all'}`;
153
+ const response = await client.getCached('/Users', params, {
154
+ enabled: true,
155
+ ttl: TTL.USER_LIST,
156
+ keyPrefix: cacheKey,
157
+ });
158
+ return formatResponse(response.users, formatOptions, { record_count: response.record_count });
159
+ }
160
+ /**
161
+ * Get a single user by ID with full details
162
+ */
163
+ export async function getUser(client, args) {
164
+ const formatOptions = args.format_options || {};
165
+ const response = await client.get(`/Users/${args.user_id}`);
166
+ return formatResponse(response, formatOptions);
167
+ }
168
+ /**
169
+ * Search users by email address
170
+ * Returns warning if multiple found (potential duplicates)
171
+ */
172
+ export async function searchUsersByEmail(client, args) {
173
+ const params = {
174
+ search: args.email,
175
+ count: 100,
176
+ includeactive: true,
177
+ includeinactive: true,
178
+ };
179
+ if (args.client_id !== undefined) {
180
+ params.client_id = args.client_id;
181
+ }
182
+ const formatOptions = args.format_options || {};
183
+ // No caching for search results
184
+ const response = await client.get('/Users', params);
185
+ // Filter to exact email matches
186
+ const exactMatches = response.users.filter((user) => user.emailaddress?.toLowerCase() === args.email.toLowerCase());
187
+ if (exactMatches.length === 0) {
188
+ return JSON.stringify({
189
+ email: args.email,
190
+ matches: [],
191
+ count: 0,
192
+ message: 'No users found with this email address',
193
+ });
194
+ }
195
+ // Warning if duplicates found
196
+ const warning = exactMatches.length > 1
197
+ ? `WARNING: Multiple users found with email ${args.email}. Potential duplicates detected.`
198
+ : undefined;
199
+ const result = {
200
+ email: args.email,
201
+ matches: JSON.parse(formatResponse(exactMatches, formatOptions)),
202
+ count: exactMatches.length,
203
+ ...(warning && { warning }),
204
+ };
205
+ return JSON.stringify(result, null, 2);
206
+ }
207
+ /**
208
+ * Create a new user
209
+ * Invalidates user cache on success
210
+ */
211
+ export async function createUser(client, args) {
212
+ const userData = {
213
+ client_id: args.client_id,
214
+ name: args.name,
215
+ };
216
+ // Add optional fields
217
+ if (args.site_id !== undefined) {
218
+ userData.site_id = args.site_id;
219
+ }
220
+ if (args.emailaddress !== undefined) {
221
+ userData.emailaddress = args.emailaddress;
222
+ }
223
+ if (args.username !== undefined) {
224
+ userData.username = args.username;
225
+ }
226
+ if (args.inactive !== undefined) {
227
+ userData.inactive = args.inactive;
228
+ }
229
+ if (args.user_customfields !== undefined) {
230
+ userData.user_customfields = args.user_customfields;
231
+ }
232
+ const response = await client.post('/Users', userData);
233
+ // Invalidate user caches
234
+ client.invalidateCache(`users:client_${args.client_id}*`);
235
+ client.invalidateCache('users:client_all*');
236
+ return formatResponse(response, { format: 'detailed' });
237
+ }
238
+ /**
239
+ * Update an existing user
240
+ * Invalidates user cache on success
241
+ */
242
+ export async function updateUser(client, args) {
243
+ const userData = {};
244
+ // Build update payload with only provided fields
245
+ if (args.site_id !== undefined) {
246
+ userData.site_id = args.site_id;
247
+ }
248
+ if (args.name !== undefined) {
249
+ userData.name = args.name;
250
+ }
251
+ if (args.emailaddress !== undefined) {
252
+ userData.emailaddress = args.emailaddress;
253
+ }
254
+ if (args.username !== undefined) {
255
+ userData.username = args.username;
256
+ }
257
+ if (args.inactive !== undefined) {
258
+ userData.inactive = args.inactive;
259
+ }
260
+ if (args.user_customfields !== undefined) {
261
+ userData.user_customfields = args.user_customfields;
262
+ }
263
+ if (Object.keys(userData).length === 0) {
264
+ return JSON.stringify({
265
+ error: true,
266
+ message: 'At least one field must be provided for update',
267
+ }, null, 2);
268
+ }
269
+ // HaloPSA uses POST for updates
270
+ const response = await client.post(`/Users/${args.user_id}`, userData);
271
+ // Invalidate user caches
272
+ client.invalidateCache('users:*');
273
+ return formatResponse(response, { format: 'detailed' });
274
+ }
275
+ /**
276
+ * Find matching user using deduplication algorithm
277
+ * Returns confidence scoring and action recommendation
278
+ *
279
+ * Confidence Thresholds:
280
+ * - 100%: Exact email match -> Auto-update
281
+ * - 95%: UPN match (Entra source of truth) -> Auto-update
282
+ * - 70%: Username match only -> Manual review
283
+ * - 0%: No match -> Create new
284
+ */
285
+ export async function findUserMatch(client, args) {
286
+ // Get all users for client with caching
287
+ const response = await client.getCached('/Users', {
288
+ client_id: args.client_id,
289
+ count: 1000,
290
+ includeactive: true,
291
+ includeinactive: true,
292
+ }, {
293
+ enabled: true,
294
+ ttl: TTL.USER_LIST,
295
+ keyPrefix: `users:client_${args.client_id}`,
296
+ });
297
+ if (!response.users || response.users.length === 0) {
298
+ return JSON.stringify({
299
+ match: null,
300
+ confidence: 0,
301
+ matchField: 'none',
302
+ action: 'CreateNew',
303
+ }, null, 2);
304
+ }
305
+ // 1. Exact email match (100% confidence)
306
+ if (args.email) {
307
+ const emailMatch = response.users.find((user) => user.emailaddress?.toLowerCase() === args.email?.toLowerCase());
308
+ if (emailMatch) {
309
+ return JSON.stringify({
310
+ match: emailMatch,
311
+ confidence: ConfidenceThresholds.USER_EMAIL_EXACT,
312
+ matchField: 'email (exact)',
313
+ action: 'Update',
314
+ }, null, 2);
315
+ }
316
+ }
317
+ // 2. UPN match (95% confidence - Entra is source of truth)
318
+ if (args.upn) {
319
+ const upnMatch = response.users.find((user) => {
320
+ const upnField = user.user_customfields?.find((cf) => cf.name.toLowerCase() === 'upn');
321
+ return upnField?.value?.toLowerCase() === args.upn?.toLowerCase();
322
+ });
323
+ if (upnMatch) {
324
+ return JSON.stringify({
325
+ match: upnMatch,
326
+ confidence: ConfidenceThresholds.USER_UPN_MATCH,
327
+ matchField: 'upn (Entra)',
328
+ action: 'Update',
329
+ }, null, 2);
330
+ }
331
+ }
332
+ // 3. Username match only (70% confidence - requires manual review)
333
+ if (args.username) {
334
+ const usernameMatch = response.users.find((user) => user.username?.toLowerCase() === args.username?.toLowerCase());
335
+ if (usernameMatch) {
336
+ return JSON.stringify({
337
+ match: usernameMatch,
338
+ confidence: ConfidenceThresholds.USER_USERNAME_ONLY,
339
+ matchField: 'username (no email match)',
340
+ action: 'ManualReview',
341
+ warning: 'Username match found but email does not match. Manual review required.',
342
+ }, null, 2);
343
+ }
344
+ }
345
+ // 4. No match found - create new
346
+ return JSON.stringify({
347
+ match: null,
348
+ confidence: 0,
349
+ matchField: 'none',
350
+ action: 'CreateNew',
351
+ }, null, 2);
352
+ }
353
+ /**
354
+ * Scan for duplicate users
355
+ * Returns groups of duplicate entities with confidence scores
356
+ */
357
+ export async function scanUserDuplicates(client, args) {
358
+ const formatOptions = args.format_options || {};
359
+ const params = {
360
+ count: 1000,
361
+ includeactive: true,
362
+ includeinactive: true,
363
+ };
364
+ if (args.client_id !== undefined) {
365
+ params.client_id = args.client_id;
366
+ }
367
+ const response = await client.getCached('/Users', params, {
368
+ enabled: true,
369
+ ttl: TTL.USER_LIST,
370
+ keyPrefix: args.client_id ? `users:client_${args.client_id}` : 'users:client_all',
371
+ });
372
+ const duplicates = [];
373
+ // Group users by email address to find duplicates
374
+ const emailToUsers = new Map();
375
+ for (const user of response.users) {
376
+ if (user.emailaddress) {
377
+ const normalizedEmail = user.emailaddress.toLowerCase();
378
+ const existing = emailToUsers.get(normalizedEmail) || [];
379
+ existing.push(user);
380
+ emailToUsers.set(normalizedEmail, existing);
381
+ }
382
+ }
383
+ // Find emails with multiple users (duplicates)
384
+ for (const [email, users] of emailToUsers.entries()) {
385
+ if (users.length > 1) {
386
+ duplicates.push({
387
+ type: 'user',
388
+ matchField: 'email',
389
+ matchValue: email,
390
+ confidence: 'High', // Exact email match = high confidence
391
+ entity_count: users.length,
392
+ entities: users.map((u) => ({
393
+ id: u.id,
394
+ name: u.name,
395
+ email: u.emailaddress,
396
+ username: u.username,
397
+ })),
398
+ });
399
+ }
400
+ }
401
+ // Also scan by username for medium confidence duplicates
402
+ const usernameToUsers = new Map();
403
+ for (const user of response.users) {
404
+ if (user.username) {
405
+ const normalizedUsername = user.username.toLowerCase();
406
+ const existing = usernameToUsers.get(normalizedUsername) || [];
407
+ existing.push(user);
408
+ usernameToUsers.set(normalizedUsername, existing);
409
+ }
410
+ }
411
+ for (const [username, users] of usernameToUsers.entries()) {
412
+ if (users.length > 1) {
413
+ // Check if these are already captured by email scan
414
+ const emails = new Set(users.map((u) => u.emailaddress?.toLowerCase()).filter(Boolean));
415
+ const isNewDuplicate = emails.size > 1; // Different emails = new duplicate group
416
+ if (isNewDuplicate) {
417
+ duplicates.push({
418
+ type: 'user',
419
+ matchField: 'username',
420
+ matchValue: username,
421
+ confidence: 'Medium', // Username only = medium confidence
422
+ entity_count: users.length,
423
+ entities: users.map((u) => ({
424
+ id: u.id,
425
+ name: u.name,
426
+ email: u.emailaddress,
427
+ username: u.username,
428
+ })),
429
+ });
430
+ }
431
+ }
432
+ }
433
+ const result = {
434
+ client_id: args.client_id || 'all',
435
+ users_scanned: response.users.length,
436
+ duplicates_found: duplicates.length,
437
+ duplicates,
438
+ };
439
+ if (formatOptions.format === 'detailed') {
440
+ return JSON.stringify(result, null, 2);
441
+ }
442
+ return JSON.stringify(result);
443
+ }
444
+ // =============================================================================
445
+ // Tool Definitions (for ToolRegistry)
446
+ // =============================================================================
447
+ export const listUsersTool = {
448
+ name: 'list_halopsa_users',
449
+ description: 'List HaloPSA users with optional filtering, caching (1min TTL), and token optimization. Only inactive=false users count for billing.',
450
+ schema: ListUsersArgsSchema,
451
+ handler: listUsers,
452
+ };
453
+ export const getUserTool = {
454
+ name: 'get_halopsa_user',
455
+ description: 'Get a single HaloPSA user by ID with full details including custom fields (user_customfields)',
456
+ schema: GetUserArgsSchema,
457
+ handler: getUser,
458
+ };
459
+ export const searchUsersByEmailTool = {
460
+ name: 'search_halopsa_users_by_email',
461
+ description: 'Search HaloPSA users by email address (primary match field). Returns warning if multiple found.',
462
+ schema: SearchUsersByEmailArgsSchema,
463
+ handler: searchUsersByEmail,
464
+ };
465
+ export const createUserTool = {
466
+ name: 'create_halopsa_user',
467
+ description: 'Create a new HaloPSA user. Invalidates user cache. Use find_halopsa_user_match first to prevent duplicates.',
468
+ schema: CreateUserArgsSchema,
469
+ handler: createUser,
470
+ };
471
+ export const updateUserTool = {
472
+ name: 'update_halopsa_user',
473
+ description: 'Update an existing HaloPSA user. Invalidates user cache.',
474
+ schema: UpdateUserArgsSchema,
475
+ handler: updateUser,
476
+ };
477
+ export const findUserMatchTool = {
478
+ name: 'find_halopsa_user_match',
479
+ description: 'Find matching user using deduplication algorithm. Email=100%, UPN=95%, Username=70% confidence. CRITICAL for billing accuracy.',
480
+ schema: FindUserMatchArgsSchema,
481
+ handler: findUserMatch,
482
+ };
483
+ export const scanUserDuplicatesTool = {
484
+ name: 'scan_halopsa_user_duplicates',
485
+ description: 'Scan for duplicate users by email/username. Returns groups with confidence scores.',
486
+ schema: ScanUserDuplicatesArgsSchema,
487
+ handler: scanUserDuplicates,
488
+ };
489
+ //# sourceMappingURL=users.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"users.js","sourceRoot":"","sources":["../../src/tools/users.ts"],"names":[],"mappings":"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"}