UNPKG

mcp-server-kubernetes

Version:

MCP server for interacting with Kubernetes clusters via kubectl

122 lines (121 loc) 4.33 kB
import { execFileSync } from "child_process"; import { McpError, ErrorCode } from "@modelcontextprotocol/sdk/types.js"; import { getSpawnMaxBuffer } from "../config/max-buffer.js"; import { contextParameter, namespaceParameter } from "../models/common-parameters.js"; export const kubectlGenericSchema = { name: "kubectl_generic", description: "Execute any kubectl command with the provided arguments and flags", inputSchema: { type: "object", properties: { command: { type: "string", description: "The kubectl command to execute (e.g. patch, rollout, top)", }, subCommand: { type: "string", description: "Subcommand if applicable (e.g. 'history' for rollout)", }, resourceType: { type: "string", description: "Resource type (e.g. pod, deployment)", }, name: { type: "string", description: "Resource name", }, namespace: namespaceParameter, outputFormat: { type: "string", description: "Output format (e.g. json, yaml, wide)", enum: ["json", "yaml", "wide", "name", "custom"], }, flags: { type: "object", description: "Command flags as key-value pairs", additionalProperties: true, }, args: { type: "array", items: { type: "string" }, description: "Additional command arguments", }, context: contextParameter, }, required: ["command"], }, }; export async function kubectlGeneric(k8sManager, input) { try { // Start building the kubectl command const command = "kubectl"; const cmdArgs = [input.command]; // Add subcommand if provided if (input.subCommand) { cmdArgs.push(input.subCommand); } // Add resource type if provided if (input.resourceType) { cmdArgs.push(input.resourceType); } // Add resource name if provided if (input.name) { cmdArgs.push(input.name); } // Add namespace if provided if (input.namespace) { cmdArgs.push(`--namespace=${input.namespace}`); } // Add output format if provided if (input.outputFormat) { cmdArgs.push(`-o=${input.outputFormat}`); } // Add any provided flags if (input.flags) { for (const [key, value] of Object.entries(input.flags)) { if (value === true) { // Handle boolean flags cmdArgs.push(`--${key}`); } else if (value !== false && value !== null && value !== undefined) { // Skip false/null/undefined values, add others as --key=value cmdArgs.push(`--${key}=${value}`); } } } // Add any additional arguments if (input.args && input.args.length > 0) { cmdArgs.push(...input.args); } // Add context if provided if (input.context) { cmdArgs.push("--context", input.context); } // Execute the command try { console.error(`Executing: kubectl ${cmdArgs.join(" ")}`); const result = execFileSync(command, cmdArgs, { encoding: "utf8", maxBuffer: getSpawnMaxBuffer(), env: { ...process.env, KUBECONFIG: process.env.KUBECONFIG }, }); return { content: [ { type: "text", text: result, }, ], }; } catch (error) { throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl command: ${error.message}`); } } catch (error) { if (error instanceof McpError) { throw error; } throw new McpError(ErrorCode.InternalError, `Failed to execute kubectl command: ${error.message}`); } }