mcp-server-kubernetes 1.6.2 → 2.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/README.md +46 -22
- package/dist/config/container-templates.d.ts +2 -2
- package/dist/index.d.ts +314 -736
- package/dist/index.js +93 -200
- package/dist/models/resource-models.d.ts +6 -6
- package/dist/tools/kubectl-apply.d.ts +46 -0
- package/dist/tools/kubectl-apply.js +110 -0
- package/dist/tools/kubectl-context.d.ts +49 -0
- package/dist/tools/kubectl-context.js +233 -0
- package/dist/tools/kubectl-create.d.ts +150 -0
- package/dist/tools/kubectl-create.js +321 -0
- package/dist/tools/kubectl-delete.d.ts +77 -0
- package/dist/tools/kubectl-delete.js +177 -0
- package/dist/tools/kubectl-describe.d.ts +47 -0
- package/dist/tools/kubectl-describe.js +96 -0
- package/dist/tools/kubectl-generic.d.ts +71 -0
- package/dist/tools/kubectl-generic.js +121 -0
- package/dist/tools/kubectl-get.d.ts +72 -0
- package/dist/tools/kubectl-get.js +251 -0
- package/dist/tools/kubectl-list.d.ts +61 -0
- package/dist/tools/kubectl-list.js +189 -0
- package/dist/tools/{get_logs.d.ts → kubectl-logs.d.ts} +35 -19
- package/dist/tools/kubectl-logs.js +312 -0
- package/dist/tools/kubectl-patch.d.ts +57 -0
- package/dist/tools/kubectl-patch.js +128 -0
- package/dist/tools/kubectl-rollout.d.ts +67 -0
- package/dist/tools/kubectl-rollout.js +115 -0
- package/dist/tools/{scale_deployment.d.ts → kubectl-scale.d.ts} +13 -3
- package/dist/tools/kubectl-scale.js +73 -0
- package/dist/utils/kubernetes-manager.d.ts +4 -0
- package/dist/utils/kubernetes-manager.js +21 -3
- package/package.json +1 -1
- package/dist/tools/create_configmap.d.ts +0 -33
- package/dist/tools/create_configmap.js +0 -66
- package/dist/tools/create_cronjob.d.ts +0 -47
- package/dist/tools/create_cronjob.js +0 -93
- package/dist/tools/create_deployment.d.ts +0 -135
- package/dist/tools/create_deployment.js +0 -162
- package/dist/tools/create_namespace.d.ts +0 -22
- package/dist/tools/create_namespace.js +0 -48
- package/dist/tools/create_pod.d.ts +0 -130
- package/dist/tools/create_pod.js +0 -153
- package/dist/tools/create_service.d.ts +0 -74
- package/dist/tools/create_service.js +0 -102
- package/dist/tools/delete_configmap.d.ts +0 -26
- package/dist/tools/delete_configmap.js +0 -49
- package/dist/tools/delete_cronjob.d.ts +0 -26
- package/dist/tools/delete_cronjob.js +0 -48
- package/dist/tools/delete_deployment.d.ts +0 -31
- package/dist/tools/delete_deployment.js +0 -47
- package/dist/tools/delete_namespace.d.ts +0 -27
- package/dist/tools/delete_namespace.js +0 -44
- package/dist/tools/delete_pod.d.ts +0 -31
- package/dist/tools/delete_pod.js +0 -45
- package/dist/tools/delete_service.d.ts +0 -32
- package/dist/tools/delete_service.js +0 -46
- package/dist/tools/describe_cronjob.d.ts +0 -27
- package/dist/tools/describe_cronjob.js +0 -83
- package/dist/tools/describe_deployment.d.ts +0 -26
- package/dist/tools/describe_deployment.js +0 -40
- package/dist/tools/describe_node.d.ts +0 -22
- package/dist/tools/describe_node.js +0 -84
- package/dist/tools/describe_pod.d.ts +0 -33
- package/dist/tools/describe_pod.js +0 -81
- package/dist/tools/describe_service.d.ts +0 -34
- package/dist/tools/describe_service.js +0 -85
- package/dist/tools/get_configmap.d.ts +0 -27
- package/dist/tools/get_configmap.js +0 -48
- package/dist/tools/get_current_context.d.ts +0 -23
- package/dist/tools/get_current_context.js +0 -55
- package/dist/tools/get_events.d.ts +0 -28
- package/dist/tools/get_events.js +0 -66
- package/dist/tools/get_job_logs.d.ts +0 -40
- package/dist/tools/get_job_logs.js +0 -104
- package/dist/tools/get_logs.js +0 -150
- package/dist/tools/list_contexts.d.ts +0 -23
- package/dist/tools/list_contexts.js +0 -39
- package/dist/tools/list_cronjobs.d.ts +0 -23
- package/dist/tools/list_cronjobs.js +0 -35
- package/dist/tools/list_deployments.d.ts +0 -23
- package/dist/tools/list_deployments.js +0 -30
- package/dist/tools/list_jobs.d.ts +0 -29
- package/dist/tools/list_jobs.js +0 -77
- package/dist/tools/list_nodes.d.ts +0 -15
- package/dist/tools/list_nodes.js +0 -21
- package/dist/tools/list_pods.d.ts +0 -23
- package/dist/tools/list_pods.js +0 -29
- package/dist/tools/list_services.d.ts +0 -23
- package/dist/tools/list_services.js +0 -31
- package/dist/tools/scale_deployment.js +0 -50
- package/dist/tools/set_current_context.d.ts +0 -23
- package/dist/tools/set_current_context.js +0 -35
- package/dist/tools/update_configmap.d.ts +0 -33
- package/dist/tools/update_configmap.js +0 -71
- package/dist/tools/update_deployment.d.ts +0 -113
- package/dist/tools/update_deployment.js +0 -155
- package/dist/tools/update_service.d.ts +0 -72
- package/dist/tools/update_service.js +0 -125
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
import * as fs from "fs";
|
|
4
|
+
import * as path from "path";
|
|
5
|
+
import * as os from "os";
|
|
6
|
+
export const kubectlPatchSchema = {
|
|
7
|
+
name: "kubectl_patch",
|
|
8
|
+
description: "Update field(s) of a resource using strategic merge patch, JSON merge patch, or JSON patch",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
resourceType: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "Type of resource to patch (e.g., pods, deployments, services)"
|
|
15
|
+
},
|
|
16
|
+
name: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Name of the resource to patch"
|
|
19
|
+
},
|
|
20
|
+
namespace: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Namespace of the resource",
|
|
23
|
+
default: "default"
|
|
24
|
+
},
|
|
25
|
+
patchType: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Type of patch to apply",
|
|
28
|
+
enum: ["strategic", "merge", "json"],
|
|
29
|
+
default: "strategic"
|
|
30
|
+
},
|
|
31
|
+
patchData: {
|
|
32
|
+
type: "object",
|
|
33
|
+
description: "Patch data as a JSON object"
|
|
34
|
+
},
|
|
35
|
+
patchFile: {
|
|
36
|
+
type: "string",
|
|
37
|
+
description: "Path to a file containing the patch data (alternative to patchData)"
|
|
38
|
+
},
|
|
39
|
+
dryRun: {
|
|
40
|
+
type: "boolean",
|
|
41
|
+
description: "If true, only print the object that would be sent, without sending it",
|
|
42
|
+
default: false
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
required: ["resourceType", "name"],
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
export async function kubectlPatch(k8sManager, input) {
|
|
49
|
+
try {
|
|
50
|
+
if (!input.patchData && !input.patchFile) {
|
|
51
|
+
throw new McpError(ErrorCode.InvalidRequest, "Either patchData or patchFile must be provided");
|
|
52
|
+
}
|
|
53
|
+
const namespace = input.namespace || "default";
|
|
54
|
+
const patchType = input.patchType || "strategic";
|
|
55
|
+
const dryRun = input.dryRun || false;
|
|
56
|
+
let tempFile = null;
|
|
57
|
+
// Build the kubectl patch command
|
|
58
|
+
let command = `kubectl patch ${input.resourceType} ${input.name} -n ${namespace}`;
|
|
59
|
+
// Add patch type flag
|
|
60
|
+
switch (patchType) {
|
|
61
|
+
case "strategic":
|
|
62
|
+
command += " --type strategic";
|
|
63
|
+
break;
|
|
64
|
+
case "merge":
|
|
65
|
+
command += " --type merge";
|
|
66
|
+
break;
|
|
67
|
+
case "json":
|
|
68
|
+
command += " --type json";
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
command += " --type strategic";
|
|
72
|
+
}
|
|
73
|
+
// Handle patch data
|
|
74
|
+
if (input.patchData) {
|
|
75
|
+
// Create a temporary file for the patch data
|
|
76
|
+
const tmpDir = os.tmpdir();
|
|
77
|
+
tempFile = path.join(tmpDir, `patch-${Date.now()}.json`);
|
|
78
|
+
fs.writeFileSync(tempFile, JSON.stringify(input.patchData));
|
|
79
|
+
command += ` --patch-file ${tempFile}`;
|
|
80
|
+
}
|
|
81
|
+
else if (input.patchFile) {
|
|
82
|
+
command += ` --patch-file ${input.patchFile}`;
|
|
83
|
+
}
|
|
84
|
+
// Add dry-run flag if requested
|
|
85
|
+
if (dryRun) {
|
|
86
|
+
command += " --dry-run=client";
|
|
87
|
+
}
|
|
88
|
+
// Execute the command
|
|
89
|
+
try {
|
|
90
|
+
const result = execSync(command, { encoding: "utf8" });
|
|
91
|
+
// Clean up temp file if created
|
|
92
|
+
if (tempFile) {
|
|
93
|
+
try {
|
|
94
|
+
fs.unlinkSync(tempFile);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
content: [
|
|
102
|
+
{
|
|
103
|
+
type: "text",
|
|
104
|
+
text: result,
|
|
105
|
+
},
|
|
106
|
+
],
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
// Clean up temp file if created, even if command failed
|
|
111
|
+
if (tempFile) {
|
|
112
|
+
try {
|
|
113
|
+
fs.unlinkSync(tempFile);
|
|
114
|
+
}
|
|
115
|
+
catch (err) {
|
|
116
|
+
console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
throw new McpError(ErrorCode.InternalError, `Failed to patch resource: ${error.message}`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
catch (error) {
|
|
123
|
+
if (error instanceof McpError) {
|
|
124
|
+
throw error;
|
|
125
|
+
}
|
|
126
|
+
throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl patch command: ${error.message}`);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const kubectlRolloutSchema: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
subCommand: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
enum: string[];
|
|
12
|
+
default: string;
|
|
13
|
+
};
|
|
14
|
+
resourceType: {
|
|
15
|
+
type: string;
|
|
16
|
+
description: string;
|
|
17
|
+
enum: string[];
|
|
18
|
+
default: string;
|
|
19
|
+
};
|
|
20
|
+
name: {
|
|
21
|
+
type: string;
|
|
22
|
+
description: string;
|
|
23
|
+
};
|
|
24
|
+
namespace: {
|
|
25
|
+
type: string;
|
|
26
|
+
description: string;
|
|
27
|
+
default: string;
|
|
28
|
+
};
|
|
29
|
+
revision: {
|
|
30
|
+
type: string;
|
|
31
|
+
description: string;
|
|
32
|
+
optional: boolean;
|
|
33
|
+
};
|
|
34
|
+
toRevision: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
optional: boolean;
|
|
38
|
+
};
|
|
39
|
+
timeout: {
|
|
40
|
+
type: string;
|
|
41
|
+
description: string;
|
|
42
|
+
optional: boolean;
|
|
43
|
+
};
|
|
44
|
+
watch: {
|
|
45
|
+
type: string;
|
|
46
|
+
description: string;
|
|
47
|
+
default: boolean;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
required: string[];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export declare function kubectlRollout(k8sManager: KubernetesManager, input: {
|
|
54
|
+
subCommand: "history" | "pause" | "restart" | "resume" | "status" | "undo";
|
|
55
|
+
resourceType: "deployment" | "daemonset" | "statefulset";
|
|
56
|
+
name: string;
|
|
57
|
+
namespace?: string;
|
|
58
|
+
revision?: number;
|
|
59
|
+
toRevision?: number;
|
|
60
|
+
timeout?: string;
|
|
61
|
+
watch?: boolean;
|
|
62
|
+
}): Promise<{
|
|
63
|
+
content: {
|
|
64
|
+
type: string;
|
|
65
|
+
text: string;
|
|
66
|
+
}[];
|
|
67
|
+
}>;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
export const kubectlRolloutSchema = {
|
|
4
|
+
name: "kubectl_rollout",
|
|
5
|
+
description: "Manage the rollout of a resource (e.g., deployment, daemonset, statefulset)",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
subCommand: {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: "Rollout subcommand to execute",
|
|
12
|
+
enum: ["history", "pause", "restart", "resume", "status", "undo"],
|
|
13
|
+
default: "status"
|
|
14
|
+
},
|
|
15
|
+
resourceType: {
|
|
16
|
+
type: "string",
|
|
17
|
+
description: "Type of resource to manage rollout for",
|
|
18
|
+
enum: ["deployment", "daemonset", "statefulset"],
|
|
19
|
+
default: "deployment"
|
|
20
|
+
},
|
|
21
|
+
name: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Name of the resource"
|
|
24
|
+
},
|
|
25
|
+
namespace: {
|
|
26
|
+
type: "string",
|
|
27
|
+
description: "Namespace of the resource",
|
|
28
|
+
default: "default"
|
|
29
|
+
},
|
|
30
|
+
revision: {
|
|
31
|
+
type: "number",
|
|
32
|
+
description: "Revision to rollback to (for undo subcommand)",
|
|
33
|
+
optional: true
|
|
34
|
+
},
|
|
35
|
+
toRevision: {
|
|
36
|
+
type: "number",
|
|
37
|
+
description: "Revision to roll back to (for history subcommand)",
|
|
38
|
+
optional: true
|
|
39
|
+
},
|
|
40
|
+
timeout: {
|
|
41
|
+
type: "string",
|
|
42
|
+
description: "The length of time to wait before giving up (e.g., '30s', '1m', '2m30s')",
|
|
43
|
+
optional: true
|
|
44
|
+
},
|
|
45
|
+
watch: {
|
|
46
|
+
type: "boolean",
|
|
47
|
+
description: "Watch the rollout status in real-time until completion",
|
|
48
|
+
default: false
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
required: ["subCommand", "resourceType", "name"]
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
export async function kubectlRollout(k8sManager, input) {
|
|
55
|
+
try {
|
|
56
|
+
const namespace = input.namespace || "default";
|
|
57
|
+
const watch = input.watch || false;
|
|
58
|
+
// Build the kubectl rollout command
|
|
59
|
+
let command = `kubectl rollout ${input.subCommand} ${input.resourceType}/${input.name} -n ${namespace}`;
|
|
60
|
+
// Add revision for undo
|
|
61
|
+
if (input.subCommand === "undo" && input.revision !== undefined) {
|
|
62
|
+
command += ` --to-revision=${input.revision}`;
|
|
63
|
+
}
|
|
64
|
+
// Add revision for history
|
|
65
|
+
if (input.subCommand === "history" && input.toRevision !== undefined) {
|
|
66
|
+
command += ` --revision=${input.toRevision}`;
|
|
67
|
+
}
|
|
68
|
+
// Add timeout if specified
|
|
69
|
+
if (input.timeout) {
|
|
70
|
+
command += ` --timeout=${input.timeout}`;
|
|
71
|
+
}
|
|
72
|
+
// Execute the command
|
|
73
|
+
try {
|
|
74
|
+
// For status command with watch flag, we need to handle it differently
|
|
75
|
+
// since it's meant to be interactive and follow the progress
|
|
76
|
+
if (input.subCommand === "status" && watch) {
|
|
77
|
+
command += " --watch";
|
|
78
|
+
// For watch we are limited in what we can do - we'll execute it with a reasonable timeout
|
|
79
|
+
// and capture the output until that point
|
|
80
|
+
const result = execSync(command, {
|
|
81
|
+
encoding: "utf8",
|
|
82
|
+
timeout: 15000 // Reduced from 30 seconds to 15 seconds
|
|
83
|
+
});
|
|
84
|
+
return {
|
|
85
|
+
content: [
|
|
86
|
+
{
|
|
87
|
+
type: "text",
|
|
88
|
+
text: result + "\n\nNote: Watch operation was limited to 15 seconds. The rollout may still be in progress.",
|
|
89
|
+
},
|
|
90
|
+
],
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
const result = execSync(command, { encoding: "utf8" });
|
|
95
|
+
return {
|
|
96
|
+
content: [
|
|
97
|
+
{
|
|
98
|
+
type: "text",
|
|
99
|
+
text: result,
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
throw new McpError(ErrorCode.InternalError, `Failed to execute rollout command: ${error.message}`);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
if (error instanceof McpError) {
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl rollout command: ${error.message}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { KubernetesManager } from "../types.js";
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const kubectlScaleSchema: {
|
|
3
3
|
name: string;
|
|
4
4
|
description: string;
|
|
5
5
|
inputSchema: {
|
|
@@ -7,21 +7,31 @@ export declare const scaleDeploymentSchema: {
|
|
|
7
7
|
properties: {
|
|
8
8
|
name: {
|
|
9
9
|
type: string;
|
|
10
|
+
description: string;
|
|
10
11
|
};
|
|
11
12
|
namespace: {
|
|
12
13
|
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
default: string;
|
|
13
16
|
};
|
|
14
17
|
replicas: {
|
|
15
18
|
type: string;
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
resourceType: {
|
|
22
|
+
type: string;
|
|
23
|
+
description: string;
|
|
24
|
+
default: string;
|
|
16
25
|
};
|
|
17
26
|
};
|
|
18
27
|
required: string[];
|
|
19
28
|
};
|
|
20
29
|
};
|
|
21
|
-
export declare function
|
|
30
|
+
export declare function kubectlScale(k8sManager: KubernetesManager, input: {
|
|
22
31
|
name: string;
|
|
23
|
-
namespace
|
|
32
|
+
namespace?: string;
|
|
24
33
|
replicas: number;
|
|
34
|
+
resourceType?: string;
|
|
25
35
|
}): Promise<{
|
|
26
36
|
content: {
|
|
27
37
|
success: boolean;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js";
|
|
3
|
+
export const kubectlScaleSchema = {
|
|
4
|
+
name: "kubectl_scale",
|
|
5
|
+
description: "Scale a Kubernetes deployment",
|
|
6
|
+
inputSchema: {
|
|
7
|
+
type: "object",
|
|
8
|
+
properties: {
|
|
9
|
+
name: {
|
|
10
|
+
type: "string",
|
|
11
|
+
description: "Name of the deployment to scale"
|
|
12
|
+
},
|
|
13
|
+
namespace: {
|
|
14
|
+
type: "string",
|
|
15
|
+
description: "Namespace of the deployment",
|
|
16
|
+
default: "default"
|
|
17
|
+
},
|
|
18
|
+
replicas: {
|
|
19
|
+
type: "number",
|
|
20
|
+
description: "Number of replicas to scale to"
|
|
21
|
+
},
|
|
22
|
+
resourceType: {
|
|
23
|
+
type: "string",
|
|
24
|
+
description: "Resource type to scale (deployment, replicaset, statefulset)",
|
|
25
|
+
default: "deployment"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
required: ["name", "replicas"]
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
export async function kubectlScale(k8sManager, input) {
|
|
32
|
+
try {
|
|
33
|
+
const namespace = input.namespace || "default";
|
|
34
|
+
const resourceType = input.resourceType || "deployment";
|
|
35
|
+
// Build the kubectl scale command
|
|
36
|
+
let command = `kubectl scale ${resourceType} ${input.name} --replicas=${input.replicas} --namespace=${namespace}`;
|
|
37
|
+
// Execute the command
|
|
38
|
+
try {
|
|
39
|
+
const result = execSync(command, { encoding: "utf8" });
|
|
40
|
+
return {
|
|
41
|
+
content: [
|
|
42
|
+
{
|
|
43
|
+
success: true,
|
|
44
|
+
message: `Scaled ${resourceType} ${input.name} to ${input.replicas} replicas`
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
catch (error) {
|
|
50
|
+
throw new McpError(ErrorCode.InternalError, `Failed to scale ${resourceType}: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
catch (error) {
|
|
54
|
+
if (error instanceof McpError) {
|
|
55
|
+
return {
|
|
56
|
+
content: [
|
|
57
|
+
{
|
|
58
|
+
success: false,
|
|
59
|
+
message: error.message
|
|
60
|
+
}
|
|
61
|
+
]
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
content: [
|
|
66
|
+
{
|
|
67
|
+
success: false,
|
|
68
|
+
message: `Failed to scale resource: ${error.message}`
|
|
69
|
+
}
|
|
70
|
+
]
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -9,6 +9,10 @@ export declare class KubernetesManager {
|
|
|
9
9
|
private k8sAppsApi;
|
|
10
10
|
private k8sBatchApi;
|
|
11
11
|
constructor();
|
|
12
|
+
/**
|
|
13
|
+
* A very simple test to check if the application is running inside a Kubernetes cluster
|
|
14
|
+
*/
|
|
15
|
+
private isRunningInCluster;
|
|
12
16
|
/**
|
|
13
17
|
* Set the current context to the desired context name.
|
|
14
18
|
*
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as k8s from "@kubernetes/client-node";
|
|
2
|
+
import * as fs from "fs";
|
|
2
3
|
export class KubernetesManager {
|
|
3
4
|
resources = [];
|
|
4
5
|
portForwards = [];
|
|
@@ -9,11 +10,28 @@ export class KubernetesManager {
|
|
|
9
10
|
k8sBatchApi;
|
|
10
11
|
constructor() {
|
|
11
12
|
this.kc = new k8s.KubeConfig();
|
|
12
|
-
this.
|
|
13
|
+
if (this.isRunningInCluster()) {
|
|
14
|
+
this.kc.loadFromCluster();
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
this.kc.loadFromDefault();
|
|
18
|
+
}
|
|
13
19
|
this.k8sApi = this.kc.makeApiClient(k8s.CoreV1Api);
|
|
14
20
|
this.k8sAppsApi = this.kc.makeApiClient(k8s.AppsV1Api);
|
|
15
21
|
this.k8sBatchApi = this.kc.makeApiClient(k8s.BatchV1Api);
|
|
16
22
|
}
|
|
23
|
+
/**
|
|
24
|
+
* A very simple test to check if the application is running inside a Kubernetes cluster
|
|
25
|
+
*/
|
|
26
|
+
isRunningInCluster() {
|
|
27
|
+
const serviceAccountPath = "/var/run/secrets/kubernetes.io/serviceaccount/token";
|
|
28
|
+
try {
|
|
29
|
+
return fs.existsSync(serviceAccountPath);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
17
35
|
/**
|
|
18
36
|
* Set the current context to the desired context name.
|
|
19
37
|
*
|
|
@@ -22,10 +40,10 @@ export class KubernetesManager {
|
|
|
22
40
|
setCurrentContext(contextName) {
|
|
23
41
|
// Get all available contexts
|
|
24
42
|
const contexts = this.kc.getContexts();
|
|
25
|
-
const contextNames = contexts.map(context => context.name);
|
|
43
|
+
const contextNames = contexts.map((context) => context.name);
|
|
26
44
|
// Check if the requested context exists
|
|
27
45
|
if (!contextNames.includes(contextName)) {
|
|
28
|
-
throw new Error(`Context '${contextName}' not found. Available contexts: ${contextNames.join(
|
|
46
|
+
throw new Error(`Context '${contextName}' not found. Available contexts: ${contextNames.join(", ")}`);
|
|
29
47
|
}
|
|
30
48
|
// Set the current context
|
|
31
49
|
this.kc.setCurrentContext(contextName);
|
package/package.json
CHANGED
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { KubernetesManager } from "../types.js";
|
|
2
|
-
export declare const CreateConfigMapSchema: {
|
|
3
|
-
name: string;
|
|
4
|
-
description: string;
|
|
5
|
-
inputSchema: {
|
|
6
|
-
type: string;
|
|
7
|
-
properties: {
|
|
8
|
-
name: {
|
|
9
|
-
type: string;
|
|
10
|
-
};
|
|
11
|
-
namespace: {
|
|
12
|
-
type: string;
|
|
13
|
-
};
|
|
14
|
-
data: {
|
|
15
|
-
type: string;
|
|
16
|
-
ConfigData: {
|
|
17
|
-
type: string;
|
|
18
|
-
};
|
|
19
|
-
};
|
|
20
|
-
};
|
|
21
|
-
required: string[];
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
export declare function createConfigMap(k8sManager: KubernetesManager, input: {
|
|
25
|
-
name: string;
|
|
26
|
-
namespace: string;
|
|
27
|
-
data: Record<string, string>;
|
|
28
|
-
}): Promise<{
|
|
29
|
-
content: {
|
|
30
|
-
success: boolean;
|
|
31
|
-
message: string;
|
|
32
|
-
}[];
|
|
33
|
-
}>;
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
export const CreateConfigMapSchema = {
|
|
2
|
-
name: "create_configmap",
|
|
3
|
-
description: "Create a new Kubernetes ConfigMap",
|
|
4
|
-
inputSchema: {
|
|
5
|
-
type: "object",
|
|
6
|
-
properties: {
|
|
7
|
-
name: { type: "string" },
|
|
8
|
-
namespace: { type: "string" },
|
|
9
|
-
data: {
|
|
10
|
-
type: "object",
|
|
11
|
-
ConfigData: { type: "string" },
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
required: ["name", "namespace", "data"],
|
|
15
|
-
},
|
|
16
|
-
};
|
|
17
|
-
export async function createConfigMap(k8sManager, input) {
|
|
18
|
-
try {
|
|
19
|
-
const configmap = {
|
|
20
|
-
apiVersion: "v1",
|
|
21
|
-
kind: "ConfigMap",
|
|
22
|
-
binaryData: undefined,
|
|
23
|
-
data: input.data,
|
|
24
|
-
immutable: false,
|
|
25
|
-
metadata: {
|
|
26
|
-
name: input.name,
|
|
27
|
-
namespace: input.namespace,
|
|
28
|
-
labels: {
|
|
29
|
-
"mcp-managed": "true",
|
|
30
|
-
app: input.name,
|
|
31
|
-
},
|
|
32
|
-
},
|
|
33
|
-
};
|
|
34
|
-
const response = await k8sManager.getCoreApi().createNamespacedConfigMap(input.namespace, configmap);
|
|
35
|
-
if (response.response?.statusCode !== undefined && (response.response.statusCode == 200 || response.response.statusCode == 201 || response.response.statusCode == 202)) {
|
|
36
|
-
return {
|
|
37
|
-
content: [
|
|
38
|
-
{
|
|
39
|
-
success: true,
|
|
40
|
-
message: `Created ConfigMap ${response.body.metadata?.name} in namespace ${response.body.metadata?.namespace}`,
|
|
41
|
-
}
|
|
42
|
-
]
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
else {
|
|
46
|
-
return {
|
|
47
|
-
content: [
|
|
48
|
-
{
|
|
49
|
-
success: false,
|
|
50
|
-
message: `Failed to create ConfigMap ${response.body.metadata?.name} in namespace ${response.body.metadata?.namespace}`,
|
|
51
|
-
}
|
|
52
|
-
]
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
catch (error) {
|
|
57
|
-
return {
|
|
58
|
-
content: [
|
|
59
|
-
{
|
|
60
|
-
success: false,
|
|
61
|
-
message: `Failed to create ConfigMap ${input.name} in namespace ${input.namespace}. Error: ${error.message}`,
|
|
62
|
-
}
|
|
63
|
-
]
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { KubernetesManager } from "../types.js";
|
|
2
|
-
export declare const createCronJobSchema: {
|
|
3
|
-
readonly name: "create_cronjob";
|
|
4
|
-
readonly description: "Create a new Kubernetes CronJob";
|
|
5
|
-
readonly inputSchema: {
|
|
6
|
-
readonly type: "object";
|
|
7
|
-
readonly properties: {
|
|
8
|
-
readonly name: {
|
|
9
|
-
readonly type: "string";
|
|
10
|
-
};
|
|
11
|
-
readonly namespace: {
|
|
12
|
-
readonly type: "string";
|
|
13
|
-
};
|
|
14
|
-
readonly schedule: {
|
|
15
|
-
readonly type: "string";
|
|
16
|
-
};
|
|
17
|
-
readonly image: {
|
|
18
|
-
readonly type: "string";
|
|
19
|
-
};
|
|
20
|
-
readonly command: {
|
|
21
|
-
readonly type: "array";
|
|
22
|
-
readonly items: {
|
|
23
|
-
readonly type: "string";
|
|
24
|
-
};
|
|
25
|
-
readonly optional: true;
|
|
26
|
-
};
|
|
27
|
-
readonly suspend: {
|
|
28
|
-
readonly type: "boolean";
|
|
29
|
-
readonly optional: true;
|
|
30
|
-
};
|
|
31
|
-
};
|
|
32
|
-
readonly required: readonly ["name", "namespace", "schedule", "image"];
|
|
33
|
-
};
|
|
34
|
-
};
|
|
35
|
-
export declare function createCronJob(k8sManager: KubernetesManager, input: {
|
|
36
|
-
name: string;
|
|
37
|
-
namespace: string;
|
|
38
|
-
schedule: string;
|
|
39
|
-
image: string;
|
|
40
|
-
command?: string[];
|
|
41
|
-
suspend?: boolean;
|
|
42
|
-
}): Promise<{
|
|
43
|
-
content: {
|
|
44
|
-
type: string;
|
|
45
|
-
text: string;
|
|
46
|
-
}[];
|
|
47
|
-
}>;
|