@mks2508/coolify-mks-cli-mcp 0.5.0 → 0.6.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/dist/cli/coolify-state.d.ts +51 -0
- package/dist/cli/coolify-state.d.ts.map +1 -0
- package/dist/cli/index.js +2862 -631
- package/dist/coolify/config.d.ts +1 -1
- package/dist/coolify/config.d.ts.map +1 -1
- package/dist/coolify/index.d.ts +626 -12
- package/dist/coolify/index.d.ts.map +1 -1
- package/dist/coolify/types.d.ts +87 -3
- package/dist/coolify/types.d.ts.map +1 -1
- package/dist/dist-C4hIkHif.js +66 -0
- package/dist/dist-C4hIkHif.js.map +1 -0
- package/dist/dist-DEPvJhbP.js +3 -0
- package/dist/index.cjs +8511 -28542
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +32 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8470 -28506
- package/dist/index.js.map +1 -1
- package/dist/network.d.ts +75 -0
- package/dist/network.d.ts.map +1 -0
- package/dist/sdk.d.ts +356 -0
- package/dist/sdk.d.ts.map +1 -0
- package/dist/server/index.d.ts +9 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/sse.js +3 -1
- package/dist/server/stdio.d.ts +0 -2
- package/dist/server/stdio.d.ts.map +1 -1
- package/dist/server/stdio.js +3307 -1618
- package/dist/tools/definitions.d.ts +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/handlers.d.ts +6 -7
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/index.d.ts +8 -0
- package/dist/tools/index.d.ts.map +1 -0
- package/dist/trace.d.ts +71 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/utils/format.d.ts +1 -1
- package/dist/utils/format.d.ts.map +1 -1
- package/package.json +13 -7
- package/src/cli/actions.ts +162 -0
- package/src/cli/commands/active-deployments.ts +24 -0
- package/src/cli/commands/build-logs.ts +25 -22
- package/src/cli/commands/cancel-deploy.ts +35 -0
- package/src/cli/commands/config.ts +53 -47
- package/src/cli/commands/create.ts +74 -53
- package/src/cli/commands/databases.ts +63 -0
- package/src/cli/commands/db.ts +68 -0
- package/src/cli/commands/delete.ts +41 -29
- package/src/cli/commands/deploy.ts +42 -21
- package/src/cli/commands/deployments.ts +41 -31
- package/src/cli/commands/destinations.ts +19 -27
- package/src/cli/commands/diagnose.ts +139 -0
- package/src/cli/commands/env.ts +66 -41
- package/src/cli/commands/environments.ts +36 -32
- package/src/cli/commands/exec.ts +39 -0
- package/src/cli/commands/keys.ts +46 -0
- package/src/cli/commands/list.ts +29 -27
- package/src/cli/commands/logs.ts +33 -18
- package/src/cli/commands/network.ts +145 -0
- package/src/cli/commands/projects.ts +51 -39
- package/src/cli/commands/restart.ts +34 -18
- package/src/cli/commands/server-resources.ts +71 -0
- package/src/cli/commands/servers.ts +23 -23
- package/src/cli/commands/service-logs.ts +24 -16
- package/src/cli/commands/services.ts +63 -0
- package/src/cli/commands/show.ts +72 -41
- package/src/cli/commands/start.ts +34 -18
- package/src/cli/commands/stop.ts +34 -18
- package/src/cli/commands/svc.ts +68 -0
- package/src/cli/commands/teams.ts +60 -0
- package/src/cli/commands/update.ts +73 -49
- package/src/cli/commands/version.ts +37 -0
- package/src/cli/coolify-state.ts +88 -0
- package/src/cli/index.ts +383 -151
- package/src/coolify/config.ts +29 -27
- package/src/coolify/index.ts +1829 -123
- package/src/coolify/types.ts +217 -124
- package/src/index.ts +82 -868
- package/src/network.ts +298 -0
- package/src/sdk.ts +597 -0
- package/src/server/index.ts +13 -0
- package/src/server/sse.ts +33 -25
- package/src/server/stdio.ts +24 -27
- package/src/tools/definitions.ts +893 -264
- package/src/tools/handlers.ts +556 -748
- package/src/tools/index.ts +8 -0
- package/src/trace.ts +116 -0
- package/src/utils/format.ts +36 -33
package/src/network.ts
ADDED
|
@@ -0,0 +1,298 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Network diagnostic module.
|
|
3
|
+
*
|
|
4
|
+
* Uses exec to inspect Docker networks, Traefik proxy, DNS, and container connectivity.
|
|
5
|
+
* All commands run inside the application container via the Coolify exec API.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { isErr, type Result, ok, err } from "@mks2508/no-throw";
|
|
11
|
+
import type { CoolifyService } from "./coolify/index.js";
|
|
12
|
+
import { OperationTracer, type IOperationTrace } from "./trace.js";
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Container network information.
|
|
16
|
+
*/
|
|
17
|
+
export interface INetworkInfo {
|
|
18
|
+
/** /etc/hosts entries */
|
|
19
|
+
hosts: string[];
|
|
20
|
+
/** DNS resolution results */
|
|
21
|
+
dns: Array<{ hostname: string; resolved: boolean; ip?: string }>;
|
|
22
|
+
/** Container environment variables related to networking */
|
|
23
|
+
networkEnv: Record<string, string>;
|
|
24
|
+
/** Reachable services (connectivity test results) */
|
|
25
|
+
connectivity: Array<{
|
|
26
|
+
target: string;
|
|
27
|
+
reachable: boolean;
|
|
28
|
+
responseTime?: number;
|
|
29
|
+
}>;
|
|
30
|
+
/** Container's network interfaces */
|
|
31
|
+
interfaces: string[];
|
|
32
|
+
/** Operation trace */
|
|
33
|
+
trace: IOperationTrace;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Deploy failure analysis.
|
|
38
|
+
*/
|
|
39
|
+
export interface IDeployFailureAnalysis {
|
|
40
|
+
/** Deployment UUID */
|
|
41
|
+
deploymentUuid: string;
|
|
42
|
+
/** Deployment status */
|
|
43
|
+
status: string;
|
|
44
|
+
/** Raw build logs */
|
|
45
|
+
rawLogs: string;
|
|
46
|
+
/** Extracted error lines */
|
|
47
|
+
errors: string[];
|
|
48
|
+
/** Likely error category */
|
|
49
|
+
category:
|
|
50
|
+
| "build_error"
|
|
51
|
+
| "install_error"
|
|
52
|
+
| "docker_error"
|
|
53
|
+
| "network_error"
|
|
54
|
+
| "timeout"
|
|
55
|
+
| "unknown";
|
|
56
|
+
/** Human-readable summary */
|
|
57
|
+
summary: string;
|
|
58
|
+
/** Suggested fix */
|
|
59
|
+
suggestion: string;
|
|
60
|
+
/** Operation trace */
|
|
61
|
+
trace: IOperationTrace;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/** Common error patterns in build logs. */
|
|
65
|
+
const ERROR_PATTERNS: Array<{
|
|
66
|
+
pattern: RegExp;
|
|
67
|
+
category: IDeployFailureAnalysis["category"];
|
|
68
|
+
summary: string;
|
|
69
|
+
suggestion: string;
|
|
70
|
+
}> = [
|
|
71
|
+
{
|
|
72
|
+
pattern: /npm ERR!|yarn error|pnpm ERR/i,
|
|
73
|
+
category: "install_error",
|
|
74
|
+
summary: "Package installation failed",
|
|
75
|
+
suggestion:
|
|
76
|
+
"Check package.json for invalid dependencies. Try deleting lock file and rebuilding.",
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
pattern: /COPY failed|COPY --from.*not found|no such file/i,
|
|
80
|
+
category: "docker_error",
|
|
81
|
+
summary: "Dockerfile COPY failed — file not found",
|
|
82
|
+
suggestion:
|
|
83
|
+
"Check Dockerfile paths and base_directory. Ensure source files exist in build context.",
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
pattern: /error TS\d+|TypeError|SyntaxError|ReferenceError/i,
|
|
87
|
+
category: "build_error",
|
|
88
|
+
summary: "TypeScript/JavaScript compilation error",
|
|
89
|
+
suggestion:
|
|
90
|
+
"Fix the type errors locally before deploying. Run `bun run typecheck`.",
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
pattern: /ECONNREFUSED|ETIMEDOUT|EAI_AGAIN|getaddrinfo/i,
|
|
94
|
+
category: "network_error",
|
|
95
|
+
summary: "Network connectivity issue during build",
|
|
96
|
+
suggestion:
|
|
97
|
+
"Server may have DNS issues or firewall blocking outbound connections. Check server network.",
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
pattern: /OOMKilled|out of memory|Cannot allocate memory/i,
|
|
101
|
+
category: "build_error",
|
|
102
|
+
summary: "Out of memory during build",
|
|
103
|
+
suggestion:
|
|
104
|
+
"Server ran out of RAM. Use a build server or increase server memory.",
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
pattern: /context deadline exceeded|timed out/i,
|
|
108
|
+
category: "timeout",
|
|
109
|
+
summary: "Operation timed out",
|
|
110
|
+
suggestion:
|
|
111
|
+
"Build took too long. Check if server is overloaded or network is slow.",
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
pattern: /permission denied|EACCES/i,
|
|
115
|
+
category: "docker_error",
|
|
116
|
+
summary: "Permission denied",
|
|
117
|
+
suggestion:
|
|
118
|
+
"Check file permissions in Dockerfile. Ensure non-root user has access to needed paths.",
|
|
119
|
+
},
|
|
120
|
+
{
|
|
121
|
+
pattern: /exec.*not found|command not found/i,
|
|
122
|
+
category: "build_error",
|
|
123
|
+
summary: "Command not found during build",
|
|
124
|
+
suggestion:
|
|
125
|
+
"A required binary is missing in the Docker image. Add it to the Dockerfile or use a different base image.",
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Safely execute a command, returning output or empty string on failure.
|
|
131
|
+
*/
|
|
132
|
+
async function safeExec(
|
|
133
|
+
svc: CoolifyService,
|
|
134
|
+
uuid: string,
|
|
135
|
+
command: string,
|
|
136
|
+
): Promise<string> {
|
|
137
|
+
const result = await svc.executeCommand(uuid, command);
|
|
138
|
+
if (isErr(result)) return "";
|
|
139
|
+
return result.value.response || result.value.message || "";
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Inspects the network environment of an application container.
|
|
144
|
+
*
|
|
145
|
+
* @param svc - CoolifyService instance
|
|
146
|
+
* @param appUuid - Application UUID
|
|
147
|
+
* @param servicesToTest - Optional list of service names to test connectivity (e.g., ['db', 'redis'])
|
|
148
|
+
* @returns Network diagnostic information
|
|
149
|
+
*/
|
|
150
|
+
export async function inspectNetwork(
|
|
151
|
+
svc: CoolifyService,
|
|
152
|
+
appUuid: string,
|
|
153
|
+
servicesToTest: string[] = [],
|
|
154
|
+
): Promise<Result<INetworkInfo, Error>> {
|
|
155
|
+
const tracer = new OperationTracer("network:inspect");
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
tracer.step("Fetching /etc/hosts");
|
|
159
|
+
const hostsRaw = await safeExec(svc, appUuid, "cat /etc/hosts 2>/dev/null");
|
|
160
|
+
const hosts = hostsRaw
|
|
161
|
+
.split("\n")
|
|
162
|
+
.filter((l) => l.trim() && !l.startsWith("#"));
|
|
163
|
+
|
|
164
|
+
tracer.step("Checking network interfaces");
|
|
165
|
+
const ifRaw = await safeExec(
|
|
166
|
+
svc,
|
|
167
|
+
appUuid,
|
|
168
|
+
"ip addr 2>/dev/null || ifconfig 2>/dev/null || cat /proc/net/if_inet6 2>/dev/null || echo 'no network tools'",
|
|
169
|
+
);
|
|
170
|
+
const interfaces = ifRaw
|
|
171
|
+
.split("\n")
|
|
172
|
+
.filter((l) => l.includes("inet") || l.includes("scope"));
|
|
173
|
+
|
|
174
|
+
tracer.step("Extracting network env vars");
|
|
175
|
+
const envRaw = await safeExec(
|
|
176
|
+
svc,
|
|
177
|
+
appUuid,
|
|
178
|
+
"env 2>/dev/null | grep -iE '(HOST|PORT|URL|DATABASE|REDIS|MONGO|POSTGRES|MYSQL|DB_|COOLIFY)' | sort",
|
|
179
|
+
);
|
|
180
|
+
const networkEnv: Record<string, string> = {};
|
|
181
|
+
for (const line of envRaw.split("\n").filter(Boolean)) {
|
|
182
|
+
const [key, ...rest] = line.split("=");
|
|
183
|
+
if (key) networkEnv[key] = rest.join("=");
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
tracer.step("Testing DNS resolution");
|
|
187
|
+
const dnsTargets = [
|
|
188
|
+
...servicesToTest,
|
|
189
|
+
...Object.values(networkEnv)
|
|
190
|
+
.filter((v) => !v.includes("/") && !v.includes(":"))
|
|
191
|
+
.filter((v) => /^[a-z][a-z0-9-]*$/i.test(v)),
|
|
192
|
+
];
|
|
193
|
+
const uniqueTargets = [...new Set(dnsTargets)].slice(0, 10);
|
|
194
|
+
|
|
195
|
+
const dns: INetworkInfo["dns"] = [];
|
|
196
|
+
for (const hostname of uniqueTargets) {
|
|
197
|
+
const nslookup = await safeExec(
|
|
198
|
+
svc,
|
|
199
|
+
appUuid,
|
|
200
|
+
`getent hosts ${hostname} 2>/dev/null || nslookup ${hostname} 2>/dev/null || echo 'FAIL'`,
|
|
201
|
+
);
|
|
202
|
+
const resolved = !nslookup.includes("FAIL") && nslookup.trim().length > 0;
|
|
203
|
+
const ip = resolved ? nslookup.split(/\s+/)[0] : undefined;
|
|
204
|
+
dns.push({ hostname, resolved, ip });
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
tracer.step(
|
|
208
|
+
"Testing service connectivity",
|
|
209
|
+
`${uniqueTargets.length} targets`,
|
|
210
|
+
);
|
|
211
|
+
const connectivity: INetworkInfo["connectivity"] = [];
|
|
212
|
+
for (const target of servicesToTest) {
|
|
213
|
+
const start = Date.now();
|
|
214
|
+
const curlResult = await safeExec(
|
|
215
|
+
svc,
|
|
216
|
+
appUuid,
|
|
217
|
+
`timeout 3 sh -c "echo > /dev/tcp/${target}/80 2>/dev/null && echo OK || curl -sf --max-time 2 http://${target}/ >/dev/null 2>&1 && echo OK || echo FAIL"`,
|
|
218
|
+
);
|
|
219
|
+
connectivity.push({
|
|
220
|
+
target,
|
|
221
|
+
reachable: curlResult.includes("OK"),
|
|
222
|
+
responseTime: Date.now() - start,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
const trace = tracer.finish(true);
|
|
227
|
+
return ok({ hosts, dns, networkEnv, connectivity, interfaces, trace });
|
|
228
|
+
} catch (error) {
|
|
229
|
+
const trace = tracer.finish(
|
|
230
|
+
false,
|
|
231
|
+
error instanceof Error ? error.message : String(error),
|
|
232
|
+
);
|
|
233
|
+
return err(new Error(`Network inspection failed: ${trace.error}`));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Analyzes a failed deployment, extracting errors from build logs.
|
|
239
|
+
*
|
|
240
|
+
* @param svc - CoolifyService instance
|
|
241
|
+
* @param deploymentUuid - Deployment UUID
|
|
242
|
+
* @returns Failure analysis with categorized errors
|
|
243
|
+
*/
|
|
244
|
+
export async function analyzeDeployFailure(
|
|
245
|
+
svc: CoolifyService,
|
|
246
|
+
deploymentUuid: string,
|
|
247
|
+
): Promise<Result<IDeployFailureAnalysis, Error>> {
|
|
248
|
+
const tracer = new OperationTracer("deploy:analyze");
|
|
249
|
+
|
|
250
|
+
try {
|
|
251
|
+
tracer.step("Fetching deployment details");
|
|
252
|
+
const deployResult = await svc.getDeploymentLogs(deploymentUuid);
|
|
253
|
+
if (isErr(deployResult)) {
|
|
254
|
+
return err(deployResult.error);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
const { status, logs: rawLogs } = deployResult.value;
|
|
258
|
+
|
|
259
|
+
tracer.step("Extracting error lines", `${rawLogs.length} chars`);
|
|
260
|
+
const lines = rawLogs.split("\n");
|
|
261
|
+
const errors = lines.filter(
|
|
262
|
+
(l) =>
|
|
263
|
+
/error|ERR!|failed|FAIL|fatal|panic|exception/i.test(l) &&
|
|
264
|
+
!/no error|success/i.test(l),
|
|
265
|
+
);
|
|
266
|
+
|
|
267
|
+
tracer.step("Categorizing error");
|
|
268
|
+
let matchedPattern = ERROR_PATTERNS.find((p) => p.pattern.test(rawLogs));
|
|
269
|
+
|
|
270
|
+
if (!matchedPattern) {
|
|
271
|
+
matchedPattern = {
|
|
272
|
+
pattern: /./,
|
|
273
|
+
category: "unknown",
|
|
274
|
+
summary: "Unknown build failure",
|
|
275
|
+
suggestion:
|
|
276
|
+
"Check the full build logs with `build-logs <deployment-uuid>` for details.",
|
|
277
|
+
};
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
const trace = tracer.finish(true);
|
|
281
|
+
return ok({
|
|
282
|
+
deploymentUuid,
|
|
283
|
+
status,
|
|
284
|
+
rawLogs,
|
|
285
|
+
errors: errors.slice(0, 20),
|
|
286
|
+
category: matchedPattern.category,
|
|
287
|
+
summary: matchedPattern.summary,
|
|
288
|
+
suggestion: matchedPattern.suggestion,
|
|
289
|
+
trace,
|
|
290
|
+
});
|
|
291
|
+
} catch (error) {
|
|
292
|
+
const trace = tracer.finish(
|
|
293
|
+
false,
|
|
294
|
+
error instanceof Error ? error.message : String(error),
|
|
295
|
+
);
|
|
296
|
+
return err(new Error(`Deploy analysis failed: ${trace.error}`));
|
|
297
|
+
}
|
|
298
|
+
}
|