@wilnertech/halopsa-mcp-server 1.0.2 → 1.2.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 (78) hide show
  1. package/.env.example +18 -18
  2. package/LICENSE +21 -21
  3. package/README.md +290 -205
  4. package/dist/api/client.d.ts +7 -2
  5. package/dist/api/client.d.ts.map +1 -1
  6. package/dist/api/client.js +35 -8
  7. package/dist/api/client.js.map +1 -1
  8. package/dist/cache/memory-cache.d.ts +7 -0
  9. package/dist/cache/memory-cache.d.ts.map +1 -1
  10. package/dist/cache/memory-cache.js +7 -0
  11. package/dist/cache/memory-cache.js.map +1 -1
  12. package/dist/cache/prewarm.d.ts +3 -1
  13. package/dist/cache/prewarm.d.ts.map +1 -1
  14. package/dist/cache/prewarm.js +17 -1
  15. package/dist/cache/prewarm.js.map +1 -1
  16. package/dist/schemas/common.d.ts +30 -99
  17. package/dist/schemas/common.d.ts.map +1 -1
  18. package/dist/schemas/common.js +2 -2
  19. package/dist/schemas/common.js.map +1 -1
  20. package/dist/tools/assets.d.ts +87 -297
  21. package/dist/tools/assets.d.ts.map +1 -1
  22. package/dist/tools/assets.js +7 -3
  23. package/dist/tools/assets.js.map +1 -1
  24. package/dist/tools/batch-operations.d.ts +49 -81
  25. package/dist/tools/batch-operations.d.ts.map +1 -1
  26. package/dist/tools/batch-operations.js +62 -0
  27. package/dist/tools/batch-operations.js.map +1 -1
  28. package/dist/tools/clients.d.ts +24 -92
  29. package/dist/tools/clients.d.ts.map +1 -1
  30. package/dist/tools/reference-data.d.ts +44 -72
  31. package/dist/tools/reference-data.d.ts.map +1 -1
  32. package/dist/tools/reference-data.js +27 -0
  33. package/dist/tools/reference-data.js.map +1 -1
  34. package/dist/tools/registrations.d.ts +7 -1
  35. package/dist/tools/registrations.d.ts.map +1 -1
  36. package/dist/tools/registrations.js +43 -7
  37. package/dist/tools/registrations.js.map +1 -1
  38. package/dist/tools/registry.d.ts +12 -5
  39. package/dist/tools/registry.d.ts.map +1 -1
  40. package/dist/tools/registry.js +26 -2
  41. package/dist/tools/registry.js.map +1 -1
  42. package/dist/tools/sites.d.ts +28 -111
  43. package/dist/tools/sites.d.ts.map +1 -1
  44. package/dist/tools/sites.js +4 -2
  45. package/dist/tools/sites.js.map +1 -1
  46. package/dist/tools/ticket-actions.d.ts +50 -0
  47. package/dist/tools/ticket-actions.d.ts.map +1 -0
  48. package/dist/tools/ticket-actions.js +224 -0
  49. package/dist/tools/ticket-actions.js.map +1 -0
  50. package/dist/tools/ticket-custom-fields.d.ts +33 -0
  51. package/dist/tools/ticket-custom-fields.d.ts.map +1 -0
  52. package/dist/tools/ticket-custom-fields.js +155 -0
  53. package/dist/tools/ticket-custom-fields.js.map +1 -0
  54. package/dist/tools/ticket-reference-data.d.ts +88 -0
  55. package/dist/tools/ticket-reference-data.d.ts.map +1 -0
  56. package/dist/tools/ticket-reference-data.js +185 -0
  57. package/dist/tools/ticket-reference-data.js.map +1 -0
  58. package/dist/tools/tickets.d.ts +190 -0
  59. package/dist/tools/tickets.d.ts.map +1 -0
  60. package/dist/tools/tickets.js +592 -0
  61. package/dist/tools/tickets.js.map +1 -0
  62. package/dist/tools/users.d.ts +55 -193
  63. package/dist/tools/users.d.ts.map +1 -1
  64. package/dist/tools/users.js +7 -3
  65. package/dist/tools/users.js.map +1 -1
  66. package/dist/types/tickets.d.ts +193 -0
  67. package/dist/types/tickets.d.ts.map +1 -0
  68. package/dist/types/tickets.js +14 -0
  69. package/dist/types/tickets.js.map +1 -0
  70. package/dist/utils/formatter.d.ts +34 -1
  71. package/dist/utils/formatter.d.ts.map +1 -1
  72. package/dist/utils/formatter.js +203 -6
  73. package/dist/utils/formatter.js.map +1 -1
  74. package/package.json +68 -61
  75. package/dist/utils/zod-to-schema.d.ts +0 -29
  76. package/dist/utils/zod-to-schema.d.ts.map +0 -1
  77. package/dist/utils/zod-to-schema.js +0 -182
  78. package/dist/utils/zod-to-schema.js.map +0 -1
@@ -8,11 +8,44 @@ export interface FormatOptions {
8
8
  omit_empty?: boolean;
9
9
  }
10
10
  /**
11
- * Format a response object based on options
11
+ * Recursively walk `payload` (objects + arrays) and replace the VALUE of any
12
+ * key matching CREDENTIAL_KEY_RE with the string '[REDACTED]'.
13
+ *
14
+ * The function is IMMUTABLE — it deep-clones before mutating so the original
15
+ * object passed by the caller is never modified.
16
+ */
17
+ export declare function scrubCredentials(payload: unknown): unknown;
18
+ /**
19
+ * Format a response object based on options.
20
+ *
21
+ * Credential scrubbing: `scrubCredentials()` is applied to `data` BEFORE
22
+ * serialization so that fields like `new_password`, `api_key`, `secret`,
23
+ * `token`, and `client_secret` are replaced with '[REDACTED]' in every tool
24
+ * response automatically. The response signature is unchanged (string).
25
+ *
12
26
  * @param data - The data to format (single object or array)
13
27
  * @param options - Formatting options
14
28
  * @param meta - Optional metadata (pagination, counts)
15
29
  * @returns JSON string formatted according to options
16
30
  */
17
31
  export declare function formatResponse<T>(data: T | T[], options?: FormatOptions, meta?: Record<string, unknown>): string;
32
+ export type WriteResponseEntityType = 'ticket' | 'asset' | 'user' | 'site' | 'action';
33
+ /**
34
+ * Strip a write-endpoint response (create/update) to a compact shape.
35
+ *
36
+ * - When `format === 'detailed'`, returns the input unchanged (passthrough).
37
+ * - When `format === 'compact'` (or unset/other), applies:
38
+ * 1. Integration-key scrubbing (pagerduty*, orion*, ai_*, etc.)
39
+ * 2. Entity-type–specific top-level key removal (nested objects whose
40
+ * important data is already in flat _id / _name siblings)
41
+ * 3. `customfields[].fieldinfo` removal (keeps `{id, name?, value}`)
42
+ *
43
+ * Credential scrubbing is intentionally NOT performed here — it is applied
44
+ * downstream by `formatResponse()` which must always run AFTER this call.
45
+ *
46
+ * @param payload - Raw API response object (or array — normalized to single object upstream)
47
+ * @param format - FormatOptions.format value from the caller's args; defaults to 'compact'
48
+ * @param entity - Which entity type to apply the strip rules for
49
+ */
50
+ export declare function stripWriteResponse(payload: unknown, format: string | undefined, entity: WriteResponseEntityType): unknown;
18
51
  //# sourceMappingURL=formatter.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,GAAE,aAAkB,EAC3B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CA0CR"}
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,aAAa;IAC5B,MAAM,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,CAAC;IAC7C,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAeD;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAoB1D;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,EACb,OAAO,GAAE,aAAkB,EAC3B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,MAAM,CA6CR;AA0QD,MAAM,MAAM,uBAAuB,GAC/B,QAAQ,GACR,OAAO,GACP,MAAM,GACN,MAAM,GACN,QAAQ,CAAC;AAEb;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,MAAM,EAAE,uBAAuB,GAC9B,OAAO,CAwCT"}
@@ -3,7 +3,51 @@
3
3
  * Provides compact, standard, and detailed output modes for HaloPSA responses
4
4
  */
5
5
  /**
6
- * Format a response object based on options
6
+ * Regex that matches credential-bearing key names (case-insensitive).
7
+ *
8
+ * Covered patterns:
9
+ * password, new_password
10
+ * api_key, apikey, api-key
11
+ * secret
12
+ * token, access_token
13
+ * client_secret
14
+ */
15
+ const CREDENTIAL_KEY_RE = /^(new_)?password$|api[_-]?key$|secret$|(access_)?token$|client_secret$/i;
16
+ /**
17
+ * Recursively walk `payload` (objects + arrays) and replace the VALUE of any
18
+ * key matching CREDENTIAL_KEY_RE with the string '[REDACTED]'.
19
+ *
20
+ * The function is IMMUTABLE — it deep-clones before mutating so the original
21
+ * object passed by the caller is never modified.
22
+ */
23
+ export function scrubCredentials(payload) {
24
+ if (Array.isArray(payload)) {
25
+ return payload.map((item) => scrubCredentials(item));
26
+ }
27
+ if (payload !== null && typeof payload === 'object') {
28
+ const source = payload;
29
+ const result = {};
30
+ for (const key of Object.keys(source)) {
31
+ if (CREDENTIAL_KEY_RE.test(key)) {
32
+ result[key] = '[REDACTED]';
33
+ }
34
+ else {
35
+ result[key] = scrubCredentials(source[key]);
36
+ }
37
+ }
38
+ return result;
39
+ }
40
+ // Primitives (string, number, boolean, null, undefined) — return as-is
41
+ return payload;
42
+ }
43
+ /**
44
+ * Format a response object based on options.
45
+ *
46
+ * Credential scrubbing: `scrubCredentials()` is applied to `data` BEFORE
47
+ * serialization so that fields like `new_password`, `api_key`, `secret`,
48
+ * `token`, and `client_secret` are replaced with '[REDACTED]' in every tool
49
+ * response automatically. The response signature is unchanged (string).
50
+ *
7
51
  * @param data - The data to format (single object or array)
8
52
  * @param options - Formatting options
9
53
  * @param meta - Optional metadata (pagination, counts)
@@ -11,20 +55,22 @@
11
55
  */
12
56
  export function formatResponse(data, options = {}, meta) {
13
57
  const { format = 'standard', fields, omit_empty = false, } = options;
58
+ // Scrub credential fields before any further processing
59
+ const safeData = scrubCredentials(data);
14
60
  // Process data
15
61
  let processedData;
16
- if (Array.isArray(data)) {
17
- processedData = data.map((item) => processItem(item, fields, omit_empty, format));
62
+ if (Array.isArray(safeData)) {
63
+ processedData = safeData.map((item) => processItem(item, fields, omit_empty, format));
18
64
  }
19
65
  else {
20
- processedData = processItem(data, fields, omit_empty, format);
66
+ processedData = processItem(safeData, fields, omit_empty, format);
21
67
  }
22
68
  // Build result object
23
- const result = Array.isArray(data)
69
+ const result = Array.isArray(safeData)
24
70
  ? { data: processedData }
25
71
  : processedData;
26
72
  // Add metadata if provided and data is array
27
- if (meta && Array.isArray(data)) {
73
+ if (meta && Array.isArray(safeData)) {
28
74
  result.meta = meta;
29
75
  }
30
76
  // Return with appropriate formatting
@@ -175,4 +221,155 @@ function setNestedValue(obj, parts, value) {
175
221
  }
176
222
  current[parts[parts.length - 1]] = value;
177
223
  }
224
+ // =============================================================================
225
+ // Write-response stripping (compact mode)
226
+ // =============================================================================
227
+ /**
228
+ * Keys stripped from EVERY level of a compact write response.
229
+ * These are integration-scaffolding fields (third-party system IDs,
230
+ * workflow-audit internals, RMM connectors) that 99% of callers never need.
231
+ * The "detailed" format returns them untouched.
232
+ */
233
+ const INTEGRATION_KEY_RE = /^(_.*|pagerduty.*|splunkoncall.*|splunkoncall_id|splunkoncallurl|splunkoncallstatus|orion.*|ai_.*|auvik_.*|automate_id|device_automate_id|connectwise_.*|autotask_.*|freshdesk_.*|ninja.*|meraki.*|servicenow.*|atera_alert_id|scomalertstate|datto_alert_state|pagerdutyeragent|gfialerttype|useworkinghours.*|statusnochangehours.*|statusemail.*|nochangetemplate|messsent|auditstatus|auditunum|auditdate|azure_tenant.*|passportal_id|liongardid|kashflowid|snelstart_id|xeroid|syncroid|ateraid|connectwiseid|autotaskid|device42id|servicenowid|ncentral_details_id|dattocommerce_tenantid|kasea.*)$/i;
234
+ /**
235
+ * Top-level keys to STRIP entirely from a compact ticket write response.
236
+ * These are heavy nested objects whose important data is already
237
+ * denormalized into the flat _id / _name siblings.
238
+ */
239
+ const TICKET_STRIP_TOP_KEYS = new Set([
240
+ 'tickettype', // keep tickettype_id + tickettype_name (flat)
241
+ 'user', // keep user_id + user_name (flat); contains user.site.client.quickbooks_details
242
+ 'client', // keep client_id + client_name (flat)
243
+ 'priority', // keep priority_id (flat)
244
+ 'popup_notes',
245
+ 'external_links',
246
+ 'outcomes',
247
+ 'delivery_address',
248
+ 'billing_address',
249
+ 'contact_address',
250
+ ]);
251
+ /**
252
+ * Top-level keys to STRIP from a compact asset write response.
253
+ * Assets have similar integration scaffolding plus nested type/client objects.
254
+ */
255
+ const ASSET_STRIP_TOP_KEYS = new Set([
256
+ 'assettype', // keep assettype_id (flat)
257
+ 'client', // keep client_id + client_name (flat)
258
+ 'site', // keep site_id + site_name (flat)
259
+ 'linked_tickets',
260
+ 'linked_assets',
261
+ ]);
262
+ /**
263
+ * Top-level keys to STRIP from a compact user write response.
264
+ */
265
+ const USER_STRIP_TOP_KEYS = new Set([
266
+ 'client', // keep client_id (flat)
267
+ 'site', // keep site_id (flat)
268
+ 'agent',
269
+ 'linked_tickets',
270
+ ]);
271
+ /**
272
+ * Top-level keys to STRIP from a compact site write response.
273
+ */
274
+ const SITE_STRIP_TOP_KEYS = new Set([
275
+ 'client', // keep client_id (flat)
276
+ 'users',
277
+ 'linked_tickets',
278
+ ]);
279
+ /**
280
+ * Top-level keys to STRIP from a compact ticket-action write response.
281
+ */
282
+ const ACTION_STRIP_TOP_KEYS = new Set([
283
+ 'ticket', // keep ticket_id (flat)
284
+ 'agent',
285
+ 'attachments',
286
+ ]);
287
+ /**
288
+ * Recursively walk a plain object/array and remove any key whose name matches
289
+ * INTEGRATION_KEY_RE. Operates on a clone — does not mutate `input`.
290
+ */
291
+ function stripIntegrationKeys(input) {
292
+ if (Array.isArray(input)) {
293
+ return input.map(stripIntegrationKeys);
294
+ }
295
+ if (input !== null && typeof input === 'object') {
296
+ const src = input;
297
+ const out = {};
298
+ for (const key of Object.keys(src)) {
299
+ if (!INTEGRATION_KEY_RE.test(key)) {
300
+ out[key] = stripIntegrationKeys(src[key]);
301
+ }
302
+ }
303
+ return out;
304
+ }
305
+ return input;
306
+ }
307
+ /**
308
+ * Strip the `fieldinfo` sub-object from each element of a customfields array,
309
+ * keeping only `{ id, name?, value }`.
310
+ */
311
+ function stripCustomFieldInfo(cfs) {
312
+ if (!Array.isArray(cfs))
313
+ return cfs;
314
+ return cfs.map((cf) => {
315
+ if (cf === null || typeof cf !== 'object')
316
+ return cf;
317
+ const { id, name, value } = cf;
318
+ const slim = { id, value };
319
+ if (name !== undefined)
320
+ slim.name = name;
321
+ return slim;
322
+ });
323
+ }
324
+ /**
325
+ * Strip a write-endpoint response (create/update) to a compact shape.
326
+ *
327
+ * - When `format === 'detailed'`, returns the input unchanged (passthrough).
328
+ * - When `format === 'compact'` (or unset/other), applies:
329
+ * 1. Integration-key scrubbing (pagerduty*, orion*, ai_*, etc.)
330
+ * 2. Entity-type–specific top-level key removal (nested objects whose
331
+ * important data is already in flat _id / _name siblings)
332
+ * 3. `customfields[].fieldinfo` removal (keeps `{id, name?, value}`)
333
+ *
334
+ * Credential scrubbing is intentionally NOT performed here — it is applied
335
+ * downstream by `formatResponse()` which must always run AFTER this call.
336
+ *
337
+ * @param payload - Raw API response object (or array — normalized to single object upstream)
338
+ * @param format - FormatOptions.format value from the caller's args; defaults to 'compact'
339
+ * @param entity - Which entity type to apply the strip rules for
340
+ */
341
+ export function stripWriteResponse(payload, format, entity) {
342
+ // Detailed format: return untouched so callers always get the full payload.
343
+ if (format === 'detailed') {
344
+ return payload;
345
+ }
346
+ if (payload === null || typeof payload !== 'object') {
347
+ return payload;
348
+ }
349
+ // Step 1: Strip integration-scaffolding keys at every level.
350
+ const afterIntegration = stripIntegrationKeys(payload);
351
+ // Step 2: Strip entity-specific top-level keys (heavy nested objects).
352
+ const stripKeys = entity === 'ticket' ? TICKET_STRIP_TOP_KEYS
353
+ : entity === 'asset' ? ASSET_STRIP_TOP_KEYS
354
+ : entity === 'user' ? USER_STRIP_TOP_KEYS
355
+ : entity === 'site' ? SITE_STRIP_TOP_KEYS
356
+ : ACTION_STRIP_TOP_KEYS;
357
+ const afterTopStrip = {};
358
+ for (const [key, val] of Object.entries(afterIntegration)) {
359
+ if (!stripKeys.has(key)) {
360
+ afterTopStrip[key] = val;
361
+ }
362
+ }
363
+ // Step 3: Strip fieldinfo from customfields[] (ticket) or fields[] (asset).
364
+ if (entity === 'ticket' && Array.isArray(afterTopStrip['customfields'])) {
365
+ afterTopStrip['customfields'] = stripCustomFieldInfo(afterTopStrip['customfields']);
366
+ }
367
+ if (entity === 'asset' && Array.isArray(afterTopStrip['fields'])) {
368
+ afterTopStrip['fields'] = stripCustomFieldInfo(afterTopStrip['fields']);
369
+ }
370
+ if (entity === 'user' && Array.isArray(afterTopStrip['user_customfields'])) {
371
+ afterTopStrip['user_customfields'] = stripCustomFieldInfo(afterTopStrip['user_customfields']);
372
+ }
373
+ return afterTopStrip;
374
+ }
178
375
  //# sourceMappingURL=formatter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../src/utils/formatter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,61 +1,68 @@
1
- {
2
- "name": "@wilnertech/halopsa-mcp-server",
3
- "version": "1.0.2",
4
- "description": "Model Context Protocol server for HaloPSA API integration with asset, user, and site management",
5
- "main": "dist/index.js",
6
- "type": "module",
7
- "bin": {
8
- "halopsa-mcp-server": "dist/index.js"
9
- },
10
- "files": [
11
- "dist",
12
- "README.md",
13
- "LICENSE",
14
- ".env.example"
15
- ],
16
- "scripts": {
17
- "build": "tsc",
18
- "dev": "tsc --watch",
19
- "start": "node dist/index.js",
20
- "test:smoke": "node tests/smoke-crud.mjs",
21
- "lint": "eslint src",
22
- "format": "prettier --write \"src/**/*.ts\"",
23
- "prepublishOnly": "npm run build"
24
- },
25
- "dependencies": {
26
- "@modelcontextprotocol/sdk": "^1.0.4",
27
- "axios": "^1.7.9",
28
- "zod": "^3.24.1"
29
- },
30
- "devDependencies": {
31
- "@types/node": "^22.10.5",
32
- "@typescript-eslint/eslint-plugin": "^8.20.0",
33
- "@typescript-eslint/parser": "^8.20.0",
34
- "eslint": "^9.18.0",
35
- "prettier": "^3.4.2",
36
- "typescript": "^5.7.3"
37
- },
38
- "engines": {
39
- "node": ">=18.0.0"
40
- },
41
- "keywords": [
42
- "mcp",
43
- "halopsa",
44
- "api",
45
- "psa",
46
- "claude"
47
- ],
48
- "author": "Yisroel Wilner",
49
- "license": "MIT",
50
- "repository": {
51
- "type": "git",
52
- "url": "https://github.com/SuperGaco/halopsa-mcp-server.git"
53
- },
54
- "homepage": "https://github.com/SuperGaco/halopsa-mcp-server#readme",
55
- "bugs": {
56
- "url": "https://github.com/SuperGaco/halopsa-mcp-server/issues"
57
- },
58
- "publishConfig": {
59
- "access": "public"
60
- }
61
- }
1
+ {
2
+ "name": "@wilnertech/halopsa-mcp-server",
3
+ "version": "1.2.0",
4
+ "description": "Model Context Protocol server for HaloPSA API integration with asset, user, and site management",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "halopsa-mcp-server": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist",
12
+ "README.md",
13
+ "LICENSE",
14
+ ".env.example"
15
+ ],
16
+ "scripts": {
17
+ "build": "tsc",
18
+ "dev": "tsc --watch",
19
+ "start": "node dist/index.js",
20
+ "test": "node --experimental-vm-modules node_modules/jest/bin/jest.js",
21
+ "test:smoke": "node tests/smoke-crud.mjs",
22
+ "test:smoke:local": "node --env-file=.env tests/smoke-crud.mjs",
23
+ "start:local": "node --env-file=.env dist/index.js",
24
+ "typecheck": "tsc --noEmit",
25
+ "lint": "eslint src",
26
+ "format": "prettier --write \"src/**/*.ts\"",
27
+ "prepublishOnly": "npm run build"
28
+ },
29
+ "dependencies": {
30
+ "@modelcontextprotocol/sdk": "^1.0.4",
31
+ "axios": "^1.7.9",
32
+ "zod": "^4.3.0"
33
+ },
34
+ "devDependencies": {
35
+ "@types/jest": "^30.0.0",
36
+ "@types/node": "^22.10.5",
37
+ "@typescript-eslint/eslint-plugin": "^8.20.0",
38
+ "@typescript-eslint/parser": "^8.20.0",
39
+ "eslint": "^9.18.0",
40
+ "jest": "^30.3.0",
41
+ "prettier": "^3.4.2",
42
+ "ts-jest": "^29.2.5",
43
+ "typescript": "^5.7.3"
44
+ },
45
+ "engines": {
46
+ "node": ">=18.0.0"
47
+ },
48
+ "keywords": [
49
+ "mcp",
50
+ "halopsa",
51
+ "api",
52
+ "psa",
53
+ "claude"
54
+ ],
55
+ "author": "Yisroel Wilner",
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/SuperGaco/halopsa-mcp-server.git"
60
+ },
61
+ "homepage": "https://github.com/SuperGaco/halopsa-mcp-server#readme",
62
+ "bugs": {
63
+ "url": "https://github.com/SuperGaco/halopsa-mcp-server/issues"
64
+ },
65
+ "publishConfig": {
66
+ "access": "public"
67
+ }
68
+ }
@@ -1,29 +0,0 @@
1
- /**
2
- * Converts Zod schemas to MCP-compatible JSON Schema objects.
3
- *
4
- * The MCP SDK expects inputSchema as:
5
- * { type: 'object', properties: Record<string, unknown>, required?: string[] }
6
- *
7
- * This utility traverses Zod's internal _def structure to produce that shape,
8
- * handling the types used across ITGlue MCP tool schemas: string, number,
9
- * boolean, array, object, enum, literal, optional, default, and effects
10
- * (z.coerce). Descriptions and numeric min/max checks are preserved.
11
- */
12
- import { z } from 'zod';
13
- /**
14
- * MCP-compatible JSON Schema for a tool's inputSchema.
15
- */
16
- interface McpInputSchema {
17
- type: 'object';
18
- properties: Record<string, unknown>;
19
- required?: string[];
20
- }
21
- /**
22
- * Convert a top-level Zod object schema to an MCP-compatible inputSchema.
23
- *
24
- * The input is expected to be a z.ZodObject (possibly wrapped in optional/effects).
25
- * Returns { type: 'object', properties: {...}, required?: [...] }.
26
- */
27
- export declare function zodToJsonSchema(schema: z.ZodType): McpInputSchema;
28
- export {};
29
- //# sourceMappingURL=zod-to-schema.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"zod-to-schema.d.ts","sourceRoot":"","sources":["../../src/utils/zod-to-schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;GAEG;AACH,UAAU,cAAc;IACtB,IAAI,EAAE,QAAQ,CAAC;IACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAkLD;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,CAAC,CAAC,OAAO,GAAG,cAAc,CASjE"}
@@ -1,182 +0,0 @@
1
- /**
2
- * Converts Zod schemas to MCP-compatible JSON Schema objects.
3
- *
4
- * The MCP SDK expects inputSchema as:
5
- * { type: 'object', properties: Record<string, unknown>, required?: string[] }
6
- *
7
- * This utility traverses Zod's internal _def structure to produce that shape,
8
- * handling the types used across ITGlue MCP tool schemas: string, number,
9
- * boolean, array, object, enum, literal, optional, default, and effects
10
- * (z.coerce). Descriptions and numeric min/max checks are preserved.
11
- */
12
- /**
13
- * Convert a single Zod type to a JSON Schema property descriptor.
14
- * Handles wrapper types (optional, default, effects/coerce, nullable)
15
- * by recursing into their inner types.
16
- */
17
- function zodTypeToJsonSchema(schema) {
18
- const def = schema._def;
19
- const typeName = def.typeName;
20
- const result = {};
21
- // Preserve .describe() text
22
- if (typeof def.description === 'string') {
23
- result.description = def.description;
24
- }
25
- switch (typeName) {
26
- case 'ZodString': {
27
- result.type = 'string';
28
- break;
29
- }
30
- case 'ZodNumber': {
31
- result.type = 'number';
32
- // Propagate min/max constraints from .min()/.max() checks
33
- const checks = def.checks;
34
- if (checks) {
35
- for (const check of checks) {
36
- if (check.kind === 'min') {
37
- result.minimum = check.value;
38
- }
39
- else if (check.kind === 'max') {
40
- result.maximum = check.value;
41
- }
42
- }
43
- }
44
- break;
45
- }
46
- case 'ZodBoolean': {
47
- result.type = 'boolean';
48
- break;
49
- }
50
- case 'ZodEnum': {
51
- result.type = 'string';
52
- result.enum = def.values;
53
- break;
54
- }
55
- case 'ZodLiteral': {
56
- const value = def.value;
57
- if (typeof value === 'string') {
58
- result.type = 'string';
59
- }
60
- else if (typeof value === 'number') {
61
- result.type = 'number';
62
- }
63
- else if (typeof value === 'boolean') {
64
- result.type = 'boolean';
65
- }
66
- result.const = value;
67
- break;
68
- }
69
- case 'ZodArray': {
70
- result.type = 'array';
71
- const itemSchema = def.type;
72
- result.items = zodTypeToJsonSchema(itemSchema);
73
- break;
74
- }
75
- case 'ZodObject': {
76
- result.type = 'object';
77
- const shape = schema._def.shape();
78
- const properties = {};
79
- const required = [];
80
- for (const [key, fieldSchema] of Object.entries(shape)) {
81
- properties[key] = zodTypeToJsonSchema(fieldSchema);
82
- if (!isOptionalType(fieldSchema)) {
83
- required.push(key);
84
- }
85
- }
86
- result.properties = properties;
87
- if (required.length > 0) {
88
- result.required = required;
89
- }
90
- break;
91
- }
92
- // Wrapper types: unwrap and recurse
93
- case 'ZodOptional': {
94
- const innerOptional = def.innerType;
95
- const inner = zodTypeToJsonSchema(innerOptional);
96
- // Merge description from the optional wrapper if present, inner takes precedence
97
- if (result.description && !inner.description) {
98
- inner.description = result.description;
99
- }
100
- return inner;
101
- }
102
- case 'ZodDefault': {
103
- const innerDefault = def.innerType;
104
- const inner = zodTypeToJsonSchema(innerDefault);
105
- if (result.description && !inner.description) {
106
- inner.description = result.description;
107
- }
108
- return inner;
109
- }
110
- case 'ZodNullable': {
111
- const innerNullable = def.innerType;
112
- const inner = zodTypeToJsonSchema(innerNullable);
113
- if (result.description && !inner.description) {
114
- inner.description = result.description;
115
- }
116
- return inner;
117
- }
118
- case 'ZodEffects': {
119
- // z.coerce.number(), z.coerce.string(), z.preprocess(), z.transform()
120
- const innerEffects = def.schema;
121
- const inner = zodTypeToJsonSchema(innerEffects);
122
- if (result.description && !inner.description) {
123
- inner.description = result.description;
124
- }
125
- return inner;
126
- }
127
- case 'ZodAny': {
128
- // z.any() — no type constraint, description carries the semantics
129
- break;
130
- }
131
- case 'ZodRecord': {
132
- // z.record() — open-ended object
133
- result.type = 'object';
134
- break;
135
- }
136
- default: {
137
- // Fallback for unknown types - warn and treat as opaque object
138
- console.warn(`zod-to-schema: unhandled Zod type "${typeName}" — falling back to { type: "object" }`);
139
- result.type = 'object';
140
- break;
141
- }
142
- }
143
- return result;
144
- }
145
- /**
146
- * Check whether a Zod type represents an optional field.
147
- * Optional, default, and nullable wrappers all make a field non-required.
148
- */
149
- function isOptionalType(schema) {
150
- const def = schema._def;
151
- const typeName = def.typeName;
152
- if (typeName === 'ZodOptional' || typeName === 'ZodDefault') {
153
- return true;
154
- }
155
- // ZodNullable wrapping an optional
156
- if (typeName === 'ZodNullable') {
157
- const inner = def.innerType;
158
- return isOptionalType(inner);
159
- }
160
- // ZodEffects wrapping an optional (e.g., z.coerce.number().optional() piped through transform)
161
- if (typeName === 'ZodEffects') {
162
- const inner = def.schema;
163
- return isOptionalType(inner);
164
- }
165
- return false;
166
- }
167
- /**
168
- * Convert a top-level Zod object schema to an MCP-compatible inputSchema.
169
- *
170
- * The input is expected to be a z.ZodObject (possibly wrapped in optional/effects).
171
- * Returns { type: 'object', properties: {...}, required?: [...] }.
172
- */
173
- export function zodToJsonSchema(schema) {
174
- const converted = zodTypeToJsonSchema(schema);
175
- // The top-level must always be type: 'object'
176
- return {
177
- type: 'object',
178
- properties: converted.properties || {},
179
- ...(converted.required ? { required: converted.required } : {}),
180
- };
181
- }
182
- //# sourceMappingURL=zod-to-schema.js.map