mcp-server-kubernetes 1.3.2 → 1.5.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 +9 -2
- package/dist/index.js +101 -40
- package/dist/models/response-schemas.d.ts +88 -0
- package/dist/models/response-schemas.js +12 -0
- package/dist/tools/create_service.d.ts +74 -0
- package/dist/tools/create_service.js +102 -0
- package/dist/tools/delete_service.d.ts +32 -0
- package/dist/tools/delete_service.js +46 -0
- package/dist/tools/describe_node.d.ts +22 -0
- package/dist/tools/describe_node.js +84 -0
- package/dist/tools/describe_service.d.ts +34 -0
- package/dist/tools/describe_service.js +85 -0
- package/dist/tools/get_current_context.d.ts +23 -0
- package/dist/tools/get_current_context.js +55 -0
- package/dist/tools/helm-operations.js +5 -1
- package/dist/tools/list_contexts.d.ts +23 -0
- package/dist/tools/list_contexts.js +39 -0
- package/dist/tools/set_current_context.d.ts +23 -0
- package/dist/tools/set_current_context.js +35 -0
- package/dist/tools/update_deployment.d.ts +113 -0
- package/dist/tools/update_deployment.js +155 -0
- package/dist/tools/update_service.d.ts +72 -0
- package/dist/tools/update_service.js +125 -0
- package/dist/utils/kubernetes-manager.d.ts +6 -0
- package/dist/utils/kubernetes-manager.js +19 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,9 +67,11 @@ npx mcp-chat --config "%APPDATA%\Claude\claude_desktop_config.json"
|
|
|
67
67
|
|
|
68
68
|
- [x] Connect to a Kubernetes cluster
|
|
69
69
|
- [x] List all pods, services, deployments, nodes
|
|
70
|
+
- [x] Describe nodes
|
|
70
71
|
- [x] Create, describe, delete a pod
|
|
71
72
|
- [x] List all namespaces, create a namespace
|
|
72
73
|
- [x] Create custom pod & deployment configs, update deployment replicas
|
|
74
|
+
- [x] Create, describe, delete, update a service
|
|
73
75
|
- [x] Get logs from a pod for debugging (supports pods, deployments, jobs, and label selectors)
|
|
74
76
|
- [x] Support Helm v3 for installing charts
|
|
75
77
|
- Install charts with custom values
|
|
@@ -82,9 +84,12 @@ npx mcp-chat --config "%APPDATA%\Claude\claude_desktop_config.json"
|
|
|
82
84
|
- [x] Get Kubernetes events from the cluster
|
|
83
85
|
- [x] Port forward to a pod or service
|
|
84
86
|
- [x] Create, list, and decribe cronjobs
|
|
87
|
+
- [x] Non-destructive mode for read and create/update-only access to clusters
|
|
85
88
|
|
|
86
89
|
## Local Development
|
|
87
90
|
|
|
91
|
+
Make sure that you have [bun installed](https://bun.sh/docs/installation). Clone the repo & install dependencies:
|
|
92
|
+
|
|
88
93
|
```bash
|
|
89
94
|
git clone https://github.com/Flux159/mcp-server-kubernetes.git
|
|
90
95
|
cd mcp-server-kubernetes
|
|
@@ -134,7 +139,7 @@ npx @modelcontextprotocol/inspector node dist/index.js
|
|
|
134
139
|
6. Local testing with [mcp-chat](https://github.com/Flux159/mcp-chat)
|
|
135
140
|
|
|
136
141
|
```bash
|
|
137
|
-
|
|
142
|
+
bun run chat
|
|
138
143
|
```
|
|
139
144
|
|
|
140
145
|
## Contributing
|
|
@@ -143,7 +148,9 @@ See the [CONTRIBUTING.md](CONTRIBUTING.md) file for details.
|
|
|
143
148
|
|
|
144
149
|
## Advanced
|
|
145
150
|
|
|
146
|
-
|
|
151
|
+
### Additional Advanced Features
|
|
152
|
+
|
|
153
|
+
For more advanced information like using SSE transport, Non-destructive mode with `ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS`, see the [ADVANCED_README.md](ADVANCED_README.md).
|
|
147
154
|
|
|
148
155
|
## Architecture
|
|
149
156
|
|
package/dist/index.js
CHANGED
|
@@ -6,9 +6,10 @@ import { listNodes, listNodesSchema } from "./tools/list_nodes.js";
|
|
|
6
6
|
import { listServices, listServicesSchema } from "./tools/list_services.js";
|
|
7
7
|
import { listDeployments, listDeploymentsSchema, } from "./tools/list_deployments.js";
|
|
8
8
|
import { listCronJobs, listCronJobsSchema } from "./tools/list_cronjobs.js";
|
|
9
|
-
import { describeCronJob, describeCronJobSchema } from "./tools/describe_cronjob.js";
|
|
9
|
+
import { describeCronJob, describeCronJobSchema, } from "./tools/describe_cronjob.js";
|
|
10
10
|
import { listJobs, listJobsSchema } from "./tools/list_jobs.js";
|
|
11
11
|
import { getJobLogs, getJobLogsSchema } from "./tools/get_job_logs.js";
|
|
12
|
+
import { describeNode, describeNodeSchema } from "./tools/describe_node.js";
|
|
12
13
|
import { installHelmChart, installHelmChartSchema, upgradeHelmChart, upgradeHelmChartSchema, uninstallHelmChart, uninstallHelmChartSchema, } from "./tools/helm-operations.js";
|
|
13
14
|
import { explainResource, explainResourceSchema, listApiResources, listApiResourcesSchema, } from "./tools/kubectl-operations.js";
|
|
14
15
|
import { createNamespace, createNamespaceSchema, } from "./tools/create_namespace.js";
|
|
@@ -25,57 +26,90 @@ import { KubernetesManager } from "./types.js";
|
|
|
25
26
|
import { serverConfig } from "./config/server-config.js";
|
|
26
27
|
import { createDeploymentSchema } from "./config/deployment-config.js";
|
|
27
28
|
import { listNamespacesSchema } from "./config/namespace-config.js";
|
|
28
|
-
import { deleteNamespace, deleteNamespaceSchema } from "./tools/delete_namespace.js";
|
|
29
|
+
import { deleteNamespace, deleteNamespaceSchema, } from "./tools/delete_namespace.js";
|
|
29
30
|
import { cleanupSchema } from "./config/cleanup-config.js";
|
|
30
31
|
import { startSSEServer } from "./utils/sse.js";
|
|
31
32
|
import { startPortForward, PortForwardSchema, stopPortForward, StopPortForwardSchema, } from "./tools/port_forward.js";
|
|
32
|
-
import { deleteDeployment, deleteDeploymentSchema } from "./tools/delete_deployment.js";
|
|
33
|
+
import { deleteDeployment, deleteDeploymentSchema, } from "./tools/delete_deployment.js";
|
|
33
34
|
import { createDeployment } from "./tools/create_deployment.js";
|
|
34
|
-
import { scaleDeployment, scaleDeploymentSchema } from "./tools/scale_deployment.js";
|
|
35
|
+
import { scaleDeployment, scaleDeploymentSchema, } from "./tools/scale_deployment.js";
|
|
35
36
|
import { describeDeployment, describeDeploymentSchema, } from "./tools/describe_deployment.js";
|
|
36
|
-
import {
|
|
37
|
+
import { updateDeployment, updateDeploymentSchema, } from "./tools/update_deployment.js";
|
|
38
|
+
import { createConfigMap, CreateConfigMapSchema, } from "./tools/create_configmap.js";
|
|
39
|
+
import { listContexts, listContextsSchema } from "./tools/list_contexts.js";
|
|
40
|
+
import { getCurrentContext, getCurrentContextSchema, } from "./tools/get_current_context.js";
|
|
41
|
+
import { setCurrentContext, setCurrentContextSchema, } from "./tools/set_current_context.js";
|
|
42
|
+
import { createService, createServiceSchema } from "./tools/create_service.js";
|
|
43
|
+
import { describeService, describeServiceSchema, } from "./tools/describe_service.js";
|
|
44
|
+
import { updateService, updateServiceSchema } from "./tools/update_service.js";
|
|
45
|
+
import { deleteService, deleteServiceSchema } from "./tools/delete_service.js";
|
|
46
|
+
// Check if non-destructive tools only mode is enabled
|
|
47
|
+
const nonDestructiveTools = process.env.ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS === "true";
|
|
37
48
|
const k8sManager = new KubernetesManager();
|
|
38
49
|
const server = new Server({
|
|
39
50
|
name: serverConfig.name,
|
|
40
51
|
version: serverConfig.version,
|
|
41
52
|
}, serverConfig);
|
|
53
|
+
// Define destructive tools (delete and uninstall operations)
|
|
54
|
+
const destructiveTools = [
|
|
55
|
+
deletePodSchema,
|
|
56
|
+
deleteServiceSchema,
|
|
57
|
+
deleteDeploymentSchema,
|
|
58
|
+
deleteNamespaceSchema,
|
|
59
|
+
uninstallHelmChartSchema,
|
|
60
|
+
DeleteCronJobSchema,
|
|
61
|
+
cleanupSchema, // Cleanup is also destructive as it deletes resources
|
|
62
|
+
];
|
|
42
63
|
// Tools handlers
|
|
43
64
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
65
|
+
// Get all available tools
|
|
66
|
+
const allTools = [
|
|
67
|
+
cleanupSchema,
|
|
68
|
+
createDeploymentSchema,
|
|
69
|
+
createNamespaceSchema,
|
|
70
|
+
createPodSchema,
|
|
71
|
+
createCronJobSchema,
|
|
72
|
+
createServiceSchema,
|
|
73
|
+
deletePodSchema,
|
|
74
|
+
deleteDeploymentSchema,
|
|
75
|
+
deleteNamespaceSchema,
|
|
76
|
+
deleteServiceSchema,
|
|
77
|
+
describeCronJobSchema,
|
|
78
|
+
describePodSchema,
|
|
79
|
+
describeNodeSchema,
|
|
80
|
+
describeDeploymentSchema,
|
|
81
|
+
describeServiceSchema,
|
|
82
|
+
explainResourceSchema,
|
|
83
|
+
getEventsSchema,
|
|
84
|
+
getJobLogsSchema,
|
|
85
|
+
getLogsSchema,
|
|
86
|
+
installHelmChartSchema,
|
|
87
|
+
listApiResourcesSchema,
|
|
88
|
+
listCronJobsSchema,
|
|
89
|
+
listContextsSchema,
|
|
90
|
+
getCurrentContextSchema,
|
|
91
|
+
setCurrentContextSchema,
|
|
92
|
+
listDeploymentsSchema,
|
|
93
|
+
listJobsSchema,
|
|
94
|
+
listNamespacesSchema,
|
|
95
|
+
listNodesSchema,
|
|
96
|
+
listPodsSchema,
|
|
97
|
+
listServicesSchema,
|
|
98
|
+
uninstallHelmChartSchema,
|
|
99
|
+
updateDeploymentSchema,
|
|
100
|
+
upgradeHelmChartSchema,
|
|
101
|
+
PortForwardSchema,
|
|
102
|
+
StopPortForwardSchema,
|
|
103
|
+
scaleDeploymentSchema,
|
|
104
|
+
DeleteCronJobSchema,
|
|
105
|
+
CreateConfigMapSchema,
|
|
106
|
+
updateServiceSchema,
|
|
107
|
+
];
|
|
108
|
+
// Filter out destructive tools if ALLOW_ONLY_NON_DESTRUCTIVE_TOOLS is set to 'true'
|
|
109
|
+
const tools = nonDestructiveTools
|
|
110
|
+
? allTools.filter((tool) => !destructiveTools.some((dt) => dt.name === tool.name))
|
|
111
|
+
: allTools;
|
|
112
|
+
return { tools };
|
|
79
113
|
});
|
|
80
114
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
81
115
|
try {
|
|
@@ -112,6 +146,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
112
146
|
case "describe_pod": {
|
|
113
147
|
return await describePod(k8sManager, input);
|
|
114
148
|
}
|
|
149
|
+
case "describe_node": {
|
|
150
|
+
return await describeNode(k8sManager, input);
|
|
151
|
+
}
|
|
115
152
|
case "explain_resource": {
|
|
116
153
|
return await explainResource(input);
|
|
117
154
|
}
|
|
@@ -158,6 +195,15 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
158
195
|
case "list_cronjobs": {
|
|
159
196
|
return await listCronJobs(k8sManager, input);
|
|
160
197
|
}
|
|
198
|
+
case "list_contexts": {
|
|
199
|
+
return await listContexts(k8sManager, input);
|
|
200
|
+
}
|
|
201
|
+
case "get_current_context": {
|
|
202
|
+
return await getCurrentContext(k8sManager, input);
|
|
203
|
+
}
|
|
204
|
+
case "set_current_context": {
|
|
205
|
+
return await setCurrentContext(k8sManager, input);
|
|
206
|
+
}
|
|
161
207
|
case "describe_cronjob": {
|
|
162
208
|
return await describeCronJob(k8sManager, input);
|
|
163
209
|
}
|
|
@@ -188,6 +234,9 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
188
234
|
case "create_deployment": {
|
|
189
235
|
return await createDeployment(k8sManager, input);
|
|
190
236
|
}
|
|
237
|
+
case "update_deployment": {
|
|
238
|
+
return await updateDeployment(k8sManager, input);
|
|
239
|
+
}
|
|
191
240
|
case "describe_deployment": {
|
|
192
241
|
return await describeDeployment(k8sManager, input);
|
|
193
242
|
}
|
|
@@ -197,6 +246,18 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
197
246
|
case "create_configmap": {
|
|
198
247
|
return await createConfigMap(k8sManager, input);
|
|
199
248
|
}
|
|
249
|
+
case "create_service": {
|
|
250
|
+
return await createService(k8sManager, input);
|
|
251
|
+
}
|
|
252
|
+
case "update_service": {
|
|
253
|
+
return await updateService(k8sManager, input);
|
|
254
|
+
}
|
|
255
|
+
case "delete_service": {
|
|
256
|
+
return await deleteService(k8sManager, input);
|
|
257
|
+
}
|
|
258
|
+
case "describe_service": {
|
|
259
|
+
return await describeService(k8sManager, input);
|
|
260
|
+
}
|
|
200
261
|
default:
|
|
201
262
|
throw new McpError(ErrorCode.InvalidRequest, `Unknown tool: ${name}`);
|
|
202
263
|
}
|
|
@@ -505,3 +505,91 @@ export declare const CreateConfigMapResponseSchema: z.ZodObject<{
|
|
|
505
505
|
success: boolean;
|
|
506
506
|
}[];
|
|
507
507
|
}>;
|
|
508
|
+
export declare const ListContextsResponseSchema: z.ZodObject<{
|
|
509
|
+
content: z.ZodArray<z.ZodObject<{
|
|
510
|
+
type: z.ZodLiteral<"text">;
|
|
511
|
+
text: z.ZodString;
|
|
512
|
+
}, "strip", z.ZodTypeAny, {
|
|
513
|
+
type: "text";
|
|
514
|
+
text: string;
|
|
515
|
+
}, {
|
|
516
|
+
type: "text";
|
|
517
|
+
text: string;
|
|
518
|
+
}>, "many">;
|
|
519
|
+
}, "strip", z.ZodTypeAny, {
|
|
520
|
+
content: {
|
|
521
|
+
type: "text";
|
|
522
|
+
text: string;
|
|
523
|
+
}[];
|
|
524
|
+
}, {
|
|
525
|
+
content: {
|
|
526
|
+
type: "text";
|
|
527
|
+
text: string;
|
|
528
|
+
}[];
|
|
529
|
+
}>;
|
|
530
|
+
export declare const GetCurrentContextResponseSchema: z.ZodObject<{
|
|
531
|
+
content: z.ZodArray<z.ZodObject<{
|
|
532
|
+
type: z.ZodLiteral<"text">;
|
|
533
|
+
text: z.ZodString;
|
|
534
|
+
}, "strip", z.ZodTypeAny, {
|
|
535
|
+
type: "text";
|
|
536
|
+
text: string;
|
|
537
|
+
}, {
|
|
538
|
+
type: "text";
|
|
539
|
+
text: string;
|
|
540
|
+
}>, "many">;
|
|
541
|
+
}, "strip", z.ZodTypeAny, {
|
|
542
|
+
content: {
|
|
543
|
+
type: "text";
|
|
544
|
+
text: string;
|
|
545
|
+
}[];
|
|
546
|
+
}, {
|
|
547
|
+
content: {
|
|
548
|
+
type: "text";
|
|
549
|
+
text: string;
|
|
550
|
+
}[];
|
|
551
|
+
}>;
|
|
552
|
+
export declare const SetCurrentContextResponseSchema: z.ZodObject<{
|
|
553
|
+
content: z.ZodArray<z.ZodObject<{
|
|
554
|
+
type: z.ZodLiteral<"text">;
|
|
555
|
+
text: z.ZodString;
|
|
556
|
+
}, "strip", z.ZodTypeAny, {
|
|
557
|
+
type: "text";
|
|
558
|
+
text: string;
|
|
559
|
+
}, {
|
|
560
|
+
type: "text";
|
|
561
|
+
text: string;
|
|
562
|
+
}>, "many">;
|
|
563
|
+
}, "strip", z.ZodTypeAny, {
|
|
564
|
+
content: {
|
|
565
|
+
type: "text";
|
|
566
|
+
text: string;
|
|
567
|
+
}[];
|
|
568
|
+
}, {
|
|
569
|
+
content: {
|
|
570
|
+
type: "text";
|
|
571
|
+
text: string;
|
|
572
|
+
}[];
|
|
573
|
+
}>;
|
|
574
|
+
export declare const DescribeNodeResponseSchema: z.ZodObject<{
|
|
575
|
+
content: z.ZodArray<z.ZodObject<{
|
|
576
|
+
type: z.ZodLiteral<"text">;
|
|
577
|
+
text: z.ZodString;
|
|
578
|
+
}, "strip", z.ZodTypeAny, {
|
|
579
|
+
type: "text";
|
|
580
|
+
text: string;
|
|
581
|
+
}, {
|
|
582
|
+
type: "text";
|
|
583
|
+
text: string;
|
|
584
|
+
}>, "many">;
|
|
585
|
+
}, "strip", z.ZodTypeAny, {
|
|
586
|
+
content: {
|
|
587
|
+
type: "text";
|
|
588
|
+
text: string;
|
|
589
|
+
}[];
|
|
590
|
+
}, {
|
|
591
|
+
content: {
|
|
592
|
+
type: "text";
|
|
593
|
+
text: string;
|
|
594
|
+
}[];
|
|
595
|
+
}>;
|
|
@@ -85,3 +85,15 @@ export const CreateConfigMapResponseSchema = z.object({
|
|
|
85
85
|
message: z.string(),
|
|
86
86
|
})),
|
|
87
87
|
});
|
|
88
|
+
export const ListContextsResponseSchema = z.object({
|
|
89
|
+
content: z.array(ToolResponseContent),
|
|
90
|
+
});
|
|
91
|
+
export const GetCurrentContextResponseSchema = z.object({
|
|
92
|
+
content: z.array(ToolResponseContent),
|
|
93
|
+
});
|
|
94
|
+
export const SetCurrentContextResponseSchema = z.object({
|
|
95
|
+
content: z.array(ToolResponseContent),
|
|
96
|
+
});
|
|
97
|
+
export const DescribeNodeResponseSchema = z.object({
|
|
98
|
+
content: z.array(ToolResponseContent),
|
|
99
|
+
});
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const createServiceSchema: {
|
|
3
|
+
readonly name: "create_service";
|
|
4
|
+
readonly description: "Create a new Kubernetes service";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
};
|
|
11
|
+
readonly namespace: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly default: "default";
|
|
14
|
+
};
|
|
15
|
+
readonly type: {
|
|
16
|
+
readonly type: "string";
|
|
17
|
+
readonly enum: readonly ["ClusterIP", "NodePort", "LoadBalancer"];
|
|
18
|
+
readonly default: "ClusterIP";
|
|
19
|
+
};
|
|
20
|
+
readonly selector: {
|
|
21
|
+
readonly type: "object";
|
|
22
|
+
readonly additionalProperties: {
|
|
23
|
+
readonly type: "string";
|
|
24
|
+
};
|
|
25
|
+
readonly default: {};
|
|
26
|
+
};
|
|
27
|
+
readonly ports: {
|
|
28
|
+
readonly type: "array";
|
|
29
|
+
readonly items: {
|
|
30
|
+
readonly type: "object";
|
|
31
|
+
readonly properties: {
|
|
32
|
+
readonly port: {
|
|
33
|
+
readonly type: "number";
|
|
34
|
+
};
|
|
35
|
+
readonly targetPort: {
|
|
36
|
+
readonly type: "number";
|
|
37
|
+
};
|
|
38
|
+
readonly protocol: {
|
|
39
|
+
readonly type: "string";
|
|
40
|
+
readonly enum: readonly ["TCP", "UDP"];
|
|
41
|
+
readonly default: "TCP";
|
|
42
|
+
};
|
|
43
|
+
readonly name: {
|
|
44
|
+
readonly type: "string";
|
|
45
|
+
};
|
|
46
|
+
readonly nodePort: {
|
|
47
|
+
readonly type: "number";
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
readonly required: readonly ["port"];
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
readonly required: readonly ["name", "ports"];
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
export declare function createService(k8sManager: KubernetesManager, input: {
|
|
58
|
+
name: string;
|
|
59
|
+
namespace?: string;
|
|
60
|
+
type?: "ClusterIP" | "NodePort" | "LoadBalancer";
|
|
61
|
+
selector?: Record<string, string>;
|
|
62
|
+
ports: Array<{
|
|
63
|
+
port: number;
|
|
64
|
+
targetPort?: number;
|
|
65
|
+
protocol?: string;
|
|
66
|
+
name?: string;
|
|
67
|
+
nodePort?: number;
|
|
68
|
+
}>;
|
|
69
|
+
}): Promise<{
|
|
70
|
+
content: {
|
|
71
|
+
type: string;
|
|
72
|
+
text: string;
|
|
73
|
+
}[];
|
|
74
|
+
}>;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export const createServiceSchema = {
|
|
2
|
+
name: "create_service",
|
|
3
|
+
description: "Create a new Kubernetes service",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
namespace: { type: "string", default: "default" },
|
|
9
|
+
type: {
|
|
10
|
+
type: "string",
|
|
11
|
+
enum: ["ClusterIP", "NodePort", "LoadBalancer"],
|
|
12
|
+
default: "ClusterIP"
|
|
13
|
+
},
|
|
14
|
+
selector: {
|
|
15
|
+
type: "object",
|
|
16
|
+
additionalProperties: { type: "string" },
|
|
17
|
+
default: {}
|
|
18
|
+
},
|
|
19
|
+
ports: {
|
|
20
|
+
type: "array",
|
|
21
|
+
items: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
port: { type: "number" },
|
|
25
|
+
targetPort: { type: "number" },
|
|
26
|
+
protocol: {
|
|
27
|
+
type: "string",
|
|
28
|
+
enum: ["TCP", "UDP"],
|
|
29
|
+
default: "TCP"
|
|
30
|
+
},
|
|
31
|
+
name: { type: "string" },
|
|
32
|
+
nodePort: { type: "number" }
|
|
33
|
+
},
|
|
34
|
+
required: ["port"]
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
required: ["name", "ports"],
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
export async function createService(k8sManager, input) {
|
|
42
|
+
const namespace = input.namespace || "default";
|
|
43
|
+
const serviceType = input.type || "ClusterIP";
|
|
44
|
+
// Convert ports to k8s.V1ServicePort format
|
|
45
|
+
const servicePorts = input.ports.map((portConfig, index) => {
|
|
46
|
+
return {
|
|
47
|
+
port: portConfig.port,
|
|
48
|
+
targetPort: portConfig.targetPort !== undefined ? portConfig.targetPort : portConfig.port,
|
|
49
|
+
protocol: portConfig.protocol || "TCP",
|
|
50
|
+
name: portConfig.name || `port-${index}`,
|
|
51
|
+
...(serviceType === "NodePort" && portConfig.nodePort ? { nodePort: portConfig.nodePort } : {})
|
|
52
|
+
};
|
|
53
|
+
});
|
|
54
|
+
// Default selector
|
|
55
|
+
const selector = input.selector || { app: input.name };
|
|
56
|
+
const service = {
|
|
57
|
+
apiVersion: "v1",
|
|
58
|
+
kind: "Service",
|
|
59
|
+
metadata: {
|
|
60
|
+
name: input.name,
|
|
61
|
+
namespace: namespace,
|
|
62
|
+
labels: {
|
|
63
|
+
"mcp-managed": "true",
|
|
64
|
+
app: input.name,
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
spec: {
|
|
68
|
+
type: serviceType,
|
|
69
|
+
selector: selector,
|
|
70
|
+
ports: servicePorts
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
try {
|
|
74
|
+
const response = await k8sManager
|
|
75
|
+
.getCoreApi()
|
|
76
|
+
.createNamespacedService(namespace, service);
|
|
77
|
+
k8sManager.trackResource("Service", input.name, namespace);
|
|
78
|
+
return {
|
|
79
|
+
content: [
|
|
80
|
+
{
|
|
81
|
+
type: "text",
|
|
82
|
+
text: JSON.stringify({
|
|
83
|
+
serviceName: response.body.metadata.name,
|
|
84
|
+
namespace: response.body.metadata.namespace,
|
|
85
|
+
type: response.body.spec.type,
|
|
86
|
+
clusterIP: response.body.spec.clusterIP,
|
|
87
|
+
ports: response.body.spec.ports,
|
|
88
|
+
status: "created",
|
|
89
|
+
}, null, 2),
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (error) {
|
|
95
|
+
console.error("Service creation error:", {
|
|
96
|
+
status: error.response?.statusCode,
|
|
97
|
+
message: error.response?.body?.message || error.message,
|
|
98
|
+
details: error.response?.body,
|
|
99
|
+
});
|
|
100
|
+
throw error;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const deleteServiceSchema: {
|
|
3
|
+
readonly name: "delete_service";
|
|
4
|
+
readonly description: "Delete a Kubernetes service";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
};
|
|
11
|
+
readonly namespace: {
|
|
12
|
+
readonly type: "string";
|
|
13
|
+
readonly default: "default";
|
|
14
|
+
};
|
|
15
|
+
readonly ignoreNotFound: {
|
|
16
|
+
readonly type: "boolean";
|
|
17
|
+
readonly default: false;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
readonly required: readonly ["name"];
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export declare function deleteService(k8sManager: KubernetesManager, input: {
|
|
24
|
+
name: string;
|
|
25
|
+
namespace?: string;
|
|
26
|
+
ignoreNotFound?: boolean;
|
|
27
|
+
}): Promise<{
|
|
28
|
+
content: {
|
|
29
|
+
type: string;
|
|
30
|
+
text: string;
|
|
31
|
+
}[];
|
|
32
|
+
}>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
export const deleteServiceSchema = {
|
|
2
|
+
name: "delete_service",
|
|
3
|
+
description: "Delete a Kubernetes service",
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: "object",
|
|
6
|
+
properties: {
|
|
7
|
+
name: { type: "string" },
|
|
8
|
+
namespace: { type: "string", default: "default" },
|
|
9
|
+
ignoreNotFound: { type: "boolean", default: false },
|
|
10
|
+
},
|
|
11
|
+
required: ["name"],
|
|
12
|
+
},
|
|
13
|
+
};
|
|
14
|
+
export async function deleteService(k8sManager, input) {
|
|
15
|
+
const namespace = input.namespace || "default";
|
|
16
|
+
try {
|
|
17
|
+
await k8sManager.getCoreApi().deleteNamespacedService(input.name, namespace);
|
|
18
|
+
return {
|
|
19
|
+
content: [
|
|
20
|
+
{
|
|
21
|
+
type: "text",
|
|
22
|
+
text: JSON.stringify({
|
|
23
|
+
success: true,
|
|
24
|
+
status: "deleted",
|
|
25
|
+
}, null, 2),
|
|
26
|
+
},
|
|
27
|
+
],
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
if (input.ignoreNotFound && error.response?.statusCode === 404) {
|
|
32
|
+
return {
|
|
33
|
+
content: [
|
|
34
|
+
{
|
|
35
|
+
type: "text",
|
|
36
|
+
text: JSON.stringify({
|
|
37
|
+
success: true,
|
|
38
|
+
status: "not_found",
|
|
39
|
+
}, null, 2),
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
throw error;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { KubernetesManager } from "../types.js";
|
|
2
|
+
export declare const describeNodeSchema: {
|
|
3
|
+
readonly name: "describe_node";
|
|
4
|
+
readonly description: "Describe a Kubernetes node (read details like status, capacity, conditions, etc.)";
|
|
5
|
+
readonly inputSchema: {
|
|
6
|
+
readonly type: "object";
|
|
7
|
+
readonly properties: {
|
|
8
|
+
readonly name: {
|
|
9
|
+
readonly type: "string";
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
readonly required: readonly ["name"];
|
|
13
|
+
};
|
|
14
|
+
};
|
|
15
|
+
export declare function describeNode(k8sManager: KubernetesManager, input: {
|
|
16
|
+
name: string;
|
|
17
|
+
}): Promise<{
|
|
18
|
+
content: {
|
|
19
|
+
type: string;
|
|
20
|
+
text: string;
|
|
21
|
+
}[];
|
|
22
|
+
}>;
|