mcp-server-kubernetes 1.6.2 → 2.0.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/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
package/dist/index.js
CHANGED
|
@@ -1,111 +1,75 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
3
3
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
4
|
-
import { listPods, listPodsSchema } from "./tools/list_pods.js";
|
|
5
|
-
import { listNodes, listNodesSchema } from "./tools/list_nodes.js";
|
|
6
|
-
import { listServices, listServicesSchema } from "./tools/list_services.js";
|
|
7
|
-
import { listDeployments, listDeploymentsSchema, } from "./tools/list_deployments.js";
|
|
8
|
-
import { listCronJobs, listCronJobsSchema } from "./tools/list_cronjobs.js";
|
|
9
|
-
import { describeCronJob, describeCronJobSchema, } from "./tools/describe_cronjob.js";
|
|
10
|
-
import { listJobs, listJobsSchema } from "./tools/list_jobs.js";
|
|
11
|
-
import { getJobLogs, getJobLogsSchema } from "./tools/get_job_logs.js";
|
|
12
|
-
import { describeNode, describeNodeSchema } from "./tools/describe_node.js";
|
|
13
4
|
import { installHelmChart, installHelmChartSchema, upgradeHelmChart, upgradeHelmChartSchema, uninstallHelmChart, uninstallHelmChartSchema, } from "./tools/helm-operations.js";
|
|
14
5
|
import { explainResource, explainResourceSchema, listApiResources, listApiResourcesSchema, } from "./tools/kubectl-operations.js";
|
|
15
|
-
import { createNamespace, createNamespaceSchema, } from "./tools/create_namespace.js";
|
|
16
|
-
import { createPod, createPodSchema } from "./tools/create_pod.js";
|
|
17
|
-
import { createCronJob, createCronJobSchema } from "./tools/create_cronjob.js";
|
|
18
|
-
import { DeleteCronJob, DeleteCronJobSchema } from "./tools/delete_cronjob.js";
|
|
19
|
-
import { deletePod, deletePodSchema } from "./tools/delete_pod.js";
|
|
20
|
-
import { describePod, describePodSchema } from "./tools/describe_pod.js";
|
|
21
|
-
import { getLogs, getLogsSchema } from "./tools/get_logs.js";
|
|
22
|
-
import { getEvents, getEventsSchema } from "./tools/get_events.js";
|
|
23
6
|
import { getResourceHandlers } from "./resources/handlers.js";
|
|
24
7
|
import { ListResourcesRequestSchema, ReadResourceRequestSchema, ListToolsRequestSchema, CallToolRequestSchema, ErrorCode, McpError, } from "@modelcontextprotocol/sdk/types.js";
|
|
25
8
|
import { KubernetesManager } from "./types.js";
|
|
26
9
|
import { serverConfig } from "./config/server-config.js";
|
|
27
|
-
import { createDeploymentSchema } from "./config/deployment-config.js";
|
|
28
|
-
import { listNamespacesSchema } from "./config/namespace-config.js";
|
|
29
|
-
import { deleteNamespace, deleteNamespaceSchema, } from "./tools/delete_namespace.js";
|
|
30
10
|
import { cleanupSchema } from "./config/cleanup-config.js";
|
|
31
11
|
import { startSSEServer } from "./utils/sse.js";
|
|
32
12
|
import { startPortForward, PortForwardSchema, stopPortForward, StopPortForwardSchema, } from "./tools/port_forward.js";
|
|
33
|
-
import {
|
|
34
|
-
import {
|
|
35
|
-
import {
|
|
36
|
-
import {
|
|
37
|
-
import {
|
|
38
|
-
import {
|
|
39
|
-
import {
|
|
40
|
-
import {
|
|
41
|
-
import {
|
|
42
|
-
import {
|
|
43
|
-
import {
|
|
44
|
-
import {
|
|
45
|
-
import { createService, createServiceSchema } from "./tools/create_service.js";
|
|
46
|
-
import { describeService, describeServiceSchema, } from "./tools/describe_service.js";
|
|
47
|
-
import { updateService, updateServiceSchema } from "./tools/update_service.js";
|
|
48
|
-
import { deleteService, deleteServiceSchema } from "./tools/delete_service.js";
|
|
13
|
+
import { kubectlScale, kubectlScaleSchema } from "./tools/kubectl-scale.js";
|
|
14
|
+
import { kubectlContext, kubectlContextSchema } from "./tools/kubectl-context.js";
|
|
15
|
+
import { kubectlGet, kubectlGetSchema } from "./tools/kubectl-get.js";
|
|
16
|
+
import { kubectlDescribe, kubectlDescribeSchema } from "./tools/kubectl-describe.js";
|
|
17
|
+
import { kubectlList, kubectlListSchema } from "./tools/kubectl-list.js";
|
|
18
|
+
import { kubectlApply, kubectlApplySchema } from "./tools/kubectl-apply.js";
|
|
19
|
+
import { kubectlDelete, kubectlDeleteSchema } from "./tools/kubectl-delete.js";
|
|
20
|
+
import { kubectlCreate, kubectlCreateSchema } from "./tools/kubectl-create.js";
|
|
21
|
+
import { kubectlLogs, kubectlLogsSchema } from "./tools/kubectl-logs.js";
|
|
22
|
+
import { kubectlGeneric, kubectlGenericSchema } from "./tools/kubectl-generic.js";
|
|
23
|
+
import { kubectlPatch, kubectlPatchSchema } from "./tools/kubectl-patch.js";
|
|
24
|
+
import { kubectlRollout, kubectlRolloutSchema } from "./tools/kubectl-rollout.js";
|
|
49
25
|
// Check if non-destructive tools only mode is enabled
|
|
50
26
|
const nonDestructiveTools = process.env.ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS === "true";
|
|
51
27
|
// Define destructive tools (delete and uninstall operations)
|
|
52
28
|
const destructiveTools = [
|
|
53
|
-
|
|
54
|
-
deleteServiceSchema,
|
|
55
|
-
deleteDeploymentSchema,
|
|
56
|
-
deleteNamespaceSchema,
|
|
29
|
+
kubectlDeleteSchema, // This replaces all individual delete operations
|
|
57
30
|
uninstallHelmChartSchema,
|
|
58
|
-
DeleteCronJobSchema,
|
|
59
31
|
cleanupSchema, // Cleanup is also destructive as it deletes resources
|
|
60
32
|
];
|
|
61
33
|
// Get all available tools
|
|
62
34
|
const allTools = [
|
|
35
|
+
// Core operation tools
|
|
63
36
|
cleanupSchema,
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
37
|
+
// Unified kubectl-style tools - these replace many specific tools
|
|
38
|
+
kubectlGetSchema,
|
|
39
|
+
kubectlDescribeSchema,
|
|
40
|
+
kubectlListSchema,
|
|
41
|
+
kubectlApplySchema,
|
|
42
|
+
kubectlDeleteSchema,
|
|
43
|
+
kubectlCreateSchema,
|
|
44
|
+
kubectlLogsSchema,
|
|
45
|
+
kubectlScaleSchema,
|
|
46
|
+
kubectlPatchSchema,
|
|
47
|
+
kubectlRolloutSchema,
|
|
48
|
+
// Kubernetes context management
|
|
49
|
+
kubectlContextSchema,
|
|
50
|
+
// Special operations that aren't covered by simple kubectl commands
|
|
78
51
|
explainResourceSchema,
|
|
79
|
-
|
|
80
|
-
getJobLogsSchema,
|
|
81
|
-
getLogsSchema,
|
|
52
|
+
// Helm operations
|
|
82
53
|
installHelmChartSchema,
|
|
83
|
-
listApiResourcesSchema,
|
|
84
|
-
listCronJobsSchema,
|
|
85
|
-
listContextsSchema,
|
|
86
|
-
getCurrentContextSchema,
|
|
87
|
-
setCurrentContextSchema,
|
|
88
|
-
listDeploymentsSchema,
|
|
89
|
-
listJobsSchema,
|
|
90
|
-
listNamespacesSchema,
|
|
91
|
-
listNodesSchema,
|
|
92
|
-
listPodsSchema,
|
|
93
|
-
listServicesSchema,
|
|
94
|
-
uninstallHelmChartSchema,
|
|
95
|
-
updateDeploymentSchema,
|
|
96
54
|
upgradeHelmChartSchema,
|
|
55
|
+
uninstallHelmChartSchema,
|
|
56
|
+
// Port forwarding
|
|
97
57
|
PortForwardSchema,
|
|
98
58
|
StopPortForwardSchema,
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
59
|
+
// API resource operations
|
|
60
|
+
listApiResourcesSchema,
|
|
61
|
+
// Generic kubectl command
|
|
62
|
+
kubectlGenericSchema,
|
|
103
63
|
];
|
|
104
64
|
const k8sManager = new KubernetesManager();
|
|
105
65
|
const server = new Server({
|
|
106
66
|
name: serverConfig.name,
|
|
107
67
|
version: serverConfig.version,
|
|
108
68
|
}, serverConfig);
|
|
69
|
+
// Resources handlers
|
|
70
|
+
const resourceHandlers = getResourceHandlers(k8sManager);
|
|
71
|
+
server.setRequestHandler(ListResourcesRequestSchema, resourceHandlers.listResources);
|
|
72
|
+
server.setRequestHandler(ReadResourceRequestSchema, resourceHandlers.readResource);
|
|
109
73
|
// Tools handlers
|
|
110
74
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
111
75
|
// Filter out destructive tools if ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS is set to 'true'
|
|
@@ -117,6 +81,51 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
|
117
81
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
118
82
|
try {
|
|
119
83
|
const { name, arguments: input = {} } = request.params;
|
|
84
|
+
// Handle new kubectl-style commands
|
|
85
|
+
if (name === "kubectl_context") {
|
|
86
|
+
return await kubectlContext(k8sManager, input);
|
|
87
|
+
}
|
|
88
|
+
if (name === "kubectl_get") {
|
|
89
|
+
return await kubectlGet(k8sManager, input);
|
|
90
|
+
}
|
|
91
|
+
if (name === "kubectl_describe") {
|
|
92
|
+
return await kubectlDescribe(k8sManager, input);
|
|
93
|
+
}
|
|
94
|
+
if (name === "kubectl_list") {
|
|
95
|
+
return await kubectlList(k8sManager, input);
|
|
96
|
+
}
|
|
97
|
+
if (name === "kubectl_apply") {
|
|
98
|
+
return await kubectlApply(k8sManager, input);
|
|
99
|
+
}
|
|
100
|
+
if (name === "kubectl_delete") {
|
|
101
|
+
return await kubectlDelete(k8sManager, input);
|
|
102
|
+
}
|
|
103
|
+
if (name === "kubectl_create") {
|
|
104
|
+
return await kubectlCreate(k8sManager, input);
|
|
105
|
+
}
|
|
106
|
+
if (name === "kubectl_logs") {
|
|
107
|
+
return await kubectlLogs(k8sManager, input);
|
|
108
|
+
}
|
|
109
|
+
if (name === "kubectl_patch") {
|
|
110
|
+
return await kubectlPatch(k8sManager, input);
|
|
111
|
+
}
|
|
112
|
+
if (name === "kubectl_rollout") {
|
|
113
|
+
return await kubectlRollout(k8sManager, input);
|
|
114
|
+
}
|
|
115
|
+
if (name === "kubectl_generic") {
|
|
116
|
+
return await kubectlGeneric(k8sManager, input);
|
|
117
|
+
}
|
|
118
|
+
if (name === "kubectl_events") {
|
|
119
|
+
return await kubectlGet(k8sManager, {
|
|
120
|
+
resourceType: "events",
|
|
121
|
+
namespace: input.namespace,
|
|
122
|
+
fieldSelector: input.fieldSelector,
|
|
123
|
+
labelSelector: input.labelSelector,
|
|
124
|
+
sortBy: input.sortBy,
|
|
125
|
+
output: input.output
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
// Handle specific non-kubectl operations
|
|
120
129
|
switch (name) {
|
|
121
130
|
case "cleanup": {
|
|
122
131
|
await k8sManager.cleanup();
|
|
@@ -131,144 +140,29 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
131
140
|
],
|
|
132
141
|
};
|
|
133
142
|
}
|
|
134
|
-
case "create_namespace": {
|
|
135
|
-
return await createNamespace(k8sManager, input);
|
|
136
|
-
}
|
|
137
|
-
case "create_pod": {
|
|
138
|
-
return await createPod(k8sManager, input);
|
|
139
|
-
}
|
|
140
|
-
case "create_cronjob": {
|
|
141
|
-
return await createCronJob(k8sManager, input);
|
|
142
|
-
}
|
|
143
|
-
case "delete_cronjob": {
|
|
144
|
-
return await DeleteCronJob(k8sManager, input);
|
|
145
|
-
}
|
|
146
|
-
case "delete_pod": {
|
|
147
|
-
return await deletePod(k8sManager, input);
|
|
148
|
-
}
|
|
149
|
-
case "describe_pod": {
|
|
150
|
-
return await describePod(k8sManager, input);
|
|
151
|
-
}
|
|
152
|
-
case "describe_node": {
|
|
153
|
-
return await describeNode(k8sManager, input);
|
|
154
|
-
}
|
|
155
143
|
case "explain_resource": {
|
|
156
144
|
return await explainResource(input);
|
|
157
145
|
}
|
|
158
|
-
case "get_events": {
|
|
159
|
-
return await getEvents(k8sManager, input);
|
|
160
|
-
}
|
|
161
|
-
case "get_logs": {
|
|
162
|
-
return await getLogs(k8sManager, input);
|
|
163
|
-
}
|
|
164
146
|
case "install_helm_chart": {
|
|
165
147
|
return await installHelmChart(input);
|
|
166
148
|
}
|
|
167
|
-
case "list_api_resources": {
|
|
168
|
-
return await listApiResources(input);
|
|
169
|
-
}
|
|
170
|
-
case "list_deployments": {
|
|
171
|
-
return await listDeployments(k8sManager, input);
|
|
172
|
-
}
|
|
173
|
-
case "list_namespaces": {
|
|
174
|
-
const { body } = await k8sManager.getCoreApi().listNamespace();
|
|
175
|
-
const namespaces = body.items.map((ns) => ({
|
|
176
|
-
name: ns.metadata?.name || "",
|
|
177
|
-
status: ns.status?.phase || "",
|
|
178
|
-
createdAt: ns.metadata?.creationTimestamp,
|
|
179
|
-
}));
|
|
180
|
-
return {
|
|
181
|
-
content: [
|
|
182
|
-
{
|
|
183
|
-
type: "text",
|
|
184
|
-
text: JSON.stringify({ namespaces }, null, 2),
|
|
185
|
-
},
|
|
186
|
-
],
|
|
187
|
-
};
|
|
188
|
-
}
|
|
189
|
-
case "list_nodes": {
|
|
190
|
-
return await listNodes(k8sManager);
|
|
191
|
-
}
|
|
192
|
-
case "list_pods": {
|
|
193
|
-
return await listPods(k8sManager, input);
|
|
194
|
-
}
|
|
195
|
-
case "list_services": {
|
|
196
|
-
return await listServices(k8sManager, input);
|
|
197
|
-
}
|
|
198
|
-
case "list_cronjobs": {
|
|
199
|
-
return await listCronJobs(k8sManager, input);
|
|
200
|
-
}
|
|
201
|
-
case "list_contexts": {
|
|
202
|
-
return await listContexts(k8sManager, input);
|
|
203
|
-
}
|
|
204
|
-
case "get_current_context": {
|
|
205
|
-
return await getCurrentContext(k8sManager, input);
|
|
206
|
-
}
|
|
207
|
-
case "set_current_context": {
|
|
208
|
-
return await setCurrentContext(k8sManager, input);
|
|
209
|
-
}
|
|
210
|
-
case "describe_cronjob": {
|
|
211
|
-
return await describeCronJob(k8sManager, input);
|
|
212
|
-
}
|
|
213
|
-
case "list_jobs": {
|
|
214
|
-
return await listJobs(k8sManager, input);
|
|
215
|
-
}
|
|
216
|
-
case "get_job_logs": {
|
|
217
|
-
return await getJobLogs(k8sManager, input);
|
|
218
|
-
}
|
|
219
149
|
case "uninstall_helm_chart": {
|
|
220
150
|
return await uninstallHelmChart(input);
|
|
221
151
|
}
|
|
222
152
|
case "upgrade_helm_chart": {
|
|
223
153
|
return await upgradeHelmChart(input);
|
|
224
154
|
}
|
|
155
|
+
case "list_api_resources": {
|
|
156
|
+
return await listApiResources(input);
|
|
157
|
+
}
|
|
225
158
|
case "port_forward": {
|
|
226
159
|
return await startPortForward(k8sManager, input);
|
|
227
160
|
}
|
|
228
161
|
case "stop_port_forward": {
|
|
229
162
|
return await stopPortForward(k8sManager, input);
|
|
230
163
|
}
|
|
231
|
-
case "
|
|
232
|
-
return await
|
|
233
|
-
}
|
|
234
|
-
case "delete_deployment": {
|
|
235
|
-
return await deleteDeployment(k8sManager, input);
|
|
236
|
-
}
|
|
237
|
-
case "create_deployment": {
|
|
238
|
-
return await createDeployment(k8sManager, input);
|
|
239
|
-
}
|
|
240
|
-
case "update_deployment": {
|
|
241
|
-
return await updateDeployment(k8sManager, input);
|
|
242
|
-
}
|
|
243
|
-
case "describe_deployment": {
|
|
244
|
-
return await describeDeployment(k8sManager, input);
|
|
245
|
-
}
|
|
246
|
-
case "scale_deployment": {
|
|
247
|
-
return await scaleDeployment(k8sManager, input);
|
|
248
|
-
}
|
|
249
|
-
case "create_configmap": {
|
|
250
|
-
return await createConfigMap(k8sManager, input);
|
|
251
|
-
}
|
|
252
|
-
case "get_configmap": {
|
|
253
|
-
return await getConfigMap(k8sManager, input);
|
|
254
|
-
}
|
|
255
|
-
case "update_configmap": {
|
|
256
|
-
return await updateConfigMap(k8sManager, input);
|
|
257
|
-
}
|
|
258
|
-
case "delete_configmap": {
|
|
259
|
-
return await deleteConfigMap(k8sManager, input);
|
|
260
|
-
}
|
|
261
|
-
case "create_service": {
|
|
262
|
-
return await createService(k8sManager, input);
|
|
263
|
-
}
|
|
264
|
-
case "update_service": {
|
|
265
|
-
return await updateService(k8sManager, input);
|
|
266
|
-
}
|
|
267
|
-
case "delete_service": {
|
|
268
|
-
return await deleteService(k8sManager, input);
|
|
269
|
-
}
|
|
270
|
-
case "describe_service": {
|
|
271
|
-
return await describeService(k8sManager, input);
|
|
164
|
+
case "kubectl_scale": {
|
|
165
|
+
return await kubectlScale(k8sManager, input);
|
|
272
166
|
}
|
|
273
167
|
default:
|
|
274
168
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown tool: ${name}`);
|
|
@@ -280,16 +174,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
280
174
|
throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${error}`);
|
|
281
175
|
}
|
|
282
176
|
});
|
|
283
|
-
//
|
|
284
|
-
const resourceHandlers = getResourceHandlers(k8sManager);
|
|
285
|
-
server.setRequestHandler(ListResourcesRequestSchema, resourceHandlers.listResources);
|
|
286
|
-
server.setRequestHandler(ReadResourceRequestSchema, resourceHandlers.readResource);
|
|
177
|
+
// Start the server
|
|
287
178
|
if (process.env.ENABLE_UNSAFE_SSE_TRANSPORT) {
|
|
288
179
|
startSSEServer(server);
|
|
180
|
+
console.log(`SSE server started`);
|
|
289
181
|
}
|
|
290
182
|
else {
|
|
291
183
|
const transport = new StdioServerTransport();
|
|
292
|
-
|
|
184
|
+
console.log(`Starting Kubernetes MCP server v${serverConfig.version}, handling commands...`);
|
|
185
|
+
server.connect(transport);
|
|
293
186
|
}
|
|
294
187
|
["SIGINT", "SIGTERM"].forEach((signal) => {
|
|
295
188
|
process.on(signal, async () => {
|
|
@@ -4,12 +4,12 @@ export declare const ResourceSchema: z.ZodObject<{
|
|
|
4
4
|
name: z.ZodString;
|
|
5
5
|
description: z.ZodString;
|
|
6
6
|
}, "strip", z.ZodTypeAny, {
|
|
7
|
-
uri: string;
|
|
8
7
|
name: string;
|
|
8
|
+
uri: string;
|
|
9
9
|
description: string;
|
|
10
10
|
}, {
|
|
11
|
-
uri: string;
|
|
12
11
|
name: string;
|
|
12
|
+
uri: string;
|
|
13
13
|
description: string;
|
|
14
14
|
}>;
|
|
15
15
|
export declare const ListResourcesResponseSchema: z.ZodObject<{
|
|
@@ -18,24 +18,24 @@ export declare const ListResourcesResponseSchema: z.ZodObject<{
|
|
|
18
18
|
name: z.ZodString;
|
|
19
19
|
description: z.ZodString;
|
|
20
20
|
}, "strip", z.ZodTypeAny, {
|
|
21
|
-
uri: string;
|
|
22
21
|
name: string;
|
|
22
|
+
uri: string;
|
|
23
23
|
description: string;
|
|
24
24
|
}, {
|
|
25
|
-
uri: string;
|
|
26
25
|
name: string;
|
|
26
|
+
uri: string;
|
|
27
27
|
description: string;
|
|
28
28
|
}>, "many">;
|
|
29
29
|
}, "strip", z.ZodTypeAny, {
|
|
30
30
|
resources: {
|
|
31
|
-
uri: string;
|
|
32
31
|
name: string;
|
|
32
|
+
uri: string;
|
|
33
33
|
description: string;
|
|
34
34
|
}[];
|
|
35
35
|
}, {
|
|
36
36
|
resources: {
|
|
37
|
-
uri: string;
|
|
38
37
|
name: string;
|
|
38
|
+
uri: string;
|
|
39
39
|
description: string;
|
|
40
40
|
}[];
|
|
41
41
|
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const kubectlApplySchema: {
|
|
3
|
+
readonly name: "kubectl_apply";
|
|
4
|
+
readonly description: "Apply a Kubernetes YAML manifest from a string or file";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly manifest: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly description: "YAML manifest to apply";
|
|
11
|
+
};
|
|
12
|
+
readonly filename: {
|
|
13
|
+
readonly type: "string";
|
|
14
|
+
readonly description: "Path to a YAML file to apply (optional - use either manifest or filename)";
|
|
15
|
+
};
|
|
16
|
+
readonly namespace: {
|
|
17
|
+
readonly type: "string";
|
|
18
|
+
readonly description: "Namespace to apply the resource to (optional)";
|
|
19
|
+
readonly default: "default";
|
|
20
|
+
};
|
|
21
|
+
readonly dryRun: {
|
|
22
|
+
readonly type: "boolean";
|
|
23
|
+
readonly description: "If true, only validate the resource, don't apply it";
|
|
24
|
+
readonly default: false;
|
|
25
|
+
};
|
|
26
|
+
readonly force: {
|
|
27
|
+
readonly type: "boolean";
|
|
28
|
+
readonly description: "If true, immediately remove resources from API and bypass graceful deletion";
|
|
29
|
+
readonly default: false;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
readonly required: readonly [];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export declare function kubectlApply(k8sManager: KubernetesManager, input: {
|
|
36
|
+
manifest?: string;
|
|
37
|
+
filename?: string;
|
|
38
|
+
namespace?: string;
|
|
39
|
+
dryRun?: boolean;
|
|
40
|
+
force?: boolean;
|
|
41
|
+
}): Promise<{
|
|
42
|
+
content: {
|
|
43
|
+
type: string;
|
|
44
|
+
text: string;
|
|
45
|
+
}[];
|
|
46
|
+
}>;
|
|
@@ -0,0 +1,110 @@
|
|
|
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 kubectlApplySchema = {
|
|
7
|
+
name: "kubectl_apply",
|
|
8
|
+
description: "Apply a Kubernetes YAML manifest from a string or file",
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: "object",
|
|
11
|
+
properties: {
|
|
12
|
+
manifest: {
|
|
13
|
+
type: "string",
|
|
14
|
+
description: "YAML manifest to apply"
|
|
15
|
+
},
|
|
16
|
+
filename: {
|
|
17
|
+
type: "string",
|
|
18
|
+
description: "Path to a YAML file to apply (optional - use either manifest or filename)"
|
|
19
|
+
},
|
|
20
|
+
namespace: {
|
|
21
|
+
type: "string",
|
|
22
|
+
description: "Namespace to apply the resource to (optional)",
|
|
23
|
+
default: "default"
|
|
24
|
+
},
|
|
25
|
+
dryRun: {
|
|
26
|
+
type: "boolean",
|
|
27
|
+
description: "If true, only validate the resource, don't apply it",
|
|
28
|
+
default: false
|
|
29
|
+
},
|
|
30
|
+
force: {
|
|
31
|
+
type: "boolean",
|
|
32
|
+
description: "If true, immediately remove resources from API and bypass graceful deletion",
|
|
33
|
+
default: false
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
required: [],
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
export async function kubectlApply(k8sManager, input) {
|
|
40
|
+
try {
|
|
41
|
+
if (!input.manifest && !input.filename) {
|
|
42
|
+
throw new McpError(ErrorCode.InvalidRequest, "Either manifest or filename must be provided");
|
|
43
|
+
}
|
|
44
|
+
const namespace = input.namespace || "default";
|
|
45
|
+
const dryRun = input.dryRun || false;
|
|
46
|
+
const force = input.force || false;
|
|
47
|
+
let command = "kubectl apply";
|
|
48
|
+
let tempFile = null;
|
|
49
|
+
// Process manifest content if provided
|
|
50
|
+
if (input.manifest) {
|
|
51
|
+
// Create temporary file for the manifest
|
|
52
|
+
const tmpDir = os.tmpdir();
|
|
53
|
+
tempFile = path.join(tmpDir, `manifest-${Date.now()}.yaml`);
|
|
54
|
+
fs.writeFileSync(tempFile, input.manifest);
|
|
55
|
+
command += ` -f ${tempFile}`;
|
|
56
|
+
}
|
|
57
|
+
else if (input.filename) {
|
|
58
|
+
command += ` -f ${input.filename}`;
|
|
59
|
+
}
|
|
60
|
+
// Add namespace
|
|
61
|
+
command += ` -n ${namespace}`;
|
|
62
|
+
// Add dry-run flag if requested
|
|
63
|
+
if (dryRun) {
|
|
64
|
+
command += " --dry-run=client";
|
|
65
|
+
}
|
|
66
|
+
// Add force flag if requested
|
|
67
|
+
if (force) {
|
|
68
|
+
command += " --force";
|
|
69
|
+
}
|
|
70
|
+
// Execute the command
|
|
71
|
+
try {
|
|
72
|
+
const result = execSync(command, { encoding: "utf8" });
|
|
73
|
+
// Clean up temp file if created
|
|
74
|
+
if (tempFile) {
|
|
75
|
+
try {
|
|
76
|
+
fs.unlinkSync(tempFile);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
content: [
|
|
84
|
+
{
|
|
85
|
+
type: "text",
|
|
86
|
+
text: result,
|
|
87
|
+
},
|
|
88
|
+
],
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
// Clean up temp file if created, even if command failed
|
|
93
|
+
if (tempFile) {
|
|
94
|
+
try {
|
|
95
|
+
fs.unlinkSync(tempFile);
|
|
96
|
+
}
|
|
97
|
+
catch (err) {
|
|
98
|
+
console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
throw new McpError(ErrorCode.InternalError, `Failed to apply manifest: ${error.message}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
catch (error) {
|
|
105
|
+
if (error instanceof McpError) {
|
|
106
|
+
throw error;
|
|
107
|
+
}
|
|
108
|
+
throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl apply command: ${error.message}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const kubectlContextSchema: {
|
|
3
|
+
readonly name: "kubectl_context";
|
|
4
|
+
readonly description: "Manage Kubernetes contexts - list, get, or set the current context";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly operation: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
readonly enum: readonly ["list", "get", "set"];
|
|
11
|
+
readonly description: "Operation to perform: list contexts, get current context, or set current context";
|
|
12
|
+
readonly default: "list";
|
|
13
|
+
};
|
|
14
|
+
readonly name: {
|
|
15
|
+
readonly type: "string";
|
|
16
|
+
readonly description: "Name of the context to set as current (required for set operation)";
|
|
17
|
+
};
|
|
18
|
+
readonly showCurrent: {
|
|
19
|
+
readonly type: "boolean";
|
|
20
|
+
readonly description: "When listing contexts, highlight which one is currently active";
|
|
21
|
+
readonly default: true;
|
|
22
|
+
};
|
|
23
|
+
readonly detailed: {
|
|
24
|
+
readonly type: "boolean";
|
|
25
|
+
readonly description: "Include detailed information about the context";
|
|
26
|
+
readonly default: false;
|
|
27
|
+
};
|
|
28
|
+
readonly output: {
|
|
29
|
+
readonly type: "string";
|
|
30
|
+
readonly enum: readonly ["json", "yaml", "name", "custom"];
|
|
31
|
+
readonly description: "Output format";
|
|
32
|
+
readonly default: "json";
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
readonly required: readonly ["operation"];
|
|
36
|
+
};
|
|
37
|
+
};
|
|
38
|
+
export declare function kubectlContext(k8sManager: KubernetesManager, input: {
|
|
39
|
+
operation: "list" | "get" | "set";
|
|
40
|
+
name?: string;
|
|
41
|
+
showCurrent?: boolean;
|
|
42
|
+
detailed?: boolean;
|
|
43
|
+
output?: string;
|
|
44
|
+
}): Promise<{
|
|
45
|
+
content: {
|
|
46
|
+
type: string;
|
|
47
|
+
text: string;
|
|
48
|
+
}[];
|
|
49
|
+
}>;
|