@soyrageagency/docker-mcp 1.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.
- package/LICENSE +21 -0
- package/README.md +882 -0
- package/dist/ai/credentials.d.ts +72 -0
- package/dist/ai/credentials.js +157 -0
- package/dist/ai/credentials.js.map +1 -0
- package/dist/ai/login.d.ts +22 -0
- package/dist/ai/login.js +189 -0
- package/dist/ai/login.js.map +1 -0
- package/dist/ai/provider.d.ts +29 -0
- package/dist/ai/provider.js +113 -0
- package/dist/ai/provider.js.map +1 -0
- package/dist/assets.d.ts +20 -0
- package/dist/assets.js +56 -0
- package/dist/assets.js.map +1 -0
- package/dist/branding.d.ts +31 -0
- package/dist/branding.js +61 -0
- package/dist/branding.js.map +1 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.js +128 -0
- package/dist/config.js.map +1 -0
- package/dist/docker/client.d.ts +66 -0
- package/dist/docker/client.js +161 -0
- package/dist/docker/client.js.map +1 -0
- package/dist/docker/compose.d.ts +74 -0
- package/dist/docker/compose.js +126 -0
- package/dist/docker/compose.js.map +1 -0
- package/dist/entry.d.ts +15 -0
- package/dist/entry.js +33 -0
- package/dist/entry.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/dist/logger.d.ts +25 -0
- package/dist/logger.js +68 -0
- package/dist/logger.js.map +1 -0
- package/dist/panel/index.d.ts +16 -0
- package/dist/panel/index.js +53 -0
- package/dist/panel/index.js.map +1 -0
- package/dist/panel/public/app.js +1004 -0
- package/dist/panel/public/index.html +243 -0
- package/dist/panel/public/styles.css +428 -0
- package/dist/panel/server.d.ts +23 -0
- package/dist/panel/server.js +355 -0
- package/dist/panel/server.js.map +1 -0
- package/dist/panel/service.d.ts +327 -0
- package/dist/panel/service.js +1356 -0
- package/dist/panel/service.js.map +1 -0
- package/dist/plugins.d.ts +50 -0
- package/dist/plugins.js +121 -0
- package/dist/plugins.js.map +1 -0
- package/dist/ragedocker.d.ts +21 -0
- package/dist/ragedocker.js +164 -0
- package/dist/ragedocker.js.map +1 -0
- package/dist/tools/about.d.ts +15 -0
- package/dist/tools/about.js +55 -0
- package/dist/tools/about.js.map +1 -0
- package/dist/tools/compose.d.ts +19 -0
- package/dist/tools/compose.js +145 -0
- package/dist/tools/compose.js.map +1 -0
- package/dist/tools/containers.d.ts +13 -0
- package/dist/tools/containers.js +119 -0
- package/dist/tools/containers.js.map +1 -0
- package/dist/tools/context.d.ts +37 -0
- package/dist/tools/context.js +13 -0
- package/dist/tools/context.js.map +1 -0
- package/dist/tools/images.d.ts +11 -0
- package/dist/tools/images.js +38 -0
- package/dist/tools/images.js.map +1 -0
- package/dist/tools/index.d.ts +15 -0
- package/dist/tools/index.js +34 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/lifecycle.d.ts +16 -0
- package/dist/tools/lifecycle.js +165 -0
- package/dist/tools/lifecycle.js.map +1 -0
- package/dist/tools/logs.d.ts +15 -0
- package/dist/tools/logs.js +110 -0
- package/dist/tools/logs.js.map +1 -0
- package/dist/tools/system.d.ts +14 -0
- package/dist/tools/system.js +108 -0
- package/dist/tools/system.js.map +1 -0
- package/dist/tui/ansi.d.ts +66 -0
- package/dist/tui/ansi.js +118 -0
- package/dist/tui/ansi.js.map +1 -0
- package/dist/tui/app.d.ts +160 -0
- package/dist/tui/app.js +1339 -0
- package/dist/tui/app.js.map +1 -0
- package/dist/tui/box.d.ts +18 -0
- package/dist/tui/box.js +38 -0
- package/dist/tui/box.js.map +1 -0
- package/dist/tui/index.d.ts +19 -0
- package/dist/tui/index.js +66 -0
- package/dist/tui/index.js.map +1 -0
- package/dist/update/channel.d.ts +82 -0
- package/dist/update/channel.js +178 -0
- package/dist/update/channel.js.map +1 -0
- package/dist/updates.json +42 -0
- package/dist/utils/format.d.ts +24 -0
- package/dist/utils/format.js +69 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/result.d.ts +35 -0
- package/dist/utils/result.js +31 -0
- package/dist/utils/result.js.map +1 -0
- package/package.json +90 -0
- package/scripts/install.mjs +132 -0
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Presentation helpers.
|
|
3
|
+
*
|
|
4
|
+
* Tools return human-readable text that an LLM can quote back to the user, so
|
|
5
|
+
* these helpers turn raw Docker payloads into compact, aligned tables and
|
|
6
|
+
* friendly units (bytes → "1.4 GB", uptime → "3 days ago").
|
|
7
|
+
*
|
|
8
|
+
* Part of Docker MCP Server.
|
|
9
|
+
* Crafted by SoyRage Agency — https://soyrage.es/
|
|
10
|
+
* Licensed under the MIT License.
|
|
11
|
+
*/
|
|
12
|
+
/** Render a value as a human-readable byte size (SI-ish, base 1024). */
|
|
13
|
+
export function formatBytes(bytes) {
|
|
14
|
+
if (!Number.isFinite(bytes) || bytes <= 0)
|
|
15
|
+
return "0 B";
|
|
16
|
+
const units = ["B", "KB", "MB", "GB", "TB", "PB"];
|
|
17
|
+
const exponent = Math.min(Math.floor(Math.log(bytes) / Math.log(1024)), units.length - 1);
|
|
18
|
+
const value = bytes / Math.pow(1024, exponent);
|
|
19
|
+
const decimals = exponent === 0 ? 0 : value >= 100 ? 0 : 1;
|
|
20
|
+
return `${value.toFixed(decimals)} ${units[exponent]}`;
|
|
21
|
+
}
|
|
22
|
+
/** Turn a Unix timestamp (seconds) into a relative "x ago" string. */
|
|
23
|
+
export function formatRelativeTime(unixSeconds) {
|
|
24
|
+
if (!unixSeconds)
|
|
25
|
+
return "unknown";
|
|
26
|
+
const deltaMs = Date.now() - unixSeconds * 1000;
|
|
27
|
+
const seconds = Math.round(deltaMs / 1000);
|
|
28
|
+
if (seconds < 60)
|
|
29
|
+
return `${seconds}s ago`;
|
|
30
|
+
const minutes = Math.round(seconds / 60);
|
|
31
|
+
if (minutes < 60)
|
|
32
|
+
return `${minutes}m ago`;
|
|
33
|
+
const hours = Math.round(minutes / 60);
|
|
34
|
+
if (hours < 24)
|
|
35
|
+
return `${hours}h ago`;
|
|
36
|
+
const days = Math.round(hours / 24);
|
|
37
|
+
if (days < 30)
|
|
38
|
+
return `${days}d ago`;
|
|
39
|
+
const months = Math.round(days / 30);
|
|
40
|
+
if (months < 12)
|
|
41
|
+
return `${months}mo ago`;
|
|
42
|
+
return `${Math.round(months / 12)}y ago`;
|
|
43
|
+
}
|
|
44
|
+
/** Truncate a string to `max` characters with an ellipsis. */
|
|
45
|
+
export function truncate(value, max) {
|
|
46
|
+
if (value.length <= max)
|
|
47
|
+
return value;
|
|
48
|
+
return `${value.slice(0, Math.max(0, max - 1))}…`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Render a fixed-width, left-aligned ASCII table. Empty tables render a short
|
|
52
|
+
* placeholder so the model gets a clear "nothing here" signal.
|
|
53
|
+
*/
|
|
54
|
+
export function renderTable(headers, rows) {
|
|
55
|
+
if (rows.length === 0)
|
|
56
|
+
return "(no results)";
|
|
57
|
+
const widths = headers.map((header, columnIndex) => Math.max(header.length, ...rows.map((row) => (row[columnIndex] ?? "").length)));
|
|
58
|
+
const pad = (cells) => cells
|
|
59
|
+
.map((cell, index) => (cell ?? "").padEnd(widths[index]))
|
|
60
|
+
.join(" ")
|
|
61
|
+
.trimEnd();
|
|
62
|
+
const separator = widths.map((width) => "-".repeat(width)).join(" ");
|
|
63
|
+
return [pad(headers), separator, ...rows.map((row) => pad(row))].join("\n");
|
|
64
|
+
}
|
|
65
|
+
/** Pretty-print an object as fenced JSON for the model to read. */
|
|
66
|
+
export function asJsonBlock(value) {
|
|
67
|
+
return "```json\n" + JSON.stringify(value, null, 2) + "\n```";
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool-result helpers.
|
|
3
|
+
*
|
|
4
|
+
* Every tool returns the same `{ content: [...] }` shape. These wrappers keep
|
|
5
|
+
* call sites terse and guarantee consistent error surfacing: failures come
|
|
6
|
+
* back as `isError: true` text so the LLM can react instead of the transport
|
|
7
|
+
* throwing.
|
|
8
|
+
*
|
|
9
|
+
* Part of Docker MCP Server.
|
|
10
|
+
* Crafted by SoyRage Agency — https://soyrage.es/
|
|
11
|
+
* Licensed under the MIT License.
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* The subset of the MCP tool-result shape this server produces.
|
|
15
|
+
*
|
|
16
|
+
* The index signature keeps us structurally compatible with the SDK's
|
|
17
|
+
* `CallToolResult` type (which allows arbitrary extra fields via `_meta`).
|
|
18
|
+
*/
|
|
19
|
+
export interface ToolResult {
|
|
20
|
+
content: Array<{
|
|
21
|
+
type: "text";
|
|
22
|
+
text: string;
|
|
23
|
+
}>;
|
|
24
|
+
isError?: boolean;
|
|
25
|
+
[key: string]: unknown;
|
|
26
|
+
}
|
|
27
|
+
/** Build a successful text result. */
|
|
28
|
+
export declare function ok(text: string): ToolResult;
|
|
29
|
+
/** Build an error text result the LLM can read and recover from. */
|
|
30
|
+
export declare function fail(message: string): ToolResult;
|
|
31
|
+
/**
|
|
32
|
+
* Wrap an async tool handler so any thrown error becomes a clean `fail(...)`
|
|
33
|
+
* result. This keeps individual handlers focused on the happy path.
|
|
34
|
+
*/
|
|
35
|
+
export declare function guard(handler: () => Promise<ToolResult>): Promise<ToolResult>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* MCP tool-result helpers.
|
|
3
|
+
*
|
|
4
|
+
* Every tool returns the same `{ content: [...] }` shape. These wrappers keep
|
|
5
|
+
* call sites terse and guarantee consistent error surfacing: failures come
|
|
6
|
+
* back as `isError: true` text so the LLM can react instead of the transport
|
|
7
|
+
* throwing.
|
|
8
|
+
*
|
|
9
|
+
* Part of Docker MCP Server.
|
|
10
|
+
* Crafted by SoyRage Agency — https://soyrage.es/
|
|
11
|
+
* Licensed under the MIT License.
|
|
12
|
+
*/
|
|
13
|
+
/** Build a successful text result. */
|
|
14
|
+
export function ok(text) {
|
|
15
|
+
return { content: [{ type: "text", text }] };
|
|
16
|
+
}
|
|
17
|
+
/** Build an error text result the LLM can read and recover from. */
|
|
18
|
+
export function fail(message) {
|
|
19
|
+
return { content: [{ type: "text", text: `Error: ${message}` }], isError: true };
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Wrap an async tool handler so any thrown error becomes a clean `fail(...)`
|
|
23
|
+
* result. This keeps individual handlers focused on the happy path.
|
|
24
|
+
*/
|
|
25
|
+
export function guard(handler) {
|
|
26
|
+
return handler().catch((error) => {
|
|
27
|
+
const message = error instanceof Error ? error.message : String(error ?? "unknown error");
|
|
28
|
+
return fail(message);
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/utils/result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAcH,sCAAsC;AACtC,MAAM,UAAU,EAAE,CAAC,IAAY;IAC7B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,IAAI,CAAC,OAAe;IAClC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,OAAO,EAAE,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACnF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,KAAK,CACnB,OAAkC;IAElC,OAAO,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;QACxC,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,CAAC;QAC5E,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@soyrageagency/docker-mcp",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "Chat with your Docker host. A Model Context Protocol (MCP) server that lets any LLM list containers, read logs, manage lifecycle and deploy Compose stacks — safely. Built by SoyRage Agency.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"mcpName": "io.github.soyrageagency/docker-mcp-server",
|
|
8
|
+
"author": "SoyRage Agency (https://soyrage.es/)",
|
|
9
|
+
"homepage": "https://soyrage.es/tools/docker-mcp",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/soyrageagency/docker-mcp-server.git"
|
|
13
|
+
},
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/soyrageagency/docker-mcp-server/issues"
|
|
16
|
+
},
|
|
17
|
+
"keywords": [
|
|
18
|
+
"mcp",
|
|
19
|
+
"model-context-protocol",
|
|
20
|
+
"docker",
|
|
21
|
+
"docker-compose",
|
|
22
|
+
"devops",
|
|
23
|
+
"llm",
|
|
24
|
+
"ai",
|
|
25
|
+
"claude",
|
|
26
|
+
"self-hosted",
|
|
27
|
+
"containers"
|
|
28
|
+
],
|
|
29
|
+
"publishConfig": {
|
|
30
|
+
"access": "public"
|
|
31
|
+
},
|
|
32
|
+
"bin": {
|
|
33
|
+
"docker-mcp": "dist/index.js",
|
|
34
|
+
"ragedocker": "dist/ragedocker.js",
|
|
35
|
+
"docker-mcp-server": "dist/index.js",
|
|
36
|
+
"docker-mcp-panel": "dist/panel/index.js",
|
|
37
|
+
"docker-mcp-tui": "dist/tui/index.js",
|
|
38
|
+
"docker-mcp-install": "scripts/install.mjs"
|
|
39
|
+
},
|
|
40
|
+
"funding": {
|
|
41
|
+
"type": "paypal",
|
|
42
|
+
"url": "https://www.paypal.com/paypalme/soyrageagency"
|
|
43
|
+
},
|
|
44
|
+
"main": "dist/index.js",
|
|
45
|
+
"files": [
|
|
46
|
+
"dist",
|
|
47
|
+
"scripts/install.mjs",
|
|
48
|
+
"README.md",
|
|
49
|
+
"LICENSE"
|
|
50
|
+
],
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=18"
|
|
53
|
+
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc && node scripts/copy-public.mjs",
|
|
56
|
+
"prepublishOnly": "npm run build",
|
|
57
|
+
"dev": "tsx watch src/index.ts",
|
|
58
|
+
"start": "node dist/index.js",
|
|
59
|
+
"panel": "node dist/panel/index.js",
|
|
60
|
+
"panel:dev": "tsx watch src/panel/index.ts",
|
|
61
|
+
"panel:demo": "node -e \"process.env.DOCKER_MCP_PANEL_DEMO='true';import('./dist/panel/index.js')\"",
|
|
62
|
+
"tui": "node dist/tui/index.js",
|
|
63
|
+
"tui:dev": "tsx src/tui/index.ts",
|
|
64
|
+
"tui:demo": "node -e \"process.env.DOCKER_MCP_PANEL_DEMO='true';import('./dist/tui/index.js')\"",
|
|
65
|
+
"ragedocker": "node dist/ragedocker.js",
|
|
66
|
+
"ia": "node dist/ragedocker.js ia",
|
|
67
|
+
"doctor": "node dist/ragedocker.js doctor",
|
|
68
|
+
"build:sea": "node scripts/build-sea.mjs",
|
|
69
|
+
"inspect": "npx @modelcontextprotocol/inspector node dist/index.js",
|
|
70
|
+
"setup": "npm run build && node scripts/install.mjs",
|
|
71
|
+
"install:claude": "node scripts/install.mjs",
|
|
72
|
+
"shots": "node scripts/shots.mjs",
|
|
73
|
+
"typecheck": "tsc --noEmit",
|
|
74
|
+
"clean": "node -e \"require('fs').rmSync('dist',{recursive:true,force:true})\""
|
|
75
|
+
},
|
|
76
|
+
"dependencies": {
|
|
77
|
+
"@modelcontextprotocol/sdk": "^1.12.0",
|
|
78
|
+
"dockerode": "^4.0.2",
|
|
79
|
+
"zod": "^3.23.8"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@types/dockerode": "^3.3.31",
|
|
83
|
+
"@types/node": "^20.14.0",
|
|
84
|
+
"esbuild": "^0.28.1",
|
|
85
|
+
"playwright": "^1.61.1",
|
|
86
|
+
"postject": "^1.0.0-alpha.6",
|
|
87
|
+
"tsx": "^4.16.0",
|
|
88
|
+
"typescript": "^5.5.0"
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* One-command installer / configurator for beginners.
|
|
4
|
+
*
|
|
5
|
+
* Registers this Docker MCP Server in your AI client's config (Claude Desktop
|
|
6
|
+
* by default) with the correct absolute path — no manual JSON editing. It
|
|
7
|
+
* builds the project first if needed, backs up any existing config, and MERGES
|
|
8
|
+
* the entry so your other MCP servers are preserved.
|
|
9
|
+
*
|
|
10
|
+
* node scripts/install.mjs # configure Claude Desktop
|
|
11
|
+
* node scripts/install.mjs --client claude # (same)
|
|
12
|
+
* node scripts/install.mjs --print # just print the JSON snippet
|
|
13
|
+
*
|
|
14
|
+
* Crafted by SoyRage Agency — https://soyrage.es/ · https://www.paypal.com/paypalme/soyrageagency
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync } from "node:fs";
|
|
18
|
+
import { dirname, join, resolve } from "node:path";
|
|
19
|
+
import { fileURLToPath } from "node:url";
|
|
20
|
+
import { homedir, platform } from "node:os";
|
|
21
|
+
import { spawnSync } from "node:child_process";
|
|
22
|
+
|
|
23
|
+
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
24
|
+
const DIST = join(ROOT, "dist", "index.js");
|
|
25
|
+
const argv = process.argv.slice(2);
|
|
26
|
+
const has = (flag) => argv.includes(flag);
|
|
27
|
+
|
|
28
|
+
const c = {
|
|
29
|
+
reset: "\x1b[0m", dim: "\x1b[2m", bold: "\x1b[1m",
|
|
30
|
+
blue: "\x1b[38;5;39m", green: "\x1b[32m", yellow: "\x1b[33m", red: "\x1b[31m",
|
|
31
|
+
};
|
|
32
|
+
const say = (s) => process.stdout.write(s + "\n");
|
|
33
|
+
const ok = (s) => say(`${c.green}✓${c.reset} ${s}`);
|
|
34
|
+
const warn = (s) => say(`${c.yellow}!${c.reset} ${s}`);
|
|
35
|
+
|
|
36
|
+
say("");
|
|
37
|
+
say(`${c.blue}${c.bold} Docker MCP Server — installer${c.reset} ${c.dim}by SoyRage Agency${c.reset}`);
|
|
38
|
+
say(`${c.dim} https://soyrage.es/${c.reset}`);
|
|
39
|
+
say("");
|
|
40
|
+
|
|
41
|
+
// 1) Ensure the project is built.
|
|
42
|
+
if (!existsSync(DIST)) {
|
|
43
|
+
warn("Build output not found — building now (npm install && npm run build)…");
|
|
44
|
+
const npm = platform() === "win32" ? "npm.cmd" : "npm";
|
|
45
|
+
if (!existsSync(join(ROOT, "node_modules"))) run(npm, ["install"]);
|
|
46
|
+
run(npm, ["run", "build"]);
|
|
47
|
+
}
|
|
48
|
+
if (!existsSync(DIST)) fail("Build failed: dist/index.js is still missing.");
|
|
49
|
+
ok(`Server built at ${c.dim}${DIST}${c.reset}`);
|
|
50
|
+
|
|
51
|
+
// 2) The MCP server entry we want to install.
|
|
52
|
+
const entry = {
|
|
53
|
+
command: "node",
|
|
54
|
+
args: [DIST],
|
|
55
|
+
env: {
|
|
56
|
+
DOCKER_MCP_READONLY: "false",
|
|
57
|
+
DOCKER_MCP_ALLOW_EXEC: "false",
|
|
58
|
+
DOCKER_MCP_DEFAULT_LOG_TAIL: "200",
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
if (has("--print")) {
|
|
63
|
+
say("");
|
|
64
|
+
say(JSON.stringify({ mcpServers: { docker: entry } }, null, 2));
|
|
65
|
+
say("");
|
|
66
|
+
process.exit(0);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// 3) Locate the Claude Desktop config for this OS.
|
|
70
|
+
const configPath = claudeConfigPath();
|
|
71
|
+
if (!configPath) fail("Unsupported platform for auto-config. Use --print and paste it manually.");
|
|
72
|
+
say(`${c.dim}Target config:${c.reset} ${configPath}`);
|
|
73
|
+
|
|
74
|
+
// 4) Merge & write (with a backup).
|
|
75
|
+
let config = {};
|
|
76
|
+
if (existsSync(configPath)) {
|
|
77
|
+
try {
|
|
78
|
+
config = JSON.parse(readFileSync(configPath, "utf8"));
|
|
79
|
+
} catch {
|
|
80
|
+
warn("Existing config is not valid JSON; a fresh one will be written (old kept as .bak).");
|
|
81
|
+
}
|
|
82
|
+
copyFileSync(configPath, configPath + ".bak");
|
|
83
|
+
ok(`Backed up existing config → ${c.dim}${configPath}.bak${c.reset}`);
|
|
84
|
+
} else {
|
|
85
|
+
mkdirSync(dirname(configPath), { recursive: true });
|
|
86
|
+
warn("No existing config found — creating a new one. (Is Claude Desktop installed?)");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
config.mcpServers = config.mcpServers || {};
|
|
90
|
+
const existed = Boolean(config.mcpServers.docker);
|
|
91
|
+
config.mcpServers.docker = entry;
|
|
92
|
+
writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
|
|
93
|
+
ok(`${existed ? "Updated" : "Added"} the "docker" MCP server in your Claude config.`);
|
|
94
|
+
|
|
95
|
+
// 5) Done — next steps + a friendly nudge.
|
|
96
|
+
say("");
|
|
97
|
+
say(`${c.green}${c.bold} All set!${c.reset}`);
|
|
98
|
+
say(` 1. Fully ${c.bold}restart Claude Desktop${c.reset} (quit from the tray, not just the window).`);
|
|
99
|
+
say(` 2. Ask it: ${c.blue}"What Docker containers are running?"${c.reset}`);
|
|
100
|
+
say("");
|
|
101
|
+
say(` ${c.dim}Optional visual dashboard:${c.reset} ${c.bold}npm run panel${c.reset} → http://127.0.0.1:4600`);
|
|
102
|
+
say(` ${c.dim}Terminal UI:${c.reset} ${c.bold}npm run tui${c.reset}`);
|
|
103
|
+
say("");
|
|
104
|
+
say(` ${c.yellow}Enjoying it?${c.reset} Support development: ${c.blue}https://www.paypal.com/paypalme/soyrageagency${c.reset}`);
|
|
105
|
+
say(` ${c.yellow}★${c.reset} And a star helps a lot: ${c.blue}https://github.com/soyrageagency/docker-mcp-server${c.reset}`);
|
|
106
|
+
say("");
|
|
107
|
+
|
|
108
|
+
// ---- helpers --------------------------------------------------------------
|
|
109
|
+
|
|
110
|
+
function claudeConfigPath() {
|
|
111
|
+
const home = homedir();
|
|
112
|
+
switch (platform()) {
|
|
113
|
+
case "win32":
|
|
114
|
+
return join(process.env.APPDATA || join(home, "AppData", "Roaming"), "Claude", "claude_desktop_config.json");
|
|
115
|
+
case "darwin":
|
|
116
|
+
return join(home, "Library", "Application Support", "Claude", "claude_desktop_config.json");
|
|
117
|
+
case "linux":
|
|
118
|
+
return join(process.env.XDG_CONFIG_HOME || join(home, ".config"), "Claude", "claude_desktop_config.json");
|
|
119
|
+
default:
|
|
120
|
+
return null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function run(cmd, args) {
|
|
125
|
+
const r = spawnSync(cmd, args, { cwd: ROOT, stdio: "inherit" });
|
|
126
|
+
if (r.status !== 0) fail(`Command failed: ${cmd} ${args.join(" ")}`);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
function fail(msg) {
|
|
130
|
+
say(`${c.red}✗ ${msg}${c.reset}`);
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|