mcp-server-kubernetes 2.3.0 → 2.3.1
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import
|
|
2
|
+
import type { V1Container } from "@kubernetes/client-node";
|
|
3
3
|
export declare const ContainerTemplate: z.ZodEnum<["ubuntu", "nginx", "busybox", "alpine", "custom"]>;
|
|
4
4
|
export type ContainerTemplateName = z.infer<typeof ContainerTemplate>;
|
|
5
5
|
export declare const CustomContainerConfig: z.ZodObject<{
|
|
@@ -103,4 +103,4 @@ export declare const CustomContainerConfig: z.ZodObject<{
|
|
|
103
103
|
}[] | undefined;
|
|
104
104
|
}>;
|
|
105
105
|
export type CustomContainerConfigType = z.infer<typeof CustomContainerConfig>;
|
|
106
|
-
export declare const containerTemplates: Record<string,
|
|
106
|
+
export declare const containerTemplates: Record<string, V1Container>;
|
package/dist/index.js
CHANGED
|
@@ -11,22 +11,22 @@ import { cleanupSchema } from "./config/cleanup-config.js";
|
|
|
11
11
|
import { startSSEServer } from "./utils/sse.js";
|
|
12
12
|
import { startPortForward, PortForwardSchema, stopPortForward, StopPortForwardSchema, } from "./tools/port_forward.js";
|
|
13
13
|
import { kubectlScale, kubectlScaleSchema } from "./tools/kubectl-scale.js";
|
|
14
|
-
import { kubectlContext, kubectlContextSchema } from "./tools/kubectl-context.js";
|
|
14
|
+
import { kubectlContext, kubectlContextSchema, } from "./tools/kubectl-context.js";
|
|
15
15
|
import { kubectlGet, kubectlGetSchema } from "./tools/kubectl-get.js";
|
|
16
|
-
import { kubectlDescribe, kubectlDescribeSchema } from "./tools/kubectl-describe.js";
|
|
16
|
+
import { kubectlDescribe, kubectlDescribeSchema, } from "./tools/kubectl-describe.js";
|
|
17
17
|
import { kubectlList, kubectlListSchema } from "./tools/kubectl-list.js";
|
|
18
18
|
import { kubectlApply, kubectlApplySchema } from "./tools/kubectl-apply.js";
|
|
19
19
|
import { kubectlDelete, kubectlDeleteSchema } from "./tools/kubectl-delete.js";
|
|
20
20
|
import { kubectlCreate, kubectlCreateSchema } from "./tools/kubectl-create.js";
|
|
21
21
|
import { kubectlLogs, kubectlLogsSchema } from "./tools/kubectl-logs.js";
|
|
22
|
-
import { kubectlGeneric, kubectlGenericSchema } from "./tools/kubectl-generic.js";
|
|
22
|
+
import { kubectlGeneric, kubectlGenericSchema, } from "./tools/kubectl-generic.js";
|
|
23
23
|
import { kubectlPatch, kubectlPatchSchema } from "./tools/kubectl-patch.js";
|
|
24
|
-
import { kubectlRollout, kubectlRolloutSchema } from "./tools/kubectl-rollout.js";
|
|
24
|
+
import { kubectlRollout, kubectlRolloutSchema, } from "./tools/kubectl-rollout.js";
|
|
25
25
|
// Check if non-destructive tools only mode is enabled
|
|
26
26
|
const nonDestructiveTools = process.env.ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS === "true";
|
|
27
27
|
// Define destructive tools (delete and uninstall operations)
|
|
28
28
|
const destructiveTools = [
|
|
29
|
-
kubectlDeleteSchema, // This replaces all individual delete operations
|
|
29
|
+
kubectlDeleteSchema, // This replaces all individual delete operations
|
|
30
30
|
uninstallHelmChartSchema,
|
|
31
31
|
cleanupSchema, // Cleanup is also destructive as it deletes resources
|
|
32
32
|
kubectlGenericSchema, // Generic kubectl command can perform destructive operations
|
|
@@ -123,7 +123,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
123
123
|
fieldSelector: input.fieldSelector,
|
|
124
124
|
labelSelector: input.labelSelector,
|
|
125
125
|
sortBy: input.sortBy,
|
|
126
|
-
output: input.output
|
|
126
|
+
output: input.output,
|
|
127
127
|
});
|
|
128
128
|
}
|
|
129
129
|
// Handle specific non-kubectl operations
|
|
@@ -44,13 +44,13 @@ export const getResourceHandlers = (k8sManager) => ({
|
|
|
44
44
|
const isNodes = parts[0] === "nodes";
|
|
45
45
|
if ((isNamespaces || isNodes) && parts.length === 1) {
|
|
46
46
|
const fn = isNodes ? "listNode" : "listNamespace";
|
|
47
|
-
const {
|
|
47
|
+
const { items } = await k8sManager.getCoreApi()[fn]();
|
|
48
48
|
return {
|
|
49
49
|
contents: [
|
|
50
50
|
{
|
|
51
51
|
uri: request.params.uri,
|
|
52
52
|
mimeType: "application/json",
|
|
53
|
-
text: JSON.stringify(
|
|
53
|
+
text: JSON.stringify(items, null, 2),
|
|
54
54
|
},
|
|
55
55
|
],
|
|
56
56
|
};
|
|
@@ -58,43 +58,43 @@ export const getResourceHandlers = (k8sManager) => ({
|
|
|
58
58
|
const [namespace, resourceType] = parts;
|
|
59
59
|
switch (resourceType) {
|
|
60
60
|
case "pods": {
|
|
61
|
-
const {
|
|
61
|
+
const { items } = await k8sManager
|
|
62
62
|
.getCoreApi()
|
|
63
|
-
.listNamespacedPod(namespace);
|
|
63
|
+
.listNamespacedPod({ namespace });
|
|
64
64
|
return {
|
|
65
65
|
contents: [
|
|
66
66
|
{
|
|
67
67
|
uri: request.params.uri,
|
|
68
68
|
mimeType: "application/json",
|
|
69
|
-
text: JSON.stringify(
|
|
69
|
+
text: JSON.stringify(items, null, 2),
|
|
70
70
|
},
|
|
71
71
|
],
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
74
|
case "deployments": {
|
|
75
|
-
const {
|
|
75
|
+
const { items } = await k8sManager
|
|
76
76
|
.getAppsApi()
|
|
77
|
-
.listNamespacedDeployment(namespace);
|
|
77
|
+
.listNamespacedDeployment({ namespace });
|
|
78
78
|
return {
|
|
79
79
|
contents: [
|
|
80
80
|
{
|
|
81
81
|
uri: request.params.uri,
|
|
82
82
|
mimeType: "application/json",
|
|
83
|
-
text: JSON.stringify(
|
|
83
|
+
text: JSON.stringify(items, null, 2),
|
|
84
84
|
},
|
|
85
85
|
],
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
88
|
case "services": {
|
|
89
|
-
const {
|
|
89
|
+
const { items } = await k8sManager
|
|
90
90
|
.getCoreApi()
|
|
91
|
-
.listNamespacedService(namespace);
|
|
91
|
+
.listNamespacedService({ namespace });
|
|
92
92
|
return {
|
|
93
93
|
contents: [
|
|
94
94
|
{
|
|
95
95
|
uri: request.params.uri,
|
|
96
96
|
mimeType: "application/json",
|
|
97
|
-
text: JSON.stringify(
|
|
97
|
+
text: JSON.stringify(items, null, 2),
|
|
98
98
|
},
|
|
99
99
|
],
|
|
100
100
|
};
|
|
@@ -8,43 +8,43 @@ export const kubectlGetSchema = {
|
|
|
8
8
|
properties: {
|
|
9
9
|
resourceType: {
|
|
10
10
|
type: "string",
|
|
11
|
-
description: "Type of resource to get (e.g., pods, deployments, services, configmaps, events, etc.)"
|
|
11
|
+
description: "Type of resource to get (e.g., pods, deployments, services, configmaps, events, etc.)",
|
|
12
12
|
},
|
|
13
13
|
name: {
|
|
14
14
|
type: "string",
|
|
15
|
-
description: "Name of the resource (optional - if not provided, lists all resources of the specified type)"
|
|
15
|
+
description: "Name of the resource (optional - if not provided, lists all resources of the specified type)",
|
|
16
16
|
},
|
|
17
17
|
namespace: {
|
|
18
18
|
type: "string",
|
|
19
19
|
description: "Namespace of the resource (optional - defaults to 'default' for namespaced resources)",
|
|
20
|
-
default: "default"
|
|
20
|
+
default: "default",
|
|
21
21
|
},
|
|
22
22
|
output: {
|
|
23
23
|
type: "string",
|
|
24
24
|
enum: ["json", "yaml", "wide", "name", "custom"],
|
|
25
25
|
description: "Output format",
|
|
26
|
-
default: "json"
|
|
26
|
+
default: "json",
|
|
27
27
|
},
|
|
28
28
|
allNamespaces: {
|
|
29
29
|
type: "boolean",
|
|
30
30
|
description: "If true, list resources across all namespaces",
|
|
31
|
-
default: false
|
|
31
|
+
default: false,
|
|
32
32
|
},
|
|
33
33
|
labelSelector: {
|
|
34
34
|
type: "string",
|
|
35
35
|
description: "Filter resources by label selector (e.g. 'app=nginx')",
|
|
36
|
-
optional: true
|
|
36
|
+
optional: true,
|
|
37
37
|
},
|
|
38
38
|
fieldSelector: {
|
|
39
39
|
type: "string",
|
|
40
40
|
description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')",
|
|
41
|
-
optional: true
|
|
41
|
+
optional: true,
|
|
42
42
|
},
|
|
43
43
|
sortBy: {
|
|
44
44
|
type: "string",
|
|
45
45
|
description: "Sort events by a field (default: lastTimestamp). Only applicable for events.",
|
|
46
|
-
optional: true
|
|
47
|
-
}
|
|
46
|
+
optional: true,
|
|
47
|
+
},
|
|
48
48
|
},
|
|
49
49
|
required: ["resourceType"],
|
|
50
50
|
},
|
|
@@ -68,8 +68,11 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
68
68
|
command += ` ${name}`;
|
|
69
69
|
}
|
|
70
70
|
// For events, default to all namespaces unless explicitly specified
|
|
71
|
-
const shouldShowAllNamespaces = resourceType === "events"
|
|
72
|
-
|
|
71
|
+
const shouldShowAllNamespaces = resourceType === "events"
|
|
72
|
+
? input.namespace
|
|
73
|
+
? false
|
|
74
|
+
: true
|
|
75
|
+
: allNamespaces;
|
|
73
76
|
// Add namespace flag unless all namespaces is specified
|
|
74
77
|
if (shouldShowAllNamespaces) {
|
|
75
78
|
command += " --all-namespaces";
|
|
@@ -115,7 +118,10 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
115
118
|
}
|
|
116
119
|
// Execute the command
|
|
117
120
|
try {
|
|
118
|
-
const result = execSync(command, {
|
|
121
|
+
const result = execSync(command, {
|
|
122
|
+
encoding: "utf8",
|
|
123
|
+
env: { ...process.env, KUBECONFIG: process.env.KUBECONFIG },
|
|
124
|
+
});
|
|
119
125
|
// Format the results for better readability
|
|
120
126
|
const isListOperation = !name;
|
|
121
127
|
if (isListOperation && output === "json") {
|
|
@@ -152,7 +158,7 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
152
158
|
namespace: item.metadata?.namespace || "",
|
|
153
159
|
kind: item.kind || resourceType,
|
|
154
160
|
status: getResourceStatus(item),
|
|
155
|
-
createdAt: item.metadata?.creationTimestamp
|
|
161
|
+
createdAt: item.metadata?.creationTimestamp,
|
|
156
162
|
}));
|
|
157
163
|
return {
|
|
158
164
|
content: [
|
|
@@ -239,13 +245,21 @@ function getResourceStatus(resource) {
|
|
|
239
245
|
// Helper function to determine if a resource is non-namespaced
|
|
240
246
|
function isNonNamespacedResource(resourceType) {
|
|
241
247
|
const nonNamespacedResources = [
|
|
242
|
-
"nodes",
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
248
|
+
"nodes",
|
|
249
|
+
"node",
|
|
250
|
+
"no",
|
|
251
|
+
"namespaces",
|
|
252
|
+
"namespace",
|
|
253
|
+
"ns",
|
|
254
|
+
"persistentvolumes",
|
|
255
|
+
"pv",
|
|
256
|
+
"storageclasses",
|
|
257
|
+
"sc",
|
|
246
258
|
"clusterroles",
|
|
247
259
|
"clusterrolebindings",
|
|
248
|
-
"customresourcedefinitions",
|
|
260
|
+
"customresourcedefinitions",
|
|
261
|
+
"crd",
|
|
262
|
+
"crds",
|
|
249
263
|
];
|
|
250
264
|
return nonNamespacedResources.includes(resourceType.toLowerCase());
|
|
251
265
|
}
|
|
@@ -217,16 +217,16 @@ export class KubernetesManager {
|
|
|
217
217
|
async deleteResource(kind, name, namespace) {
|
|
218
218
|
switch (kind.toLowerCase()) {
|
|
219
219
|
case "pod":
|
|
220
|
-
await this.k8sApi.deleteNamespacedPod(name, namespace);
|
|
220
|
+
await this.k8sApi.deleteNamespacedPod({ name, namespace });
|
|
221
221
|
break;
|
|
222
222
|
case "deployment":
|
|
223
|
-
await this.k8sAppsApi.deleteNamespacedDeployment(name, namespace);
|
|
223
|
+
await this.k8sAppsApi.deleteNamespacedDeployment({ name, namespace });
|
|
224
224
|
break;
|
|
225
225
|
case "service":
|
|
226
|
-
await this.k8sApi.deleteNamespacedService(name, namespace);
|
|
226
|
+
await this.k8sApi.deleteNamespacedService({ name, namespace });
|
|
227
227
|
break;
|
|
228
228
|
case "cronjob":
|
|
229
|
-
await this.k8sBatchApi.deleteNamespacedCronJob(name, namespace);
|
|
229
|
+
await this.k8sBatchApi.deleteNamespacedCronJob({ name, namespace });
|
|
230
230
|
break;
|
|
231
231
|
}
|
|
232
232
|
this.resources = this.resources.filter((r) => !(r.kind === kind && r.name === name && r.namespace === namespace));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-server-kubernetes",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.1",
|
|
4
4
|
"description": "MCP server for interacting with Kubernetes clusters via kubectl",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"node": ">=18"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@kubernetes/client-node": "
|
|
38
|
+
"@kubernetes/client-node": "1.3.0",
|
|
39
39
|
"@modelcontextprotocol/sdk": "1.7.0",
|
|
40
40
|
"express": "4.21.2",
|
|
41
41
|
"js-yaml": "4.1.0",
|
|
@@ -49,10 +49,5 @@
|
|
|
49
49
|
"shx": "0.3.4",
|
|
50
50
|
"typescript": "5.6.2",
|
|
51
51
|
"vitest": "2.1.9"
|
|
52
|
-
},
|
|
53
|
-
"overrides": {
|
|
54
|
-
"@kubernetes/client-node": {
|
|
55
|
-
"jsonpath-plus": "^10.3.0"
|
|
56
|
-
}
|
|
57
52
|
}
|
|
58
53
|
}
|