This guide walks you through setting up the Kubernetes MCP Server for deployment in a Kubernetes cluster. You'll create a dedicated, read-only ServiceAccount and generate a secure kubeconfig file that can be used with various MCP clients.
Note: This setup is recommended for production use but not strictly required. The MCP Server can use your existing kubeconfig file (e.g.,
~/.kube/config), but using a dedicated ServiceAccount with limited permissions follows the principle of least privilege and is more secure.
Next: After completing this guide, continue with the Claude Code CLI guide. See the docs README for all available guides.
By the end of this guide, you'll have:
- A dedicated
mcp-viewerServiceAccount with read-only cluster access - A secure, time-bound authentication token
- A dedicated kubeconfig file (
~/.kube/mcp-viewer.kubeconfig)
- A running Kubernetes cluster
kubectlCLI installed and configured- Cluster admin permissions to create ServiceAccounts and RBAC bindings
A ServiceAccount represents a non-human identity. Binding it to a read-only role lets tools query the cluster safely without using administrator credentials.
First, create a Namespace for the ServiceAccount:
# Create or pick a Namespace for the ServiceAccount
kubectl create namespace mcp
# Create the ServiceAccount
kubectl create serviceaccount mcp-viewer -n mcpUse a ClusterRoleBinding or RoleBinding to grant read-only permissions.
This binds the ServiceAccount to the built-in view ClusterRole, which provides read-only access across the whole cluster.
# Binds the view ClusterRole to the ServiceAccount
kubectl create clusterrolebinding mcp-viewer-crb \
--clusterrole=view \
--serviceaccount=mcp:mcp-viewerThis limits read access to the mcp namespace only, using the built-in view Role.
# Binds the view role to the ServiceAccount within the 'mcp' namespace
kubectl create rolebinding mcp-viewer-rb \
--role=view \
--serviceaccount=mcp:mcp-viewer \
-n mcpVerify the permissions granted to the ServiceAccount:
# Check if the ServiceAccount can list pods cluster-wide
# Expect 'yes' if you used the view ClusterRole (Option A)
kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespacesTools authenticate via a bearer token. We use the TokenRequest API (kubectl create token) to generate a secure, short-lived token.
# Create a time-bound token (choose a duration, e.g., 2 hours)
TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)"
# Verify the token was generated (Optional)
echo "$TOKEN"Note: The kubectl create token command requires Kubernetes v1.24+. For older versions, you'll need to extract the token from the ServiceAccount's secret.
A dedicated kubeconfig file isolates this ServiceAccount's credentials from your personal admin credentials, making it easy to point external tools at.
Get the API server address and certificate authority from your current active context:
# 1. Get the current cluster API server address
API_SERVER="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')"
# 2. Get the cluster's Certificate Authority (CA) file path or data
# First, try to get the CA file path
CA_FILE="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.certificate-authority}')"
# If CA file is not set, extract the CA data and write it to a temp file
if [ -z "$CA_FILE" ]; then
CA_FILE="/tmp/k8s-ca-$$.crt"
kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > "$CA_FILE"
fi
# 3. Define the desired context name
CONTEXT_NAME="mcp-viewer-context"
KUBECONFIG_FILE="$HOME/.kube/mcp-viewer.kubeconfig"Create the new kubeconfig file by defining the cluster, user (the ServiceAccount), and context:
# Create a new kubeconfig file with cluster configuration
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-cluster mcp-viewer-cluster \
--server="$API_SERVER" \
--certificate-authority="$CA_FILE" \
--embed-certs=true
# Set the ServiceAccount token as the user credential
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer \
--token="$TOKEN"
# Define the context (links the cluster and user)
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-context "$CONTEXT_NAME" \
--cluster=mcp-viewer-cluster \
--user=mcp-viewer
# Set the new context as current
kubectl config --kubeconfig="$KUBECONFIG_FILE" use-context "$CONTEXT_NAME"
# Secure the file permissions
chmod 600 "$KUBECONFIG_FILE"
# Clean up temporary CA file if we created one
if [[ "$CA_FILE" == /tmp/k8s-ca-*.crt ]]; then
rm -f "$CA_FILE"
fiYou can now use this new file to verify access:
# Run a command using the dedicated kubeconfig file
kubectl --kubeconfig="$KUBECONFIG_FILE" get pods -AThis command should successfully list all Pods if you chose Option A: Cluster-Wide Read-Only, proving the ServiceAccount and its token are correctly configured.
Now that you have a dedicated kubeconfig file, you can use it with the Kubernetes MCP Server:
# Run the MCP server with the dedicated kubeconfig
./kubernetes-mcp-server --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"
# Or use npx
npx -y kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"
# Or use uvx
uvx kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"Alternatively, you can set the KUBECONFIG environment variable:
export KUBECONFIG="$HOME/.kube/mcp-viewer.kubeconfig"
./kubernetes-mcp-serverThe token created in Step 2 has a limited lifetime (2 hours in the example). When it expires, you'll need to:
-
Generate a new token:
TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)" -
Update the kubeconfig file:
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer --token="$TOKEN"
For long-running applications, consider:
- Using a longer token duration (up to the cluster's maximum, typically 24h)
- Implementing automatic token renewal in your application
- Using a different authentication method (e.g., client certificates)
To remove the ServiceAccount and associated RBAC bindings:
# Delete the ClusterRoleBinding (if using Option A)
kubectl delete clusterrolebinding mcp-viewer-crb
# Delete the RoleBinding (if using Option B)
kubectl delete rolebinding mcp-viewer-rb -n mcp
# Delete the ServiceAccount
kubectl delete serviceaccount mcp-viewer -n mcp
# Delete the namespace (optional - only if you created it specifically for this)
kubectl delete namespace mcp
# Remove the kubeconfig file
rm "$HOME/.kube/mcp-viewer.kubeconfig"This command requires Kubernetes v1.24+. For older versions, you'll need to extract the token from the ServiceAccount's secret manually.
Ensure you're using the correct kubeconfig file and that the ServiceAccount has the necessary RBAC permissions. Verify with:
kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespacesNow that you have a working kubeconfig with read-only access, configure Claude Code CLI:
- Using with Claude Code CLI - Configure the MCP server with Claude Code CLI
You can also:
- Explore the main README for more MCP server capabilities