mcp-server-kubernetes 0.1.1 → 0.1.2

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
@@ -4,6 +4,8 @@ MCP Server that can connect to a Kubernetes cluster and manage it.
4
4
 
5
5
  https://github.com/user-attachments/assets/f25f8f4e-4d04-479b-9ae0-5dac452dd2ed
6
6
 
7
+ <a href="https://glama.ai/mcp/servers/w71ieamqrt"><img width="380" height="200" src="https://glama.ai/mcp/servers/w71ieamqrt/badge" /></a>
8
+
7
9
  ## Usage with Claude Desktop
8
10
 
9
11
  ```json
@@ -35,21 +37,112 @@ If you have errors, open up a standard terminal and run `kubectl get pods` to se
35
37
  - [x] List all deployments
36
38
  - [x] Create a pod
37
39
  - [x] Delete a pod
40
+ - [x] Describe a pod
38
41
  - [x] List all namespaces
39
- - [] Port forward to a pod
40
- - [] Get logs from a pod for debugging
41
- - [] Choose namespace for next commands (memory)
42
- - [] Support Helm for installing charts
42
+ - [ ] Port forward to a pod
43
+ - [ ] Get logs from a pod for debugging
44
+ - [ ] Choose namespace for next commands (memory)
45
+ - [ ] Support Helm for installing charts
46
+
47
+ ## In Progress
48
+
49
+ - [ ] [Docker support](https://github.com/Flux159/mcp-server-kubernetes/pull/9)
43
50
 
44
- ## Development & Testing
51
+ ## Local Development
45
52
 
46
53
  ```bash
47
54
  git clone https://github.com/Flux159/mcp-server-kubernetes.git
48
55
  cd mcp-server-kubernetes
49
56
  bun install
57
+ ```
58
+
59
+ ### Development Workflow
60
+
61
+ 1. Start the server in development mode (watches for file changes):
62
+
63
+ ```bash
64
+ bun run dev
65
+ ```
66
+
67
+ 2. Run unit tests:
68
+
69
+ ```bash
50
70
  bun run test
51
71
  ```
52
72
 
73
+ 3. Build the project:
74
+
75
+ ```bash
76
+ bun run build
77
+ ```
78
+
79
+ 4. Local Testing with [Inspector](https://github.com/modelcontextprotocol/inspector)
80
+
81
+ ```bash
82
+ npx @modelcontextprotocol/inspector node build/index.js
83
+ # Follow further instructions on terminal for Inspector link
84
+ ```
85
+
86
+ ### Project Structure
87
+
88
+ ```
89
+ src/
90
+ ├── index.ts # Main server implementation
91
+ ├── types.ts # TypeScript type definitions
92
+ └── unit.test.ts # Unit tests
93
+ ```
94
+
95
+ ### Contributing
96
+
97
+ 1. Fork the repository
98
+ 2. Create a feature branch
99
+ 3. Make your changes
100
+ 4. Add tests for new functionality
101
+ 5. Ensure all tests pass
102
+ 6. Submit a pull request
103
+
104
+ For bigger changes, please open an issue first to discuss the proposed changes.
105
+
106
+ ## Architecture
107
+
108
+ This section describes the high-level architecture of the MCP Kubernetes server.
109
+
110
+ ### Request Flow
111
+
112
+ The sequence diagram below illustrates how requests flow through the system:
113
+
114
+ ```mermaid
115
+ sequenceDiagram
116
+ participant Client
117
+ participant Transport as StdioTransport
118
+ participant Server as MCP Server
119
+ participant Handler as Request Handler
120
+ participant K8sManager as KubernetesManager
121
+ participant K8s as Kubernetes API
122
+
123
+ Client->>Transport: Send Request via STDIO
124
+ Transport->>Server: Forward Request
125
+
126
+ alt Tools Request
127
+ Server->>Handler: Route to tools handler
128
+ Handler->>K8sManager: Execute tool operation
129
+ K8sManager->>K8s: Make API call
130
+ K8s-->>K8sManager: Return result
131
+ K8sManager-->>Handler: Process response
132
+ Handler-->>Server: Return tool result
133
+ else Resource Request
134
+ Server->>Handler: Route to resource handler
135
+ Handler->>K8sManager: Get resource data
136
+ K8sManager->>K8s: Query API
137
+ K8s-->>K8sManager: Return data
138
+ K8sManager-->>Handler: Format response
139
+ Handler-->>Server: Return resource data
140
+ end
141
+
142
+ Server-->>Transport: Send Response
143
+ Transport-->>Client: Return Final Response
144
+ ```
145
+
53
146
  ## Not planned
54
147
 
55
148
  Authentication / adding clusters to kubectx.
package/dist/index.js CHANGED
@@ -293,6 +293,18 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
293
293
  required: ["name", "namespace"],
294
294
  },
295
295
  },
296
+ {
297
+ name: "describe_pod",
298
+ description: "Describe a Kubernetes pod (read details like status, containers, etc.)",
299
+ inputSchema: {
300
+ type: "object",
301
+ properties: {
302
+ name: { type: "string" },
303
+ namespace: { type: "string" },
304
+ },
305
+ required: ["name", "namespace"],
306
+ },
307
+ },
296
308
  {
297
309
  name: "cleanup",
298
310
  description: "Cleanup all managed resources",
@@ -471,6 +483,77 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
471
483
  throw error;
472
484
  }
473
485
  }
486
+ case "describe_pod": {
487
+ const describePodInput = input;
488
+ try {
489
+ const { body } = await k8sManager
490
+ .getCoreApi()
491
+ .readNamespacedPod(describePodInput.name, describePodInput.namespace);
492
+ if (!body) {
493
+ return {
494
+ content: [
495
+ {
496
+ type: "text",
497
+ text: JSON.stringify({
498
+ error: "Pod not found",
499
+ status: "not_found"
500
+ }, null, 2),
501
+ },
502
+ ],
503
+ isError: true,
504
+ };
505
+ }
506
+ // Format the pod details for better readability
507
+ const podDetails = {
508
+ kind: body.kind,
509
+ metadata: {
510
+ name: body.metadata?.name,
511
+ namespace: body.metadata?.namespace,
512
+ creationTimestamp: body.metadata?.creationTimestamp,
513
+ labels: body.metadata?.labels,
514
+ },
515
+ spec: {
516
+ containers: body.spec?.containers.map(container => ({
517
+ name: container.name,
518
+ image: container.image,
519
+ ports: container.ports,
520
+ resources: container.resources,
521
+ })),
522
+ nodeName: body.spec?.nodeName,
523
+ },
524
+ status: {
525
+ phase: body.status?.phase,
526
+ conditions: body.status?.conditions,
527
+ containerStatuses: body.status?.containerStatuses,
528
+ }
529
+ };
530
+ return {
531
+ content: [
532
+ {
533
+ type: "text",
534
+ text: JSON.stringify(podDetails, null, 2),
535
+ },
536
+ ],
537
+ };
538
+ }
539
+ catch (error) {
540
+ if (error.response?.statusCode === 404) {
541
+ return {
542
+ content: [
543
+ {
544
+ type: "text",
545
+ text: JSON.stringify({
546
+ error: "Pod not found",
547
+ status: "not_found"
548
+ }, null, 2),
549
+ },
550
+ ],
551
+ isError: true,
552
+ };
553
+ }
554
+ throw new McpError(ErrorCode.InternalError, `Failed to describe pod: ${error.response?.body?.message || error.message}`);
555
+ }
556
+ }
474
557
  case "cleanup": {
475
558
  await k8sManager.cleanup();
476
559
  return {
@@ -597,3 +680,10 @@ server.setRequestHandler(ReadResourceRequestSchema, async (request) => {
597
680
  });
598
681
  const transport = new StdioServerTransport();
599
682
  await server.connect(transport);
683
+ ["SIGINT", "SIGTERM"].forEach((signal) => {
684
+ process.on(signal, async () => {
685
+ console.log(`Received ${signal}, shutting down...`);
686
+ await server.close();
687
+ process.exit(0);
688
+ });
689
+ });
package/dist/unit.test.js CHANGED
@@ -74,6 +74,24 @@ test("kubernetes server operations", async () => {
74
74
  const createResult = JSON.parse(createPodResult.content[0].text);
75
75
  expect(createResult.podName).toBe("test-pod");
76
76
  expect(createResult.status).toBe("created");
77
+ // Describe the pod
78
+ console.log("Describing test pod...");
79
+ const describePodResult = await client.request({
80
+ method: "tools/call",
81
+ params: {
82
+ name: "describe_pod",
83
+ arguments: {
84
+ name: "test-pod",
85
+ namespace: "default",
86
+ },
87
+ },
88
+ }, CreatePodResponseSchema // Reusing existing schema since response format is similar
89
+ );
90
+ expect(describePodResult.content[0].type).toBe("text");
91
+ const podDescription = JSON.parse(describePodResult.content[0].text);
92
+ expect(podDescription.metadata.name).toBe("test-pod");
93
+ expect(podDescription.metadata.namespace).toBe("default");
94
+ expect(podDescription.kind).toBe("Pod");
77
95
  // List pods to verify creation
78
96
  console.log("Listing pods...");
79
97
  const listPodsResult = await client.request({
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-server-kubernetes",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "MCP server for interacting with Kubernetes clusters via kubectl",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -41,6 +41,6 @@
41
41
  "@types/node": "^22.9.3",
42
42
  "shx": "^0.3.4",
43
43
  "typescript": "^5.6.2",
44
- "vitest": "2.1.8"
44
+ "vitest": "2.1.9"
45
45
  }
46
46
  }