Skip to main content
Glama
Flux159
by Flux159

kubectl_create

Create Kubernetes resources like deployments, services, and configmaps from YAML files or command parameters to manage containerized applications.

Instructions

Create Kubernetes resources using various methods (from file or using subcommands)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dryRunNoIf true, only validate the resource, don't actually execute the operation
outputNoOutput format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-fileyaml
validateNoIf true, validate resource schema against server schema
manifestNoYAML manifest to create resources from
filenameNoPath to a YAML file to create resources from
resourceTypeNoType of resource to create (namespace, configmap, deployment, service, etc.)
nameNoName of the resource to create
namespaceNoKubernetes namespacedefault
fromLiteralNoKey-value pair for creating configmap (e.g. ["key1=value1", "key2=value2"])
fromFileNoPath to file for creating configmap (e.g. ["key1=/path/to/file1", "key2=/path/to/file2"])
secretTypeNoType of secret to create (generic, docker-registry, tls)
serviceTypeNoType of service to create (clusterip, nodeport, loadbalancer, externalname)
tcpPortNoPort pairs for tcp service (e.g. ["80:8080", "443:8443"])
imageNoImage to use for the containers in the deployment
replicasNoNumber of replicas to create for the deployment
portNoPort that the container exposes
scheduleNoCron schedule expression for the CronJob (e.g. "*/5 * * * *")
suspendNoWhether to suspend the CronJob
commandNoCommand to run in the container
labelsNoLabels to apply to the resource (e.g. ["key1=value1", "key2=value2"])
annotationsNoAnnotations to apply to the resource (e.g. ["key1=value1", "key2=value2"])
contextNoKubeconfig Context to use for the command (optional - defaults to null)

Implementation Reference

  • The main handler function kubectlCreate that implements the tool logic. It constructs and executes the 'kubectl create' command based on provided parameters for various Kubernetes resources (namespace, configmap, secret, service, deployment, job, cronjob), supports manifests, dry-run, validation, labels, annotations, etc.
    export async function kubectlCreate(
      k8sManager: KubernetesManager,
      input: {
        // General options
        dryRun?: boolean;
        output?: string;
        validate?: boolean;
    
        // Create from file
        manifest?: string;
        filename?: string;
    
        // Resource type and common parameters
        resourceType?: string;
        name?: string;
        namespace?: string;
    
        // ConfigMap specific
        fromLiteral?: string[];
        fromFile?: string[];
    
        // Secret specific
        secretType?: "generic" | "docker-registry" | "tls";
    
        // Service specific
        serviceType?: "clusterip" | "nodeport" | "loadbalancer" | "externalname";
        tcpPort?: string[];
    
        // Deployment specific
        image?: string;
        replicas?: number;
        port?: number;
    
        // Job specific
        command?: string[];
    
        // Additional common parameters
        labels?: string[];
        annotations?: string[];
        schedule?: string;
        suspend?: boolean;
        context?: string;
      }
    ) {
      try {
        // Check if we have enough information to proceed
        if (!input.manifest && !input.filename && !input.resourceType) {
          throw new McpError(
            ErrorCode.InvalidRequest,
            "Either manifest, filename, or resourceType must be provided"
          );
        }
    
        // If resourceType is provided, check if name is provided for most resource types
        if (
          input.resourceType &&
          !input.name &&
          input.resourceType !== "namespace"
        ) {
          throw new McpError(
            ErrorCode.InvalidRequest,
            `Name is required when creating a ${input.resourceType}`
          );
        }
    
        // Set up common parameters
        const namespace = input.namespace || "default";
        const dryRun = input.dryRun || false;
        const validate = input.validate ?? true;
        const output = input.output || "yaml";
        const context = input.context || "";
    
        const command = "kubectl";
        const args = ["create"];
        let tempFile: string | null = null;
    
        // Process manifest content if provided (file-based creation)
        if (input.manifest || input.filename) {
          if (input.manifest) {
            // Create temporary file for the manifest
            const tmpDir = os.tmpdir();
            tempFile = path.join(tmpDir, `create-manifest-${Date.now()}.yaml`);
            fs.writeFileSync(tempFile, input.manifest);
            args.push("-f", tempFile);
          } else if (input.filename) {
            args.push("-f", input.filename);
          }
        } else {
          // Process subcommand-based creation
          switch (input.resourceType?.toLowerCase()) {
            case "namespace":
              args.push("namespace", input.name!);
              break;
    
            case "configmap":
              args.push("configmap", input.name!);
    
              // Add --from-literal arguments
              if (input.fromLiteral && input.fromLiteral.length > 0) {
                input.fromLiteral.forEach((literal) => {
                  args.push(`--from-literal=${literal}`);
                });
              }
    
              // Add --from-file arguments
              if (input.fromFile && input.fromFile.length > 0) {
                input.fromFile.forEach((file) => {
                  args.push(`--from-file=${file}`);
                });
              }
              break;
    
            case "secret":
              if (!input.secretType) {
                throw new McpError(
                  ErrorCode.InvalidRequest,
                  "secretType is required when creating a secret"
                );
              }
    
              args.push("secret", input.secretType, input.name!);
    
              // Add --from-literal arguments
              if (input.fromLiteral && input.fromLiteral.length > 0) {
                input.fromLiteral.forEach((literal) => {
                  args.push(`--from-literal=${literal}`);
                });
              }
    
              // Add --from-file arguments
              if (input.fromFile && input.fromFile.length > 0) {
                input.fromFile.forEach((file) => {
                  args.push(`--from-file=${file}`);
                });
              }
              break;
    
            case "service":
              if (!input.serviceType) {
                // Default to clusterip if not specified
                input.serviceType = "clusterip";
              }
    
              args.push("service", input.serviceType, input.name!);
    
              // Add --tcp arguments for ports
              if (input.tcpPort && input.tcpPort.length > 0) {
                input.tcpPort.forEach((port) => {
                  args.push(`--tcp=${port}`);
                });
              }
              break;
    
            case "cronjob":
              if (!input.image) {
                throw new McpError(
                  ErrorCode.InvalidRequest,
                  "image is required when creating a cronjob"
                );
              }
    
              if (!input.schedule) {
                throw new McpError(
                  ErrorCode.InvalidRequest,
                  "schedule is required when creating a cronjob"
                );
              }
    
              args.push(
                "cronjob",
                input.name!,
                `--image=${input.image}`,
                `--schedule=${input.schedule}`
              );
    
              // Add command if specified
              if (input.command && input.command.length > 0) {
                args.push("--", ...input.command);
              }
    
              // Add suspend flag if specified
              if (input.suspend === true) {
                args.push(`--suspend`);
              }
              break;
    
            case "deployment":
              if (!input.image) {
                throw new McpError(
                  ErrorCode.InvalidRequest,
                  "image is required when creating a deployment"
                );
              }
    
              args.push("deployment", input.name!, `--image=${input.image}`);
    
              // Add replicas if specified
              if (input.replicas) {
                args.push(`--replicas=${input.replicas}`);
              }
    
              // Add port if specified
              if (input.port) {
                args.push(`--port=${input.port}`);
              }
              break;
    
            case "job":
              if (!input.image) {
                throw new McpError(
                  ErrorCode.InvalidRequest,
                  "image is required when creating a job"
                );
              }
    
              args.push("job", input.name!, `--image=${input.image}`);
    
              // Add command if specified
              if (input.command && input.command.length > 0) {
                args.push("--", ...input.command);
              }
              break;
    
            default:
              throw new McpError(
                ErrorCode.InvalidRequest,
                `Unsupported resource type: ${input.resourceType}`
              );
          }
        }
    
        // Add namespace if not creating a namespace itself
        if (input.resourceType !== "namespace") {
          args.push("-n", namespace);
        }
    
        // Add labels if specified
        if (input.labels && input.labels.length > 0) {
          input.labels.forEach((label) => {
            args.push("-l", label);
          });
        }
    
        // Add annotations if specified
        if (input.annotations && input.annotations.length > 0) {
          input.annotations.forEach((annotation) => {
            args.push(`--annotation=${annotation}`);
          });
        }
    
        // Add dry-run flag if requested
        if (dryRun) {
          args.push("--dry-run=client");
        }
    
        // Add validate flag if needed
        if (!validate) {
          args.push("--validate=false");
        }
    
        // Add output format
        args.push("-o", output);
    
        // Add context if provided
        if (context) {
          args.push("--context", context);
        }
    
        // Execute the command
        try {
          const result = execFileSync(command, args, {
            encoding: "utf8",
            maxBuffer: getSpawnMaxBuffer(),
            env: { ...process.env, KUBECONFIG: process.env.KUBECONFIG },
          });
    
          // Clean up temp file if created
          if (tempFile) {
            try {
              fs.unlinkSync(tempFile);
            } catch (err) {
              console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
            }
          }
    
          return {
            content: [
              {
                type: "text",
                text: result,
              },
            ],
          };
        } catch (error: any) {
          // Clean up temp file if created, even if command failed
          if (tempFile) {
            try {
              fs.unlinkSync(tempFile);
            } catch (err) {
              console.warn(`Failed to delete temporary file ${tempFile}: ${err}`);
            }
          }
    
          throw new McpError(
            ErrorCode.InternalError,
            `Failed to create resource: ${error.message}`
          );
        }
      } catch (error: any) {
        if (error instanceof McpError) {
          throw error;
        }
    
        throw new McpError(
          ErrorCode.InternalError,
          `Failed to execute kubectl create command: ${error.message}`
        );
      }
    }
  • The input schema definition for the kubectl_create tool, defining all parameters for creating different Kubernetes resources.
    export const kubectlCreateSchema = {
      name: "kubectl_create",
      description:
        "Create Kubernetes resources using various methods (from file or using subcommands)",
      inputSchema: {
        type: "object",
        properties: {
          // General options
          dryRun: dryRunParameter,
          output: {
            type: "string",
            enum: [
              "json",
              "yaml",
              "name",
              "go-template",
              "go-template-file",
              "template",
              "templatefile",
              "jsonpath",
              "jsonpath-as-json",
              "jsonpath-file",
            ],
            description:
              "Output format. One of: json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file",
            default: "yaml",
          },
          validate: {
            type: "boolean",
            description: "If true, validate resource schema against server schema",
            default: true,
          },
    
          // Create from file method
          manifest: {
            type: "string",
            description: "YAML manifest to create resources from",
          },
          filename: {
            type: "string",
            description: "Path to a YAML file to create resources from",
          },
    
          // Resource type to create (determines which subcommand to use)
          resourceType: {
            type: "string",
            description:
              "Type of resource to create (namespace, configmap, deployment, service, etc.)",
          },
    
          // Common parameters for most resource types
          name: {
            type: "string",
            description: "Name of the resource to create",
          },
          namespace: namespaceParameter,
    
          // ConfigMap specific parameters
          fromLiteral: {
            type: "array",
            items: { type: "string" },
            description:
              'Key-value pair for creating configmap (e.g. ["key1=value1", "key2=value2"])',
          },
          fromFile: {
            type: "array",
            items: { type: "string" },
            description:
              'Path to file for creating configmap (e.g. ["key1=/path/to/file1", "key2=/path/to/file2"])',
          },
    
          // Namespace specific parameters
          // No special parameters for namespace, just name is needed
    
          // Secret specific parameters
          secretType: {
            type: "string",
            enum: ["generic", "docker-registry", "tls"],
            description: "Type of secret to create (generic, docker-registry, tls)",
          },
    
          // Service specific parameters
          serviceType: {
            type: "string",
            enum: ["clusterip", "nodeport", "loadbalancer", "externalname"],
            description:
              "Type of service to create (clusterip, nodeport, loadbalancer, externalname)",
          },
          tcpPort: {
            type: "array",
            items: { type: "string" },
            description:
              'Port pairs for tcp service (e.g. ["80:8080", "443:8443"])',
          },
    
          // Deployment specific parameters
          image: {
            type: "string",
            description: "Image to use for the containers in the deployment",
          },
          replicas: {
            type: "number",
            description: "Number of replicas to create for the deployment",
            default: 1,
          },
          port: {
            type: "number",
            description: "Port that the container exposes",
          },
    
          // CronJob specific parameters
          schedule: {
            type: "string",
            description:
              'Cron schedule expression for the CronJob (e.g. "*/5 * * * *")',
          },
          suspend: {
            type: "boolean",
            description: "Whether to suspend the CronJob",
            default: false,
          },
    
          // Job specific parameters
          command: {
            type: "array",
            items: { type: "string" },
            description: "Command to run in the container",
          },
    
          // Additional common parameters
          labels: {
            type: "array",
            items: { type: "string" },
            description:
              'Labels to apply to the resource (e.g. ["key1=value1", "key2=value2"])',
          },
          annotations: {
            type: "array",
            items: { type: "string" },
            description:
              'Annotations to apply to the resource (e.g. ["key1=value1", "key2=value2"])',
          },
          context: contextParameter,
        },
        required: [],
      },
    } as const;
  • src/index.ts:278-290 (registration)
    Registration and dispatch logic in the main CallToolRequestSchema handler that routes calls to the kubectlCreate function.
    if (name === "kubectl_create") {
      return await kubectlCreate(
        k8sManager,
        input as {
          manifest?: string;
          filename?: string;
          namespace?: string;
          dryRun?: boolean;
          validate?: boolean;
          context?: string;
        }
      );
    }
  • src/index.ts:109-109 (registration)
    Inclusion of the tool schema in the allTools array for tool listing via ListToolsRequestSchema.
    kubectlCreateSchema,
  • src/index.ts:57-57 (registration)
    Import of the kubectlCreate handler and schema from the implementation file.
    import { kubectlCreate, kubectlCreateSchema } from "./tools/kubectl-create.js";

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Flux159/mcp-server-kubernetes'

If you have feedback or need assistance with the MCP directory API, please join our Discord server