
Kubernetes MCP
STDIOKubernetes MCP server providing standardized interface for interacting with Kubernetes clusters through tools.
Kubernetes MCP server providing standardized interface for interacting with Kubernetes clusters through tools.
A Kubernetes Model Context Protocol (MCP) server that provides tools for interacting with Kubernetes clusters through a standardized interface.
kubectl describe
.stdio
mode for CLI tools or sse
mode for web applications.kubectl
configured with appropriate cluster accessClone 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 main.go
The server can run in two modes, configurable via command-line flags or environment variables.
This mode uses standard input/output for communication.
./k8s-mcp-server --mode stdio
Or using environment variables:
SERVER_MODE=stdio ./k8s-mcp-server
This mode starts an HTTP server with Server-Sent Events support.
Default (port 8080):
./k8s-mcp-server --mode sse
Specify a port:
./k8s-mcp-server --mode sse --port 9090
Or using environment variables:
SERVER_MODE=sse SERVER_PORT=9090 ./k8s-mcp-server
If no mode is specified, it defaults to SSE on port 8080.
You can also run the server using the pre-built Docker image from Docker Hub.
Pull the image:
docker pull ginnux/k8s-mcp-server:latest
You can replace latest
with a specific version tag (e.g., 1.0.0
).
Run the container:
SSE Mode (default behavior of the image):
docker run -p 8080:8080 -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest
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
.
Stdio Mode:
docker run -i --rm -v ~/.kube/config:/home/appuser/.kube/config:ro ginnux/k8s-mcp-server:latest --mode stdio
The -i
flag is important for interactive stdio communication. --rm
cleans 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
Alternative: Mount entire .kube directory:
docker run -p 8080:8080 -v ~/.kube:/home/appuser/.kube:ro ginnux/k8s-mcp-server:latest
Create a docker-compose.yml
file:
version: '3.8' services: k8s-mcp-server: image: ginnux/k8s-mcp-server:latest # Or a specific version container_name: k8s-mcp-server ports: - "8080:8080" # Host:Container, adjust if using a different SERVER_PORT volumes: - ~/.kube:/home/appuser/.kube:ro # Mount kubeconfig read-only to non-root user home environment: - KUBECONFIG=/home/appuser/.kube/config - SERVER_MODE=sse # Default, can be 'stdio' - SERVER_PORT=8080 # Port for SSE mode restart: unless-stopped healthcheck: test: ["CMD", "curl", "-f", "http://localhost:8080/"] interval: 30s timeout: 10s retries: 3 start_period: 10s # To run in stdio mode with docker-compose, you might need to adjust 'ports', # add 'stdin_open: true' and 'tty: true', and potentially override the command. # For example, to force stdio mode: # command: ["--mode", "stdio"] # stdin_open: true # tty: true
Then start with:
docker compose up -d
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/config
Once the server is running in SSE mode, you can make JSON-RPC calls to its HTTP endpoint:
curl -X POST -H "Content-Type: application/json" -d '{ "jsonrpc": "2.0", "id": 1, "method": "getAPIResources", "params": { "arguments": { "includeNamespaceScoped": true, "includeClusterScoped": true } } }' http://localhost:8080/
You can also check the health status:
curl -f http://localhost:8080/
getAPIResources
Retrieves 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:
{ "jsonrpc": "2.0", "id": 1, "method": "getAPIResources", "params": { "arguments": { "includeNamespaceScoped": true, "includeClusterScoped": true } } }
listResources
Lists 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:
{ "jsonrpc": "2.0", "id": 1, "method": "listResources", "params": { "arguments": { "Kind": "Pod", "namespace": "default", "labelSelector": "app=nginx" } } }
getResource
Retrieves 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:
{ "jsonrpc": "2.0", "id": 1, "method": "getResource", "params": { "arguments": { "kind": "Pod", "name": "nginx-pod", "namespace": "default" } } }
describeResource
Describes 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:
{ "jsonrpc": "2.0", "id": 1, "method": "describeResource", "params": { "arguments": { "Kind": "Pod", "name": "nginx-pod", "namespace": "default" } } }
getPodsLogs
Retrieves 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:
{ "jsonrpc": "2.0", "id": 1, "method": "getPodsLogs", "params": { "arguments": { "Name": "my-app-pod-12345", "namespace": "production", "containerName": "main-container" } } }
getNodeMetrics
Retrieves resource usage metrics for a specific node.
Parameters:
Name
(string, required): The name of the node.Example:
{ "jsonrpc": "2.0", "id": 1, "method": "getNodeMetrics", "params": { "arguments": { "Name": "worker-node-1" } } }
getPodMetrics
Retrieves 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:
{ "jsonrpc": "2.0", "id": 1, "method": "getPodMetrics", "params": { "arguments": { "namespace": "default", "podName": "my-app-pod-67890" } } }
getEvents
Retrieves 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):
{ "jsonrpc": "2.0", "id": 1, "method": "getEvents", "params": { "arguments": { "namespace": "default" } } }
Example (Resource Events):
{ "jsonrpc": "2.0", "id": 1, "method": "getEvents", "params": { "arguments": { "namespace": "production", "resourceName": "my-app-pod-12345", "resourceKind": "Pod" } } }
createOrUpdateResource
Creates a new resource or updates an existing one from a YAML or JSON manifest.
Parameters:
manifest
(string, required): The YAML or 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:
{ "jsonrpc": "2.0", "id": 1, "method": "createOrUpdateResource", "params": { "arguments": { "namespace": "default", "manifest": "apiVersion: v1\nkind: Pod\nmetadata:\n name: my-new-pod\nspec:\n containers:\n - name: nginx\n image: nginx:latest" } } }
helmInstall
Install 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:
{ "jsonrpc": "2.0", "id": 1, "method": "helmInstall", "params": { "arguments": { "releaseName": "my-nginx", "chartName": "bitnami/nginx", "namespace": "web", "repoURL": "https://charts.bitnami.com/bitnami", "values": { "replicaCount": 3, "service": { "type": "LoadBalancer" } } } } }
helmUpgrade
Upgrade an existing Helm release.
helmUninstall
Uninstall a Helm release from the Kubernetes cluster.
helmList
List all Helm releases in the cluster or a specific namespace.
helmGet
Get details of a specific Helm release.
helmHistory
Get the history of a Helm release.
helmRollback
Rollback a Helm release to a previous revision.
.
├── .github/workflows/ # GitHub Actions workflows
│ └── docker-build-push.yml
├── handlers/ # Tool handlers and tool definitions
│ └── handlers.go
├── pkg/ # Internal packages
│ └── k8s/ # Kubernetes client implementation
├── tools/ # MCP Tool definitions
│ └── tools.go
├── main.go # Server entry point
├── go.mod # Go module definition
├── go.sum # Go module checksums
├── Dockerfile # Docker build definition
└── docker-compose.yml # Docker Compose definition (example)
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:
curl -sSL https://raw.githubusercontent.com/reza-gholizade/k8s-mcp-server/main/scripts/install-vscode-config.sh | bash
Windows (PowerShell):
iex ((New-Object System.Net.WebClient).DownloadString('https://raw.githubusercontent.com/reza-gholizade/k8s-mcp-server/main/scripts/install-vscode-config.ps1'))
Install the MCP extension in VS Code:
code --install-extension modelcontextprotocol.mcp
Add to your VS Code settings.json:
Open VS Code settings (Cmd/Ctrl + ,) → Open Settings JSON → Add:
macOS/Linux:
{ "mcp.mcpServers": { "k8s-mcp-server": { "command": "k8s-mcp-server", "args": ["--mode", "stdio"], "env": { "KUBECONFIG": "${env:HOME}/.kube/config" } } } }
Windows:
{ "mcp.mcpServers": { "k8s-mcp-server": { "command": "k8s-mcp-server.exe", "args": ["--mode", "stdio"], "env": { "KUBECONFIG": "${env:USERPROFILE}/.kube/config" } } } }
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:
{ "mcp.mcpServers": { "k8s-mcp-server": { "command": "k8s-mcp-server", "args": ["--mode", "stdio"], "env": { "KUBECONFIG": "/path/to/your/kubeconfig", "KUBERNETES_CONTEXT": "your-context-name" } } } }
k8s-mcp-server
is in your PATHKUBECONFIG
path is correct