mcp-server-kubernetes
Version:
MCP server for interacting with Kubernetes clusters via kubectl
223 lines (222 loc) • 6.66 kB
JavaScript
import { execFileSync } from "child_process";
import { writeFileSync, unlinkSync } from "fs";
import yaml from "yaml";
import { getSpawnMaxBuffer } from "../config/max-buffer.js";
import { contextParameter, namespaceParameter } from "../models/common-parameters.js";
export const installHelmChartSchema = {
name: "install_helm_chart",
description: "Install a Helm chart",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Release name",
},
chart: {
type: "string",
description: "Chart name",
},
repo: {
type: "string",
description: "Chart repository URL",
},
namespace: namespaceParameter,
context: contextParameter,
values: {
type: "object",
description: "Chart values",
properties: {},
additionalProperties: true,
},
},
required: ["name", "chart", "repo", "namespace"],
},
};
export const upgradeHelmChartSchema = {
name: "upgrade_helm_chart",
description: "Upgrade a Helm release",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Release name",
},
chart: {
type: "string",
description: "Chart name",
},
repo: {
type: "string",
description: "Chart repository URL",
},
namespace: namespaceParameter,
context: contextParameter,
values: {
type: "object",
description: "Chart values",
properties: {},
additionalProperties: true,
},
},
required: ["name", "chart", "repo", "namespace"],
},
};
export const uninstallHelmChartSchema = {
name: "uninstall_helm_chart",
description: "Uninstall a Helm release",
inputSchema: {
type: "object",
properties: {
name: {
type: "string",
description: "Release name",
},
namespace: namespaceParameter,
context: contextParameter,
},
required: ["name", "namespace"],
},
};
const executeHelmCommand = (command, args) => {
try {
// Add a generous timeout of 60 seconds for Helm operations
return execFileSync(command, args, {
encoding: "utf8",
timeout: 60000, // 60 seconds timeout
maxBuffer: getSpawnMaxBuffer(),
env: { ...process.env, KUBECONFIG: process.env.KUBECONFIG },
});
}
catch (error) {
throw new Error(`Helm command failed: ${error.message}`);
}
};
const writeValuesFile = (name, values) => {
const filename = `${name}-values.yaml`;
writeFileSync(filename, yaml.stringify(values));
return filename;
};
export async function installHelmChart(params) {
try {
// Add helm repository if provided
if (params.repo) {
const repoName = params.chart.split("/")[0];
executeHelmCommand("helm", ["repo", "add", repoName, params.repo]);
executeHelmCommand("helm", ["repo", "update"]);
}
let command = "helm";
let args = [
"install",
params.name,
params.chart,
"--namespace",
params.namespace,
"--create-namespace",
];
// Handle values if provided
if (params.values) {
const valuesFile = writeValuesFile(params.name, params.values);
args.push("-f", valuesFile);
try {
executeHelmCommand(command, args);
}
finally {
// Cleanup values file
unlinkSync(valuesFile);
}
}
else {
executeHelmCommand(command, args);
}
const response = {
status: "installed",
message: `Successfully installed ${params.name}`,
};
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
catch (error) {
throw new Error(`Failed to install Helm chart: ${error.message}`);
}
}
export async function upgradeHelmChart(params) {
try {
// Add helm repository if provided
if (params.repo) {
const repoName = params.chart.split("/")[0];
executeHelmCommand("helm", ["repo", "add", repoName, params.repo]);
executeHelmCommand("helm", ["repo", "update"]);
}
let command = "helm";
let args = [
"upgrade",
params.name,
params.chart,
"--namespace",
params.namespace,
];
// Handle values if provided
if (params.values) {
const valuesFile = writeValuesFile(params.name, params.values);
args.push("-f", valuesFile);
try {
executeHelmCommand(command, args);
}
finally {
// Cleanup values file
unlinkSync(valuesFile);
}
}
else {
executeHelmCommand(command, args);
}
const response = {
status: "upgraded",
message: `Successfully upgraded ${params.name}`,
};
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
catch (error) {
throw new Error(`Failed to upgrade Helm chart: ${error.message}`);
}
}
export async function uninstallHelmChart(params) {
try {
executeHelmCommand("helm", [
"uninstall",
params.name,
"--namespace",
params.namespace,
]);
const response = {
status: "uninstalled",
message: `Successfully uninstalled ${params.name}`,
};
return {
content: [
{
type: "text",
text: JSON.stringify(response, null, 2),
},
],
};
}
catch (error) {
throw new Error(`Failed to uninstall Helm chart: ${error.message}`);
}
}