synapse-mcp 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 (138) hide show
  1. package/README.md +607 -0
  2. package/dist/constants.d.ts +23 -0
  3. package/dist/constants.d.ts.map +1 -0
  4. package/dist/constants.js +58 -0
  5. package/dist/constants.js.map +1 -0
  6. package/dist/formatters/index.d.ts +275 -0
  7. package/dist/formatters/index.d.ts.map +1 -0
  8. package/dist/formatters/index.js +461 -0
  9. package/dist/formatters/index.js.map +1 -0
  10. package/dist/index.d.ts +3 -0
  11. package/dist/index.d.ts.map +1 -0
  12. package/dist/index.js +178 -0
  13. package/dist/index.js.map +1 -0
  14. package/dist/schemas/common.d.ts +48 -0
  15. package/dist/schemas/common.d.ts.map +1 -0
  16. package/dist/schemas/common.js +69 -0
  17. package/dist/schemas/common.js.map +1 -0
  18. package/dist/schemas/discriminator.d.ts +20 -0
  19. package/dist/schemas/discriminator.d.ts.map +1 -0
  20. package/dist/schemas/discriminator.js +25 -0
  21. package/dist/schemas/discriminator.js.map +1 -0
  22. package/dist/schemas/flux/compose.d.ts +93 -0
  23. package/dist/schemas/flux/compose.d.ts.map +1 -0
  24. package/dist/schemas/flux/compose.js +112 -0
  25. package/dist/schemas/flux/compose.js.map +1 -0
  26. package/dist/schemas/flux/container.d.ts +144 -0
  27. package/dist/schemas/flux/container.d.ts.map +1 -0
  28. package/dist/schemas/flux/container.js +163 -0
  29. package/dist/schemas/flux/container.js.map +1 -0
  30. package/dist/schemas/flux/docker.d.ts +91 -0
  31. package/dist/schemas/flux/docker.d.ts.map +1 -0
  32. package/dist/schemas/flux/docker.js +101 -0
  33. package/dist/schemas/flux/docker.js.map +1 -0
  34. package/dist/schemas/flux/host.d.ts +61 -0
  35. package/dist/schemas/flux/host.d.ts.map +1 -0
  36. package/dist/schemas/flux/host.js +72 -0
  37. package/dist/schemas/flux/host.js.map +1 -0
  38. package/dist/schemas/flux/index.d.ts +20 -0
  39. package/dist/schemas/flux/index.d.ts.map +1 -0
  40. package/dist/schemas/flux/index.js +88 -0
  41. package/dist/schemas/flux/index.js.map +1 -0
  42. package/dist/schemas/index.d.ts +11 -0
  43. package/dist/schemas/index.d.ts.map +1 -0
  44. package/dist/schemas/index.js +11 -0
  45. package/dist/schemas/index.js.map +1 -0
  46. package/dist/schemas/scout/index.d.ts +151 -0
  47. package/dist/schemas/scout/index.d.ts.map +1 -0
  48. package/dist/schemas/scout/index.js +41 -0
  49. package/dist/schemas/scout/index.js.map +1 -0
  50. package/dist/schemas/scout/logs.d.ts +48 -0
  51. package/dist/schemas/scout/logs.d.ts.map +1 -0
  52. package/dist/schemas/scout/logs.js +47 -0
  53. package/dist/schemas/scout/logs.js.map +1 -0
  54. package/dist/schemas/scout/simple.d.ts +68 -0
  55. package/dist/schemas/scout/simple.d.ts.map +1 -0
  56. package/dist/schemas/scout/simple.js +75 -0
  57. package/dist/schemas/scout/simple.js.map +1 -0
  58. package/dist/schemas/scout/zfs.d.ts +37 -0
  59. package/dist/schemas/scout/zfs.d.ts.map +1 -0
  60. package/dist/schemas/scout/zfs.js +36 -0
  61. package/dist/schemas/scout/zfs.js.map +1 -0
  62. package/dist/schemas/unified.d.ts +674 -0
  63. package/dist/schemas/unified.d.ts.map +1 -0
  64. package/dist/schemas/unified.js +453 -0
  65. package/dist/schemas/unified.js.map +1 -0
  66. package/dist/services/compose.d.ts +107 -0
  67. package/dist/services/compose.d.ts.map +1 -0
  68. package/dist/services/compose.js +308 -0
  69. package/dist/services/compose.js.map +1 -0
  70. package/dist/services/container.d.ts +69 -0
  71. package/dist/services/container.d.ts.map +1 -0
  72. package/dist/services/container.js +111 -0
  73. package/dist/services/container.js.map +1 -0
  74. package/dist/services/docker.d.ts +243 -0
  75. package/dist/services/docker.d.ts.map +1 -0
  76. package/dist/services/docker.js +812 -0
  77. package/dist/services/docker.js.map +1 -0
  78. package/dist/services/file-service.d.ts +79 -0
  79. package/dist/services/file-service.d.ts.map +1 -0
  80. package/dist/services/file-service.js +226 -0
  81. package/dist/services/file-service.js.map +1 -0
  82. package/dist/services/interfaces.d.ts +537 -0
  83. package/dist/services/interfaces.d.ts.map +1 -0
  84. package/dist/services/interfaces.js +2 -0
  85. package/dist/services/interfaces.js.map +1 -0
  86. package/dist/services/ssh-pool-exec.d.ts +10 -0
  87. package/dist/services/ssh-pool-exec.d.ts.map +1 -0
  88. package/dist/services/ssh-pool-exec.js +10 -0
  89. package/dist/services/ssh-pool-exec.js.map +1 -0
  90. package/dist/services/ssh-pool.d.ts +66 -0
  91. package/dist/services/ssh-pool.d.ts.map +1 -0
  92. package/dist/services/ssh-pool.js +253 -0
  93. package/dist/services/ssh-pool.js.map +1 -0
  94. package/dist/services/ssh-service.d.ts +39 -0
  95. package/dist/services/ssh-service.d.ts.map +1 -0
  96. package/dist/services/ssh-service.js +143 -0
  97. package/dist/services/ssh-service.js.map +1 -0
  98. package/dist/services/ssh.d.ts +37 -0
  99. package/dist/services/ssh.d.ts.map +1 -0
  100. package/dist/services/ssh.js +50 -0
  101. package/dist/services/ssh.js.map +1 -0
  102. package/dist/tools/flux.d.ts +14 -0
  103. package/dist/tools/flux.d.ts.map +1 -0
  104. package/dist/tools/flux.js +86 -0
  105. package/dist/tools/flux.js.map +1 -0
  106. package/dist/tools/index.d.ts +7 -0
  107. package/dist/tools/index.d.ts.map +1 -0
  108. package/dist/tools/index.js +43 -0
  109. package/dist/tools/index.js.map +1 -0
  110. package/dist/tools/scout.d.ts +14 -0
  111. package/dist/tools/scout.d.ts.map +1 -0
  112. package/dist/tools/scout.js +96 -0
  113. package/dist/tools/scout.js.map +1 -0
  114. package/dist/tools/unified.d.ts +7 -0
  115. package/dist/tools/unified.d.ts.map +1 -0
  116. package/dist/tools/unified.js +827 -0
  117. package/dist/tools/unified.js.map +1 -0
  118. package/dist/types.d.ts +93 -0
  119. package/dist/types.d.ts.map +1 -0
  120. package/dist/types.js +7 -0
  121. package/dist/types.js.map +1 -0
  122. package/dist/utils/errors.d.ts +60 -0
  123. package/dist/utils/errors.d.ts.map +1 -0
  124. package/dist/utils/errors.js +131 -0
  125. package/dist/utils/errors.js.map +1 -0
  126. package/dist/utils/help.d.ts +69 -0
  127. package/dist/utils/help.d.ts.map +1 -0
  128. package/dist/utils/help.js +259 -0
  129. package/dist/utils/help.js.map +1 -0
  130. package/dist/utils/index.d.ts +4 -0
  131. package/dist/utils/index.d.ts.map +1 -0
  132. package/dist/utils/index.js +4 -0
  133. package/dist/utils/index.js.map +1 -0
  134. package/dist/utils/path-security.d.ts +64 -0
  135. package/dist/utils/path-security.d.ts.map +1 -0
  136. package/dist/utils/path-security.js +138 -0
  137. package/dist/utils/path-security.js.map +1 -0
  138. package/package.json +85 -0
@@ -0,0 +1,259 @@
1
+ /**
2
+ * Help Handler - Auto-generate documentation from Zod discriminated union schemas
3
+ *
4
+ * Provides schema introspection to generate help text for MCP tools.
5
+ * Supports schemas wrapped in z.preprocess() for backward compatibility
6
+ * with composite discriminator patterns.
7
+ *
8
+ * NOTE: This module accesses Zod internal implementation details (_def, options, etc.)
9
+ * which are not part of the public API. When upgrading Zod:
10
+ * 1. Run full test suite to verify help generation still works
11
+ * 2. Check Zod changelog for changes to internal structure
12
+ * 3. Update this module if internal structure changes
13
+ */
14
+ /**
15
+ * Safely access _def from a Zod schema
16
+ */
17
+ function getDef(schema) {
18
+ return schema._def ?? {};
19
+ }
20
+ /**
21
+ * Unwrap z.preprocess wrapper to access inner discriminated union schema
22
+ *
23
+ * In Zod 4.x, z.preprocess() creates a pipe with:
24
+ * - _def.type === 'pipe'
25
+ * - _def.out containing the inner schema
26
+ */
27
+ function unwrapSchema(schema) {
28
+ const def = getDef(schema);
29
+ // Check if schema is wrapped in z.preprocess (Zod 4.x uses pipe internally)
30
+ if (def.type === "pipe" && def.out) {
31
+ return def.out;
32
+ }
33
+ // Zod 3.x compatibility: check for innerType
34
+ if (def.innerType) {
35
+ return def.innerType;
36
+ }
37
+ return schema;
38
+ }
39
+ /**
40
+ * Get the base type name from a potentially wrapped Zod schema
41
+ *
42
+ * Handles default(), optional(), nullable() wrapping to get the underlying type.
43
+ */
44
+ function getBaseTypeName(schema) {
45
+ const def = getDef(schema);
46
+ // Handle wrapped types: default, optional, nullable, etc.
47
+ if (def.innerType) {
48
+ return getBaseTypeName(def.innerType);
49
+ }
50
+ // Handle union type
51
+ if (def.type === "union" && def.options) {
52
+ const types = def.options.map((opt) => getBaseTypeName(opt));
53
+ return types.join(" | ");
54
+ }
55
+ // Handle enum type
56
+ if (def.type === "enum" && def.values) {
57
+ return def.values.map((v) => `"${v}"`).join(" | ");
58
+ }
59
+ // Handle native enum
60
+ if (def.type === "enum" || def.type === "nativeEnum") {
61
+ return "enum";
62
+ }
63
+ // Return the base type
64
+ return def.type ?? "unknown";
65
+ }
66
+ /**
67
+ * Get default value from a schema if present
68
+ */
69
+ function getDefaultValue(schema) {
70
+ const def = getDef(schema);
71
+ if (def.type === "default" && def.defaultValue !== undefined) {
72
+ try {
73
+ // defaultValue is a getter function in Zod 4.x
74
+ return typeof def.defaultValue === "function" ? def.defaultValue() : def.defaultValue;
75
+ }
76
+ catch {
77
+ return undefined;
78
+ }
79
+ }
80
+ return undefined;
81
+ }
82
+ /**
83
+ * Get options from a discriminated union schema
84
+ */
85
+ function getOptions(schema) {
86
+ // Try direct access (Zod 4.x)
87
+ const directOptions = schema.options;
88
+ if (directOptions) {
89
+ return directOptions;
90
+ }
91
+ // Try via _def
92
+ const def = getDef(schema);
93
+ return def.options;
94
+ }
95
+ /**
96
+ * Check if a schema is a nested discriminated union (has options but no shape)
97
+ */
98
+ function isNestedDiscriminatedUnion(schema) {
99
+ const def = getDef(schema);
100
+ const hasOptions = !!getOptions(schema);
101
+ const hasShape = !!schema.shape;
102
+ return hasOptions && !hasShape && (def.type === 'discriminatedUnion' || def.type === 'union');
103
+ }
104
+ /**
105
+ * Extract help entries from a single ZodObject schema
106
+ */
107
+ function extractObjectHelpEntry(option, prefix) {
108
+ // Access shape from ZodObject
109
+ const shape = option.shape;
110
+ if (!shape) {
111
+ return null;
112
+ }
113
+ // Find literal fields for discriminator
114
+ const literals = [];
115
+ for (const key of Object.keys(shape)) {
116
+ const fieldSchema = shape[key];
117
+ const fieldDef = getDef(fieldSchema);
118
+ // In Zod 4.x, literals use _def.values array
119
+ if (fieldDef.type === "literal" && fieldDef.values) {
120
+ literals.push({ key, value: fieldDef.values[0] });
121
+ }
122
+ }
123
+ if (literals.length === 0) {
124
+ return null;
125
+ }
126
+ // Build discriminator value: action or action:subaction
127
+ let discriminatorValue;
128
+ const actionLiteral = literals.find(l => l.key === 'action');
129
+ const subactionLiteral = literals.find(l => l.key === 'subaction');
130
+ if (subactionLiteral && actionLiteral) {
131
+ // Nested pattern: action:subaction (e.g., "zfs:pools")
132
+ discriminatorValue = `${actionLiteral.value}:${subactionLiteral.value}`;
133
+ }
134
+ else if (actionLiteral) {
135
+ discriminatorValue = actionLiteral.value;
136
+ }
137
+ else if (subactionLiteral) {
138
+ discriminatorValue = prefix ? `${prefix}:${subactionLiteral.value}` : subactionLiteral.value;
139
+ }
140
+ else {
141
+ discriminatorValue = literals[0].value;
142
+ }
143
+ // Extract parameters (excluding discriminator fields)
144
+ const parameters = Object.entries(shape)
145
+ .filter(([key]) =>
146
+ // Skip discriminator-related fields
147
+ key !== "action_subaction" && key !== "action" && key !== "subaction")
148
+ .map(([name, fieldSchema]) => {
149
+ return {
150
+ name,
151
+ type: getBaseTypeName(fieldSchema),
152
+ description: fieldSchema.description,
153
+ required: !fieldSchema.isOptional(),
154
+ default: getDefaultValue(fieldSchema)
155
+ };
156
+ });
157
+ return {
158
+ discriminator: discriminatorValue,
159
+ description: option.description ?? "",
160
+ parameters
161
+ };
162
+ }
163
+ /**
164
+ * Generate help documentation from discriminated union or union schema
165
+ *
166
+ * Handles:
167
+ * - Schemas wrapped in z.preprocess()
168
+ * - z.discriminatedUnion with composite discriminator (Flux)
169
+ * - z.union with nested z.discriminatedUnion (Scout)
170
+ *
171
+ * @param schema - A Zod discriminated union or union schema
172
+ * @param topic - Optional discriminator value to filter results
173
+ * @returns Array of help entries for matching actions
174
+ */
175
+ export function generateHelp(schema, topic) {
176
+ // Unwrap z.preprocess if present
177
+ const actualSchema = unwrapSchema(schema);
178
+ // Access options from discriminated union or union
179
+ const options = getOptions(actualSchema);
180
+ if (!options || !Array.isArray(options)) {
181
+ throw new Error("Schema is not a discriminated union or union");
182
+ }
183
+ const entries = [];
184
+ for (const option of options) {
185
+ // Check if this option is a nested discriminated union (like zfs or logs in Scout)
186
+ if (isNestedDiscriminatedUnion(option)) {
187
+ const nestedOptions = getOptions(option);
188
+ if (nestedOptions) {
189
+ for (const nestedOption of nestedOptions) {
190
+ const entry = extractObjectHelpEntry(nestedOption);
191
+ if (entry) {
192
+ entries.push(entry);
193
+ }
194
+ }
195
+ }
196
+ }
197
+ else {
198
+ // Regular ZodObject option
199
+ const entry = extractObjectHelpEntry(option);
200
+ if (entry) {
201
+ entries.push(entry);
202
+ }
203
+ }
204
+ }
205
+ // Filter by topic if provided
206
+ if (topic) {
207
+ return entries.filter((e) => e.discriminator === topic || e.discriminator.startsWith(topic + ':'));
208
+ }
209
+ return entries;
210
+ }
211
+ /**
212
+ * Format help entries as markdown
213
+ *
214
+ * @param entries - Array of help entries from generateHelp
215
+ * @returns Formatted markdown string
216
+ */
217
+ export function formatHelpMarkdown(entries) {
218
+ if (entries.length === 0) {
219
+ return "No help available for the specified topic.";
220
+ }
221
+ return entries
222
+ .map((entry) => {
223
+ let md = `## ${entry.discriminator}\n\n`;
224
+ if (entry.description) {
225
+ md += `${entry.description}\n\n`;
226
+ }
227
+ if (entry.parameters.length > 0) {
228
+ md += "**Parameters:**\n\n";
229
+ entry.parameters.forEach((param) => {
230
+ const required = param.required ? " (required)" : " (optional)";
231
+ const defaultVal = param.default !== undefined ? `, default: ${JSON.stringify(param.default)}` : "";
232
+ md += `- **${param.name}** (${param.type}${required}${defaultVal})`;
233
+ if (param.description) {
234
+ md += ` - ${param.description}`;
235
+ }
236
+ md += "\n";
237
+ });
238
+ }
239
+ return md;
240
+ })
241
+ .join("\n---\n\n");
242
+ }
243
+ /**
244
+ * Format help entries as JSON
245
+ *
246
+ * Uses 'action' as the key name in output for consistency with tool parameters.
247
+ *
248
+ * @param entries - Array of help entries from generateHelp
249
+ * @returns JSON string
250
+ */
251
+ export function formatHelpJson(entries) {
252
+ const jsonEntries = entries.map((entry) => ({
253
+ action: entry.discriminator,
254
+ description: entry.description,
255
+ parameters: entry.parameters
256
+ }));
257
+ return JSON.stringify(jsonEntries, null, 2);
258
+ }
259
+ //# sourceMappingURL=help.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"help.js","sourceRoot":"","sources":["../../src/utils/help.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA4CH;;GAEG;AACH,SAAS,MAAM,CAAC,MAAoB;IAClC,OAAQ,MAA8C,CAAC,IAAI,IAAI,EAAE,CAAC;AACpE,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,MAAoB;IACxC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAE3B,4EAA4E;IAC5E,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,CAAC;QACnC,OAAO,GAAG,CAAC,GAAG,CAAC;IACjB,CAAC;IACD,6CAA6C;IAC7C,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,GAAG,CAAC,SAAS,CAAC;IACvB,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED;;;;GAIG;AACH,SAAS,eAAe,CAAC,MAAoB;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAE3B,0DAA0D;IAC1D,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAClB,OAAO,eAAe,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IACxC,CAAC;IAED,oBAAoB;IACpB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC;QAC7D,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAED,mBAAmB;IACnB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;QACtC,OAAQ,GAAG,CAAC,MAAmB,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACnE,CAAC;IAED,qBAAqB;IACrB,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;QACrD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,uBAAuB;IACvB,OAAO,GAAG,CAAC,IAAI,IAAI,SAAS,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAS,eAAe,CAAC,MAAoB;IAC3C,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAE3B,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;QAC7D,IAAI,CAAC;YACH,+CAA+C;YAC/C,OAAO,OAAO,GAAG,CAAC,YAAY,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,YAAY,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,SAAS,UAAU,CAAC,MAAoB;IACtC,8BAA8B;IAC9B,MAAM,aAAa,GAAI,MAAkD,CAAC,OAAO,CAAC;IAClF,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,aAAa,CAAC;IACvB,CAAC;IAED,eAAe;IACf,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,OAAO,GAAG,CAAC,OAAO,CAAC;AACrB,CAAC;AAED;;GAEG;AACH,SAAS,0BAA0B,CAAC,MAAoB;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,CAAC,CAAE,MAAyC,CAAC,KAAK,CAAC;IACpE,OAAO,UAAU,IAAI,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,oBAAoB,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC;AAChG,CAAC;AAED;;GAEG;AACH,SAAS,sBAAsB,CAAC,MAAoB,EAAE,MAAe;IACnE,8BAA8B;IAC9B,MAAM,KAAK,GAAI,MAA6D,CAAC,KAAK,CAAC;IAEnF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wCAAwC;IACxC,MAAM,QAAQ,GAAqC,EAAE,CAAC;IACtD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,QAAQ,GAAG,MAAM,CAAC,WAAW,CAAC,CAAC;QACrC,6CAA6C;QAC7C,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;YACnD,QAAQ,CAAC,IAAI,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAW,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,wDAAwD;IACxD,IAAI,kBAA0B,CAAC;IAC/B,MAAM,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC;IAC7D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,KAAK,WAAW,CAAC,CAAC;IAEnE,IAAI,gBAAgB,IAAI,aAAa,EAAE,CAAC;QACtC,uDAAuD;QACvD,kBAAkB,GAAG,GAAG,aAAa,CAAC,KAAK,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC;IAC1E,CAAC;SAAM,IAAI,aAAa,EAAE,CAAC;QACzB,kBAAkB,GAAG,aAAa,CAAC,KAAK,CAAC;IAC3C,CAAC;SAAM,IAAI,gBAAgB,EAAE,CAAC;QAC5B,kBAAkB,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,gBAAgB,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,CAAC;IAC/F,CAAC;SAAM,CAAC;QACN,kBAAkB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;IACzC,CAAC;IAED,sDAAsD;IACtD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC;SACrC,MAAM,CACL,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE;IACR,oCAAoC;IACpC,GAAG,KAAK,kBAAkB,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,WAAW,CACxE;SACA,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,CAAC,EAAE,EAAE;QAC3B,OAAO;YACL,IAAI;YACJ,IAAI,EAAE,eAAe,CAAC,WAAW,CAAC;YAClC,WAAW,EAAE,WAAW,CAAC,WAAW;YACpC,QAAQ,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE;YACnC,OAAO,EAAE,eAAe,CAAC,WAAW,CAAC;SACtC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEL,OAAO;QACL,aAAa,EAAE,kBAAkB;QACjC,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;QACrC,UAAU;KACX,CAAC;AACJ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,YAAY,CAAC,MAAoB,EAAE,KAAc;IAC/D,iCAAiC;IACjC,MAAM,YAAY,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IAE1C,mDAAmD;IACnD,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAEzC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACxC,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,OAAO,GAAgB,EAAE,CAAC;IAEhC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,mFAAmF;QACnF,IAAI,0BAA0B,CAAC,MAAM,CAAC,EAAE,CAAC;YACvC,MAAM,aAAa,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC;YACzC,IAAI,aAAa,EAAE,CAAC;gBAClB,KAAK,MAAM,YAAY,IAAI,aAAa,EAAE,CAAC;oBACzC,MAAM,KAAK,GAAG,sBAAsB,CAAC,YAAY,CAAC,CAAC;oBACnD,IAAI,KAAK,EAAE,CAAC;wBACV,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;oBACtB,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;aAAM,CAAC;YACN,2BAA2B;YAC3B,MAAM,KAAK,GAAG,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAC7C,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,CAAC;QACH,CAAC;IACH,CAAC;IAED,8BAA8B;IAC9B,IAAI,KAAK,EAAE,CAAC;QACV,OAAO,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,aAAa,KAAK,KAAK,IAAI,CAAC,CAAC,aAAa,CAAC,UAAU,CAAC,KAAK,GAAG,GAAG,CAAC,CAAC,CAAC;IACrG,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAoB;IACrD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,4CAA4C,CAAC;IACtD,CAAC;IAED,OAAO,OAAO;SACX,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE;QACb,IAAI,EAAE,GAAG,MAAM,KAAK,CAAC,aAAa,MAAM,CAAC;QAEzC,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;YACtB,EAAE,IAAI,GAAG,KAAK,CAAC,WAAW,MAAM,CAAC;QACnC,CAAC;QAED,IAAI,KAAK,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAChC,EAAE,IAAI,qBAAqB,CAAC;YAC5B,KAAK,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE;gBACjC,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC;gBAChE,MAAM,UAAU,GACd,KAAK,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;gBACnF,EAAE,IAAI,OAAO,KAAK,CAAC,IAAI,OAAO,KAAK,CAAC,IAAI,GAAG,QAAQ,GAAG,UAAU,GAAG,CAAC;gBACpE,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;oBACtB,EAAE,IAAI,MAAM,KAAK,CAAC,WAAW,EAAE,CAAC;gBAClC,CAAC;gBACD,EAAE,IAAI,IAAI,CAAC;YACb,CAAC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC,CAAC;SACD,IAAI,CAAC,WAAW,CAAC,CAAC;AACvB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,cAAc,CAAC,OAAoB;IACjD,MAAM,WAAW,GAAoB,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QAC3D,MAAM,EAAE,KAAK,CAAC,aAAa;QAC3B,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,UAAU,EAAE,KAAK,CAAC,UAAU;KAC7B,CAAC,CAAC,CAAC;IAEJ,OAAO,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC9C,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { validateSecurePath, HostSecurityError, validateHostFormat, escapeShellArg, isSystemPath } from "./path-security.js";
2
+ export { generateHelp, formatHelpMarkdown, formatHelpJson } from "./help.js";
3
+ export type { HelpEntry, HelpJsonEntry } from "./help.js";
4
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC7E,YAAY,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,4 @@
1
+ // Explicit named exports for better IDE support and tree-shaking
2
+ export { validateSecurePath, HostSecurityError, validateHostFormat, escapeShellArg, isSystemPath } from "./path-security.js";
3
+ export { generateHelp, formatHelpMarkdown, formatHelpJson } from "./help.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA,iEAAiE;AACjE,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,cAAc,EACd,YAAY,EACb,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Path Security Utilities
3
+ *
4
+ * SECURITY: Path Traversal Protection (CWE-22) & Command Injection Prevention (CWE-78)
5
+ *
6
+ * This module provides utilities to prevent directory traversal attacks
7
+ * in file path parameters. Used by docker.ts buildImage() to validate
8
+ * build context and Dockerfile paths.
9
+ *
10
+ * Also provides host validation to prevent command injection attacks
11
+ * when hostnames are used in SSH commands.
12
+ *
13
+ * CVSS 7.4 (HIGH) - Prevents attackers from using paths like:
14
+ * - ../../../etc/passwd
15
+ * - /valid/../../../etc/passwd
16
+ * - /path/./to/../../sensitive
17
+ *
18
+ * @see https://cwe.mitre.org/data/definitions/22.html
19
+ * @see https://cwe.mitre.org/data/definitions/78.html
20
+ */
21
+ /**
22
+ * Security error for invalid host format
23
+ */
24
+ export declare class HostSecurityError extends Error {
25
+ readonly host: string;
26
+ constructor(message: string, host: string);
27
+ }
28
+ /**
29
+ * Validates hostname format to prevent command injection
30
+ *
31
+ * @param host - Hostname to validate
32
+ * @throws HostSecurityError if host contains dangerous characters
33
+ */
34
+ export declare function validateHostFormat(host: string): void;
35
+ /**
36
+ * Escapes a string for safe use as a shell argument.
37
+ * Uses single quotes with proper escaping for embedded single quotes.
38
+ *
39
+ * @param arg - String to escape
40
+ * @returns Safely quoted string
41
+ */
42
+ export declare function escapeShellArg(arg: string): string;
43
+ /**
44
+ * Checks if a path is a system path that should be protected
45
+ *
46
+ * @param path - Path to check
47
+ * @returns true if path is in a system directory
48
+ */
49
+ export declare function isSystemPath(path: string): boolean;
50
+ /**
51
+ * Validates that a file path is safe from directory traversal attacks
52
+ *
53
+ * Rules:
54
+ * 1. Must be absolute path (starts with /)
55
+ * 2. Cannot contain .. (parent directory)
56
+ * 3. Cannot contain . as a path component (except in filenames)
57
+ * 4. Must contain only allowed characters: a-zA-Z0-9._-/
58
+ *
59
+ * @param path - The file path to validate
60
+ * @param paramName - Name of the parameter (for error messages)
61
+ * @throws Error if path contains directory traversal or is invalid
62
+ */
63
+ export declare function validateSecurePath(path: string, paramName: string): void;
64
+ //# sourceMappingURL=path-security.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-security.d.ts","sourceRoot":"","sources":["../../src/utils/path-security.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;aAGxB,IAAI,EAAE,MAAM;gBAD5B,OAAO,EAAE,MAAM,EACC,IAAI,EAAE,MAAM;CAK/B;AAQD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAYrD;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAIlD;AAiBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAyCxE"}
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Path Security Utilities
3
+ *
4
+ * SECURITY: Path Traversal Protection (CWE-22) & Command Injection Prevention (CWE-78)
5
+ *
6
+ * This module provides utilities to prevent directory traversal attacks
7
+ * in file path parameters. Used by docker.ts buildImage() to validate
8
+ * build context and Dockerfile paths.
9
+ *
10
+ * Also provides host validation to prevent command injection attacks
11
+ * when hostnames are used in SSH commands.
12
+ *
13
+ * CVSS 7.4 (HIGH) - Prevents attackers from using paths like:
14
+ * - ../../../etc/passwd
15
+ * - /valid/../../../etc/passwd
16
+ * - /path/./to/../../sensitive
17
+ *
18
+ * @see https://cwe.mitre.org/data/definitions/22.html
19
+ * @see https://cwe.mitre.org/data/definitions/78.html
20
+ */
21
+ import { resolve } from "node:path";
22
+ /**
23
+ * Security error for invalid host format
24
+ */
25
+ export class HostSecurityError extends Error {
26
+ host;
27
+ constructor(message, host) {
28
+ super(message);
29
+ this.host = host;
30
+ this.name = "HostSecurityError";
31
+ }
32
+ }
33
+ // Pattern for valid hostnames: alphanumeric, dots, hyphens, underscores
34
+ const VALID_HOST_PATTERN = /^[a-zA-Z0-9._-]+$/;
35
+ // Dangerous shell characters that could enable command injection
36
+ const DANGEROUS_HOST_CHARS = /[;|$`&<>(){}[\]'"\\!#*?]/;
37
+ /**
38
+ * Validates hostname format to prevent command injection
39
+ *
40
+ * @param host - Hostname to validate
41
+ * @throws HostSecurityError if host contains dangerous characters
42
+ */
43
+ export function validateHostFormat(host) {
44
+ if (!host || host.length === 0) {
45
+ throw new HostSecurityError("Host cannot be empty", host);
46
+ }
47
+ if (DANGEROUS_HOST_CHARS.test(host)) {
48
+ throw new HostSecurityError(`Invalid characters in hostname: ${host.substring(0, 50)}`, host);
49
+ }
50
+ if (!VALID_HOST_PATTERN.test(host)) {
51
+ throw new HostSecurityError(`Invalid hostname format: ${host.substring(0, 50)}`, host);
52
+ }
53
+ }
54
+ /**
55
+ * Escapes a string for safe use as a shell argument.
56
+ * Uses single quotes with proper escaping for embedded single quotes.
57
+ *
58
+ * @param arg - String to escape
59
+ * @returns Safely quoted string
60
+ */
61
+ export function escapeShellArg(arg) {
62
+ // Single quote the entire string, escaping any embedded single quotes
63
+ // by ending the quote, adding an escaped single quote, and starting a new quote
64
+ return "'" + arg.replace(/'/g, "'\\''") + "'";
65
+ }
66
+ /**
67
+ * System paths that should trigger warnings when used as transfer targets
68
+ */
69
+ const SYSTEM_PATH_PREFIXES = [
70
+ "/etc",
71
+ "/bin",
72
+ "/sbin",
73
+ "/usr/bin",
74
+ "/usr/sbin",
75
+ "/lib",
76
+ "/lib64",
77
+ "/boot",
78
+ "/root"
79
+ ];
80
+ /**
81
+ * Checks if a path is a system path that should be protected
82
+ *
83
+ * @param path - Path to check
84
+ * @returns true if path is in a system directory
85
+ */
86
+ export function isSystemPath(path) {
87
+ return SYSTEM_PATH_PREFIXES.some((prefix) => path === prefix || path.startsWith(prefix + "/"));
88
+ }
89
+ /**
90
+ * Validates that a file path is safe from directory traversal attacks
91
+ *
92
+ * Rules:
93
+ * 1. Must be absolute path (starts with /)
94
+ * 2. Cannot contain .. (parent directory)
95
+ * 3. Cannot contain . as a path component (except in filenames)
96
+ * 4. Must contain only allowed characters: a-zA-Z0-9._-/
97
+ *
98
+ * @param path - The file path to validate
99
+ * @param paramName - Name of the parameter (for error messages)
100
+ * @throws Error if path contains directory traversal or is invalid
101
+ */
102
+ export function validateSecurePath(path, paramName) {
103
+ // 1. Check for empty path
104
+ if (!path || path.length === 0) {
105
+ throw new Error(`${paramName}: Path cannot be empty`);
106
+ }
107
+ // 2. Character validation - only allow alphanumeric, dots, hyphens, underscores, forward slashes
108
+ if (!/^[a-zA-Z0-9._\-/]+$/.test(path)) {
109
+ throw new Error(`${paramName}: Invalid characters in path: ${path}`);
110
+ }
111
+ // 3. Split path into components and check for ".." traversal first
112
+ const components = path.split("/").filter((c) => c.length > 0);
113
+ for (const component of components) {
114
+ // Reject ".." (parent directory traversal) - check this first
115
+ if (component === "..") {
116
+ throw new Error(`${paramName}: directory traversal (..) not allowed in path: ${path}`);
117
+ }
118
+ }
119
+ // 4. Must be absolute path (starts with /) - checked after .. but before .
120
+ if (!path.startsWith("/")) {
121
+ throw new Error(`${paramName}: absolute path required, got: ${path}`);
122
+ }
123
+ // 5. Check for "." as standalone component (only in absolute paths)
124
+ for (const component of components) {
125
+ // Reject "." as standalone component (current directory)
126
+ // BUT allow dots in filenames like "file.txt" or "config.prod"
127
+ if (component === ".") {
128
+ throw new Error(`${paramName}: directory traversal (.) not allowed in path: ${path}`);
129
+ }
130
+ }
131
+ // 5. Additional safety check: resolve path and verify it doesn't traverse
132
+ // This catches cases like /valid/path/../../etc that might slip through
133
+ const resolved = resolve(path);
134
+ if (!resolved.startsWith(path.split("/")[1] ? `/${path.split("/")[1]}` : "/")) {
135
+ throw new Error(`${paramName}: Path resolution resulted in directory traversal: ${path}`);
136
+ }
137
+ }
138
+ //# sourceMappingURL=path-security.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"path-security.js","sourceRoot":"","sources":["../../src/utils/path-security.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,85 @@
1
+ {
2
+ "name": "synapse-mcp",
3
+ "version": "1.0.0",
4
+ "description": "MCP server providing Flux (Docker management) and Scout (SSH operations) tools for homelab infrastructure",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "synapse-mcp": "./dist/index.js"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "README.md"
19
+ ],
20
+ "scripts": {
21
+ "build": "tsc",
22
+ "start": "node dist/index.js",
23
+ "dev": "tsc --watch",
24
+ "clean": "rm -rf dist coverage",
25
+ "typecheck": "tsc --noEmit",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "test:coverage": "vitest run --coverage",
29
+ "test:integration": "vitest run \"**/*.integration.test.ts\"",
30
+ "test:bench": "vitest run src/schemas/unified.bench.test.ts",
31
+ "lint": "eslint src/",
32
+ "lint:fix": "eslint src/ --fix",
33
+ "format": "prettier --write src/",
34
+ "format:check": "prettier --check src/",
35
+ "prepublishOnly": "pnpm run build"
36
+ },
37
+ "keywords": [
38
+ "mcp",
39
+ "synapse",
40
+ "flux",
41
+ "scout",
42
+ "homelab",
43
+ "docker",
44
+ "ssh",
45
+ "infrastructure",
46
+ "zfs",
47
+ "remote-management"
48
+ ],
49
+ "author": "Jacob Magar",
50
+ "license": "MIT",
51
+ "repository": {
52
+ "type": "git",
53
+ "url": "git+https://github.com/jmagar/synapse-mcp.git"
54
+ },
55
+ "bugs": {
56
+ "url": "https://github.com/jmagar/synapse-mcp/issues"
57
+ },
58
+ "homepage": "https://github.com/jmagar/synapse-mcp#readme",
59
+ "engines": {
60
+ "node": ">=20.0.0"
61
+ },
62
+ "dependencies": {
63
+ "@modelcontextprotocol/sdk": "^1.25.1",
64
+ "dockerode": "^4.0.9",
65
+ "express": "^5.2.1",
66
+ "express-rate-limit": "^8.2.1",
67
+ "node-ssh": "^13.2.1",
68
+ "zod": "^4.2.1",
69
+ "zod-to-json-schema": "^3.25.1"
70
+ },
71
+ "devDependencies": {
72
+ "@eslint/js": "^9.39.2",
73
+ "@types/dockerode": "^3.3.47",
74
+ "@types/express": "^5.0.6",
75
+ "@types/node": "^25.0.3",
76
+ "@types/ssh2": "^1.15.5",
77
+ "@vitest/coverage-v8": "^4.0.16",
78
+ "eslint": "^9.39.2",
79
+ "eslint-config-prettier": "^10.1.8",
80
+ "prettier": "^3.7.4",
81
+ "typescript": "^5.7.0",
82
+ "typescript-eslint": "^8.51.0",
83
+ "vitest": "^4.0.16"
84
+ }
85
+ }