@dockndevai/mcp-kubernetes 0.1.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/LICENSE +21 -0
- package/README.md +89 -0
- package/dist/config.d.ts +18 -0
- package/dist/config.js +44 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/k8s/client.d.ts +47 -0
- package/dist/k8s/client.js +177 -0
- package/dist/k8s/client.js.map +1 -0
- package/dist/security.d.ts +61 -0
- package/dist/security.js +106 -0
- package/dist/security.js.map +1 -0
- package/dist/server.d.ts +6 -0
- package/dist/server.js +52 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/admin.d.ts +6 -0
- package/dist/tools/admin.js +78 -0
- package/dist/tools/admin.js.map +1 -0
- package/dist/tools/read.d.ts +2 -0
- package/dist/tools/read.js +222 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/types.d.ts +41 -0
- package/dist/tools/types.js +21 -0
- package/dist/tools/types.js.map +1 -0
- package/dist/tools/write.d.ts +2 -0
- package/dist/tools/write.js +148 -0
- package/dist/tools/write.js.map +1 -0
- package/package.json +55 -0
package/dist/server.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { ApiException } from "@kubernetes/client-node";
|
|
2
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
3
|
+
import { K8sClient } from "./k8s/client.js";
|
|
4
|
+
import { PolicyError, SecurityPolicy } from "./security.js";
|
|
5
|
+
import { adminTools } from "./tools/admin.js";
|
|
6
|
+
import { readTools } from "./tools/read.js";
|
|
7
|
+
import { writeTools } from "./tools/write.js";
|
|
8
|
+
const ALL_TOOLS = [...readTools, ...writeTools, ...adminTools];
|
|
9
|
+
export function buildServer(config) {
|
|
10
|
+
const policy = new SecurityPolicy(config.security);
|
|
11
|
+
const client = new K8sClient(config.connection);
|
|
12
|
+
const ctx = { client, policy };
|
|
13
|
+
const server = new McpServer({ name: "mcp-kubernetes", version: "0.1.0" });
|
|
14
|
+
const enabled = [];
|
|
15
|
+
for (const tool of ALL_TOOLS) {
|
|
16
|
+
if (!policy.isCapabilityEnabled(tool.capability))
|
|
17
|
+
continue;
|
|
18
|
+
// Extra per-tool gate (e.g. exec_in_pod needs the exec opt-in on top of admin mode).
|
|
19
|
+
if (tool.enabledWhen && !tool.enabledWhen(policy))
|
|
20
|
+
continue;
|
|
21
|
+
enabled.push(tool.name);
|
|
22
|
+
server.registerTool(tool.name, tool.config, async (args) => {
|
|
23
|
+
try {
|
|
24
|
+
return await tool.handler(args ?? {}, ctx);
|
|
25
|
+
}
|
|
26
|
+
catch (err) {
|
|
27
|
+
return toErrorResult(err);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return { server, enabled };
|
|
32
|
+
}
|
|
33
|
+
function toErrorResult(err) {
|
|
34
|
+
let message;
|
|
35
|
+
if (err instanceof PolicyError) {
|
|
36
|
+
message = `Policy denied: ${err.message}`;
|
|
37
|
+
}
|
|
38
|
+
else if (err instanceof ApiException) {
|
|
39
|
+
message = `Kubernetes API error (${err.code}): ${truncate(String(err.body ?? err.message))}`;
|
|
40
|
+
}
|
|
41
|
+
else if (err instanceof Error) {
|
|
42
|
+
message = err.message;
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
message = String(err);
|
|
46
|
+
}
|
|
47
|
+
return { content: [{ type: "text", text: message }], isError: true };
|
|
48
|
+
}
|
|
49
|
+
function truncate(s, max = 800) {
|
|
50
|
+
return s.length > max ? `${s.slice(0, max)}…` : s;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResult, textResult } from "./types.js";
|
|
3
|
+
const contextArg = {
|
|
4
|
+
context: z.string().optional().describe("kube-config context to target (defaults to current-context)"),
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Admin tools are registered only in admin mode, and the two most dangerous
|
|
8
|
+
* (delete, exec) have their own additional opt-in flags on top of that.
|
|
9
|
+
*/
|
|
10
|
+
export const adminTools = [
|
|
11
|
+
{
|
|
12
|
+
name: "delete_resource",
|
|
13
|
+
capability: "admin",
|
|
14
|
+
config: {
|
|
15
|
+
title: "Delete a resource",
|
|
16
|
+
description: "Delete an arbitrary Kubernetes object by apiVersion/kind/name. Requires admin mode AND " +
|
|
17
|
+
"K8S_ALLOW_DELETE=true. Protected namespaces are refused. Irreversible.",
|
|
18
|
+
inputSchema: {
|
|
19
|
+
apiVersion: z.string().describe("e.g. v1, apps/v1"),
|
|
20
|
+
kind: z.string().describe("e.g. Pod, Deployment"),
|
|
21
|
+
name: z.string().describe("Resource name"),
|
|
22
|
+
namespace: z.string().optional().describe("Namespace (omit for cluster-scoped resources)"),
|
|
23
|
+
...contextArg,
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
handler: async (args, { client, policy }) => {
|
|
27
|
+
const namespace = args.namespace;
|
|
28
|
+
const context = args.context;
|
|
29
|
+
const { dryRun } = policy.guard({
|
|
30
|
+
tool: "delete_resource",
|
|
31
|
+
capability: "admin",
|
|
32
|
+
namespace,
|
|
33
|
+
context,
|
|
34
|
+
destructive: true,
|
|
35
|
+
});
|
|
36
|
+
const ref = `${args.kind}/${args.name}${namespace ? ` in ${namespace}` : ""}`;
|
|
37
|
+
if (dryRun)
|
|
38
|
+
return textResult(`[dry-run] Would delete ${ref}.`);
|
|
39
|
+
await client.deleteObject(args.apiVersion, args.kind, args.name, namespace, context);
|
|
40
|
+
return jsonResult({ deleted: true, kind: args.kind, name: args.name, namespace });
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "exec_in_pod",
|
|
45
|
+
capability: "admin",
|
|
46
|
+
// Only ever registered when admin mode AND the exec opt-in are both on.
|
|
47
|
+
enabledWhen: (p) => p.execEnabled,
|
|
48
|
+
config: {
|
|
49
|
+
title: "Exec in pod",
|
|
50
|
+
description: "Run a command inside a pod container and return its output. Requires admin mode AND " +
|
|
51
|
+
"K8S_ALLOW_EXEC=true. This is powerful — treat with care.",
|
|
52
|
+
inputSchema: {
|
|
53
|
+
name: z.string().describe("Pod name"),
|
|
54
|
+
namespace: z.string().describe("Namespace"),
|
|
55
|
+
container: z.string().describe("Container name"),
|
|
56
|
+
command: z.array(z.string()).min(1).describe("Command and args, e.g. [\"sh\",\"-c\",\"ls /\"]"),
|
|
57
|
+
...contextArg,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
handler: async (args, { client, policy }) => {
|
|
61
|
+
const namespace = args.namespace;
|
|
62
|
+
const context = args.context;
|
|
63
|
+
const { dryRun } = policy.guard({
|
|
64
|
+
tool: "exec_in_pod",
|
|
65
|
+
capability: "admin",
|
|
66
|
+
namespace,
|
|
67
|
+
context,
|
|
68
|
+
requiresExec: true,
|
|
69
|
+
});
|
|
70
|
+
const command = args.command;
|
|
71
|
+
if (dryRun)
|
|
72
|
+
return textResult(`[dry-run] Would exec in ${namespace}/${args.name} [${args.container}]: ${command.join(" ")}`);
|
|
73
|
+
const result = await client.execInPod(args.name, namespace, args.container, command, context);
|
|
74
|
+
return jsonResult(result);
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
];
|
|
78
|
+
//# sourceMappingURL=admin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"admin.js","sourceRoot":"","sources":["../../src/tools/admin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResult, summarizePods } from "./types.js";
|
|
3
|
+
const contextArg = {
|
|
4
|
+
context: z.string().optional().describe("kube-config context to target (defaults to current-context)"),
|
|
5
|
+
};
|
|
6
|
+
export const readTools = [
|
|
7
|
+
{
|
|
8
|
+
name: "list_contexts",
|
|
9
|
+
capability: "read",
|
|
10
|
+
config: {
|
|
11
|
+
title: "List kube-config contexts",
|
|
12
|
+
description: "List the contexts (clusters) available in the loaded kube-config.",
|
|
13
|
+
inputSchema: {},
|
|
14
|
+
},
|
|
15
|
+
handler: async (_args, { client, policy }) => {
|
|
16
|
+
policy.guard({ tool: "list_contexts", capability: "read" });
|
|
17
|
+
const contexts = client
|
|
18
|
+
.listContextNames()
|
|
19
|
+
.filter((c) => policy.isContextAllowed(c.name));
|
|
20
|
+
return jsonResult(contexts);
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: "list_namespaces",
|
|
25
|
+
capability: "read",
|
|
26
|
+
config: {
|
|
27
|
+
title: "List namespaces",
|
|
28
|
+
description: "List namespaces in the cluster. Namespaces outside the allowlist are filtered out.",
|
|
29
|
+
inputSchema: { ...contextArg },
|
|
30
|
+
},
|
|
31
|
+
handler: async (args, { client, policy }) => {
|
|
32
|
+
const context = args.context;
|
|
33
|
+
policy.guard({ tool: "list_namespaces", capability: "read", context });
|
|
34
|
+
const res = await client.listNamespaces(context);
|
|
35
|
+
const namespaces = (res.items ?? [])
|
|
36
|
+
.map((n) => ({
|
|
37
|
+
name: n.metadata?.name,
|
|
38
|
+
status: n.status?.phase,
|
|
39
|
+
protected: n.metadata?.name ? policy.isNamespaceProtected(n.metadata.name) : false,
|
|
40
|
+
}))
|
|
41
|
+
.filter((n) => n.name && policy.isNamespaceAllowed(n.name));
|
|
42
|
+
return jsonResult(namespaces);
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: "list_pods",
|
|
47
|
+
capability: "read",
|
|
48
|
+
config: {
|
|
49
|
+
title: "List pods",
|
|
50
|
+
description: "List pods in a namespace with status, readiness, restarts, and node.",
|
|
51
|
+
inputSchema: { namespace: z.string().describe("Namespace"), ...contextArg },
|
|
52
|
+
},
|
|
53
|
+
handler: async (args, { client, policy }) => {
|
|
54
|
+
const namespace = args.namespace;
|
|
55
|
+
const context = args.context;
|
|
56
|
+
policy.guard({ tool: "list_pods", capability: "read", namespace, context });
|
|
57
|
+
const res = await client.listPods(namespace, context);
|
|
58
|
+
return jsonResult(summarizePods(res));
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: "get_pod",
|
|
63
|
+
capability: "read",
|
|
64
|
+
config: {
|
|
65
|
+
title: "Get pod",
|
|
66
|
+
description: "Fetch the full representation of a single pod.",
|
|
67
|
+
inputSchema: {
|
|
68
|
+
name: z.string().describe("Pod name"),
|
|
69
|
+
namespace: z.string().describe("Namespace"),
|
|
70
|
+
...contextArg,
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
handler: async (args, { client, policy }) => {
|
|
74
|
+
const namespace = args.namespace;
|
|
75
|
+
const context = args.context;
|
|
76
|
+
policy.guard({ tool: "get_pod", capability: "read", namespace, context });
|
|
77
|
+
const res = await client.getPod(args.name, namespace, context);
|
|
78
|
+
return jsonResult(res);
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
name: "get_pod_logs",
|
|
83
|
+
capability: "read",
|
|
84
|
+
config: {
|
|
85
|
+
title: "Get pod logs",
|
|
86
|
+
description: "Fetch recent logs from a pod container.",
|
|
87
|
+
inputSchema: {
|
|
88
|
+
name: z.string().describe("Pod name"),
|
|
89
|
+
namespace: z.string().describe("Namespace"),
|
|
90
|
+
container: z.string().optional().describe("Container name (defaults to first container)"),
|
|
91
|
+
tailLines: z.number().int().min(1).max(5000).optional().describe("Lines from the end (default 200)"),
|
|
92
|
+
previous: z.boolean().optional().describe("Fetch logs from the previous terminated container"),
|
|
93
|
+
...contextArg,
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
handler: async (args, { client, policy }) => {
|
|
97
|
+
const namespace = args.namespace;
|
|
98
|
+
const context = args.context;
|
|
99
|
+
policy.guard({ tool: "get_pod_logs", capability: "read", namespace, context });
|
|
100
|
+
const logs = await client.getPodLogs(args.name, namespace, {
|
|
101
|
+
container: args.container,
|
|
102
|
+
tailLines: args.tailLines ?? 200,
|
|
103
|
+
previous: args.previous,
|
|
104
|
+
}, context);
|
|
105
|
+
return { content: [{ type: "text", text: String(logs) || "(no output)" }] };
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
name: "list_deployments",
|
|
110
|
+
capability: "read",
|
|
111
|
+
config: {
|
|
112
|
+
title: "List deployments",
|
|
113
|
+
description: "List deployments in a namespace with replica status.",
|
|
114
|
+
inputSchema: { namespace: z.string().describe("Namespace"), ...contextArg },
|
|
115
|
+
},
|
|
116
|
+
handler: async (args, { client, policy }) => {
|
|
117
|
+
const namespace = args.namespace;
|
|
118
|
+
const context = args.context;
|
|
119
|
+
policy.guard({ tool: "list_deployments", capability: "read", namespace, context });
|
|
120
|
+
const res = await client.listDeployments(namespace, context);
|
|
121
|
+
const deployments = (res.items ?? []).map((d) => ({
|
|
122
|
+
name: d.metadata?.name,
|
|
123
|
+
namespace: d.metadata?.namespace,
|
|
124
|
+
replicas: d.spec?.replicas,
|
|
125
|
+
ready: d.status?.readyReplicas ?? 0,
|
|
126
|
+
available: d.status?.availableReplicas ?? 0,
|
|
127
|
+
images: (d.spec?.template?.spec?.containers ?? []).map((c) => `${c.name}=${c.image}`),
|
|
128
|
+
}));
|
|
129
|
+
return jsonResult(deployments);
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: "list_services",
|
|
134
|
+
capability: "read",
|
|
135
|
+
config: {
|
|
136
|
+
title: "List services",
|
|
137
|
+
description: "List services in a namespace with type and cluster IP.",
|
|
138
|
+
inputSchema: { namespace: z.string().describe("Namespace"), ...contextArg },
|
|
139
|
+
},
|
|
140
|
+
handler: async (args, { client, policy }) => {
|
|
141
|
+
const namespace = args.namespace;
|
|
142
|
+
const context = args.context;
|
|
143
|
+
policy.guard({ tool: "list_services", capability: "read", namespace, context });
|
|
144
|
+
const res = await client.listServices(namespace, context);
|
|
145
|
+
const services = (res.items ?? []).map((s) => ({
|
|
146
|
+
name: s.metadata?.name,
|
|
147
|
+
type: s.spec?.type,
|
|
148
|
+
clusterIP: s.spec?.clusterIP,
|
|
149
|
+
ports: (s.spec?.ports ?? []).map((p) => `${p.port}/${p.protocol}`),
|
|
150
|
+
}));
|
|
151
|
+
return jsonResult(services);
|
|
152
|
+
},
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
name: "list_nodes",
|
|
156
|
+
capability: "read",
|
|
157
|
+
config: {
|
|
158
|
+
title: "List nodes",
|
|
159
|
+
description: "List cluster nodes with readiness and kubelet version.",
|
|
160
|
+
inputSchema: { ...contextArg },
|
|
161
|
+
},
|
|
162
|
+
handler: async (args, { client, policy }) => {
|
|
163
|
+
const context = args.context;
|
|
164
|
+
policy.guard({ tool: "list_nodes", capability: "read", context });
|
|
165
|
+
const res = await client.listNodes(context);
|
|
166
|
+
const nodes = (res.items ?? []).map((n) => ({
|
|
167
|
+
name: n.metadata?.name,
|
|
168
|
+
ready: (n.status?.conditions ?? []).find((c) => c.type === "Ready")?.status,
|
|
169
|
+
version: n.status?.nodeInfo?.kubeletVersion,
|
|
170
|
+
os: n.status?.nodeInfo?.osImage,
|
|
171
|
+
}));
|
|
172
|
+
return jsonResult(nodes);
|
|
173
|
+
},
|
|
174
|
+
},
|
|
175
|
+
{
|
|
176
|
+
name: "list_events",
|
|
177
|
+
capability: "read",
|
|
178
|
+
config: {
|
|
179
|
+
title: "List events",
|
|
180
|
+
description: "List recent events in a namespace — useful for diagnosing failures.",
|
|
181
|
+
inputSchema: { namespace: z.string().describe("Namespace"), ...contextArg },
|
|
182
|
+
},
|
|
183
|
+
handler: async (args, { client, policy }) => {
|
|
184
|
+
const namespace = args.namespace;
|
|
185
|
+
const context = args.context;
|
|
186
|
+
policy.guard({ tool: "list_events", capability: "read", namespace, context });
|
|
187
|
+
const res = await client.listEvents(namespace, context);
|
|
188
|
+
const events = (res.items ?? []).map((e) => ({
|
|
189
|
+
type: e.type,
|
|
190
|
+
reason: e.reason,
|
|
191
|
+
object: `${e.involvedObject?.kind}/${e.involvedObject?.name}`,
|
|
192
|
+
message: e.message,
|
|
193
|
+
count: e.count,
|
|
194
|
+
lastSeen: e.lastTimestamp,
|
|
195
|
+
}));
|
|
196
|
+
return jsonResult(events);
|
|
197
|
+
},
|
|
198
|
+
},
|
|
199
|
+
{
|
|
200
|
+
name: "get_resource",
|
|
201
|
+
capability: "read",
|
|
202
|
+
config: {
|
|
203
|
+
title: "Get any resource",
|
|
204
|
+
description: "Read an arbitrary Kubernetes object by apiVersion/kind/name (e.g. apiVersion=apps/v1, kind=Deployment).",
|
|
205
|
+
inputSchema: {
|
|
206
|
+
apiVersion: z.string().describe("e.g. v1, apps/v1, networking.k8s.io/v1"),
|
|
207
|
+
kind: z.string().describe("e.g. Pod, Deployment, Ingress"),
|
|
208
|
+
name: z.string().describe("Resource name"),
|
|
209
|
+
namespace: z.string().optional().describe("Namespace (omit for cluster-scoped resources)"),
|
|
210
|
+
...contextArg,
|
|
211
|
+
},
|
|
212
|
+
},
|
|
213
|
+
handler: async (args, { client, policy }) => {
|
|
214
|
+
const namespace = args.namespace;
|
|
215
|
+
const context = args.context;
|
|
216
|
+
policy.guard({ tool: "get_resource", capability: "read", namespace, context });
|
|
217
|
+
const res = await client.getObject(args.apiVersion, args.kind, args.name, namespace, context);
|
|
218
|
+
return jsonResult(res);
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
];
|
|
222
|
+
//# sourceMappingURL=read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.js","sourceRoot":"","sources":["../../src/tools/read.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { ZodRawShape } from "zod";
|
|
2
|
+
import type { K8sClient } from "../k8s/client.js";
|
|
3
|
+
import type { Capability, SecurityPolicy } from "../security.js";
|
|
4
|
+
export interface ToolContext {
|
|
5
|
+
client: K8sClient;
|
|
6
|
+
policy: SecurityPolicy;
|
|
7
|
+
}
|
|
8
|
+
export interface ToolResult {
|
|
9
|
+
content: Array<{
|
|
10
|
+
type: "text";
|
|
11
|
+
text: string;
|
|
12
|
+
}>;
|
|
13
|
+
isError?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface ToolDef<Shape extends ZodRawShape = ZodRawShape> {
|
|
17
|
+
name: string;
|
|
18
|
+
capability: Capability;
|
|
19
|
+
/** If set, the tool is only registered when this predicate passes. */
|
|
20
|
+
enabledWhen?: (policy: SecurityPolicy) => boolean;
|
|
21
|
+
config: {
|
|
22
|
+
title: string;
|
|
23
|
+
description: string;
|
|
24
|
+
inputSchema: Shape;
|
|
25
|
+
};
|
|
26
|
+
handler: (args: Record<string, unknown>, ctx: ToolContext) => Promise<ToolResult>;
|
|
27
|
+
}
|
|
28
|
+
export declare function jsonResult(value: unknown): ToolResult;
|
|
29
|
+
export declare function textResult(text: string): ToolResult;
|
|
30
|
+
/** Trim large list responses to the essential, model-friendly fields. */
|
|
31
|
+
export declare function summarizePods(list: {
|
|
32
|
+
items?: Array<Record<string, any>>;
|
|
33
|
+
}): {
|
|
34
|
+
name: any;
|
|
35
|
+
namespace: any;
|
|
36
|
+
phase: any;
|
|
37
|
+
ready: string;
|
|
38
|
+
restarts: any;
|
|
39
|
+
node: any;
|
|
40
|
+
startTime: any;
|
|
41
|
+
}[];
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export function jsonResult(value) {
|
|
2
|
+
return { content: [{ type: "text", text: JSON.stringify(value, null, 2) }] };
|
|
3
|
+
}
|
|
4
|
+
export function textResult(text) {
|
|
5
|
+
return { content: [{ type: "text", text }] };
|
|
6
|
+
}
|
|
7
|
+
/** Trim large list responses to the essential, model-friendly fields. */
|
|
8
|
+
export function summarizePods(list) {
|
|
9
|
+
return (list.items ?? []).map((p) => ({
|
|
10
|
+
name: p.metadata?.name,
|
|
11
|
+
namespace: p.metadata?.namespace,
|
|
12
|
+
phase: p.status?.phase,
|
|
13
|
+
ready: (p.status?.containerStatuses ?? []).filter((c) => c.ready).length +
|
|
14
|
+
"/" +
|
|
15
|
+
(p.status?.containerStatuses ?? []).length,
|
|
16
|
+
restarts: (p.status?.containerStatuses ?? []).reduce((n, c) => n + (c.restartCount ?? 0), 0),
|
|
17
|
+
node: p.spec?.nodeName,
|
|
18
|
+
startTime: p.status?.startTime,
|
|
19
|
+
}));
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AA6BA,MAAM,UAAU,UAAU,CAAC,KAAc;IACvC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACrC,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AAC/C,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,aAAa,CAAC,IAA4C;IACxE,OAAO,CAAC,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACpC,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,IAAI;QACtB,SAAS,EAAE,CAAC,CAAC,QAAQ,EAAE,SAAS;QAChC,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,KAAK;QACtB,KAAK,EACH,CAAC,CAAC,CAAC,MAAM,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM;YACtE,GAAG;YACH,CAAC,CAAC,CAAC,MAAM,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC,MAAM;QAC5C,QAAQ,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,iBAAiB,IAAI,EAAE,CAAC,CAAC,MAAM,CAClD,CAAC,CAAS,EAAE,CAAM,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,YAAY,IAAI,CAAC,CAAC,EAChD,CAAC,CACF;QACD,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,QAAQ;QACtB,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,SAAS;KAC/B,CAAC,CAAC,CAAC;AACN,CAAC"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
import { jsonResult, textResult } from "./types.js";
|
|
3
|
+
const contextArg = {
|
|
4
|
+
context: z.string().optional().describe("kube-config context to target (defaults to current-context)"),
|
|
5
|
+
};
|
|
6
|
+
export const writeTools = [
|
|
7
|
+
{
|
|
8
|
+
name: "scale_deployment",
|
|
9
|
+
capability: "write",
|
|
10
|
+
config: {
|
|
11
|
+
title: "Scale deployment",
|
|
12
|
+
description: "Set the replica count of a deployment.",
|
|
13
|
+
inputSchema: {
|
|
14
|
+
name: z.string().describe("Deployment name"),
|
|
15
|
+
namespace: z.string().describe("Namespace"),
|
|
16
|
+
replicas: z.number().int().min(0).max(1000).describe("Desired replica count"),
|
|
17
|
+
...contextArg,
|
|
18
|
+
},
|
|
19
|
+
},
|
|
20
|
+
handler: async (args, { client, policy }) => {
|
|
21
|
+
const name = args.name;
|
|
22
|
+
const namespace = args.namespace;
|
|
23
|
+
const replicas = args.replicas;
|
|
24
|
+
const context = args.context;
|
|
25
|
+
const { dryRun } = policy.guard({ tool: "scale_deployment", capability: "write", namespace, context });
|
|
26
|
+
if (dryRun)
|
|
27
|
+
return textResult(`[dry-run] Would scale ${namespace}/${name} to ${replicas} replicas.`);
|
|
28
|
+
await client.scaleDeployment(name, namespace, replicas, context);
|
|
29
|
+
return jsonResult({ scaled: true, namespace, name, replicas });
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: "restart_deployment",
|
|
34
|
+
capability: "write",
|
|
35
|
+
config: {
|
|
36
|
+
title: "Restart deployment",
|
|
37
|
+
description: "Trigger a rolling restart of a deployment (equivalent to `kubectl rollout restart`).",
|
|
38
|
+
inputSchema: {
|
|
39
|
+
name: z.string().describe("Deployment name"),
|
|
40
|
+
namespace: z.string().describe("Namespace"),
|
|
41
|
+
...contextArg,
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
handler: async (args, { client, policy }) => {
|
|
45
|
+
const name = args.name;
|
|
46
|
+
const namespace = args.namespace;
|
|
47
|
+
const context = args.context;
|
|
48
|
+
const { dryRun } = policy.guard({ tool: "restart_deployment", capability: "write", namespace, context });
|
|
49
|
+
if (dryRun)
|
|
50
|
+
return textResult(`[dry-run] Would restart deployment ${namespace}/${name}.`);
|
|
51
|
+
await client.restartDeployment(name, namespace, context);
|
|
52
|
+
return jsonResult({ restarted: true, namespace, name });
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "set_deployment_image",
|
|
57
|
+
capability: "write",
|
|
58
|
+
config: {
|
|
59
|
+
title: "Set deployment image",
|
|
60
|
+
description: "Update the image of a named container in a deployment.",
|
|
61
|
+
inputSchema: {
|
|
62
|
+
name: z.string().describe("Deployment name"),
|
|
63
|
+
namespace: z.string().describe("Namespace"),
|
|
64
|
+
container: z.string().describe("Container name within the pod template"),
|
|
65
|
+
image: z.string().describe("New image reference, e.g. nginx:1.27"),
|
|
66
|
+
...contextArg,
|
|
67
|
+
},
|
|
68
|
+
},
|
|
69
|
+
handler: async (args, { client, policy }) => {
|
|
70
|
+
const name = args.name;
|
|
71
|
+
const namespace = args.namespace;
|
|
72
|
+
const container = args.container;
|
|
73
|
+
const image = args.image;
|
|
74
|
+
const context = args.context;
|
|
75
|
+
const { dryRun } = policy.guard({
|
|
76
|
+
tool: "set_deployment_image",
|
|
77
|
+
capability: "write",
|
|
78
|
+
namespace,
|
|
79
|
+
context,
|
|
80
|
+
});
|
|
81
|
+
if (dryRun)
|
|
82
|
+
return textResult(`[dry-run] Would set ${namespace}/${name} container '${container}' to ${image}.`);
|
|
83
|
+
await client.setDeploymentImage(name, namespace, container, image, context);
|
|
84
|
+
return jsonResult({ updated: true, namespace, name, container, image });
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: "create_namespace",
|
|
89
|
+
capability: "write",
|
|
90
|
+
config: {
|
|
91
|
+
title: "Create namespace",
|
|
92
|
+
description: "Create a new namespace.",
|
|
93
|
+
inputSchema: { name: z.string().describe("Namespace name"), ...contextArg },
|
|
94
|
+
},
|
|
95
|
+
handler: async (args, { client, policy }) => {
|
|
96
|
+
const name = args.name;
|
|
97
|
+
const context = args.context;
|
|
98
|
+
// The new namespace itself is the target, so scope-check it.
|
|
99
|
+
const { dryRun } = policy.guard({
|
|
100
|
+
tool: "create_namespace",
|
|
101
|
+
capability: "write",
|
|
102
|
+
namespace: name,
|
|
103
|
+
context,
|
|
104
|
+
});
|
|
105
|
+
if (dryRun)
|
|
106
|
+
return textResult(`[dry-run] Would create namespace '${name}'.`);
|
|
107
|
+
await client.createNamespace(name, context);
|
|
108
|
+
return jsonResult({ created: true, namespace: name });
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: "apply_manifest",
|
|
113
|
+
capability: "write",
|
|
114
|
+
enabledWhen: (p) => p.isCapabilityEnabled("write"),
|
|
115
|
+
config: {
|
|
116
|
+
title: "Apply a manifest",
|
|
117
|
+
description: "Create or replace an arbitrary Kubernetes object from a manifest. Requires K8S_ALLOW_APPLY=true. " +
|
|
118
|
+
"Pass the manifest as a JSON object with apiVersion, kind, metadata, and spec.",
|
|
119
|
+
inputSchema: {
|
|
120
|
+
manifest: z
|
|
121
|
+
.record(z.any())
|
|
122
|
+
.describe("The Kubernetes object as JSON (apiVersion, kind, metadata, spec, ...)"),
|
|
123
|
+
...contextArg,
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
handler: async (args, { client, policy }) => {
|
|
127
|
+
const manifest = args.manifest;
|
|
128
|
+
const namespace = manifest.metadata?.namespace;
|
|
129
|
+
const context = args.context;
|
|
130
|
+
const { dryRun } = policy.guard({
|
|
131
|
+
tool: "apply_manifest",
|
|
132
|
+
capability: "write",
|
|
133
|
+
namespace,
|
|
134
|
+
context,
|
|
135
|
+
requiresApply: true,
|
|
136
|
+
});
|
|
137
|
+
if (!manifest.apiVersion || !manifest.kind || !manifest.metadata?.name) {
|
|
138
|
+
return { content: [{ type: "text", text: "Manifest must include apiVersion, kind, and metadata.name." }], isError: true };
|
|
139
|
+
}
|
|
140
|
+
if (dryRun)
|
|
141
|
+
return textResult(`[dry-run] Would apply ${manifest.kind}/${manifest.metadata.name}` +
|
|
142
|
+
`${namespace ? ` in ${namespace}` : ""}.`);
|
|
143
|
+
const { action } = await client.applyObject(manifest, context);
|
|
144
|
+
return jsonResult({ applied: true, action, kind: manifest.kind, name: manifest.metadata.name, namespace });
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
];
|
|
148
|
+
//# sourceMappingURL=write.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"write.js","sourceRoot":"","sources":["../../src/tools/write.ts"],"names":[],"mappings":"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"}
|