The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the K8s MCP Server listing page.
A Kubernetes Model Context Protocol (MCP) server that provides tools for interacting with Kubernetes clusters through a standardized interface.
A hosted deployment is available on Fronteir AI.
kubectl describe.stdio mode for CLI tools, sse mode, or streamable-http mode for web applications, and --readonly for no change in the cluster.kubectl configured with appropriate cluster accessClone the repository:
Install dependencies:
Build the server:
The server can run in three modes, configurable via command-line flags or environment variables.
This mode uses standard input/output for communication.
Or using environment variables:
This mode starts an HTTP server with Server-Sent Events support.
HTTP transports require a bearer token and listen on loopback by default:
Specify a port:
Or using environment variables:
This mode starts an HTTP server with streamable-http transport support, following the MCP specification.
Default (port 8080):
Specify a port:
Or using environment variables:
The server will be available at http://localhost:8080/mcp (or your specified port).
If no mode is specified, the server defaults to stdio. HTTP modes bind to
127.0.0.1 by default. Set SERVER_HOST=0.0.0.0 (or --host 0.0.0.0) only
when network access is intentional, and send Authorization: Bearer <token>
on every MCP request. Browser clients must also be explicitly allowed with a
comma-separated MCP_ALLOWED_ORIGINS value.
The unauthenticated /healthz endpoint is available for container health checks;
it does not expose MCP functionality.
The server supports multiple authentication methods, which are tried in the following order of priority:
You can provide the entire kubeconfig file content via the KUBECONFIG_DATA environment variable:
This is useful when you want to avoid mounting files or when running in environments where file access is restricted.
You can authenticate using a Kubernetes API server URL and bearer token:
Optional environment variables for TLS configuration:
KUBERNETES_CA_CERT: CA certificate content (base64-encoded or PEM format)KUBERNETES_CA_CERT_PATH: Path to CA certificate fileKUBERNETES_INSECURE: Set to "true" to skip TLS verification (not recommended for production)Example with CA certificate:
When running inside a Kubernetes cluster, the server automatically detects and uses the service account token from /var/run/secrets/kubernetes.io/serviceaccount/token. This is the recommended method for running the server as a pod within a cluster.
Example Deployment:
If none of the above methods are available, the server falls back to using a kubeconfig file:
--kubeconfig flag (if implemented) or KUBECONFIG environment variable~/.kube/config if neither is specifiedNote: The server automatically detects which authentication method to use based on the available environment variables and file system. You don't need to explicitly configure the authentication method - it will use the first available method in the priority order listed above.
The server supports a read-only mode that disables all write operations, providing a safer way to explore and monitor your Kubernetes cluster without the risk of making changes.
Enable read-only mode with the --read-only flag:
You can combine read-only mode with any server mode:
When read-only mode is enabled, the following tools are disabled:
createResource (Kubernetes resource creation/updates)helmInstall (Helm chart installations)helmUpgrade (Helm chart upgrades)helmUninstall (Helm chart uninstallations)helmRollback (Helm release rollbacks)helmRepoAdd (Helm repository additions)All other read-only operations remain available, including listing resources, getting logs, viewing metrics, and inspecting Helm releases.
You can selectively disable entire categories of tools using these flags:
Disable Kubernetes Tools:
Disable Helm Tools:
Combine with other flags:
Note: You cannot use both --no-k8s and --no-helm together, as this would result in no available tools. The server will exit with an error if both flags are provided.
When --no-k8s is enabled, all Kubernetes tools are disabled:
getAPIResources, listResources, getResource, describeResourcegetPodsLogs, getNodeMetrics, getPodMetrics, getEventscreateResource (if not in read-only mode)When --no-helm is enabled, all Helm tools are disabled:
helmList, helmGet, helmHistory, helmRepoListhelmInstall, helmUpgrade, helmUninstall, helmRollback, helmRepoAdd (if not in read-only mode)You can also run the server using the pre-built Docker image from Docker Hub.
Pull the image:
You can replace latest with a specific version tag (e.g., 1.0.0).
Run the container:
Note: The server supports multiple authentication methods. You can either mount a kubeconfig file (as shown below) or use environment variables for authentication (see Kubernetes Authentication section above).
SSE Mode (default behavior of the image):
This maps port 8080 of the container to port 8080 on your host and mounts your Kubernetes config read-only to the non-root user's home directory. The server will be available at http://localhost:8080. The image defaults to sse mode on port 8080.
Streamable-HTTP Mode:
This runs the server in streamable-http mode. The server will be available at http://localhost:8080/mcp.
Stdio Mode:
The -i flag is important for interactive stdio communication. --rm cleans up the container after exit.
Custom Port for SSE Mode:
Custom Port for Streamable-HTTP Mode:
Alternative: Mount entire .kube directory:
Using environment variables for authentication (no file mounting required):
Create a docker-compose.yml file:
Option 1: Using kubeconfig file (traditional method):
Option 2: Using environment variables (no file mounting):
Note: To enable read-only mode, use the command override as shown in Option 1. For stdio mode, you might need to adjust 'ports', add 'stdin_open: true' and 'tty: true', and potentially override the command.
Then start with:
To see logs: docker compose logs -f k8s-mcp-server.
The Docker image runs as a non-root user (appuser with UID 1001) for enhanced security:
/usr/local/bin/k8s-mcp-server/home/appuser/.kube/configSSE and streamable HTTP are fail-closed unless MCP_AUTH_TOKEN is set. Never
publish an HTTP transport without authentication. Prefer stdio for local MCP
clients, use --read-only where possible, and grant the server's Kubernetes
identity only the RBAC permissions it needs. A session ID is not an authentication
credential. Put remotely accessible deployments behind TLS and an authenticating
reverse proxy, and configure MCP_ALLOWED_ORIGINS for browser-based clients.
Once the server is running in SSE or streamable-http mode, you can make JSON-RPC calls to its HTTP endpoint:
You can also check the health status:
getAPIResourcesRetrieves all available API resources in the Kubernetes cluster.
Parameters:
includeNamespaceScoped (boolean, optional): Whether to include namespace-scoped resources (defaults to true).includeClusterScoped (boolean, optional): Whether to include cluster-scoped resources (defaults to true).Example:
listResourcesLists all instances of a specific resource type.
Parameters:
Kind (string, required): The kind of resource to list (e.g., "Pod", "Deployment").namespace (string, optional): The namespace to list resources from. If omitted, lists across all namespaces for namespaced resources (subject to RBAC).labelSelector (string, optional): Filter resources by label selector (e.g., "app=nginx,env=prod").Example:
getResourceRetrieves detailed information about a specific resource.
Parameters:
kind (string, required): The kind of resource to get (e.g., "Pod", "Deployment").name (string, required): The name of the resource to get.namespace (string, optional): The namespace of the resource (required for namespaced resources).Example:
describeResourceDescribes a resource in the Kubernetes cluster, similar to kubectl describe.
Parameters:
Kind (string, required): The kind of resource to describe (e.g., "Pod", "Deployment").name (string, required): The name of the resource to describe.namespace (string, optional): The namespace of the resource (required for namespaced resources).Example:
getPodsLogsRetrieves the logs of a specific pod.
Parameters:
Name (string, required): The name of the pod.namespace (string, required): The namespace of the pod.containerName (string, optional): The specific container name within the pod. If omitted:
Example:
getNodeMetricsRetrieves resource usage metrics for a specific node.
Parameters:
Name (string, required): The name of the node.Example:
getPodMetricsRetrieves CPU and Memory metrics for a specific pod.
Parameters:
namespace (string, required): The namespace of the pod.podName (string, required): The name of the pod.Example:
getEventsRetrieves events for a specific namespace or resource.
Parameters:
namespace (string, optional): The namespace to get events from. If omitted, events from all namespaces are considered (subject to RBAC).resourceName (string, optional): The name of a specific resource (e.g., a Pod name) to filter events for.resourceKind (string, optional): The kind of the specific resource (e.g., "Pod") if resourceName is provided.Example (Namespace Events):
Example (Resource Events):
createOrUpdateResourceCreates a new resource or updates an existing one from a JSON manifest.
Parameters:
manifest (string, required): The JSON manifest of the resource.namespace (string, optional): The namespace in which to create/update the resource. If the manifest contains a namespace, this parameter can be used to override it. If not provided and the manifest doesn't specify one, "default" might be assumed or it might be an error depending on the resource type.Example:
createOrUpdateResourceYAMLCreates a new resource or updates an existing one from a YAML manifest. This tool is specifically optimized for YAML input and provides better error handling for YAML parsing issues.
Parameters:
manifest (string, required): The YAML manifest of the resource.namespace (string, optional): The namespace in which to create/update the resource. If the manifest contains a namespace, this parameter can be used to override it. If not provided and the manifest doesn't specify one, "default" might be assumed or it might be an error depending on the resource type.kind (string, optional): The kind of the resource. If not provided, the kind will be inferred from the YAML manifest.Example:
rolloutRestartTriggers a rolling restart of a Kubernetes resource that supports spec.template.metadata.annotations. This includes Deployment, DaemonSet, StatefulSet, Job, and similar resources.
Parameters:
kind (string, required): The kind of resource (e.g., "Deployment", "StatefulSet").name: (string, required): The name of the resource to restart.namespace (string, required for namespaced resources): The namespace of the resource.Example (StatefulSet):
Example (Deployment):
deleteResourceDeletes a specific resource from the Kubernetes cluster.
Parameters:
kind (string, required): The type of resource to delete.name (string, required): The name of the resource to delete.namespace (string, optional): The namespace of the resource (required for namespaced resources).Example:
getIngressesRetrieves ingress resources from the Kubernetes cluster. You can filter ingresses by host. If no host is provided, all ingresses are returned.
Parameters:
host (string, optional): The host to filter ingresses by. If omitted, all ingresses are included.Example:
helmInstallInstall a Helm chart to the Kubernetes cluster.
Parameters:
releaseName (string, required): Name of the Helm releasechartName (string, required): Name or path of the Helm chartnamespace (string, optional): Kubernetes namespace for the release (defaults to "default")repoURL (string, optional): Helm repository URLvalues (object, optional): Values to override in the chartExample:
helmUpgradeUpgrade an existing Helm release.
Parameters:
releaseName (string, required): Name of the Helm releasechartName (string, required): Name or path of the Helm chartnamespace (string, required): Kubernetes namespace for the release (defaults to "default")repoURL (string, required): Helm repository URLvalues (object, required): Values to override in the chart
Example:helmListList all Helm releases in the cluster or a specific namespace.
helmGetGet details of a specific Helm release.
helmHistoryGet the history of a Helm release.
helmRollbackRollback a Helm release to a previous revision.
helmUninstallUninstall a Helm release from the Kubernetes cluster.
tools/tools.go, define a function that returns an mcp.Tool structure. This includes the tool's name, description, and input/output schemas.handlers/handlers.go, create a handler function. This function takes *k8s.Client as an argument and returns a function with the signature func(context.Context, mcp.ToolInput) (mcp.ToolOutput, error). This inner function will contain the logic for your tool.main.go, add your new tool to the MCP server instance using s.AddTool(tools.YourToolDefinitionFunction(), handlers.YourToolHandlerFunction(client)).Contributions are welcome! Please see CONTRIBUTING.md for details on how to contribute to this project.
This project is licensed under the MIT License - see the LICENSE file for details.
macOS/Linux:
Windows (PowerShell):
Install the MCP extension in VS Code:
Add to your VS Code settings.json:
Open VS Code settings (Cmd/Ctrl + ,) → Open Settings JSON → Add:
macOS/Linux:
Read-Only Mode (recommended for safety):
Kubernetes Tools Only:
Helm Tools Only:
Read-Only with Kubernetes Tools Only:
Windows:
Ensure the binary is in your PATH:
Download the appropriate binary from the releases page and add it to your system PATH.
Restart VS Code
Once configured, you can use the Kubernetes MCP server in VS Code with Claude or other MCP-compatible tools:
You can customize the configuration by modifying the settings:
k8s-mcp-server is in your PATHKUBECONFIG path is correct