@mks2508/coolify-mks-cli-mcp 0.4.3 → 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 +58 -0
- 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 +60 -0
- package/src/cli/commands/server-resources.ts +71 -0
- package/src/cli/commands/servers.ts +23 -23
- package/src/cli/commands/service-logs.ts +59 -0
- package/src/cli/commands/services.ts +63 -0
- package/src/cli/commands/show.ts +72 -41
- package/src/cli/commands/start.ts +60 -0
- package/src/cli/commands/stop.ts +60 -0
- 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 +400 -125
- package/src/coolify/config.ts +29 -27
- package/src/coolify/index.ts +2221 -371
- package/src/coolify/types.ts +218 -123
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,
|
|
1
|
+
{"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAE/D;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,IAAI,EAmqC9B,CAAC"}
|
package/dist/tools/handlers.d.ts
CHANGED
|
@@ -1,19 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Tool handlers for Coolify.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
4
|
+
* All handlers route through the Coolify SDK facade.
|
|
5
|
+
* Uses a generic mcpCall wrapper to eliminate boilerplate.
|
|
5
6
|
*
|
|
6
7
|
* @module
|
|
7
8
|
*/
|
|
8
|
-
import type { CallToolResult } from
|
|
9
|
-
import type { CoolifyService } from '../coolify/index.js';
|
|
9
|
+
import type { CallToolResult } from "@modelcontextprotocol/sdk/types.js";
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
11
|
+
* Main handler — routes tool calls to SDK methods.
|
|
12
12
|
*
|
|
13
13
|
* @param name - Tool name
|
|
14
14
|
* @param args - Tool arguments
|
|
15
|
-
* @
|
|
16
|
-
* @returns Tool call result
|
|
15
|
+
* @returns MCP tool result
|
|
17
16
|
*/
|
|
18
|
-
export declare function handleToolCall(name: string, args: Record<string, unknown
|
|
17
|
+
export declare function handleToolCall(name: string, args: Record<string, unknown>): Promise<CallToolResult>;
|
|
19
18
|
//# sourceMappingURL=handlers.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"handlers.d.ts","sourceRoot":"","sources":["../../src/tools/handlers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oCAAoC,CAAC;AA+DzE;;;;;;GAMG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,cAAc,CAAC,CAgfzB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAChD,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC"}
|
package/dist/trace.d.ts
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Operation tracing system.
|
|
3
|
+
*
|
|
4
|
+
* Provides step-by-step tracing for all operations across CLI, MCP, and SDK.
|
|
5
|
+
* - **CLI mode**: Logs to stderr with chalk colors (no spinners in trace)
|
|
6
|
+
* - **MCP mode**: Collects steps silently, returns in response
|
|
7
|
+
* - **SDK mode**: Fires callback if provided, otherwise collects
|
|
8
|
+
*
|
|
9
|
+
* @module
|
|
10
|
+
*/
|
|
11
|
+
/**
|
|
12
|
+
* A single trace step.
|
|
13
|
+
*/
|
|
14
|
+
export interface ITraceStep {
|
|
15
|
+
/** Timestamp */
|
|
16
|
+
ts: string;
|
|
17
|
+
/** Step label */
|
|
18
|
+
step: string;
|
|
19
|
+
/** Duration in ms (filled after completion) */
|
|
20
|
+
durationMs?: number;
|
|
21
|
+
/** Optional detail */
|
|
22
|
+
detail?: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Complete operation trace.
|
|
26
|
+
*/
|
|
27
|
+
export interface IOperationTrace {
|
|
28
|
+
/** Operation name */
|
|
29
|
+
operation: string;
|
|
30
|
+
/** All steps */
|
|
31
|
+
steps: ITraceStep[];
|
|
32
|
+
/** Total duration */
|
|
33
|
+
totalMs: number;
|
|
34
|
+
/** Whether operation succeeded */
|
|
35
|
+
success: boolean;
|
|
36
|
+
/** Error message if failed */
|
|
37
|
+
error?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Callback for real-time trace updates.
|
|
41
|
+
*/
|
|
42
|
+
export type TraceCallback = (step: string, detail?: string) => void;
|
|
43
|
+
/** Detect if running as MCP server (stdout is the transport). */
|
|
44
|
+
export declare function isMcpMode(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Operation tracer that collects steps.
|
|
47
|
+
*/
|
|
48
|
+
export declare class OperationTracer {
|
|
49
|
+
readonly operation: string;
|
|
50
|
+
private steps;
|
|
51
|
+
private startTime;
|
|
52
|
+
private stepStart;
|
|
53
|
+
private onStep?;
|
|
54
|
+
constructor(operation: string, onStep?: TraceCallback);
|
|
55
|
+
/**
|
|
56
|
+
* Records a trace step.
|
|
57
|
+
*
|
|
58
|
+
* @param step - Step description
|
|
59
|
+
* @param detail - Optional detail
|
|
60
|
+
*/
|
|
61
|
+
step(step: string, detail?: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Finalizes the trace.
|
|
64
|
+
*
|
|
65
|
+
* @param success - Whether operation succeeded
|
|
66
|
+
* @param error - Error message if failed
|
|
67
|
+
* @returns Complete operation trace
|
|
68
|
+
*/
|
|
69
|
+
finish(success: boolean, error?: string): IOperationTrace;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=trace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trace.d.ts","sourceRoot":"","sources":["../src/trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,gBAAgB;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,iBAAiB;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,sBAAsB;IACtB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,qBAAqB;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB;IAChB,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,qBAAqB;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;AAEpE,iEAAiE;AACjE,wBAAgB,SAAS,IAAI,OAAO,CAGnC;AAED;;GAEG;AACH,qBAAa,eAAe;aAOR,SAAS,EAAE,MAAM;IANnC,OAAO,CAAC,KAAK,CAAoB;IACjC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAgB;gBAGb,SAAS,EAAE,MAAM,EACjC,MAAM,CAAC,EAAE,aAAa;IAOxB;;;;;OAKG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI;IAuBzC;;;;;;OAMG;IACH,MAAM,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe;CAS1D"}
|
package/dist/utils/format.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,YAAY,
|
|
1
|
+
{"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/utils/format.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,MAAM,YAAY,CAAC;AAY/B;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,SAAS,CAAC,EAAE,MAAM,EAAE,eAOlE;AAmBD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWnD;AAED;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAQjD;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAY5D"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mks2508/coolify-mks-cli-mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "MCP server and CLI for Coolify deployment management",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -20,13 +20,21 @@
|
|
|
20
20
|
"import": "./dist/coolify/index.js"
|
|
21
21
|
},
|
|
22
22
|
"./tools": {
|
|
23
|
-
"types": "./dist/tools/
|
|
24
|
-
"import": "./dist/tools/
|
|
23
|
+
"types": "./dist/tools/index.d.ts",
|
|
24
|
+
"import": "./dist/tools/index.js"
|
|
25
25
|
},
|
|
26
|
-
"./server": {
|
|
26
|
+
"./server/stdio": {
|
|
27
27
|
"types": "./dist/server/stdio.d.ts",
|
|
28
28
|
"import": "./dist/server/stdio.js"
|
|
29
29
|
},
|
|
30
|
+
"./server/sse": {
|
|
31
|
+
"types": "./dist/server/sse.d.ts",
|
|
32
|
+
"import": "./dist/server/sse.js"
|
|
33
|
+
},
|
|
34
|
+
"./state": {
|
|
35
|
+
"types": "./dist/cli/coolify-state.d.ts",
|
|
36
|
+
"import": "./dist/cli/coolify-state.js"
|
|
37
|
+
},
|
|
30
38
|
"./package.json": "./package.json"
|
|
31
39
|
},
|
|
32
40
|
"files": [
|
|
@@ -44,7 +52,6 @@
|
|
|
44
52
|
"typecheck": "tsgo --noEmit"
|
|
45
53
|
},
|
|
46
54
|
"dependencies": {
|
|
47
|
-
"@anthropic-ai/claude-agent-sdk": "^0.2.1",
|
|
48
55
|
"@mks2508/better-logger": "^4.0.0",
|
|
49
56
|
"@mks2508/no-throw": "^0.1.0",
|
|
50
57
|
"@modelcontextprotocol/sdk": "^1.25.2",
|
|
@@ -52,8 +59,7 @@
|
|
|
52
59
|
"cli-table3": "^0.6.5",
|
|
53
60
|
"commander": "^12.1.0",
|
|
54
61
|
"ora": "^8.1.1",
|
|
55
|
-
"prompts": "^2.4.2"
|
|
56
|
-
"zod": "^3.24.1"
|
|
62
|
+
"prompts": "^2.4.2"
|
|
57
63
|
},
|
|
58
64
|
"devDependencies": {
|
|
59
65
|
"@types/node": "^22.10.5",
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CLI action runners — all go through Coolify SDK.
|
|
3
|
+
*
|
|
4
|
+
* Eliminates boilerplate across CLI commands by providing reusable
|
|
5
|
+
* patterns for init → call → format output.
|
|
6
|
+
*
|
|
7
|
+
* @module
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import ora from "ora";
|
|
11
|
+
import chalk from "chalk";
|
|
12
|
+
import Table from "cli-table3";
|
|
13
|
+
import { Coolify } from "../sdk.js";
|
|
14
|
+
import { formatStatus } from "../utils/format.js";
|
|
15
|
+
import { resolveUuid } from "./coolify-state.js";
|
|
16
|
+
|
|
17
|
+
/** Singleton SDK instance for CLI (uses env vars / config file). */
|
|
18
|
+
let _sdk: Coolify | null = null;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Gets or creates the Coolify SDK singleton for CLI usage.
|
|
22
|
+
*
|
|
23
|
+
* @returns Coolify SDK instance
|
|
24
|
+
*/
|
|
25
|
+
function getSdk(): Coolify {
|
|
26
|
+
if (!_sdk) _sdk = Coolify.fromEnv();
|
|
27
|
+
return _sdk;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Runs a simple action (uuid → message) with spinner.
|
|
32
|
+
* Used for: start, stop, restart, delete, cancel, etc.
|
|
33
|
+
*
|
|
34
|
+
* @param uuid - UUID (optional, reads .coolify.json if undefined)
|
|
35
|
+
* @param actionLabel - Human label like "Starting application"
|
|
36
|
+
* @param callFn - Function that calls the SDK method (throws on error)
|
|
37
|
+
* @param successMsg - Success message template (receives uuid)
|
|
38
|
+
*/
|
|
39
|
+
export async function runAction(
|
|
40
|
+
uuid: string | undefined,
|
|
41
|
+
actionLabel: string,
|
|
42
|
+
callFn: (sdk: Coolify, uuid: string) => Promise<unknown>,
|
|
43
|
+
successMsg: (uuid: string) => string,
|
|
44
|
+
): Promise<void> {
|
|
45
|
+
const resolved = resolveUuid(uuid);
|
|
46
|
+
if (!resolved) {
|
|
47
|
+
console.error(
|
|
48
|
+
chalk.red("Error: No UUID provided and no .coolify.json found"),
|
|
49
|
+
);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
const spinner = ora("Connecting to Coolify...").start();
|
|
54
|
+
try {
|
|
55
|
+
spinner.text = `${actionLabel}...`;
|
|
56
|
+
await callFn(getSdk(), resolved);
|
|
57
|
+
spinner.succeed(chalk.green(successMsg(resolved)));
|
|
58
|
+
} catch (error) {
|
|
59
|
+
spinner.fail(
|
|
60
|
+
chalk.red(
|
|
61
|
+
`Failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Column definition for table rendering.
|
|
69
|
+
*/
|
|
70
|
+
interface IColumnDef<T> {
|
|
71
|
+
/** Column header */
|
|
72
|
+
header: string;
|
|
73
|
+
/** Value extractor */
|
|
74
|
+
value: (item: T) => string;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Runs a list action and renders a table.
|
|
79
|
+
* Used for: list apps, databases, services, servers, keys, etc.
|
|
80
|
+
*
|
|
81
|
+
* @param resourceLabel - Human label like "databases"
|
|
82
|
+
* @param callFn - Function that calls the SDK list method (throws on error)
|
|
83
|
+
* @param columns - Column definitions for table
|
|
84
|
+
*/
|
|
85
|
+
export async function runList<T>(
|
|
86
|
+
resourceLabel: string,
|
|
87
|
+
callFn: (sdk: Coolify) => Promise<T[]>,
|
|
88
|
+
columns: IColumnDef<T>[],
|
|
89
|
+
): Promise<void> {
|
|
90
|
+
try {
|
|
91
|
+
const items = await callFn(getSdk());
|
|
92
|
+
|
|
93
|
+
if (items.length === 0) {
|
|
94
|
+
console.log(chalk.yellow(`No ${resourceLabel} found`));
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const table = new Table({
|
|
99
|
+
head: columns.map((c) => chalk.cyan(c.header)),
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
for (const item of items) {
|
|
103
|
+
table.push(columns.map((c) => c.value(item)));
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(table.toString());
|
|
107
|
+
console.log(chalk.gray(`Total: ${items.length} ${resourceLabel}`));
|
|
108
|
+
} catch (error) {
|
|
109
|
+
console.error(
|
|
110
|
+
chalk.red(
|
|
111
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
112
|
+
),
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Runs a get-by-uuid action and prints details.
|
|
119
|
+
* Used for: show app, get database, get service, etc.
|
|
120
|
+
*
|
|
121
|
+
* @param uuid - UUID (optional, reads .coolify.json if undefined)
|
|
122
|
+
* @param _resourceLabel - Human label
|
|
123
|
+
* @param callFn - Function that calls the SDK get method (throws on error)
|
|
124
|
+
* @param formatFn - Function that formats the result for display
|
|
125
|
+
*/
|
|
126
|
+
export async function runGet<T>(
|
|
127
|
+
uuid: string | undefined,
|
|
128
|
+
_resourceLabel: string,
|
|
129
|
+
callFn: (sdk: Coolify, uuid: string) => Promise<T>,
|
|
130
|
+
formatFn: (item: T) => void,
|
|
131
|
+
): Promise<void> {
|
|
132
|
+
const resolved = resolveUuid(uuid);
|
|
133
|
+
if (!resolved) {
|
|
134
|
+
console.error(
|
|
135
|
+
chalk.red("Error: No UUID provided and no .coolify.json found"),
|
|
136
|
+
);
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
try {
|
|
141
|
+
const item = await callFn(getSdk(), resolved);
|
|
142
|
+
formatFn(item);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.error(
|
|
145
|
+
chalk.red(
|
|
146
|
+
`Error: ${error instanceof Error ? error.message : String(error)}`,
|
|
147
|
+
),
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Gets the CLI SDK instance for commands that need direct access.
|
|
154
|
+
*
|
|
155
|
+
* @returns Coolify SDK instance
|
|
156
|
+
*/
|
|
157
|
+
export function getCliSdk(): Coolify {
|
|
158
|
+
return getSdk();
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Re-export for convenience
|
|
162
|
+
export { formatStatus, chalk, Table };
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Active deployments command for CLI — goes through SDK.
|
|
3
|
+
*
|
|
4
|
+
* @module
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { runList, formatStatus } from "../actions.js";
|
|
8
|
+
import type { ICoolifyDeployment } from "../../coolify/types.js";
|
|
9
|
+
|
|
10
|
+
/** List all active deployments. */
|
|
11
|
+
export const activeDeploymentsCommand = () =>
|
|
12
|
+
runList<ICoolifyDeployment>(
|
|
13
|
+
"active deployment(s)",
|
|
14
|
+
(s) => s.deployments.active(),
|
|
15
|
+
[
|
|
16
|
+
{ header: "UUID", value: (d) => d.uuid },
|
|
17
|
+
{ header: "Status", value: (d) => formatStatus(d.status) },
|
|
18
|
+
{ header: "Commit", value: (d) => d.commit?.slice(0, 7) || "-" },
|
|
19
|
+
{
|
|
20
|
+
header: "Created",
|
|
21
|
+
value: (d) => new Date(d.created_at).toLocaleString(),
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
);
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build logs command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Shows deployment/build logs for a specific deployment.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { isErr } from "@mks2508/no-throw";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { getCoolifyService } from "../../coolify/index.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Build logs command handler.
|
|
15
|
+
*
|
|
16
|
+
* @param deploymentUuid - Deployment UUID
|
|
17
|
+
* @param options - Build logs options
|
|
18
|
+
*/
|
|
19
|
+
export async function buildLogsCommand(
|
|
20
|
+
deploymentUuid: string,
|
|
21
|
+
options: { lines?: number },
|
|
22
|
+
) {
|
|
23
|
+
const coolify = getCoolifyService();
|
|
24
|
+
const initResult = await coolify.init();
|
|
25
|
+
|
|
26
|
+
if (isErr(initResult)) {
|
|
27
|
+
console.error(chalk.red(`Error: ${initResult.error.message}`));
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const result = await coolify.getDeploymentLogs(deploymentUuid);
|
|
32
|
+
|
|
33
|
+
if (isErr(result)) {
|
|
34
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const { status, logs } = result.value;
|
|
39
|
+
|
|
40
|
+
console.log(chalk.cyan("Deployment:") + " " + chalk.white(deploymentUuid));
|
|
41
|
+
console.log(chalk.cyan("Status: ") + " " + chalk.white(status));
|
|
42
|
+
console.log("");
|
|
43
|
+
|
|
44
|
+
if (!logs || logs.length === 0) {
|
|
45
|
+
console.log(chalk.yellow("No build logs available"));
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
const lines = logs.split("\n");
|
|
50
|
+
const tail = options.lines || lines.length;
|
|
51
|
+
const output = lines.slice(-tail);
|
|
52
|
+
|
|
53
|
+
console.log(chalk.gray(`Build logs (${output.length} lines):\n`));
|
|
54
|
+
|
|
55
|
+
for (const line of output) {
|
|
56
|
+
console.log(line);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cancel deploy command for CLI.
|
|
3
|
+
*
|
|
4
|
+
* Cancels an in-progress deployment.
|
|
5
|
+
*
|
|
6
|
+
* @module
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { isErr } from "@mks2508/no-throw";
|
|
10
|
+
import chalk from "chalk";
|
|
11
|
+
import { getCoolifyService } from "../../coolify/index.js";
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Cancel deploy command handler.
|
|
15
|
+
*
|
|
16
|
+
* @param deploymentUuid - Deployment UUID to cancel
|
|
17
|
+
*/
|
|
18
|
+
export async function cancelDeployCommand(deploymentUuid: string) {
|
|
19
|
+
const coolify = getCoolifyService();
|
|
20
|
+
const initResult = await coolify.init();
|
|
21
|
+
|
|
22
|
+
if (isErr(initResult)) {
|
|
23
|
+
console.error(chalk.red(`Error: ${initResult.error.message}`));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const result = await coolify.cancelDeployment(deploymentUuid);
|
|
28
|
+
|
|
29
|
+
if (isErr(result)) {
|
|
30
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
console.log(chalk.green(`Deployment ${deploymentUuid} cancelled`));
|
|
35
|
+
}
|
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* @module
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import { isOk } from
|
|
8
|
-
import chalk from
|
|
9
|
-
import { existsSync } from
|
|
10
|
-
import { loadConfig, saveConfig, CONFIG_FILE } from
|
|
7
|
+
import { isOk } from "@mks2508/no-throw";
|
|
8
|
+
import chalk from "chalk";
|
|
9
|
+
import { existsSync } from "node:fs";
|
|
10
|
+
import { loadConfig, saveConfig, CONFIG_FILE } from "../../coolify/config.js";
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Config command handler.
|
|
@@ -17,67 +17,73 @@ import { loadConfig, saveConfig, CONFIG_FILE } from '../../coolify/config.js'
|
|
|
17
17
|
*/
|
|
18
18
|
export async function configCommand(
|
|
19
19
|
action: string | undefined,
|
|
20
|
-
args: { key?: string; value?: string }
|
|
20
|
+
args: { key?: string; value?: string },
|
|
21
21
|
) {
|
|
22
|
-
if (action ===
|
|
22
|
+
if (action === "set") {
|
|
23
23
|
if (!args.key || !args.value) {
|
|
24
|
-
console.error(
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
24
|
+
console.error(
|
|
25
|
+
chalk.red('Error: key and value are required for "set" command'),
|
|
26
|
+
);
|
|
27
|
+
console.log(chalk.gray("Usage: coolify-mcp config set <key> <value>"));
|
|
28
|
+
console.log(chalk.gray("Keys: url, token"));
|
|
29
|
+
return;
|
|
28
30
|
}
|
|
29
31
|
|
|
30
|
-
const result = await loadConfig()
|
|
32
|
+
const result = await loadConfig();
|
|
31
33
|
if (isOk(result)) {
|
|
32
|
-
const config = result.value
|
|
33
|
-
if (args.key ===
|
|
34
|
-
config.url = args.value
|
|
35
|
-
} else if (args.key ===
|
|
36
|
-
config.token = args.value
|
|
34
|
+
const config = result.value;
|
|
35
|
+
if (args.key === "url") {
|
|
36
|
+
config.url = args.value;
|
|
37
|
+
} else if (args.key === "token") {
|
|
38
|
+
config.token = args.value;
|
|
37
39
|
} else {
|
|
38
|
-
console.error(chalk.red(`Error: Unknown key "${args.key}"`))
|
|
39
|
-
return
|
|
40
|
+
console.error(chalk.red(`Error: Unknown key "${args.key}"`));
|
|
41
|
+
return;
|
|
40
42
|
}
|
|
41
43
|
|
|
42
|
-
const saveResult = await saveConfig(config)
|
|
44
|
+
const saveResult = await saveConfig(config);
|
|
43
45
|
if (isOk(saveResult)) {
|
|
44
|
-
console.log(chalk.green(`Config updated: ${args.key} = ${args.value}`))
|
|
46
|
+
console.log(chalk.green(`Config updated: ${args.key} = ${args.value}`));
|
|
45
47
|
} else {
|
|
46
|
-
console.error(chalk.red(`Error: ${saveResult.error.message}`))
|
|
48
|
+
console.error(chalk.red(`Error: ${saveResult.error.message}`));
|
|
47
49
|
}
|
|
48
50
|
}
|
|
49
|
-
} else if (action ===
|
|
50
|
-
const result = await loadConfig()
|
|
51
|
+
} else if (action === "get") {
|
|
52
|
+
const result = await loadConfig();
|
|
51
53
|
if (isOk(result)) {
|
|
52
|
-
const config = result.value
|
|
53
|
-
console.log(chalk.cyan(
|
|
54
|
-
console.log(` URL: ${chalk.gray(config.url ||
|
|
55
|
-
console.log(
|
|
54
|
+
const config = result.value;
|
|
55
|
+
console.log(chalk.cyan("Current configuration:"));
|
|
56
|
+
console.log(` URL: ${chalk.gray(config.url || "(not set)")}`);
|
|
57
|
+
console.log(
|
|
58
|
+
` Token: ${chalk.gray(config.token ? "(set)" : "(not set)")}`,
|
|
59
|
+
);
|
|
56
60
|
} else {
|
|
57
|
-
console.error(chalk.red(`Error: ${result.error.message}`))
|
|
61
|
+
console.error(chalk.red(`Error: ${result.error.message}`));
|
|
58
62
|
}
|
|
59
|
-
} else if (action ===
|
|
60
|
-
console.log(chalk.cyan(
|
|
61
|
-
console.log(` ${CONFIG_FILE}`)
|
|
63
|
+
} else if (action === "path") {
|
|
64
|
+
console.log(chalk.cyan("Config file:"));
|
|
65
|
+
console.log(` ${CONFIG_FILE}`);
|
|
62
66
|
if (existsSync(CONFIG_FILE)) {
|
|
63
|
-
console.log(chalk.gray(
|
|
67
|
+
console.log(chalk.gray(" Status: File exists"));
|
|
64
68
|
} else {
|
|
65
|
-
console.log(chalk.yellow(
|
|
69
|
+
console.log(chalk.yellow(" Status: File does not exist"));
|
|
66
70
|
}
|
|
67
71
|
} else {
|
|
68
|
-
console.log(chalk.cyan(
|
|
69
|
-
console.log()
|
|
70
|
-
console.log(chalk.gray(
|
|
71
|
-
console.log(
|
|
72
|
-
console.log(
|
|
73
|
-
console.log(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
console.log(
|
|
77
|
-
console.log(
|
|
78
|
-
console.log()
|
|
79
|
-
console.log(
|
|
80
|
-
console.log(
|
|
81
|
-
console.log(
|
|
72
|
+
console.log(chalk.cyan("Coolify MCP Configuration"));
|
|
73
|
+
console.log();
|
|
74
|
+
console.log(chalk.gray("Commands:"));
|
|
75
|
+
console.log(" coolify-mcp config set <key> <value> Set a config value");
|
|
76
|
+
console.log(" coolify-mcp config get Show current config");
|
|
77
|
+
console.log(
|
|
78
|
+
" coolify-mcp config path Show config file path",
|
|
79
|
+
);
|
|
80
|
+
console.log();
|
|
81
|
+
console.log(chalk.gray("Keys:"));
|
|
82
|
+
console.log(" url - Coolify instance URL");
|
|
83
|
+
console.log(" token - Coolify API token");
|
|
84
|
+
console.log();
|
|
85
|
+
console.log(chalk.gray("Environment variables:"));
|
|
86
|
+
console.log(" COOLIFY_URL - Coolify instance URL");
|
|
87
|
+
console.log(" COOLIFY_TOKEN - Coolify API token");
|
|
82
88
|
}
|
|
83
89
|
}
|