mcp-server-kubernetes 0.2.5 → 0.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.
- package/README.md +32 -0
- package/dist/index.js +52 -38
- package/dist/models/kubectl-models.d.ts +35 -0
- package/dist/models/kubectl-models.js +7 -0
- package/dist/models/response-schemas.d.ts +22 -0
- package/dist/models/response-schemas.js +3 -0
- package/dist/tools/get_events.d.ts +28 -0
- package/dist/tools/get_events.js +66 -0
- package/dist/tools/kubectl-operations.d.ts +72 -0
- package/dist/tools/kubectl-operations.js +124 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -6,6 +6,8 @@ https://github.com/user-attachments/assets/f25f8f4e-4d04-479b-9ae0-5dac452dd2ed
|
|
|
6
6
|
|
|
7
7
|
<a href="https://glama.ai/mcp/servers/w71ieamqrt"><img width="380" height="200" src="https://glama.ai/mcp/servers/w71ieamqrt/badge" /></a>
|
|
8
8
|
|
|
9
|
+
[](https://smithery.ai/server/mcp-server-kubernetes)
|
|
10
|
+
|
|
9
11
|
## Usage with Claude Desktop
|
|
10
12
|
|
|
11
13
|
```json
|
|
@@ -30,6 +32,28 @@ You can verify your connection by asking Claude to list your pods or create a te
|
|
|
30
32
|
|
|
31
33
|
If you have errors open up a standard terminal and run `kubectl get pods` to see if you can connect to your cluster without credentials issues.
|
|
32
34
|
|
|
35
|
+
## Usage with mcp-chat
|
|
36
|
+
|
|
37
|
+
[mcp-chat](https://github.com/Flux159/mcp-chat) is a CLI chat client for MCP servers. You can use it to interact with the Kubernetes server.
|
|
38
|
+
|
|
39
|
+
```shell
|
|
40
|
+
npx mcp-chat --server "npx mcp-server-kubernetes"
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Alternatively, pass it your existing Claude Desktop configuration file from above (Linux should pass the correct path to config):
|
|
44
|
+
|
|
45
|
+
Mac:
|
|
46
|
+
|
|
47
|
+
```shell
|
|
48
|
+
npx mcp-chat --config "~/Library/Application Support/Claude/claude_desktop_config.json"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Windows:
|
|
52
|
+
|
|
53
|
+
```shell
|
|
54
|
+
npx mcp-chat --config "%APPDATA%\Claude\claude_desktop_config.json"
|
|
55
|
+
```
|
|
56
|
+
|
|
33
57
|
## Features
|
|
34
58
|
|
|
35
59
|
- [x] Connect to a Kubernetes cluster
|
|
@@ -49,6 +73,8 @@ If you have errors open up a standard terminal and run `kubectl get pods` to see
|
|
|
49
73
|
- Support for namespaces
|
|
50
74
|
- Support for version specification
|
|
51
75
|
- Support for custom repositories
|
|
76
|
+
- [x] kubectl explain and kubectl api-resources support
|
|
77
|
+
- [x] Get Kubernetes events from the cluster
|
|
52
78
|
- [ ] Port forward to a pod
|
|
53
79
|
- [ ] Choose namespace for next commands (memory)
|
|
54
80
|
|
|
@@ -87,6 +113,12 @@ npx @modelcontextprotocol/inspector node build/index.js
|
|
|
87
113
|
# Follow further instructions on terminal for Inspector link
|
|
88
114
|
```
|
|
89
115
|
|
|
116
|
+
5. Local testing with [mcp-chat](https://github.com/Flux159/mcp-chat)
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
npm run chat
|
|
120
|
+
```
|
|
121
|
+
|
|
90
122
|
### Project Structure
|
|
91
123
|
|
|
92
124
|
```
|
package/dist/index.js
CHANGED
|
@@ -4,12 +4,14 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
4
4
|
import { listPods, listPodsSchema } from "./tools/list_pods.js";
|
|
5
5
|
import { listNodes, listNodesSchema } from "./tools/list_nodes.js";
|
|
6
6
|
import { listServices, listServicesSchema } from "./tools/list_services.js";
|
|
7
|
-
import { listDeployments, listDeploymentsSchema } from "./tools/list_deployments.js";
|
|
7
|
+
import { listDeployments, listDeploymentsSchema, } from "./tools/list_deployments.js";
|
|
8
8
|
import { installHelmChart, installHelmChartSchema, upgradeHelmChart, upgradeHelmChartSchema, uninstallHelmChart, uninstallHelmChartSchema, } from "./tools/helm-operations.js";
|
|
9
|
+
import { explainResource, explainResourceSchema, listApiResources, listApiResourcesSchema, } from "./tools/kubectl-operations.js";
|
|
9
10
|
import { createPod, createPodSchema } from "./tools/create_pod.js";
|
|
10
11
|
import { deletePod, deletePodSchema } from "./tools/delete_pod.js";
|
|
11
12
|
import { describePod, describePodSchema } from "./tools/describe_pod.js";
|
|
12
13
|
import { getLogs, getLogsSchema } from "./tools/get_logs.js";
|
|
14
|
+
import { getEvents, getEventsSchema } from "./tools/get_events.js";
|
|
13
15
|
import { getResourceHandlers } from "./resources/handlers.js";
|
|
14
16
|
import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
15
17
|
import { KubernetesManager } from "./types.js";
|
|
@@ -26,20 +28,23 @@ const server = new Server({
|
|
|
26
28
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
27
29
|
return {
|
|
28
30
|
tools: [
|
|
29
|
-
|
|
30
|
-
listDeploymentsSchema,
|
|
31
|
-
listServicesSchema,
|
|
32
|
-
listNamespacesSchema,
|
|
33
|
-
createPodSchema,
|
|
31
|
+
cleanupSchema,
|
|
34
32
|
createDeploymentSchema,
|
|
33
|
+
createPodSchema,
|
|
35
34
|
deletePodSchema,
|
|
36
35
|
describePodSchema,
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
explainResourceSchema,
|
|
37
|
+
getEventsSchema,
|
|
39
38
|
getLogsSchema,
|
|
40
39
|
installHelmChartSchema,
|
|
41
|
-
|
|
40
|
+
listApiResourcesSchema,
|
|
41
|
+
listDeploymentsSchema,
|
|
42
|
+
listNamespacesSchema,
|
|
43
|
+
listNodesSchema,
|
|
44
|
+
listPodsSchema,
|
|
45
|
+
listServicesSchema,
|
|
42
46
|
uninstallHelmChartSchema,
|
|
47
|
+
upgradeHelmChartSchema,
|
|
43
48
|
],
|
|
44
49
|
};
|
|
45
50
|
});
|
|
@@ -47,27 +52,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
47
52
|
try {
|
|
48
53
|
const { name, arguments: input = {} } = request.params;
|
|
49
54
|
switch (name) {
|
|
50
|
-
case "
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
case "list_deployments": {
|
|
54
|
-
return await listDeployments(k8sManager, input);
|
|
55
|
-
}
|
|
56
|
-
case "list_services": {
|
|
57
|
-
return await listServices(k8sManager, input);
|
|
58
|
-
}
|
|
59
|
-
case "list_namespaces": {
|
|
60
|
-
const { body } = await k8sManager.getCoreApi().listNamespace();
|
|
61
|
-
const namespaces = body.items.map((ns) => ({
|
|
62
|
-
name: ns.metadata?.name || "",
|
|
63
|
-
status: ns.status?.phase || "",
|
|
64
|
-
createdAt: ns.metadata?.creationTimestamp,
|
|
65
|
-
}));
|
|
55
|
+
case "cleanup": {
|
|
56
|
+
await k8sManager.cleanup();
|
|
66
57
|
return {
|
|
67
58
|
content: [
|
|
68
59
|
{
|
|
69
60
|
type: "text",
|
|
70
|
-
text: JSON.stringify({
|
|
61
|
+
text: JSON.stringify({
|
|
62
|
+
success: true,
|
|
63
|
+
}, null, 2),
|
|
71
64
|
},
|
|
72
65
|
],
|
|
73
66
|
};
|
|
@@ -81,15 +74,36 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
81
74
|
case "describe_pod": {
|
|
82
75
|
return await describePod(k8sManager, input);
|
|
83
76
|
}
|
|
84
|
-
case "
|
|
85
|
-
await
|
|
77
|
+
case "explain_resource": {
|
|
78
|
+
return await explainResource(input);
|
|
79
|
+
}
|
|
80
|
+
case "get_events": {
|
|
81
|
+
return await getEvents(k8sManager, input);
|
|
82
|
+
}
|
|
83
|
+
case "get_logs": {
|
|
84
|
+
return await getLogs(k8sManager, input);
|
|
85
|
+
}
|
|
86
|
+
case "install_helm_chart": {
|
|
87
|
+
return await installHelmChart(input);
|
|
88
|
+
}
|
|
89
|
+
case "list_api_resources": {
|
|
90
|
+
return await listApiResources(input);
|
|
91
|
+
}
|
|
92
|
+
case "list_deployments": {
|
|
93
|
+
return await listDeployments(k8sManager, input);
|
|
94
|
+
}
|
|
95
|
+
case "list_namespaces": {
|
|
96
|
+
const { body } = await k8sManager.getCoreApi().listNamespace();
|
|
97
|
+
const namespaces = body.items.map((ns) => ({
|
|
98
|
+
name: ns.metadata?.name || "",
|
|
99
|
+
status: ns.status?.phase || "",
|
|
100
|
+
createdAt: ns.metadata?.creationTimestamp,
|
|
101
|
+
}));
|
|
86
102
|
return {
|
|
87
103
|
content: [
|
|
88
104
|
{
|
|
89
105
|
type: "text",
|
|
90
|
-
text: JSON.stringify({
|
|
91
|
-
success: true,
|
|
92
|
-
}, null, 2),
|
|
106
|
+
text: JSON.stringify({ namespaces }, null, 2),
|
|
93
107
|
},
|
|
94
108
|
],
|
|
95
109
|
};
|
|
@@ -97,18 +111,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
97
111
|
case "list_nodes": {
|
|
98
112
|
return await listNodes(k8sManager);
|
|
99
113
|
}
|
|
100
|
-
case "
|
|
101
|
-
return await
|
|
102
|
-
}
|
|
103
|
-
case "install_helm_chart": {
|
|
104
|
-
return await installHelmChart(input);
|
|
114
|
+
case "list_pods": {
|
|
115
|
+
return await listPods(k8sManager, input);
|
|
105
116
|
}
|
|
106
|
-
case "
|
|
107
|
-
return await
|
|
117
|
+
case "list_services": {
|
|
118
|
+
return await listServices(k8sManager, input);
|
|
108
119
|
}
|
|
109
120
|
case "uninstall_helm_chart": {
|
|
110
121
|
return await uninstallHelmChart(input);
|
|
111
122
|
}
|
|
123
|
+
case "upgrade_helm_chart": {
|
|
124
|
+
return await upgradeHelmChart(input);
|
|
125
|
+
}
|
|
112
126
|
default:
|
|
113
127
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown tool: ${name}`);
|
|
114
128
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const KubectlResponseSchema: z.ZodObject<{
|
|
3
|
+
content: z.ZodArray<z.ZodObject<{
|
|
4
|
+
type: z.ZodLiteral<"text">;
|
|
5
|
+
text: z.ZodString;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
type: "text";
|
|
8
|
+
text: string;
|
|
9
|
+
}, {
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}>, "many">;
|
|
13
|
+
}, "strip", z.ZodTypeAny, {
|
|
14
|
+
content: {
|
|
15
|
+
type: "text";
|
|
16
|
+
text: string;
|
|
17
|
+
}[];
|
|
18
|
+
}, {
|
|
19
|
+
content: {
|
|
20
|
+
type: "text";
|
|
21
|
+
text: string;
|
|
22
|
+
}[];
|
|
23
|
+
}>;
|
|
24
|
+
export interface ExplainResourceParams {
|
|
25
|
+
resource: string;
|
|
26
|
+
apiVersion?: string;
|
|
27
|
+
recursive?: boolean;
|
|
28
|
+
output?: "plaintext" | "plaintext-openapiv2";
|
|
29
|
+
}
|
|
30
|
+
export interface ListApiResourcesParams {
|
|
31
|
+
apiGroup?: string;
|
|
32
|
+
namespaced?: boolean;
|
|
33
|
+
verbs?: string[];
|
|
34
|
+
output?: "wide" | "name" | "no-headers";
|
|
35
|
+
}
|
|
@@ -219,3 +219,25 @@ export declare const GetLogsResponseSchema: z.ZodObject<{
|
|
|
219
219
|
text: string;
|
|
220
220
|
}[];
|
|
221
221
|
}>;
|
|
222
|
+
export declare const GetEventsResponseSchema: z.ZodObject<{
|
|
223
|
+
content: z.ZodArray<z.ZodObject<{
|
|
224
|
+
type: z.ZodLiteral<"text">;
|
|
225
|
+
text: z.ZodString;
|
|
226
|
+
}, "strip", z.ZodTypeAny, {
|
|
227
|
+
type: "text";
|
|
228
|
+
text: string;
|
|
229
|
+
}, {
|
|
230
|
+
type: "text";
|
|
231
|
+
text: string;
|
|
232
|
+
}>, "many">;
|
|
233
|
+
}, "strip", z.ZodTypeAny, {
|
|
234
|
+
content: {
|
|
235
|
+
type: "text";
|
|
236
|
+
text: string;
|
|
237
|
+
}[];
|
|
238
|
+
}, {
|
|
239
|
+
content: {
|
|
240
|
+
type: "text";
|
|
241
|
+
text: string;
|
|
242
|
+
}[];
|
|
243
|
+
}>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const getEventsSchema: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
namespace: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
fieldSelector: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
required: never[];
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export declare function getEvents(k8sManager: KubernetesManager, params: {
|
|
21
|
+
namespace?: string;
|
|
22
|
+
fieldSelector?: string;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
content: {
|
|
25
|
+
type: string;
|
|
26
|
+
text: string;
|
|
27
|
+
}[];
|
|
28
|
+
}>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
export const getEventsSchema = {
|
|
2
|
+
name: "get_events",
|
|
3
|
+
description: "Get Kubernetes events from the cluster",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
namespace: {
|
|
8
|
+
type: "string",
|
|
9
|
+
description: "Namespace to get events from. If not specified, gets events from all namespaces",
|
|
10
|
+
},
|
|
11
|
+
fieldSelector: {
|
|
12
|
+
type: "string",
|
|
13
|
+
description: "Field selector to filter events",
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
required: [],
|
|
17
|
+
},
|
|
18
|
+
};
|
|
19
|
+
export async function getEvents(k8sManager, params) {
|
|
20
|
+
const { namespace, fieldSelector } = params;
|
|
21
|
+
const api = k8sManager.getCoreApi();
|
|
22
|
+
let events;
|
|
23
|
+
if (namespace) {
|
|
24
|
+
const { body } = await api.listNamespacedEvent(namespace, undefined, // pretty
|
|
25
|
+
undefined, // allowWatchBookmarks
|
|
26
|
+
undefined, // _continue
|
|
27
|
+
undefined, // fieldSelector
|
|
28
|
+
fieldSelector // fieldSelector
|
|
29
|
+
);
|
|
30
|
+
events = body;
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
const { body } = await api.listEventForAllNamespaces(undefined, // allowWatchBookmarks
|
|
34
|
+
undefined, // _continue
|
|
35
|
+
fieldSelector, // fieldSelector
|
|
36
|
+
undefined, // labelSelector
|
|
37
|
+
undefined, // limit
|
|
38
|
+
undefined, // pretty
|
|
39
|
+
undefined, // resourceVersion
|
|
40
|
+
undefined, // resourceVersionMatch
|
|
41
|
+
undefined // timeoutSeconds
|
|
42
|
+
);
|
|
43
|
+
events = body;
|
|
44
|
+
}
|
|
45
|
+
const formattedEvents = events.items.map((event) => ({
|
|
46
|
+
type: event.type || "",
|
|
47
|
+
reason: event.reason || "",
|
|
48
|
+
message: event.message || "",
|
|
49
|
+
involvedObject: {
|
|
50
|
+
kind: event.involvedObject.kind || "",
|
|
51
|
+
name: event.involvedObject.name || "",
|
|
52
|
+
namespace: event.involvedObject.namespace || "",
|
|
53
|
+
},
|
|
54
|
+
firstTimestamp: event.firstTimestamp || "",
|
|
55
|
+
lastTimestamp: event.lastTimestamp || "",
|
|
56
|
+
count: event.count || 0,
|
|
57
|
+
}));
|
|
58
|
+
return {
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
61
|
+
type: "text",
|
|
62
|
+
text: JSON.stringify({ events: formattedEvents }, null, 2),
|
|
63
|
+
},
|
|
64
|
+
],
|
|
65
|
+
};
|
|
66
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { ExplainResourceParams, ListApiResourcesParams } from "../models/kubectl-models.js";
|
|
2
|
+
export declare const explainResourceSchema: {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: string;
|
|
7
|
+
properties: {
|
|
8
|
+
resource: {
|
|
9
|
+
type: string;
|
|
10
|
+
description: string;
|
|
11
|
+
};
|
|
12
|
+
apiVersion: {
|
|
13
|
+
type: string;
|
|
14
|
+
description: string;
|
|
15
|
+
};
|
|
16
|
+
recursive: {
|
|
17
|
+
type: string;
|
|
18
|
+
description: string;
|
|
19
|
+
default: boolean;
|
|
20
|
+
};
|
|
21
|
+
output: {
|
|
22
|
+
type: string;
|
|
23
|
+
description: string;
|
|
24
|
+
enum: string[];
|
|
25
|
+
default: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
required: string[];
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
export declare const listApiResourcesSchema: {
|
|
32
|
+
name: string;
|
|
33
|
+
description: string;
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: string;
|
|
36
|
+
properties: {
|
|
37
|
+
apiGroup: {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
};
|
|
41
|
+
namespaced: {
|
|
42
|
+
type: string;
|
|
43
|
+
description: string;
|
|
44
|
+
};
|
|
45
|
+
verbs: {
|
|
46
|
+
type: string;
|
|
47
|
+
items: {
|
|
48
|
+
type: string;
|
|
49
|
+
};
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
output: {
|
|
53
|
+
type: string;
|
|
54
|
+
description: string;
|
|
55
|
+
enum: string[];
|
|
56
|
+
default: string;
|
|
57
|
+
};
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
export declare function explainResource(params: ExplainResourceParams): Promise<{
|
|
62
|
+
content: {
|
|
63
|
+
type: string;
|
|
64
|
+
text: string;
|
|
65
|
+
}[];
|
|
66
|
+
}>;
|
|
67
|
+
export declare function listApiResources(params: ListApiResourcesParams): Promise<{
|
|
68
|
+
content: {
|
|
69
|
+
type: string;
|
|
70
|
+
text: string;
|
|
71
|
+
}[];
|
|
72
|
+
}>;
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { execSync } from "child_process";
|
|
2
|
+
export const explainResourceSchema = {
|
|
3
|
+
name: "explain_resource",
|
|
4
|
+
description: "Get documentation for a Kubernetes resource or field",
|
|
5
|
+
inputSchema: {
|
|
6
|
+
type: "object",
|
|
7
|
+
properties: {
|
|
8
|
+
resource: {
|
|
9
|
+
type: "string",
|
|
10
|
+
description: "Resource name or field path (e.g. 'pods' or 'pods.spec.containers')",
|
|
11
|
+
},
|
|
12
|
+
apiVersion: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "API version to use (e.g. 'apps/v1')",
|
|
15
|
+
},
|
|
16
|
+
recursive: {
|
|
17
|
+
type: "boolean",
|
|
18
|
+
description: "Print the fields of fields recursively",
|
|
19
|
+
default: false,
|
|
20
|
+
},
|
|
21
|
+
output: {
|
|
22
|
+
type: "string",
|
|
23
|
+
description: "Output format (plaintext or plaintext-openapiv2)",
|
|
24
|
+
enum: ["plaintext", "plaintext-openapiv2"],
|
|
25
|
+
default: "plaintext",
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
required: ["resource"],
|
|
29
|
+
},
|
|
30
|
+
};
|
|
31
|
+
export const listApiResourcesSchema = {
|
|
32
|
+
name: "list_api_resources",
|
|
33
|
+
description: "List the API resources available in the cluster",
|
|
34
|
+
inputSchema: {
|
|
35
|
+
type: "object",
|
|
36
|
+
properties: {
|
|
37
|
+
apiGroup: {
|
|
38
|
+
type: "string",
|
|
39
|
+
description: "API group to filter by",
|
|
40
|
+
},
|
|
41
|
+
namespaced: {
|
|
42
|
+
type: "boolean",
|
|
43
|
+
description: "If true, only show namespaced resources",
|
|
44
|
+
},
|
|
45
|
+
verbs: {
|
|
46
|
+
type: "array",
|
|
47
|
+
items: {
|
|
48
|
+
type: "string",
|
|
49
|
+
},
|
|
50
|
+
description: "List of verbs to filter by",
|
|
51
|
+
},
|
|
52
|
+
output: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "Output format (wide, name, or no-headers)",
|
|
55
|
+
enum: ["wide", "name", "no-headers"],
|
|
56
|
+
default: "wide",
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
const executeKubectlCommand = (command) => {
|
|
62
|
+
try {
|
|
63
|
+
return execSync(command, { encoding: "utf8" });
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
throw new Error(`Kubectl command failed: ${error.message}`);
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
export async function explainResource(params) {
|
|
70
|
+
try {
|
|
71
|
+
let command = "kubectl explain";
|
|
72
|
+
if (params.apiVersion) {
|
|
73
|
+
command += ` --api-version=${params.apiVersion}`;
|
|
74
|
+
}
|
|
75
|
+
if (params.recursive) {
|
|
76
|
+
command += " --recursive";
|
|
77
|
+
}
|
|
78
|
+
if (params.output) {
|
|
79
|
+
command += ` --output=${params.output}`;
|
|
80
|
+
}
|
|
81
|
+
command += ` ${params.resource}`;
|
|
82
|
+
const result = executeKubectlCommand(command);
|
|
83
|
+
return {
|
|
84
|
+
content: [
|
|
85
|
+
{
|
|
86
|
+
type: "text",
|
|
87
|
+
text: result,
|
|
88
|
+
},
|
|
89
|
+
],
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
catch (error) {
|
|
93
|
+
throw new Error(`Failed to explain resource: ${error.message}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
export async function listApiResources(params) {
|
|
97
|
+
try {
|
|
98
|
+
let command = "kubectl api-resources";
|
|
99
|
+
if (params.apiGroup) {
|
|
100
|
+
command += ` --api-group=${params.apiGroup}`;
|
|
101
|
+
}
|
|
102
|
+
if (params.namespaced !== undefined) {
|
|
103
|
+
command += ` --namespaced=${params.namespaced}`;
|
|
104
|
+
}
|
|
105
|
+
if (params.verbs && params.verbs.length > 0) {
|
|
106
|
+
command += ` --verbs=${params.verbs.join(",")}`;
|
|
107
|
+
}
|
|
108
|
+
if (params.output) {
|
|
109
|
+
command += ` -o ${params.output}`;
|
|
110
|
+
}
|
|
111
|
+
const result = executeKubectlCommand(command);
|
|
112
|
+
return {
|
|
113
|
+
content: [
|
|
114
|
+
{
|
|
115
|
+
type: "text",
|
|
116
|
+
text: result,
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
throw new Error(`Failed to list API resources: ${error.message}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "mcp-server-kubernetes",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "MCP server for interacting with Kubernetes clusters via kubectl",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,7 +21,8 @@
|
|
|
21
21
|
"start": "node dist/index.js",
|
|
22
22
|
"test": "vitest run",
|
|
23
23
|
"prepublishOnly": "npm run build",
|
|
24
|
-
"dockerbuild": "docker buildx build -t flux159/mcp-server-kubernetes --platform linux/amd64,linux/arm64 --push ."
|
|
24
|
+
"dockerbuild": "docker buildx build -t flux159/mcp-server-kubernetes --platform linux/amd64,linux/arm64 --push .",
|
|
25
|
+
"chat": "npx mcp-chat --server \"./dist/index.js\""
|
|
25
26
|
},
|
|
26
27
|
"keywords": [
|
|
27
28
|
"mcp",
|