mcp-server-kubernetes 3.2.0 → 3.2.1

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.
@@ -168,7 +168,7 @@ export async function kubectlGet(k8sManager, input) {
168
168
  name: item.metadata?.name || "",
169
169
  namespace: item.metadata?.namespace || "",
170
170
  kind: item.kind || resourceType,
171
- status: getResourceStatus(item),
171
+ status: getResourceStatus(item, resourceType),
172
172
  createdAt: item.metadata?.creationTimestamp,
173
173
  }));
174
174
  return {
@@ -218,13 +218,94 @@ export async function kubectlGet(k8sManager, input) {
218
218
  throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl get command: ${error.message}`);
219
219
  }
220
220
  }
221
+ // Compute pod status the same way kubectl does, by inspecting container statuses
222
+ // Based on kubernetes/pkg/printers/internalversion/printers.go printPod()
223
+ function getPodStatus(pod) {
224
+ let reason = pod.status?.phase || "Unknown";
225
+ if (pod.status?.reason) {
226
+ reason = pod.status.reason;
227
+ }
228
+ // Check init container statuses
229
+ const initContainerStatuses = pod.status?.initContainerStatuses || [];
230
+ for (let i = 0; i < initContainerStatuses.length; i++) {
231
+ const container = initContainerStatuses[i];
232
+ const terminated = container.state?.terminated;
233
+ const waiting = container.state?.waiting;
234
+ if (terminated && terminated.exitCode === 0) {
235
+ // Init container completed successfully, continue
236
+ continue;
237
+ }
238
+ if (terminated) {
239
+ if (terminated.reason) {
240
+ reason = `Init:${terminated.reason}`;
241
+ }
242
+ else if (terminated.signal) {
243
+ reason = `Init:Signal:${terminated.signal}`;
244
+ }
245
+ else {
246
+ reason = `Init:ExitCode:${terminated.exitCode}`;
247
+ }
248
+ }
249
+ else if (waiting && waiting.reason && waiting.reason !== "PodInitializing") {
250
+ reason = `Init:${waiting.reason}`;
251
+ }
252
+ else {
253
+ const totalInit = initContainerStatuses.length;
254
+ reason = `Init:${i}/${totalInit}`;
255
+ }
256
+ break;
257
+ }
258
+ // If all init containers are done, check regular container statuses
259
+ if (initContainerStatuses.length === 0 ||
260
+ !reason.startsWith("Init:")) {
261
+ const containerStatuses = pod.status?.containerStatuses || [];
262
+ let hasRunning = false;
263
+ for (let i = containerStatuses.length - 1; i >= 0; i--) {
264
+ const container = containerStatuses[i];
265
+ const waiting = container.state?.waiting;
266
+ const terminated = container.state?.terminated;
267
+ if (waiting && waiting.reason) {
268
+ reason = waiting.reason;
269
+ }
270
+ else if (terminated) {
271
+ if (terminated.reason) {
272
+ reason = terminated.reason;
273
+ }
274
+ else if (terminated.signal) {
275
+ reason = `Signal:${terminated.signal}`;
276
+ }
277
+ else {
278
+ reason = `ExitCode:${terminated.exitCode}`;
279
+ }
280
+ }
281
+ else if (container.ready && container.state?.running) {
282
+ hasRunning = true;
283
+ }
284
+ }
285
+ // If all containers are ready and running, use the phase
286
+ if (hasRunning && reason === (pod.status?.phase || "Unknown")) {
287
+ reason = pod.status?.phase || "Running";
288
+ }
289
+ }
290
+ // Handle pod deletion
291
+ if (pod.metadata?.deletionTimestamp) {
292
+ reason = "Terminating";
293
+ }
294
+ return reason;
295
+ }
221
296
  // Extract status from various resource types
222
- function getResourceStatus(resource) {
297
+ function getResourceStatus(resource, resourceType) {
223
298
  if (!resource)
224
299
  return "Unknown";
225
- // Pod status
226
- if (resource.status?.phase) {
227
- return resource.status.phase;
300
+ const isPod = resource.kind === "Pod" ||
301
+ resourceType === "pods" ||
302
+ resourceType === "pod" ||
303
+ resourceType === "po" ||
304
+ (resource.status?.phase !== undefined &&
305
+ resource.status?.containerStatuses !== undefined);
306
+ // Pod status - use kubectl-equivalent logic
307
+ if (isPod) {
308
+ return getPodStatus(resource);
228
309
  }
229
310
  // Deployment, ReplicaSet, StatefulSet status
230
311
  if (resource.status?.readyReplicas !== undefined) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-server-kubernetes",
3
- "version": "3.2.0",
3
+ "version": "3.2.1",
4
4
  "description": "MCP server for interacting with Kubernetes clusters via kubectl",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -38,7 +38,7 @@
38
38
  },
39
39
  "dependencies": {
40
40
  "@kubernetes/client-node": "1.3.0",
41
- "@modelcontextprotocol/sdk": "1.25.2",
41
+ "@modelcontextprotocol/sdk": "1.26.0",
42
42
  "express": "4.21.2",
43
43
  "js-yaml": "4.1.1",
44
44
  "yaml": "2.7.0",