mcp-server-kubernetes 0.2.4 → 0.3.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
CHANGED
|
@@ -49,6 +49,7 @@ If you have errors open up a standard terminal and run `kubectl get pods` to see
|
|
|
49
49
|
- Support for namespaces
|
|
50
50
|
- Support for version specification
|
|
51
51
|
- Support for custom repositories
|
|
52
|
+
- [x] kubectl explain and kubectl api-resources support
|
|
52
53
|
- [ ] Port forward to a pod
|
|
53
54
|
- [ ] Choose namespace for next commands (memory)
|
|
54
55
|
|
|
@@ -168,6 +169,12 @@ sequenceDiagram
|
|
|
168
169
|
Transport-->>Client: Return Final Response
|
|
169
170
|
```
|
|
170
171
|
|
|
172
|
+
## Publishing new release
|
|
173
|
+
|
|
174
|
+
Go to the [releases page](https://github.com/Flux159/mcp-server-kubernetes/releases), click on "Draft New Release", click "Choose a tag" and create a new tag by typing out a new version number using "v{major}.{minor}.{patch}" semver format. Then, write a release title "Release v{major}.{minor}.{patch}" and description / changelog if necessary and click "Publish Release".
|
|
175
|
+
|
|
176
|
+
This will create a new tag which will trigger a new release build via the cd.yml workflow. Once successful, the new release will be published to [npm](https://www.npmjs.com/package/mcp-server-kubernetes). Note that there is no need to update the package.json version manually, as the workflow will automatically update the version number in the package.json file & push a commit to main.
|
|
177
|
+
|
|
171
178
|
## Not planned
|
|
172
179
|
|
|
173
180
|
Authentication / adding clusters to kubectx.
|
package/dist/index.js
CHANGED
|
@@ -4,8 +4,9 @@ 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";
|
|
@@ -40,6 +41,8 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
40
41
|
installHelmChartSchema,
|
|
41
42
|
upgradeHelmChartSchema,
|
|
42
43
|
uninstallHelmChartSchema,
|
|
44
|
+
explainResourceSchema,
|
|
45
|
+
listApiResourcesSchema,
|
|
43
46
|
],
|
|
44
47
|
};
|
|
45
48
|
});
|
|
@@ -109,6 +112,12 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
109
112
|
case "uninstall_helm_chart": {
|
|
110
113
|
return await uninstallHelmChart(input);
|
|
111
114
|
}
|
|
115
|
+
case "explain_resource": {
|
|
116
|
+
return await explainResource(input);
|
|
117
|
+
}
|
|
118
|
+
case "list_api_resources": {
|
|
119
|
+
return await listApiResources(input);
|
|
120
|
+
}
|
|
112
121
|
default:
|
|
113
122
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown tool: ${name}`);
|
|
114
123
|
}
|
|
@@ -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
|
+
}
|
|
@@ -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
|
+
}
|