@mseep/mcp-swarmpit 0.1.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 (98) hide show
  1. package/CLAUDE.md +128 -0
  2. package/README.md +416 -0
  3. package/dist/client.d.ts +107 -0
  4. package/dist/client.js +297 -0
  5. package/dist/client.js.map +1 -0
  6. package/dist/config.d.ts +8 -0
  7. package/dist/config.js +41 -0
  8. package/dist/config.js.map +1 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +41 -0
  11. package/dist/index.js.map +1 -0
  12. package/dist/sanitize.d.ts +41 -0
  13. package/dist/sanitize.js +165 -0
  14. package/dist/sanitize.js.map +1 -0
  15. package/dist/test/config.test.d.ts +1 -0
  16. package/dist/test/config.test.js +103 -0
  17. package/dist/test/config.test.js.map +1 -0
  18. package/dist/test/file-ref.test.d.ts +1 -0
  19. package/dist/test/file-ref.test.js +163 -0
  20. package/dist/test/file-ref.test.js.map +1 -0
  21. package/dist/test/helpers.test.d.ts +1 -0
  22. package/dist/test/helpers.test.js +133 -0
  23. package/dist/test/helpers.test.js.map +1 -0
  24. package/dist/test/sanitize.test.d.ts +1 -0
  25. package/dist/test/sanitize.test.js +207 -0
  26. package/dist/test/sanitize.test.js.map +1 -0
  27. package/dist/tools/admin.d.ts +3 -0
  28. package/dist/tools/admin.js +64 -0
  29. package/dist/tools/admin.js.map +1 -0
  30. package/dist/tools/configs.d.ts +4 -0
  31. package/dist/tools/configs.js +70 -0
  32. package/dist/tools/configs.js.map +1 -0
  33. package/dist/tools/dashboard.d.ts +3 -0
  34. package/dist/tools/dashboard.js +41 -0
  35. package/dist/tools/dashboard.js.map +1 -0
  36. package/dist/tools/helpers.d.ts +16 -0
  37. package/dist/tools/helpers.js +74 -0
  38. package/dist/tools/helpers.js.map +1 -0
  39. package/dist/tools/networks.d.ts +3 -0
  40. package/dist/tools/networks.js +70 -0
  41. package/dist/tools/networks.js.map +1 -0
  42. package/dist/tools/nodes.d.ts +3 -0
  43. package/dist/tools/nodes.js +59 -0
  44. package/dist/tools/nodes.js.map +1 -0
  45. package/dist/tools/register.d.ts +3 -0
  46. package/dist/tools/register.js +30 -0
  47. package/dist/tools/register.js.map +1 -0
  48. package/dist/tools/secrets.d.ts +4 -0
  49. package/dist/tools/secrets.js +70 -0
  50. package/dist/tools/secrets.js.map +1 -0
  51. package/dist/tools/services.d.ts +4 -0
  52. package/dist/tools/services.js +198 -0
  53. package/dist/tools/services.js.map +1 -0
  54. package/dist/tools/stacks.d.ts +4 -0
  55. package/dist/tools/stacks.js +196 -0
  56. package/dist/tools/stacks.js.map +1 -0
  57. package/dist/tools/tasks.d.ts +3 -0
  58. package/dist/tools/tasks.js +23 -0
  59. package/dist/tools/tasks.js.map +1 -0
  60. package/dist/tools/timeseries.d.ts +3 -0
  61. package/dist/tools/timeseries.js +41 -0
  62. package/dist/tools/timeseries.js.map +1 -0
  63. package/dist/tools/util.d.ts +3 -0
  64. package/dist/tools/util.js +10 -0
  65. package/dist/tools/util.js.map +1 -0
  66. package/dist/tools/volumes.d.ts +3 -0
  67. package/dist/tools/volumes.js +59 -0
  68. package/dist/tools/volumes.js.map +1 -0
  69. package/dist/types.d.ts +119 -0
  70. package/dist/types.js +2 -0
  71. package/dist/types.js.map +1 -0
  72. package/package.json +43 -0
  73. package/src/client.ts +391 -0
  74. package/src/config.ts +57 -0
  75. package/src/index.ts +49 -0
  76. package/src/sanitize.ts +218 -0
  77. package/src/test/config.test.ts +118 -0
  78. package/src/test/file-ref.test.ts +191 -0
  79. package/src/test/helpers.test.ts +147 -0
  80. package/src/test/sanitize.test.ts +234 -0
  81. package/src/tools/admin.ts +93 -0
  82. package/src/tools/configs.ts +101 -0
  83. package/src/tools/dashboard.ts +65 -0
  84. package/src/tools/helpers.ts +91 -0
  85. package/src/tools/networks.ts +99 -0
  86. package/src/tools/nodes.ts +88 -0
  87. package/src/tools/register.ts +36 -0
  88. package/src/tools/secrets.ts +101 -0
  89. package/src/tools/services.ts +283 -0
  90. package/src/tools/stacks.ts +282 -0
  91. package/src/tools/tasks.ts +37 -0
  92. package/src/tools/timeseries.ts +65 -0
  93. package/src/tools/util.ts +20 -0
  94. package/src/tools/volumes.ts +88 -0
  95. package/src/types.ts +131 -0
  96. package/swagger.json +1 -0
  97. package/swarmpit-config.example.json +9 -0
  98. package/tsconfig.json +15 -0
package/dist/client.js ADDED
@@ -0,0 +1,297 @@
1
+ export class SwarmpitApiError extends Error {
2
+ status;
3
+ statusText;
4
+ body;
5
+ constructor(status, statusText, body) {
6
+ super(`Swarmpit API error ${status} ${statusText}: ${body}`);
7
+ this.status = status;
8
+ this.statusText = statusText;
9
+ this.body = body;
10
+ this.name = "SwarmpitApiError";
11
+ }
12
+ }
13
+ export class SwarmpitClient {
14
+ baseUrl;
15
+ token;
16
+ timeout;
17
+ constructor(baseUrl, token, timeout = 30_000) {
18
+ this.baseUrl = baseUrl;
19
+ this.token = token;
20
+ this.timeout = timeout;
21
+ }
22
+ async request(method, path, body) {
23
+ const url = `${this.baseUrl}${path}`;
24
+ const headers = {
25
+ Authorization: this.token.startsWith("Bearer ") ? this.token : `Bearer ${this.token}`,
26
+ Accept: "application/json",
27
+ };
28
+ if (body !== undefined) {
29
+ headers["Content-Type"] = "application/json";
30
+ }
31
+ const controller = new AbortController();
32
+ const timer = setTimeout(() => controller.abort(), this.timeout);
33
+ try {
34
+ const response = await fetch(url, {
35
+ method,
36
+ headers,
37
+ body: body !== undefined ? JSON.stringify(body) : undefined,
38
+ signal: controller.signal,
39
+ });
40
+ if (!response.ok) {
41
+ const text = await response.text().catch(() => "");
42
+ if (response.status === 401) {
43
+ throw new SwarmpitApiError(401, response.statusText, "Token expired or invalid — regenerate the API token in Swarmpit");
44
+ }
45
+ throw new SwarmpitApiError(response.status, response.statusText, text);
46
+ }
47
+ const text = await response.text();
48
+ if (!text)
49
+ return undefined;
50
+ return JSON.parse(text);
51
+ }
52
+ catch (err) {
53
+ if (err instanceof SwarmpitApiError)
54
+ throw err;
55
+ if (err instanceof Error && err.name === "AbortError") {
56
+ throw new Error(`Swarmpit API request timed out after ${this.timeout}ms: ${method} ${path}`);
57
+ }
58
+ throw err;
59
+ }
60
+ finally {
61
+ clearTimeout(timer);
62
+ }
63
+ }
64
+ // Services
65
+ async listServices() {
66
+ return this.request("GET", "/api/services");
67
+ }
68
+ async getService(id) {
69
+ return this.request("GET", `/api/services/${encodeURIComponent(id)}`);
70
+ }
71
+ async getServiceLogs(id, since = "5m") {
72
+ // Swarmpit accepts Go duration strings: "1s", "1m", "1h", "24h" etc.
73
+ return this.request("GET", `/api/services/${encodeURIComponent(id)}/logs?since=${encodeURIComponent(since)}`);
74
+ }
75
+ async createService(spec) {
76
+ return this.request("POST", "/api/services", spec);
77
+ }
78
+ async updateService(id, spec) {
79
+ await this.request("POST", `/api/services/${encodeURIComponent(id)}`, spec);
80
+ }
81
+ async redeployService(id, tag) {
82
+ const query = tag ? `?tag=${encodeURIComponent(tag)}` : "";
83
+ await this.request("POST", `/api/services/${encodeURIComponent(id)}/redeploy${query}`);
84
+ }
85
+ async rollbackService(id) {
86
+ await this.request("POST", `/api/services/${encodeURIComponent(id)}/rollback`);
87
+ }
88
+ async stopService(id) {
89
+ await this.request("POST", `/api/services/${encodeURIComponent(id)}/stop`);
90
+ }
91
+ async deleteService(id) {
92
+ await this.request("DELETE", `/api/services/${encodeURIComponent(id)}`);
93
+ }
94
+ async getServiceTasks(id) {
95
+ return this.request("GET", `/api/services/${encodeURIComponent(id)}/tasks`);
96
+ }
97
+ async getServiceCompose(id) {
98
+ const result = await this.request("GET", `/api/services/${encodeURIComponent(id)}/compose`);
99
+ return { compose: result.spec?.compose ?? result.compose ?? "" };
100
+ }
101
+ async getServiceNetworks(id) {
102
+ return this.request("GET", `/api/services/${encodeURIComponent(id)}/networks`);
103
+ }
104
+ // Stacks
105
+ async listStacks() {
106
+ return this.request("GET", "/api/stacks");
107
+ }
108
+ async getStackServices(name) {
109
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/services`);
110
+ }
111
+ async getStackFile(name) {
112
+ const result = await this.request("GET", `/api/stacks/${encodeURIComponent(name)}/file`);
113
+ // API returns { spec: { compose } } but we normalize to { compose }
114
+ const compose = result.spec?.compose ?? result.compose ?? "";
115
+ return { compose };
116
+ }
117
+ async createStack(spec) {
118
+ await this.request("POST", "/api/stacks", spec);
119
+ }
120
+ async updateStack(name, compose) {
121
+ await this.request("POST", `/api/stacks/${encodeURIComponent(name)}`, {
122
+ name,
123
+ spec: { compose },
124
+ });
125
+ }
126
+ async redeployStack(name) {
127
+ await this.request("POST", `/api/stacks/${encodeURIComponent(name)}/redeploy`);
128
+ }
129
+ async rollbackStack(name) {
130
+ await this.request("POST", `/api/stacks/${encodeURIComponent(name)}/rollback`);
131
+ }
132
+ async deactivateStack(name) {
133
+ await this.request("POST", `/api/stacks/${encodeURIComponent(name)}/deactivate`);
134
+ }
135
+ async getStackTasks(name) {
136
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/tasks`);
137
+ }
138
+ async getStackVolumes(name) {
139
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/volumes`);
140
+ }
141
+ async getStackNetworks(name) {
142
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/networks`);
143
+ }
144
+ async getStackCompose(name) {
145
+ const result = await this.request("GET", `/api/stacks/${encodeURIComponent(name)}/compose`);
146
+ return { compose: result.spec?.compose ?? result.compose ?? "" };
147
+ }
148
+ async getStackSecrets(name) {
149
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/secrets`);
150
+ }
151
+ async getStackConfigs(name) {
152
+ return this.request("GET", `/api/stacks/${encodeURIComponent(name)}/configs`);
153
+ }
154
+ async createStackFile(name, compose) {
155
+ await this.request("POST", `/api/stacks/${encodeURIComponent(name)}/file`, { name, spec: { compose } });
156
+ }
157
+ async deleteStackFile(name) {
158
+ await this.request("DELETE", `/api/stacks/${encodeURIComponent(name)}/file`);
159
+ }
160
+ async deleteStack(name) {
161
+ await this.request("DELETE", `/api/stacks/${encodeURIComponent(name)}`);
162
+ }
163
+ // Networks
164
+ async listNetworks() {
165
+ return this.request("GET", "/api/networks");
166
+ }
167
+ async getNetwork(id) {
168
+ return this.request("GET", `/api/networks/${encodeURIComponent(id)}`);
169
+ }
170
+ async getNetworkServices(id) {
171
+ return this.request("GET", `/api/networks/${encodeURIComponent(id)}/services`);
172
+ }
173
+ async createNetwork(spec) {
174
+ await this.request("POST", "/api/networks", spec);
175
+ }
176
+ async deleteNetwork(id) {
177
+ await this.request("DELETE", `/api/networks/${encodeURIComponent(id)}`);
178
+ }
179
+ // Nodes
180
+ async listNodes() {
181
+ return this.request("GET", "/api/nodes");
182
+ }
183
+ async getNode(id) {
184
+ return this.request("GET", `/api/nodes/${encodeURIComponent(id)}`);
185
+ }
186
+ async editNode(id, spec) {
187
+ await this.request("POST", `/api/nodes/${encodeURIComponent(id)}`, spec);
188
+ }
189
+ async deleteNode(id) {
190
+ await this.request("DELETE", `/api/nodes/${encodeURIComponent(id)}`);
191
+ }
192
+ async getNodeTasks(id) {
193
+ return this.request("GET", `/api/nodes/${encodeURIComponent(id)}/tasks`);
194
+ }
195
+ // Tasks
196
+ async listTasks() {
197
+ return this.request("GET", "/api/tasks");
198
+ }
199
+ async getTask(id) {
200
+ return this.request("GET", `/api/tasks/${encodeURIComponent(id)}`);
201
+ }
202
+ // Volumes
203
+ async listVolumes() {
204
+ return this.request("GET", "/api/volumes");
205
+ }
206
+ async getVolume(name) {
207
+ return this.request("GET", `/api/volumes/${encodeURIComponent(name)}`);
208
+ }
209
+ async getVolumeServices(name) {
210
+ return this.request("GET", `/api/volumes/${encodeURIComponent(name)}/services`);
211
+ }
212
+ async createVolume(spec) {
213
+ await this.request("POST", "/api/volumes", spec);
214
+ }
215
+ async deleteVolume(name) {
216
+ await this.request("DELETE", `/api/volumes/${encodeURIComponent(name)}`);
217
+ }
218
+ // Secrets
219
+ async listSecrets() {
220
+ return this.request("GET", "/api/secrets");
221
+ }
222
+ async getSecret(id) {
223
+ return this.request("GET", `/api/secrets/${encodeURIComponent(id)}`);
224
+ }
225
+ async getSecretServices(id) {
226
+ return this.request("GET", `/api/secrets/${encodeURIComponent(id)}/services`);
227
+ }
228
+ async createSecret(spec) {
229
+ // Swarmpit expects base64-encoded data
230
+ const encoded = Buffer.from(spec.data, "utf-8").toString("base64");
231
+ await this.request("POST", "/api/secrets", { ...spec, data: encoded });
232
+ }
233
+ async deleteSecret(id) {
234
+ await this.request("DELETE", `/api/secrets/${encodeURIComponent(id)}`);
235
+ }
236
+ // Configs
237
+ async listConfigs() {
238
+ return this.request("GET", "/api/configs");
239
+ }
240
+ async getConfig(id) {
241
+ return this.request("GET", `/api/configs/${encodeURIComponent(id)}`);
242
+ }
243
+ async getConfigServices(id) {
244
+ return this.request("GET", `/api/configs/${encodeURIComponent(id)}/services`);
245
+ }
246
+ async createConfig(spec) {
247
+ // Swarmpit expects base64-encoded data
248
+ const encoded = Buffer.from(spec.data, "utf-8").toString("base64");
249
+ await this.request("POST", "/api/configs", { ...spec, data: encoded });
250
+ }
251
+ async deleteConfig(id) {
252
+ await this.request("DELETE", `/api/configs/${encodeURIComponent(id)}`);
253
+ }
254
+ // Admin
255
+ async listUsers() {
256
+ return this.request("GET", "/api/admin/users");
257
+ }
258
+ async getUser(id) {
259
+ return this.request("GET", `/api/admin/users/${encodeURIComponent(id)}`);
260
+ }
261
+ async createUser(spec) {
262
+ await this.request("POST", "/api/admin/users", spec);
263
+ }
264
+ async editUser(id, spec) {
265
+ await this.request("POST", `/api/admin/users/${encodeURIComponent(id)}`, spec);
266
+ }
267
+ async deleteUser(id) {
268
+ await this.request("DELETE", `/api/admin/users/${encodeURIComponent(id)}`);
269
+ }
270
+ // Dashboard
271
+ async pinNodeToDashboard(id) {
272
+ await this.request("POST", `/api/nodes/${encodeURIComponent(id)}/dashboard`);
273
+ }
274
+ async unpinNodeFromDashboard(id) {
275
+ await this.request("DELETE", `/api/nodes/${encodeURIComponent(id)}/dashboard`);
276
+ }
277
+ async pinServiceToDashboard(id) {
278
+ await this.request("POST", `/api/services/${encodeURIComponent(id)}/dashboard`);
279
+ }
280
+ async unpinServiceFromDashboard(id) {
281
+ await this.request("DELETE", `/api/services/${encodeURIComponent(id)}/dashboard`);
282
+ }
283
+ // Timeseries
284
+ async getNodesTimeseries() {
285
+ return this.request("GET", "/api/nodes/ts");
286
+ }
287
+ async getServicesCpuTimeseries() {
288
+ return this.request("GET", "/api/services/ts/cpu");
289
+ }
290
+ async getServicesMemoryTimeseries() {
291
+ return this.request("GET", "/api/services/ts/memory");
292
+ }
293
+ async getTaskTimeseries(name) {
294
+ return this.request("GET", `/api/tasks/${encodeURIComponent(name)}/ts`);
295
+ }
296
+ }
297
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export type RedactMode = "all" | "sensitive" | "none";
2
+ export interface SwarmpitConfig {
3
+ url: string;
4
+ token: string;
5
+ redact: RedactMode;
6
+ redactPatterns: string[];
7
+ }
8
+ export declare function loadConfig(): SwarmpitConfig;
package/dist/config.js ADDED
@@ -0,0 +1,41 @@
1
+ import { readFileSync } from "node:fs";
2
+ function loadToken() {
3
+ const tokenFile = process.env.SWARMPIT_TOKEN_FILE;
4
+ if (tokenFile) {
5
+ try {
6
+ return readFileSync(tokenFile, "utf-8").trim();
7
+ }
8
+ catch (err) {
9
+ throw new Error(`SWARMPIT_TOKEN_FILE "${tokenFile}" could not be read: ${err instanceof Error ? err.message : err}`);
10
+ }
11
+ }
12
+ const token = process.env.SWARMPIT_TOKEN;
13
+ if (!token) {
14
+ throw new Error("Neither SWARMPIT_TOKEN nor SWARMPIT_TOKEN_FILE is set. Use SWARMPIT_TOKEN_FILE to avoid storing the token in MCP client config files.");
15
+ }
16
+ return token;
17
+ }
18
+ export function loadConfig() {
19
+ const url = process.env.SWARMPIT_URL;
20
+ if (!url)
21
+ throw new Error("SWARMPIT_URL is not set");
22
+ const token = loadToken();
23
+ const redactRaw = process.env.SWARMPIT_REDACT;
24
+ let redact = "all";
25
+ if (redactRaw !== undefined) {
26
+ if (redactRaw !== "all" && redactRaw !== "sensitive" && redactRaw !== "none") {
27
+ throw new Error('SWARMPIT_REDACT must be "all" (default), "sensitive", or "none"');
28
+ }
29
+ redact = redactRaw;
30
+ }
31
+ const redactPatterns = process.env.SWARMPIT_REDACT_PATTERNS
32
+ ? process.env.SWARMPIT_REDACT_PATTERNS.split(",").map((p) => p.trim()).filter(Boolean)
33
+ : [];
34
+ return {
35
+ url: url.replace(/\/+$/, ""),
36
+ token,
37
+ redact,
38
+ redactPatterns,
39
+ };
40
+ }
41
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAWvC,SAAS,SAAS;IAChB,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,CAAC;IAClD,IAAI,SAAS,EAAE,CAAC;QACd,IAAI,CAAC;YACH,OAAO,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;QACjD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CACb,wBAAwB,SAAS,wBAAwB,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,CACpG,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;IACzC,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,uIAAuI,CACxI,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC;IACrC,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAErD,MAAM,KAAK,GAAG,SAAS,EAAE,CAAC;IAE1B,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IAC9C,IAAI,MAAM,GAAe,KAAK,CAAC;IAC/B,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,IAAI,SAAS,KAAK,KAAK,IAAI,SAAS,KAAK,WAAW,IAAI,SAAS,KAAK,MAAM,EAAE,CAAC;YAC7E,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;QACrF,CAAC;QACD,MAAM,GAAG,SAAS,CAAC;IACrB,CAAC;IAED,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,wBAAwB;QACzD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QACtF,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO;QACL,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;QAC5B,KAAK;QACL,MAAM;QACN,cAAc;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/index.js ADDED
@@ -0,0 +1,41 @@
1
+ #!/usr/bin/env node
2
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
3
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
4
+ import { loadConfig } from "./config.js";
5
+ import { SwarmpitClient } from "./client.js";
6
+ import { setExtraRedactPatterns } from "./sanitize.js";
7
+ import { registerAllTools } from "./tools/register.js";
8
+ async function checkConnection(url, token) {
9
+ const client = new SwarmpitClient(url, token, 10_000);
10
+ try {
11
+ await client.listNodes();
12
+ console.error(`mcp-swarmpit: connected to ${url}`);
13
+ }
14
+ catch (err) {
15
+ const msg = err instanceof Error ? err.message : String(err);
16
+ console.error(`mcp-swarmpit: WARNING — cannot reach ${url}: ${msg}`);
17
+ console.error(`mcp-swarmpit: tools will be available but API calls may fail`);
18
+ }
19
+ }
20
+ async function main() {
21
+ const config = loadConfig();
22
+ if (config.redactPatterns.length > 0) {
23
+ setExtraRedactPatterns(config.redactPatterns);
24
+ console.error(`mcp-swarmpit: extra redact patterns: ${config.redactPatterns.join(", ")}`);
25
+ }
26
+ await checkConnection(config.url, config.token);
27
+ const server = new McpServer({
28
+ name: "mcp-swarmpit",
29
+ version: "0.1.0",
30
+ });
31
+ registerAllTools(server, config);
32
+ const transport = new StdioServerTransport();
33
+ await server.connect(transport);
34
+ console.error("mcp-swarmpit: running on stdio");
35
+ }
36
+ main().catch((err) => {
37
+ console.error("mcp-swarmpit fatal:", err);
38
+ process.exit(1);
39
+ });
40
+ process.on("SIGINT", () => process.exit(0));
41
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAC;AACjF,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,KAAK,UAAU,eAAe,CAAC,GAAW,EAAE,KAAa;IACvD,MAAM,MAAM,GAAG,IAAI,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC;IACtD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,SAAS,EAAE,CAAC;QACzB,OAAO,CAAC,KAAK,CAAC,8BAA8B,GAAG,EAAE,CAAC,CAAC;IACrD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,GAAG,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,OAAO,CAAC,KAAK,CAAC,wCAAwC,GAAG,KAAK,GAAG,EAAE,CAAC,CAAC;QACrE,OAAO,CAAC,KAAK,CAAC,8DAA8D,CAAC,CAAC;IAChF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,MAAM,CAAC,cAAc,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,sBAAsB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QAC9C,OAAO,CAAC,KAAK,CAAC,wCAAwC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,eAAe,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhD,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;QAC3B,IAAI,EAAE,cAAc;QACpB,OAAO,EAAE,OAAO;KACjB,CAAC,CAAC;IAEH,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEjC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;IAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAChC,OAAO,CAAC,KAAK,CAAC,gCAAgC,CAAC,CAAC;AAClD,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,qBAAqB,EAAE,GAAG,CAAC,CAAC;IAC1C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,41 @@
1
+ import type { SwarmpitService } from "./types.js";
2
+ export declare function setExtraRedactPatterns(patterns: string[]): void;
3
+ export declare function sanitizeService(service: SwarmpitService, redactAll?: boolean): SwarmpitService;
4
+ export declare function sanitizeServices(services: SwarmpitService[], redactAll?: boolean): SwarmpitService[];
5
+ /**
6
+ * Sanitize a Docker Compose YAML string by redacting environment variable
7
+ * values that look sensitive. Handles both forms:
8
+ *
9
+ * environment:
10
+ * DATABASE_PASSWORD: supersecret → DATABASE_PASSWORD: [REDACTED]
11
+ * - DATABASE_PASSWORD=supersecret → - DATABASE_PASSWORD=[REDACTED]
12
+ */
13
+ export declare function sanitizeComposeYaml(yaml: string, redactAll?: boolean): string;
14
+ /**
15
+ * Resolve $env:VAR_NAME references in a compose YAML string.
16
+ * Plain values pass through unchanged. Only $env: prefixed values
17
+ * are resolved from process.env.
18
+ *
19
+ * DATABASE_PASSWORD: $env:MY_DB_PASS → DATABASE_PASSWORD: actual-value
20
+ * NODE_ENV: production → NODE_ENV: production
21
+ */
22
+ /**
23
+ * Resolve $env:VAR_NAME references in a compose YAML string.
24
+ * Plain values pass through unchanged. Only $env: prefixed values
25
+ * are resolved from process.env.
26
+ *
27
+ * DATABASE_PASSWORD: $env:MY_DB_PASS → DATABASE_PASSWORD: actual-value
28
+ * NODE_ENV: production → NODE_ENV: production
29
+ */
30
+ export declare function resolveComposeEnvRefs(yaml: string): string;
31
+ /**
32
+ * Restore [REDACTED] values in an edited compose YAML from the original
33
+ * raw compose. This allows safe round-tripping:
34
+ *
35
+ * 1. swarmpit_get_stack returns compose with sensitive values as [REDACTED]
36
+ * 2. Claude edits only what it needs, leaves [REDACTED] in place
37
+ * 3. This function restores original values where [REDACTED] remains
38
+ * 4. $env:VAR references are resolved from process.env
39
+ * 5. Plaintext values pass through as-is
40
+ */
41
+ export declare function restoreRedactedValues(editedYaml: string, originalYaml: string): string;
@@ -0,0 +1,165 @@
1
+ const DEFAULT_SENSITIVE_PATTERNS = [
2
+ /pass/i,
3
+ /secret/i,
4
+ /token/i,
5
+ /key/i,
6
+ /auth/i,
7
+ /credential/i,
8
+ /private/i,
9
+ /connection.?string/i,
10
+ /dsn/i,
11
+ ];
12
+ let extraPatterns = [];
13
+ export function setExtraRedactPatterns(patterns) {
14
+ extraPatterns = patterns.map((p) => new RegExp(p, "i"));
15
+ }
16
+ function isSensitiveEnvVar(name) {
17
+ return DEFAULT_SENSITIVE_PATTERNS.some((p) => p.test(name))
18
+ || extraPatterns.some((p) => p.test(name));
19
+ }
20
+ function redactEnvVars(variables, redactAll) {
21
+ if (!variables)
22
+ return undefined;
23
+ return variables.map((v) => ({
24
+ name: v.name,
25
+ value: redactAll || isSensitiveEnvVar(v.name) ? "[REDACTED]" : v.value,
26
+ }));
27
+ }
28
+ export function sanitizeService(service, redactAll = true) {
29
+ return {
30
+ ...service,
31
+ variables: redactEnvVars(service.variables, redactAll) ?? [],
32
+ secrets: service.secrets?.map(({ id, secretName, secretTarget }) => ({
33
+ id,
34
+ secretName,
35
+ secretTarget,
36
+ })) ?? [],
37
+ configs: service.configs?.map(({ id, configName, configTarget }) => ({
38
+ id,
39
+ configName,
40
+ configTarget,
41
+ })) ?? [],
42
+ };
43
+ }
44
+ export function sanitizeServices(services, redactAll = true) {
45
+ return services.map((s) => sanitizeService(s, redactAll));
46
+ }
47
+ /**
48
+ * Sanitize a Docker Compose YAML string by redacting environment variable
49
+ * values that look sensitive. Handles both forms:
50
+ *
51
+ * environment:
52
+ * DATABASE_PASSWORD: supersecret → DATABASE_PASSWORD: [REDACTED]
53
+ * - DATABASE_PASSWORD=supersecret → - DATABASE_PASSWORD=[REDACTED]
54
+ */
55
+ export function sanitizeComposeYaml(yaml, redactAll = true) {
56
+ if (!yaml)
57
+ return yaml;
58
+ // Key-value form: SOME_KEY: some_value
59
+ const sanitized = yaml.replace(/^(\s+)([A-Z_][A-Z0-9_]*):\s*(.+)$/gm, (match, indent, key, value) => {
60
+ // Skip non-env-var-looking keys (lowercase, contains dots, etc.)
61
+ if (key !== key.toUpperCase())
62
+ return match;
63
+ // Skip values that look like YAML references, objects, or arrays
64
+ if (value.startsWith("&") || value.startsWith("*") || value.startsWith("{") || value.startsWith("["))
65
+ return match;
66
+ if (redactAll || isSensitiveEnvVar(key)) {
67
+ return `${indent}${key}: [REDACTED]`;
68
+ }
69
+ return match;
70
+ });
71
+ // List form: - SOME_KEY=some_value
72
+ return sanitized.replace(/^(\s+-\s+)([A-Z_][A-Z0-9_]*)=(.+)$/gm, (match, prefix, key, value) => {
73
+ if (redactAll || isSensitiveEnvVar(key)) {
74
+ return `${prefix}${key}=[REDACTED]`;
75
+ }
76
+ return match;
77
+ });
78
+ }
79
+ /**
80
+ * Resolve $env:VAR_NAME references in a compose YAML string.
81
+ * Plain values pass through unchanged. Only $env: prefixed values
82
+ * are resolved from process.env.
83
+ *
84
+ * DATABASE_PASSWORD: $env:MY_DB_PASS → DATABASE_PASSWORD: actual-value
85
+ * NODE_ENV: production → NODE_ENV: production
86
+ */
87
+ /**
88
+ * Resolve $env:VAR_NAME references in a compose YAML string.
89
+ * Plain values pass through unchanged. Only $env: prefixed values
90
+ * are resolved from process.env.
91
+ *
92
+ * DATABASE_PASSWORD: $env:MY_DB_PASS → DATABASE_PASSWORD: actual-value
93
+ * NODE_ENV: production → NODE_ENV: production
94
+ */
95
+ export function resolveComposeEnvRefs(yaml) {
96
+ if (!yaml)
97
+ return yaml;
98
+ // Key-value form: KEY: $env:VAR_NAME
99
+ const resolved = yaml.replace(/^(\s+[A-Z_][A-Z0-9_]*:\s*)\$env:([A-Z_][A-Z0-9_]*)$/gm, (match, prefix, varName) => {
100
+ const value = process.env[varName];
101
+ if (!value) {
102
+ throw new Error(`$env:${varName} referenced in compose but not set in environment`);
103
+ }
104
+ return `${prefix}${value}`;
105
+ });
106
+ // List form: - KEY=$env:VAR_NAME
107
+ return resolved.replace(/^(\s+-\s+[A-Z_][A-Z0-9_]*=)\$env:([A-Z_][A-Z0-9_]*)$/gm, (match, prefix, varName) => {
108
+ const value = process.env[varName];
109
+ if (!value) {
110
+ throw new Error(`$env:${varName} referenced in compose but not set in environment`);
111
+ }
112
+ return `${prefix}${value}`;
113
+ });
114
+ }
115
+ /**
116
+ * Build env var lookup from raw compose YAML. Extracts KEY=value pairs
117
+ * so [REDACTED] values can be restored from the original.
118
+ */
119
+ function extractComposeEnvVars(yaml) {
120
+ const vars = new Map();
121
+ if (!yaml)
122
+ return vars;
123
+ // Key-value form: KEY: value
124
+ for (const match of yaml.matchAll(/^\s+([A-Z_][A-Z0-9_]*):\s*(.+)$/gm)) {
125
+ vars.set(match[1], match[2]);
126
+ }
127
+ // List form: - KEY=value
128
+ for (const match of yaml.matchAll(/^\s+-\s+([A-Z_][A-Z0-9_]*)=(.+)$/gm)) {
129
+ vars.set(match[1], match[2]);
130
+ }
131
+ return vars;
132
+ }
133
+ /**
134
+ * Restore [REDACTED] values in an edited compose YAML from the original
135
+ * raw compose. This allows safe round-tripping:
136
+ *
137
+ * 1. swarmpit_get_stack returns compose with sensitive values as [REDACTED]
138
+ * 2. Claude edits only what it needs, leaves [REDACTED] in place
139
+ * 3. This function restores original values where [REDACTED] remains
140
+ * 4. $env:VAR references are resolved from process.env
141
+ * 5. Plaintext values pass through as-is
142
+ */
143
+ export function restoreRedactedValues(editedYaml, originalYaml) {
144
+ if (!editedYaml)
145
+ return editedYaml;
146
+ const origVars = extractComposeEnvVars(originalYaml);
147
+ // Key-value form: restore KEY: [REDACTED]
148
+ let restored = editedYaml.replace(/^(\s+)([A-Z_][A-Z0-9_]*):\s*\[REDACTED\]$/gm, (match, indent, key) => {
149
+ const original = origVars.get(key);
150
+ if (original) {
151
+ return `${indent}${key}: ${original}`;
152
+ }
153
+ return match;
154
+ });
155
+ // List form: restore - KEY=[REDACTED]
156
+ restored = restored.replace(/^(\s+-\s+)([A-Z_][A-Z0-9_]*)=\[REDACTED\]$/gm, (match, prefix, key) => {
157
+ const original = origVars.get(key);
158
+ if (original) {
159
+ return `${prefix}${key}=${original}`;
160
+ }
161
+ return match;
162
+ });
163
+ return restored;
164
+ }
165
+ //# sourceMappingURL=sanitize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sanitize.js","sourceRoot":"","sources":["../src/sanitize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};