mcp-server-kubernetes 2.3.0 → 2.4.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/config/container-templates.d.ts +2 -2
- package/dist/index.d.ts +4 -22
- package/dist/index.js +6 -6
- package/dist/resources/handlers.js +11 -11
- package/dist/tools/kubectl-delete.d.ts +1 -5
- package/dist/tools/kubectl-delete.js +5 -9
- package/dist/tools/kubectl-generic.d.ts +0 -7
- package/dist/tools/kubectl-generic.js +6 -13
- package/dist/tools/kubectl-get.d.ts +1 -4
- package/dist/tools/kubectl-get.js +33 -22
- package/dist/tools/kubectl-list.d.ts +1 -3
- package/dist/tools/kubectl-list.js +3 -5
- package/dist/tools/kubectl-logs.d.ts +0 -5
- package/dist/tools/kubectl-logs.js +5 -10
- package/dist/tools/kubectl-rollout.d.ts +0 -3
- package/dist/tools/kubectl-rollout.js +4 -7
- package/dist/utils/kubernetes-manager.js +4 -4
- package/package.json +2 -7
|
@@ -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.d.ts
CHANGED
|
@@ -45,17 +45,14 @@ declare const destructiveTools: ({
|
|
|
45
45
|
readonly labelSelector: {
|
|
46
46
|
readonly type: "string";
|
|
47
47
|
readonly description: "Delete resources matching this label selector (e.g. 'app=nginx')";
|
|
48
|
-
readonly optional: true;
|
|
49
48
|
};
|
|
50
49
|
readonly manifest: {
|
|
51
50
|
readonly type: "string";
|
|
52
51
|
readonly description: "YAML manifest defining resources to delete (optional)";
|
|
53
|
-
readonly optional: true;
|
|
54
52
|
};
|
|
55
53
|
readonly filename: {
|
|
56
54
|
readonly type: "string";
|
|
57
55
|
readonly description: "Path to a YAML file to delete resources from (optional)";
|
|
58
|
-
readonly optional: true;
|
|
59
56
|
};
|
|
60
57
|
readonly allNamespaces: {
|
|
61
58
|
readonly type: "boolean";
|
|
@@ -70,10 +67,9 @@ declare const destructiveTools: ({
|
|
|
70
67
|
readonly gracePeriodSeconds: {
|
|
71
68
|
readonly type: "number";
|
|
72
69
|
readonly description: "Period of time in seconds given to the resource to terminate gracefully";
|
|
73
|
-
readonly optional: true;
|
|
74
70
|
};
|
|
75
71
|
};
|
|
76
|
-
readonly required: readonly [];
|
|
72
|
+
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
77
73
|
};
|
|
78
74
|
})[];
|
|
79
75
|
declare const allTools: ({
|
|
@@ -261,20 +257,17 @@ declare const allTools: ({
|
|
|
261
257
|
readonly labelSelector: {
|
|
262
258
|
readonly type: "string";
|
|
263
259
|
readonly description: "Filter resources by label selector (e.g. 'app=nginx')";
|
|
264
|
-
readonly optional: true;
|
|
265
260
|
};
|
|
266
261
|
readonly fieldSelector: {
|
|
267
262
|
readonly type: "string";
|
|
268
263
|
readonly description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')";
|
|
269
|
-
readonly optional: true;
|
|
270
264
|
};
|
|
271
265
|
readonly sortBy: {
|
|
272
266
|
readonly type: "string";
|
|
273
267
|
readonly description: "Sort events by a field (default: lastTimestamp). Only applicable for events.";
|
|
274
|
-
readonly optional: true;
|
|
275
268
|
};
|
|
276
269
|
};
|
|
277
|
-
readonly required: readonly ["resourceType"];
|
|
270
|
+
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
278
271
|
};
|
|
279
272
|
} | {
|
|
280
273
|
readonly name: "kubectl_describe";
|
|
@@ -332,15 +325,13 @@ declare const allTools: ({
|
|
|
332
325
|
readonly labelSelector: {
|
|
333
326
|
readonly type: "string";
|
|
334
327
|
readonly description: "Filter resources by label selector (e.g. 'app=nginx')";
|
|
335
|
-
readonly optional: true;
|
|
336
328
|
};
|
|
337
329
|
readonly fieldSelector: {
|
|
338
330
|
readonly type: "string";
|
|
339
331
|
readonly description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')";
|
|
340
|
-
readonly optional: true;
|
|
341
332
|
};
|
|
342
333
|
};
|
|
343
|
-
readonly required: readonly ["resourceType"];
|
|
334
|
+
readonly required: readonly ["resourceType", "namespace"];
|
|
344
335
|
};
|
|
345
336
|
} | {
|
|
346
337
|
readonly name: "kubectl_apply";
|
|
@@ -396,17 +387,14 @@ declare const allTools: ({
|
|
|
396
387
|
readonly labelSelector: {
|
|
397
388
|
readonly type: "string";
|
|
398
389
|
readonly description: "Delete resources matching this label selector (e.g. 'app=nginx')";
|
|
399
|
-
readonly optional: true;
|
|
400
390
|
};
|
|
401
391
|
readonly manifest: {
|
|
402
392
|
readonly type: "string";
|
|
403
393
|
readonly description: "YAML manifest defining resources to delete (optional)";
|
|
404
|
-
readonly optional: true;
|
|
405
394
|
};
|
|
406
395
|
readonly filename: {
|
|
407
396
|
readonly type: "string";
|
|
408
397
|
readonly description: "Path to a YAML file to delete resources from (optional)";
|
|
409
|
-
readonly optional: true;
|
|
410
398
|
};
|
|
411
399
|
readonly allNamespaces: {
|
|
412
400
|
readonly type: "boolean";
|
|
@@ -421,10 +409,9 @@ declare const allTools: ({
|
|
|
421
409
|
readonly gracePeriodSeconds: {
|
|
422
410
|
readonly type: "number";
|
|
423
411
|
readonly description: "Period of time in seconds given to the resource to terminate gracefully";
|
|
424
|
-
readonly optional: true;
|
|
425
412
|
};
|
|
426
413
|
};
|
|
427
|
-
readonly required: readonly [];
|
|
414
|
+
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
428
415
|
};
|
|
429
416
|
} | {
|
|
430
417
|
readonly name: "kubectl_create";
|
|
@@ -569,22 +556,18 @@ declare const allTools: ({
|
|
|
569
556
|
readonly container: {
|
|
570
557
|
readonly type: "string";
|
|
571
558
|
readonly description: "Container name (required when pod has multiple containers)";
|
|
572
|
-
readonly optional: true;
|
|
573
559
|
};
|
|
574
560
|
readonly tail: {
|
|
575
561
|
readonly type: "number";
|
|
576
562
|
readonly description: "Number of lines to show from end of logs";
|
|
577
|
-
readonly optional: true;
|
|
578
563
|
};
|
|
579
564
|
readonly since: {
|
|
580
565
|
readonly type: "string";
|
|
581
566
|
readonly description: "Show logs since relative time (e.g. '5s', '2m', '3h')";
|
|
582
|
-
readonly optional: true;
|
|
583
567
|
};
|
|
584
568
|
readonly sinceTime: {
|
|
585
569
|
readonly type: "string";
|
|
586
570
|
readonly description: "Show logs since absolute time (RFC3339)";
|
|
587
|
-
readonly optional: true;
|
|
588
571
|
};
|
|
589
572
|
readonly timestamps: {
|
|
590
573
|
readonly type: "boolean";
|
|
@@ -604,7 +587,6 @@ declare const allTools: ({
|
|
|
604
587
|
readonly labelSelector: {
|
|
605
588
|
readonly type: "string";
|
|
606
589
|
readonly description: "Filter resources by label selector";
|
|
607
|
-
readonly optional: true;
|
|
608
590
|
};
|
|
609
591
|
};
|
|
610
592
|
readonly required: readonly ["resourceType", "name", "namespace"];
|
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
|
};
|
|
@@ -21,17 +21,14 @@ export declare const kubectlDeleteSchema: {
|
|
|
21
21
|
readonly labelSelector: {
|
|
22
22
|
readonly type: "string";
|
|
23
23
|
readonly description: "Delete resources matching this label selector (e.g. 'app=nginx')";
|
|
24
|
-
readonly optional: true;
|
|
25
24
|
};
|
|
26
25
|
readonly manifest: {
|
|
27
26
|
readonly type: "string";
|
|
28
27
|
readonly description: "YAML manifest defining resources to delete (optional)";
|
|
29
|
-
readonly optional: true;
|
|
30
28
|
};
|
|
31
29
|
readonly filename: {
|
|
32
30
|
readonly type: "string";
|
|
33
31
|
readonly description: "Path to a YAML file to delete resources from (optional)";
|
|
34
|
-
readonly optional: true;
|
|
35
32
|
};
|
|
36
33
|
readonly allNamespaces: {
|
|
37
34
|
readonly type: "boolean";
|
|
@@ -46,10 +43,9 @@ export declare const kubectlDeleteSchema: {
|
|
|
46
43
|
readonly gracePeriodSeconds: {
|
|
47
44
|
readonly type: "number";
|
|
48
45
|
readonly description: "Period of time in seconds given to the resource to terminate gracefully";
|
|
49
|
-
readonly optional: true;
|
|
50
46
|
};
|
|
51
47
|
};
|
|
52
|
-
readonly required: readonly [];
|
|
48
|
+
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
53
49
|
};
|
|
54
50
|
};
|
|
55
51
|
export declare function kubectlDelete(k8sManager: KubernetesManager, input: {
|
|
@@ -24,18 +24,15 @@ export const kubectlDeleteSchema = {
|
|
|
24
24
|
},
|
|
25
25
|
labelSelector: {
|
|
26
26
|
type: "string",
|
|
27
|
-
description: "Delete resources matching this label selector (e.g. 'app=nginx')"
|
|
28
|
-
optional: true
|
|
27
|
+
description: "Delete resources matching this label selector (e.g. 'app=nginx')"
|
|
29
28
|
},
|
|
30
29
|
manifest: {
|
|
31
30
|
type: "string",
|
|
32
|
-
description: "YAML manifest defining resources to delete (optional)"
|
|
33
|
-
optional: true
|
|
31
|
+
description: "YAML manifest defining resources to delete (optional)"
|
|
34
32
|
},
|
|
35
33
|
filename: {
|
|
36
34
|
type: "string",
|
|
37
|
-
description: "Path to a YAML file to delete resources from (optional)"
|
|
38
|
-
optional: true
|
|
35
|
+
description: "Path to a YAML file to delete resources from (optional)"
|
|
39
36
|
},
|
|
40
37
|
allNamespaces: {
|
|
41
38
|
type: "boolean",
|
|
@@ -49,11 +46,10 @@ export const kubectlDeleteSchema = {
|
|
|
49
46
|
},
|
|
50
47
|
gracePeriodSeconds: {
|
|
51
48
|
type: "number",
|
|
52
|
-
description: "Period of time in seconds given to the resource to terminate gracefully"
|
|
53
|
-
optional: true
|
|
49
|
+
description: "Period of time in seconds given to the resource to terminate gracefully"
|
|
54
50
|
}
|
|
55
51
|
},
|
|
56
|
-
required: [],
|
|
52
|
+
required: ["resourceType", "name", "namespace"],
|
|
57
53
|
},
|
|
58
54
|
};
|
|
59
55
|
export async function kubectlDelete(k8sManager, input) {
|
|
@@ -12,34 +12,28 @@ export declare const kubectlGenericSchema: {
|
|
|
12
12
|
subCommand: {
|
|
13
13
|
type: string;
|
|
14
14
|
description: string;
|
|
15
|
-
optional: boolean;
|
|
16
15
|
};
|
|
17
16
|
resourceType: {
|
|
18
17
|
type: string;
|
|
19
18
|
description: string;
|
|
20
|
-
optional: boolean;
|
|
21
19
|
};
|
|
22
20
|
name: {
|
|
23
21
|
type: string;
|
|
24
22
|
description: string;
|
|
25
|
-
optional: boolean;
|
|
26
23
|
};
|
|
27
24
|
namespace: {
|
|
28
25
|
type: string;
|
|
29
26
|
description: string;
|
|
30
27
|
default: string;
|
|
31
|
-
optional: boolean;
|
|
32
28
|
};
|
|
33
29
|
outputFormat: {
|
|
34
30
|
type: string;
|
|
35
31
|
description: string;
|
|
36
32
|
enum: string[];
|
|
37
|
-
optional: boolean;
|
|
38
33
|
};
|
|
39
34
|
flags: {
|
|
40
35
|
type: string;
|
|
41
36
|
description: string;
|
|
42
|
-
optional: boolean;
|
|
43
37
|
additionalProperties: boolean;
|
|
44
38
|
};
|
|
45
39
|
args: {
|
|
@@ -48,7 +42,6 @@ export declare const kubectlGenericSchema: {
|
|
|
48
42
|
type: string;
|
|
49
43
|
};
|
|
50
44
|
description: string;
|
|
51
|
-
optional: boolean;
|
|
52
45
|
};
|
|
53
46
|
};
|
|
54
47
|
required: string[];
|
|
@@ -12,42 +12,35 @@ export const kubectlGenericSchema = {
|
|
|
12
12
|
},
|
|
13
13
|
subCommand: {
|
|
14
14
|
type: "string",
|
|
15
|
-
description: "Subcommand if applicable (e.g. 'history' for rollout)"
|
|
16
|
-
optional: true
|
|
15
|
+
description: "Subcommand if applicable (e.g. 'history' for rollout)"
|
|
17
16
|
},
|
|
18
17
|
resourceType: {
|
|
19
18
|
type: "string",
|
|
20
|
-
description: "Resource type (e.g. pod, deployment)"
|
|
21
|
-
optional: true
|
|
19
|
+
description: "Resource type (e.g. pod, deployment)"
|
|
22
20
|
},
|
|
23
21
|
name: {
|
|
24
22
|
type: "string",
|
|
25
|
-
description: "Resource name"
|
|
26
|
-
optional: true
|
|
23
|
+
description: "Resource name"
|
|
27
24
|
},
|
|
28
25
|
namespace: {
|
|
29
26
|
type: "string",
|
|
30
27
|
description: "Namespace",
|
|
31
|
-
default: "default"
|
|
32
|
-
optional: true
|
|
28
|
+
default: "default"
|
|
33
29
|
},
|
|
34
30
|
outputFormat: {
|
|
35
31
|
type: "string",
|
|
36
32
|
description: "Output format (e.g. json, yaml, wide)",
|
|
37
|
-
enum: ["json", "yaml", "wide", "name", "custom"]
|
|
38
|
-
optional: true
|
|
33
|
+
enum: ["json", "yaml", "wide", "name", "custom"]
|
|
39
34
|
},
|
|
40
35
|
flags: {
|
|
41
36
|
type: "object",
|
|
42
37
|
description: "Command flags as key-value pairs",
|
|
43
|
-
optional: true,
|
|
44
38
|
additionalProperties: true
|
|
45
39
|
},
|
|
46
40
|
args: {
|
|
47
41
|
type: "array",
|
|
48
42
|
items: { type: "string" },
|
|
49
|
-
description: "Additional command arguments"
|
|
50
|
-
optional: true
|
|
43
|
+
description: "Additional command arguments"
|
|
51
44
|
}
|
|
52
45
|
},
|
|
53
46
|
required: ["command"]
|
|
@@ -32,20 +32,17 @@ export declare const kubectlGetSchema: {
|
|
|
32
32
|
readonly labelSelector: {
|
|
33
33
|
readonly type: "string";
|
|
34
34
|
readonly description: "Filter resources by label selector (e.g. 'app=nginx')";
|
|
35
|
-
readonly optional: true;
|
|
36
35
|
};
|
|
37
36
|
readonly fieldSelector: {
|
|
38
37
|
readonly type: "string";
|
|
39
38
|
readonly description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')";
|
|
40
|
-
readonly optional: true;
|
|
41
39
|
};
|
|
42
40
|
readonly sortBy: {
|
|
43
41
|
readonly type: "string";
|
|
44
42
|
readonly description: "Sort events by a field (default: lastTimestamp). Only applicable for events.";
|
|
45
|
-
readonly optional: true;
|
|
46
43
|
};
|
|
47
44
|
};
|
|
48
|
-
readonly required: readonly ["resourceType"];
|
|
45
|
+
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
49
46
|
};
|
|
50
47
|
};
|
|
51
48
|
export declare function kubectlGet(k8sManager: KubernetesManager, input: {
|
|
@@ -8,45 +8,42 @@ 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
|
-
description: "Filter resources by label selector (e.g. 'app=nginx')"
|
|
36
|
-
optional: true
|
|
35
|
+
description: "Filter resources by label selector (e.g. 'app=nginx')"
|
|
37
36
|
},
|
|
38
37
|
fieldSelector: {
|
|
39
38
|
type: "string",
|
|
40
|
-
description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')"
|
|
41
|
-
optional: true
|
|
39
|
+
description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')"
|
|
42
40
|
},
|
|
43
41
|
sortBy: {
|
|
44
42
|
type: "string",
|
|
45
|
-
description: "Sort events by a field (default: lastTimestamp). Only applicable for events."
|
|
46
|
-
|
|
47
|
-
}
|
|
43
|
+
description: "Sort events by a field (default: lastTimestamp). Only applicable for events."
|
|
44
|
+
},
|
|
48
45
|
},
|
|
49
|
-
required: ["resourceType"],
|
|
46
|
+
required: ["resourceType", "name", "namespace"],
|
|
50
47
|
},
|
|
51
48
|
};
|
|
52
49
|
export async function kubectlGet(k8sManager, input) {
|
|
@@ -68,8 +65,11 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
68
65
|
command += ` ${name}`;
|
|
69
66
|
}
|
|
70
67
|
// For events, default to all namespaces unless explicitly specified
|
|
71
|
-
const shouldShowAllNamespaces = resourceType === "events"
|
|
72
|
-
|
|
68
|
+
const shouldShowAllNamespaces = resourceType === "events"
|
|
69
|
+
? input.namespace
|
|
70
|
+
? false
|
|
71
|
+
: true
|
|
72
|
+
: allNamespaces;
|
|
73
73
|
// Add namespace flag unless all namespaces is specified
|
|
74
74
|
if (shouldShowAllNamespaces) {
|
|
75
75
|
command += " --all-namespaces";
|
|
@@ -115,7 +115,10 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
115
115
|
}
|
|
116
116
|
// Execute the command
|
|
117
117
|
try {
|
|
118
|
-
const result = execSync(command, {
|
|
118
|
+
const result = execSync(command, {
|
|
119
|
+
encoding: "utf8",
|
|
120
|
+
env: { ...process.env, KUBECONFIG: process.env.KUBECONFIG },
|
|
121
|
+
});
|
|
119
122
|
// Format the results for better readability
|
|
120
123
|
const isListOperation = !name;
|
|
121
124
|
if (isListOperation && output === "json") {
|
|
@@ -152,7 +155,7 @@ export async function kubectlGet(k8sManager, input) {
|
|
|
152
155
|
namespace: item.metadata?.namespace || "",
|
|
153
156
|
kind: item.kind || resourceType,
|
|
154
157
|
status: getResourceStatus(item),
|
|
155
|
-
createdAt: item.metadata?.creationTimestamp
|
|
158
|
+
createdAt: item.metadata?.creationTimestamp,
|
|
156
159
|
}));
|
|
157
160
|
return {
|
|
158
161
|
content: [
|
|
@@ -239,13 +242,21 @@ function getResourceStatus(resource) {
|
|
|
239
242
|
// Helper function to determine if a resource is non-namespaced
|
|
240
243
|
function isNonNamespacedResource(resourceType) {
|
|
241
244
|
const nonNamespacedResources = [
|
|
242
|
-
"nodes",
|
|
243
|
-
"
|
|
244
|
-
"
|
|
245
|
-
"
|
|
245
|
+
"nodes",
|
|
246
|
+
"node",
|
|
247
|
+
"no",
|
|
248
|
+
"namespaces",
|
|
249
|
+
"namespace",
|
|
250
|
+
"ns",
|
|
251
|
+
"persistentvolumes",
|
|
252
|
+
"pv",
|
|
253
|
+
"storageclasses",
|
|
254
|
+
"sc",
|
|
246
255
|
"clusterroles",
|
|
247
256
|
"clusterrolebindings",
|
|
248
|
-
"customresourcedefinitions",
|
|
257
|
+
"customresourcedefinitions",
|
|
258
|
+
"crd",
|
|
259
|
+
"crds",
|
|
249
260
|
];
|
|
250
261
|
return nonNamespacedResources.includes(resourceType.toLowerCase());
|
|
251
262
|
}
|
|
@@ -28,15 +28,13 @@ export declare const kubectlListSchema: {
|
|
|
28
28
|
readonly labelSelector: {
|
|
29
29
|
readonly type: "string";
|
|
30
30
|
readonly description: "Filter resources by label selector (e.g. 'app=nginx')";
|
|
31
|
-
readonly optional: true;
|
|
32
31
|
};
|
|
33
32
|
readonly fieldSelector: {
|
|
34
33
|
readonly type: "string";
|
|
35
34
|
readonly description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')";
|
|
36
|
-
readonly optional: true;
|
|
37
35
|
};
|
|
38
36
|
};
|
|
39
|
-
readonly required: readonly ["resourceType"];
|
|
37
|
+
readonly required: readonly ["resourceType", "namespace"];
|
|
40
38
|
};
|
|
41
39
|
};
|
|
42
40
|
export declare function kubectlList(k8sManager: KubernetesManager, input: {
|
|
@@ -29,16 +29,14 @@ export const kubectlListSchema = {
|
|
|
29
29
|
},
|
|
30
30
|
labelSelector: {
|
|
31
31
|
type: "string",
|
|
32
|
-
description: "Filter resources by label selector (e.g. 'app=nginx')"
|
|
33
|
-
optional: true
|
|
32
|
+
description: "Filter resources by label selector (e.g. 'app=nginx')"
|
|
34
33
|
},
|
|
35
34
|
fieldSelector: {
|
|
36
35
|
type: "string",
|
|
37
|
-
description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')"
|
|
38
|
-
optional: true
|
|
36
|
+
description: "Filter resources by field selector (e.g. 'metadata.name=my-pod')"
|
|
39
37
|
}
|
|
40
38
|
},
|
|
41
|
-
required: ["resourceType"],
|
|
39
|
+
required: ["resourceType", "namespace"],
|
|
42
40
|
},
|
|
43
41
|
};
|
|
44
42
|
export async function kubectlList(k8sManager, input) {
|
|
@@ -22,22 +22,18 @@ export declare const kubectlLogsSchema: {
|
|
|
22
22
|
readonly container: {
|
|
23
23
|
readonly type: "string";
|
|
24
24
|
readonly description: "Container name (required when pod has multiple containers)";
|
|
25
|
-
readonly optional: true;
|
|
26
25
|
};
|
|
27
26
|
readonly tail: {
|
|
28
27
|
readonly type: "number";
|
|
29
28
|
readonly description: "Number of lines to show from end of logs";
|
|
30
|
-
readonly optional: true;
|
|
31
29
|
};
|
|
32
30
|
readonly since: {
|
|
33
31
|
readonly type: "string";
|
|
34
32
|
readonly description: "Show logs since relative time (e.g. '5s', '2m', '3h')";
|
|
35
|
-
readonly optional: true;
|
|
36
33
|
};
|
|
37
34
|
readonly sinceTime: {
|
|
38
35
|
readonly type: "string";
|
|
39
36
|
readonly description: "Show logs since absolute time (RFC3339)";
|
|
40
|
-
readonly optional: true;
|
|
41
37
|
};
|
|
42
38
|
readonly timestamps: {
|
|
43
39
|
readonly type: "boolean";
|
|
@@ -57,7 +53,6 @@ export declare const kubectlLogsSchema: {
|
|
|
57
53
|
readonly labelSelector: {
|
|
58
54
|
readonly type: "string";
|
|
59
55
|
readonly description: "Filter resources by label selector";
|
|
60
|
-
readonly optional: true;
|
|
61
56
|
};
|
|
62
57
|
};
|
|
63
58
|
readonly required: readonly ["resourceType", "name", "namespace"];
|
|
@@ -22,23 +22,19 @@ export const kubectlLogsSchema = {
|
|
|
22
22
|
},
|
|
23
23
|
container: {
|
|
24
24
|
type: "string",
|
|
25
|
-
description: "Container name (required when pod has multiple containers)"
|
|
26
|
-
optional: true,
|
|
25
|
+
description: "Container name (required when pod has multiple containers)"
|
|
27
26
|
},
|
|
28
27
|
tail: {
|
|
29
28
|
type: "number",
|
|
30
|
-
description: "Number of lines to show from end of logs"
|
|
31
|
-
optional: true,
|
|
29
|
+
description: "Number of lines to show from end of logs"
|
|
32
30
|
},
|
|
33
31
|
since: {
|
|
34
32
|
type: "string",
|
|
35
|
-
description: "Show logs since relative time (e.g. '5s', '2m', '3h')"
|
|
36
|
-
optional: true,
|
|
33
|
+
description: "Show logs since relative time (e.g. '5s', '2m', '3h')"
|
|
37
34
|
},
|
|
38
35
|
sinceTime: {
|
|
39
36
|
type: "string",
|
|
40
|
-
description: "Show logs since absolute time (RFC3339)"
|
|
41
|
-
optional: true,
|
|
37
|
+
description: "Show logs since absolute time (RFC3339)"
|
|
42
38
|
},
|
|
43
39
|
timestamps: {
|
|
44
40
|
type: "boolean",
|
|
@@ -57,8 +53,7 @@ export const kubectlLogsSchema = {
|
|
|
57
53
|
},
|
|
58
54
|
labelSelector: {
|
|
59
55
|
type: "string",
|
|
60
|
-
description: "Filter resources by label selector"
|
|
61
|
-
optional: true,
|
|
56
|
+
description: "Filter resources by label selector"
|
|
62
57
|
}
|
|
63
58
|
},
|
|
64
59
|
required: ["resourceType", "name", "namespace"],
|
|
@@ -29,17 +29,14 @@ export declare const kubectlRolloutSchema: {
|
|
|
29
29
|
revision: {
|
|
30
30
|
type: string;
|
|
31
31
|
description: string;
|
|
32
|
-
optional: boolean;
|
|
33
32
|
};
|
|
34
33
|
toRevision: {
|
|
35
34
|
type: string;
|
|
36
35
|
description: string;
|
|
37
|
-
optional: boolean;
|
|
38
36
|
};
|
|
39
37
|
timeout: {
|
|
40
38
|
type: string;
|
|
41
39
|
description: string;
|
|
42
|
-
optional: boolean;
|
|
43
40
|
};
|
|
44
41
|
watch: {
|
|
45
42
|
type: string;
|
|
@@ -29,18 +29,15 @@ export const kubectlRolloutSchema = {
|
|
|
29
29
|
},
|
|
30
30
|
revision: {
|
|
31
31
|
type: "number",
|
|
32
|
-
description: "Revision to rollback to (for undo subcommand)"
|
|
33
|
-
optional: true
|
|
32
|
+
description: "Revision to rollback to (for undo subcommand)"
|
|
34
33
|
},
|
|
35
34
|
toRevision: {
|
|
36
35
|
type: "number",
|
|
37
|
-
description: "Revision to roll back to (for history subcommand)"
|
|
38
|
-
optional: true
|
|
36
|
+
description: "Revision to roll back to (for history subcommand)"
|
|
39
37
|
},
|
|
40
38
|
timeout: {
|
|
41
39
|
type: "string",
|
|
42
|
-
description: "The length of time to wait before giving up (e.g., '30s', '1m', '2m30s')"
|
|
43
|
-
optional: true
|
|
40
|
+
description: "The length of time to wait before giving up (e.g., '30s', '1m', '2m30s')"
|
|
44
41
|
},
|
|
45
42
|
watch: {
|
|
46
43
|
type: "boolean",
|
|
@@ -48,7 +45,7 @@ export const kubectlRolloutSchema = {
|
|
|
48
45
|
default: false
|
|
49
46
|
}
|
|
50
47
|
},
|
|
51
|
-
required: ["subCommand", "resourceType", "name"]
|
|
48
|
+
required: ["subCommand", "resourceType", "name", "namespace"]
|
|
52
49
|
}
|
|
53
50
|
};
|
|
54
51
|
export async function kubectlRollout(k8sManager, input) {
|
|
@@ -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
|
+
"version": "2.4.0",
|
|
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
|
}
|