@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,182 @@
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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zod-to-schema.js","sourceRoot":"","sources":["../../src/utils/zod-to-schema.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@wilnertech/halopsa-mcp-server",
3
+ "version": "1.0.0",
4
+ "description": "Model Context Protocol server for HaloPSA API integration - WilnerTech billing backbone",
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 --ext .ts",
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
+ "wilnertech"
47
+ ],
48
+ "author": "WilnerTech <dev@wilnertech.com>",
49
+ "license": "MIT",
50
+ "repository": {
51
+ "type": "git",
52
+ "url": "https://github.com/WilnerTech/halopsa-mcp-server.git"
53
+ },
54
+ "homepage": "https://github.com/WilnerTech/halopsa-mcp-server#readme",
55
+ "bugs": {
56
+ "url": "https://github.com/WilnerTech/halopsa-mcp-server/issues"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }