Skip to content

Commit e376e4a

Browse files
Merge pull request containers#61 from matzew/sync-downstream
NO-JIRA: Sync downstream with the latest changes in upstream
2 parents ce29678 + 2a8e9e2 commit e376e4a

20 files changed

+800
-95
lines changed

README.md

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,15 @@ If you're using the native binaries you don't need to have Node or Python instal
5454

5555
- Access to a Kubernetes cluster.
5656

57+
<details>
58+
<summary><b>Claude Code</b></summary>
59+
60+
Follow the [dedicated Claude Code getting started guide](docs/GETTING_STARTED_CLAUDE_CODE.md) in our [user documentation](docs/).
61+
62+
For a secure production setup with dedicated ServiceAccount and read-only access, also review the [Kubernetes setup guide](docs/GETTING_STARTED_KUBERNETES.md).
63+
64+
</details>
65+
5766
### Claude Desktop
5867

5968
#### Using npx
@@ -235,6 +244,11 @@ In case multi-cluster support is enabled (default) and you have access to multip
235244

236245
- **projects_list** - List all the OpenShift projects in the current cluster
237246

247+
- **nodes_log** - Get logs from a Kubernetes node (kubelet, kube-proxy, or other system logs). This accesses node logs through the Kubernetes API proxy to the kubelet
248+
- `name` (`string`) **(required)** - Name of the node to get logs from
249+
- `query` (`string`) **(required)** - query specifies services(s) or files from which to return logs (required). Example: "kubelet" to fetch kubelet logs, "/<log-file-name>" to fetch a specific log file from the node (e.g., "/var/log/kubelet.log" or "/var/log/kube-proxy.log")
250+
- `tailLines` (`integer`) - Number of lines to retrieve from the end of the logs (Optional, 0 means all logs)
251+
238252
- **pods_list** - List all the Kubernetes pods in the current cluster from all namespaces
239253
- `labelSelector` (`string`) - Optional Kubernetes label selector (e.g. 'app=myapp,env=prod' or 'app in (myapp,yourapp)'), use this option when you want to filter the pods by label
240254

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# Using Kubernetes MCP Server with Claude Code CLI
2+
3+
This guide shows you how to configure the Kubernetes MCP Server with Claude Code CLI.
4+
5+
> **Prerequisites:** Complete the [Getting Started with Kubernetes](GETTING_STARTED_KUBERNETES.md) guide first to create a ServiceAccount and kubeconfig file.
6+
7+
## Quick Setup
8+
9+
Add the MCP server using the `claude mcp add-json` command:
10+
11+
```bash
12+
claude mcp add-json kubernetes-mcp-server \
13+
'{"command":"npx","args":["-y","kubernetes-mcp-server@latest","--read-only"],"env":{"KUBECONFIG":"'${HOME}'/.kube/mcp-viewer.kubeconfig"}}' \
14+
-s user
15+
```
16+
17+
**What this does:**
18+
- Adds the Kubernetes MCP Server to your Claude Code configuration
19+
- Uses `npx` to automatically download and run the latest version
20+
- Enables read-only mode for safety
21+
- Uses the kubeconfig file you created in the Getting Started guide
22+
- `-s user` makes it available in all your projects
23+
24+
## Manual Configuration (Alternative)
25+
26+
If you prefer to edit the config file manually:
27+
28+
**Location:** `~/.config/claude-code/config.toml`
29+
30+
```toml
31+
[[mcp_servers]]
32+
name = "kubernetes-mcp-server"
33+
command = "npx"
34+
args = [
35+
"-y",
36+
"kubernetes-mcp-server@latest",
37+
"--read-only"
38+
]
39+
40+
[mcp_servers.env]
41+
KUBECONFIG = "/home/YOUR_USERNAME/.kube/mcp-viewer.kubeconfig"
42+
```
43+
44+
**Important:** Replace `/home/YOUR_USERNAME/` with your actual home directory path.
45+
46+
## Verify Connection
47+
48+
After adding the MCP server, verify it's connected:
49+
50+
```bash
51+
claude mcp list
52+
```
53+
54+
Expected output:
55+
```
56+
Checking MCP server health...
57+
58+
kubernetes-mcp-server: npx -y kubernetes-mcp-server@latest --read-only - ✓ Connected
59+
```
60+
61+
## Using the MCP Server
62+
63+
Once connected, interact with your Kubernetes cluster using natural language! Claude will use the Kubernetes MCP Server
64+
to fetch and display the relevant information from your cluster:
65+
66+
```bash
67+
> List all namespaces in my cluster
68+
69+
● I'll list all the namespaces in your Kubernetes cluster.
70+
⎿ APIVERSION KIND NAME STATUS AGE LABELS
71+
v1 Namespace default Active 77m kubernetes.io/metadata.name=default
72+
v1 Namespace kube-node-lease Active 77m kubernetes.io/metadata.name=kube-node-lease
73+
… +4 lines (ctrl+o to expand)
74+
75+
● Your cluster has 6 namespaces:
76+
77+
1. default - The default namespace for resources without a specified namespace
78+
2. kube-node-lease - Used for node heartbeat/lease objects
79+
3. kube-public - Publicly accessible namespace, typically for cluster information
80+
4. kube-system - System namespace for Kubernetes control plane components
81+
5. local-path-storage - Likely used for local storage provisioning
82+
6. mcp - Custom namespace (created ~75 minutes ago)
83+
84+
All namespaces are in Active status and the cluster appears to be running for about 77 minutes.
85+
```
86+
87+
## Configuration Options
88+
89+
Common command-line flags you can add to the `args` array:
90+
91+
| Flag | Description |
92+
|------|-------------|
93+
| `--read-only` | Enable read-only mode (recommended) |
94+
| `--kubeconfig <path>` | Path to kubeconfig file (or use `KUBECONFIG` env var) |
95+
96+
## Next Steps
97+
98+
- Review the [Getting Started with Kubernetes](GETTING_STARTED_KUBERNETES.md) guide for more details on ServiceAccount setup
99+
- Explore the [main README](../README.md) for more MCP server capabilities

docs/GETTING_STARTED_KUBERNETES.md

Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
# Getting Started with Kubernetes MCP Server
2+
3+
This guide walks you through the foundational setup for using the Kubernetes MCP Server with your Kubernetes cluster. You'll create a dedicated, read-only ServiceAccount and generate a secure kubeconfig file that can be used with various MCP clients.
4+
5+
> **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.
6+
7+
> **Next:** After completing this guide, continue with the [Claude Code CLI guide](GETTING_STARTED_CLAUDE_CODE.md). See the [docs README](README.md) for all available guides.
8+
9+
## What You'll Create
10+
11+
By the end of this guide, you'll have:
12+
- A dedicated `mcp-viewer` ServiceAccount with read-only cluster access
13+
- A secure, time-bound authentication token
14+
- A dedicated kubeconfig file (`~/.kube/mcp-viewer.kubeconfig`)
15+
16+
## Prerequisites
17+
18+
- A running Kubernetes cluster
19+
- `kubectl` CLI installed and configured
20+
- Cluster admin permissions to create ServiceAccounts and RBAC bindings
21+
22+
## 1. Create a Read-Only ServiceAccount and RBAC
23+
24+
A ServiceAccount represents a non-human identity. Binding it to a read-only role lets tools query the cluster safely without using administrator credentials.
25+
26+
### Step 1.1: Create the Namespace and ServiceAccount
27+
28+
First, create a Namespace for the ServiceAccount:
29+
30+
```bash
31+
# Create or pick a Namespace for the ServiceAccount
32+
kubectl create namespace mcp
33+
34+
# Create the ServiceAccount
35+
kubectl create serviceaccount mcp-viewer -n mcp
36+
```
37+
38+
### Step 1.2: Grant Read-Only Access (RBAC)
39+
40+
Use a ClusterRoleBinding or RoleBinding to grant read-only permissions.
41+
42+
#### Option A: Cluster-Wide Read-Only (Most Common)
43+
44+
This binds the ServiceAccount to the built-in `view` ClusterRole, which provides read-only access across the whole cluster.
45+
46+
```bash
47+
# Binds the view ClusterRole to the ServiceAccount
48+
kubectl create clusterrolebinding mcp-viewer-crb \
49+
--clusterrole=view \
50+
--serviceaccount=mcp:mcp-viewer
51+
```
52+
53+
#### Option B: Namespace-Scoped Only (Tighter Scope)
54+
55+
This limits read access to the `mcp` namespace only, using the built-in `view` Role.
56+
57+
```bash
58+
# Binds the view role to the ServiceAccount within the 'mcp' namespace
59+
kubectl create rolebinding mcp-viewer-rb \
60+
--role=view \
61+
--serviceaccount=mcp:mcp-viewer \
62+
-n mcp
63+
```
64+
65+
### Quick Verification (Optional)
66+
67+
Verify the permissions granted to the ServiceAccount:
68+
69+
```bash
70+
# Check if the ServiceAccount can list pods cluster-wide
71+
# Expect 'yes' if you used the view ClusterRole (Option A)
72+
kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespaces
73+
```
74+
75+
## 2. Mint a ServiceAccount Token
76+
77+
Tools authenticate via a bearer token. We use the TokenRequest API (`kubectl create token`) to generate a secure, short-lived token.
78+
79+
```bash
80+
# Create a time-bound token (choose a duration, e.g., 2 hours)
81+
TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)"
82+
83+
# Verify the token was generated (Optional)
84+
echo "$TOKEN"
85+
```
86+
87+
**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.
88+
89+
## 3. Build a Dedicated Kubeconfig
90+
91+
A dedicated kubeconfig file isolates this ServiceAccount's credentials from your personal admin credentials, making it easy to point external tools at.
92+
93+
### Step 3.1: Get Cluster Details
94+
95+
Get the API server address and certificate authority from your current active context:
96+
97+
```bash
98+
# 1. Get the current cluster API server address
99+
API_SERVER="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.server}')"
100+
101+
# 2. Get the cluster's Certificate Authority (CA) file path or data
102+
# First, try to get the CA file path
103+
CA_FILE="$(kubectl config view --minify -o jsonpath='{.clusters[0].cluster.certificate-authority}')"
104+
105+
# If CA file is not set, extract the CA data and write it to a temp file
106+
if [ -z "$CA_FILE" ]; then
107+
CA_FILE="/tmp/k8s-ca-$$.crt"
108+
kubectl config view --minify --raw -o jsonpath='{.clusters[0].cluster.certificate-authority-data}' | base64 -d > "$CA_FILE"
109+
fi
110+
111+
# 3. Define the desired context name
112+
CONTEXT_NAME="mcp-viewer-context"
113+
KUBECONFIG_FILE="$HOME/.kube/mcp-viewer.kubeconfig"
114+
```
115+
116+
### Step 3.2: Create and Configure the Kubeconfig File
117+
118+
Create the new kubeconfig file by defining the cluster, user (the ServiceAccount), and context:
119+
120+
```bash
121+
# Create a new kubeconfig file with cluster configuration
122+
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-cluster mcp-viewer-cluster \
123+
--server="$API_SERVER" \
124+
--certificate-authority="$CA_FILE" \
125+
--embed-certs=true
126+
127+
# Set the ServiceAccount token as the user credential
128+
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer \
129+
--token="$TOKEN"
130+
131+
# Define the context (links the cluster and user)
132+
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-context "$CONTEXT_NAME" \
133+
--cluster=mcp-viewer-cluster \
134+
--user=mcp-viewer
135+
136+
# Set the new context as current
137+
kubectl config --kubeconfig="$KUBECONFIG_FILE" use-context "$CONTEXT_NAME"
138+
139+
# Secure the file permissions
140+
chmod 600 "$KUBECONFIG_FILE"
141+
142+
# Clean up temporary CA file if we created one
143+
if [[ "$CA_FILE" == /tmp/k8s-ca-*.crt ]]; then
144+
rm -f "$CA_FILE"
145+
fi
146+
```
147+
148+
### Quick Sanity Check
149+
150+
You can now use this new file to verify access:
151+
152+
```bash
153+
# Run a command using the dedicated kubeconfig file
154+
kubectl --kubeconfig="$KUBECONFIG_FILE" get pods -A
155+
```
156+
157+
This command should successfully list all Pods if you chose **Option A: Cluster-Wide Read-Only**, proving the ServiceAccount and its token are correctly configured.
158+
159+
## 4. Use with Kubernetes MCP Server
160+
161+
Now that you have a dedicated kubeconfig file, you can use it with the Kubernetes MCP Server:
162+
163+
```bash
164+
# Run the MCP server with the dedicated kubeconfig
165+
./kubernetes-mcp-server --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"
166+
167+
# Or use npx
168+
npx -y kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"
169+
170+
# Or use uvx
171+
uvx kubernetes-mcp-server@latest --kubeconfig="$HOME/.kube/mcp-viewer.kubeconfig"
172+
```
173+
174+
Alternatively, you can set the `KUBECONFIG` environment variable:
175+
176+
```bash
177+
export KUBECONFIG="$HOME/.kube/mcp-viewer.kubeconfig"
178+
./kubernetes-mcp-server
179+
```
180+
181+
## Token Expiration and Renewal
182+
183+
The token created in Step 2 has a limited lifetime (2 hours in the example). When it expires, you'll need to:
184+
185+
1. Generate a new token:
186+
```bash
187+
TOKEN="$(kubectl create token mcp-viewer --duration=2h -n mcp)"
188+
```
189+
190+
2. Update the kubeconfig file:
191+
```bash
192+
kubectl config --kubeconfig="$KUBECONFIG_FILE" set-credentials mcp-viewer --token="$TOKEN"
193+
```
194+
195+
For long-running applications, consider:
196+
- Using a longer token duration (up to the cluster's maximum, typically 24h)
197+
- Implementing automatic token renewal in your application
198+
- Using a different authentication method (e.g., client certificates)
199+
200+
## Cleanup
201+
202+
To remove the ServiceAccount and associated RBAC bindings:
203+
204+
```bash
205+
# Delete the ClusterRoleBinding (if using Option A)
206+
kubectl delete clusterrolebinding mcp-viewer-crb
207+
208+
# Delete the RoleBinding (if using Option B)
209+
kubectl delete rolebinding mcp-viewer-rb -n mcp
210+
211+
# Delete the ServiceAccount
212+
kubectl delete serviceaccount mcp-viewer -n mcp
213+
214+
# Delete the namespace (optional - only if you created it specifically for this)
215+
kubectl delete namespace mcp
216+
217+
# Remove the kubeconfig file
218+
rm "$HOME/.kube/mcp-viewer.kubeconfig"
219+
```
220+
221+
## Troubleshooting
222+
223+
### kubectl create token: command not found
224+
225+
This command requires Kubernetes v1.24+. For older versions, you'll need to extract the token from the ServiceAccount's secret manually.
226+
227+
### Permission denied errors
228+
229+
Ensure you're using the correct kubeconfig file and that the ServiceAccount has the necessary RBAC permissions. Verify with:
230+
231+
```bash
232+
kubectl auth can-i list pods --as=system:serviceaccount:mcp:mcp-viewer --all-namespaces
233+
```
234+
235+
## Next Steps
236+
237+
Now that you have a working kubeconfig with read-only access, configure Claude Code CLI:
238+
239+
- **[Using with Claude Code CLI](GETTING_STARTED_CLAUDE_CODE.md)** - Configure the MCP server with Claude Code CLI
240+
241+
You can also:
242+
- Explore the [main README](../README.md) for more MCP server capabilities

0 commit comments

Comments
 (0)