Kubernetes MCP Server
A Kubernetes Model Context Protocol (MCP) server that provides tools for interacting with Kubernetes clusters through a standardized interface.
Hosted deployment
A hosted deployment is available on Fronteir AI.
Features
- API Resource Discovery: Get all available API resources in your Kubernetes cluster.
- Resource Listing: List resources of any type with optional namespace and label filtering.
- Resource Details: Get detailed information about specific Kubernetes resources.
- Resource Description: Get comprehensive descriptions of Kubernetes resources, similar to
kubectl describe. - Pod Logs: Retrieve logs from specific pods (optionally from a specific container, or all containers if unspecified).
- Node Metrics: Get resource usage metrics for specific nodes.
- Pod Metrics: Get CPU and Memory metrics for specific pods.
- Event Listing: List events within a namespace or for a specific resource.
- Resource Creation/Updating: Create new Kubernetes resources or update existing ones from a YAML or JSON manifest.
- Resource Deletion: It deletes a resource in the Kubernetes cluster based on the provided namespace and kind.
- Standardized Interface: Uses the MCP protocol for consistent tool interaction.
- Flexible Configuration: Supports different Kubernetes contexts and resource scopes.
- Multiple Modes: Run in
stdiomode for CLI tools,ssemode, orstreamable-httpmode for web applications, and--readonlyfor no change in the cluster. - Security: Runs as non-root user in Docker containers for enhanced security.
Prerequisites
- Go 1.23 or later
- Access to a Kubernetes cluster
kubectlconfigured with appropriate cluster access
Installation
-
Clone the repository:
git clone https://github.com/reza-gholizade/k8s-mcp-server.git cd k8s-mcp-server -
Install dependencies:
go mod download -
Build the server:
go build -o k8s-mcp-server .
Usage
Starting the Server
The server can run in three modes, configurable via command-line flags or environment variables.
Stdio Mode (for CLI integrations)
This mode uses standard input/output for communication.
./k8s-mcp-server --mode stdioOr using environment variables:
SERVER_MODE=stdio ./k8s-mcp-serverSSE Mode (for web applications)
This mode starts an HTTP server with Server-Sent Events support.
HTTP transports require a bearer token and listen on loopback by default:
MCP_AUTH_TOKEN="$(openssl rand -hex 32)" ./k8s-mcp-server --mode sseSpecify a port:
MCP_AUTH_TOKEN="your-random-secret" ./k8s-mcp-server --mode sse --port 9090Or using environment variables:
SERVER_MODE=sse SERVER_PORT=9090 MCP_AUTH_TOKEN="your-random-secret" ./k8s-mcp-serverStreamable-HTTP Mode (for web applications)
This mode starts an HTTP server with streamable-http transport support, following the MCP specification.
Default (port 8080):
MCP_AUTH_TOKEN="your-random-secret" ./k8s-mcp-server --mode streamable-httpSpecify a port:
MCP_AUTH_TOKEN="your-random-secret" ./k8s-mcp-server --mode streamable-http --port 9090Or using environment variables:
SERVER_MODE=streamable-http SERVER_PORT=9090 MCP_AUTH_TOKEN="your-random-secret" ./k8s-mcp-serverThe 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.
Kubernetes Authentication
The server supports multiple authentication methods, which are tried in the following order of priority:
1. Kubeconfig Content from Environment Variable
You can provide the entire kubeconfig file content via the KUBECONFIG_DATA environment variable:
export KUBECONFIG_DATA="$(cat ~/.kube/config)"
./k8s-mcp-serverThis is useful when you want to avoid mounting files or when running in environments where file access is restricted.
2. API Server URL and Token
You can authenticate using a Kubernetes API server URL and bearer token:
export KUBERNETES_SERVER="https://kubernetes.example.com:6443"
export KUBERNETES_TOKEN="your-bearer-token-here"
./k8s-mcp-serverOptional 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:
export KUBERNETES_SERVER="https://kubernetes.example.com:6443"
export KUBERNETES_TOKEN="your-bearer-token-here"
export KUBERNETES_CA_CERT_PATH="/path/to/ca.crt"
./k8s-mcp-server3. In-Cluster Authentication (Service Account)
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:
apiVersion: v1
kind: ServiceAccount
metadata:
name: k8s-mcp-server-sa
namespace: default
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: k8s-mcp-server-role
rules:
- apiGroups: [""]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
- apiGroups: ["apps"]
resources: ["*"]
verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
# Add more rules as needed for your use case
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: k8s-mcp-server-rb
subjects:
- kind: ServiceAccount
name: k8s-mcp-server-sa
namespace: default
roleRef:
kind: ClusterRole
name: k8s-mcp-server-role
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-mcp-server
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: k8s-mcp-server
template:
metadata:
labels:
app: k8s-mcp-server
spec:
serviceAccountName: k8s-mcp-server-sa
containers:
- name: k8s-mcp-server
image: ginnux/k8s-mcp-server:latest
ports:
- containerPort: 8080
env:
- name: SERVER_MODE
value: "sse"
- name: SERVER_PORT
value: "8080"4. Kubeconfig File Path (Default)
If none of the above methods are available, the server falls back to using a kubeconfig file:
- Uses the path provided via
--kubeconfigflag (if implemented) orKUBECONFIGenvironment variable - Defaults to
~/.kube/configif neither is specified
# Using default ~/.kube/config
./k8s-mcp-server
# Using custom kubeconfig path
export KUBECONFIG=/path/to/your/kubeconfig
./k8s-mcp-serverNote: 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.
Read-Only Mode
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:
./k8s-mcp-server --read-onlyYou can combine read-only mode with any server mode:
# Read-only with stdio mode
./k8s-mcp-server --mode stdio --read-only
# Read-only with SSE mode
./k8s-mcp-server --mode sse --read-only
# Read-only with streamable-http mode
./k8s-mcp-server --mode streamable-http --read-onlyWhen 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.
Tool Category Flags
You can selectively disable entire categories of tools using these flags:
Disable Kubernetes Tools:
./k8s-mcp-server --no-k8sDisable Helm Tools:
./k8s-mcp-server --no-helmCombine with other flags:
# Read-only mode with only Kubernetes tools (no Helm)
./k8s-mcp-server --read-only --no-helm
# Read-only mode with only Helm tools (no Kubernetes)
./k8s-mcp-server --read-only --no-k8s
# SSE mode with only Kubernetes tools
./k8s-mcp-server --mode sse --no-helm
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)
Using the Docker Image
You can also run the server using the pre-built Docker image from Docker Hub.
-
Pull the image:
docker pull ginnux/k8s-mcp-server:latestYou can replace
latestwith 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):
docker run -p 8080:8080 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latestThis 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 tossemode on port8080. -
Streamable-HTTP Mode:
docker run -p 8080:8080 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode streamable-httpThis runs the server in streamable-http mode. The server will be available at
http://localhost:8080/mcp. -
Stdio Mode:
docker run -i --rm -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode stdioThe
-iflag is important for interactive stdio communication.--rmcleans up the container after exit. -
Custom Port for SSE Mode:
docker run -p 9090:9090 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode sse --port 9090 -
Custom Port for Streamable-HTTP Mode:
docker run -p 9090:9090 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode streamable-http --port 9090 -
**Alternati
-
…