Docs · AI
UpdatedConnect Claude Code or Cursor to Kubernetes
Point an AI client at Subnomic’s MCP server with a credential that can read one cluster and nothing else. The client never holds a kubeconfig, the cluster opens no port, and every call is checked and logged.
The short version
- Run the Subnomic Kubernetes agent in the cluster and register the cluster (Kubernetes).
- In the console, under Runa → MCP clients, mint a credential with
kube.readandresource.read, that one cluster as its only target, and a short expiry. - Add it to your client:
claude mcp add --transport http subnomic https://app.subnomic.com/mcp \ --header "Authorization: Bearer $SUBNOMIC_AGENT_TOKEN"
- Ask it something about the cluster: “Which pods in
shopare restarting, and why?”
Nothing runs on your laptop but the client. There is no kubeconfig to hand the agent, and the cluster opens no port: calls go to app.subnomic.com/mcp, and from there through the agent already in the cluster.
Before you start
- A Kubernetes agent running in the cluster, and the cluster registered under Kubernetes → New cluster. The agent talks to the API server with its own ServiceAccount, so what an MCP client can ever reach is bounded by that ServiceAccount’s RBAC too. Installing it is in Agents.
- MCP for your own clients is part of the Team and Enterprise plans. Minting a credential needs
mcp.manage, which owners and admins hold. - A client that speaks remote MCP over Streamable HTTP. Claude Code and Cursor do; a client that only starts local stdio servers can use
mcp-remote, shown below.
Mint a read-only credential
Start with a credential that can look and not touch. Under Runa → MCP clients, create one with:
| Field | For a first, read-only credential |
|---|---|
| Capabilities | kube.read to see the cluster, resource.read to list resources, read events and logs. Add kube.proxy for read-only Kubernetes API GETs. |
| Targets | Only the cluster you are working on. The agent cannot reach anything not on this list. |
| Expiry | 7 days while you try it; 30 to 360 for a credential you keep. |
The token, subnomic_live_agt_…, is shown once. Keep it in your password manager or an environment variable, not in a file you commit. The full list of capabilities is in Agent access.
Add it to Claude Code
export SUBNOMIC_AGENT_TOKEN=subnomic_live_agt_… claude mcp add --transport http subnomic https://app.subnomic.com/mcp \ --header "Authorization: Bearer $SUBNOMIC_AGENT_TOKEN"
Without --scope, the server is added for you in the current project only. --scope user makes it available in every project. Avoid --scope project for this one: it writes the server, header included, to .mcp.json, which is shared with everyone in the repository.
Add it to Cursor
In Cursor’s MCP settings, add a server with the URL and the header:
{
"mcpServers": {
"subnomic": {
"url": "https://app.subnomic.com/mcp",
"headers": { "Authorization": "Bearer subnomic_live_agt_…" }
}
}
}
VS Code and other clients
Any client that can add a remote HTTP MCP server with a custom header works the same way: the URL is https://app.subnomic.com/mcp and the header is Authorization: Bearer <token>. For VS Code, add it as an HTTP server; the file format is in VS Code’s MCP configuration reference. A client that can only start a local process can reach it through mcp-remote:
{ "mcpServers": { "subnomic": {
"command": "npx",
"args": ["mcp-remote", "https://app.subnomic.com/mcp",
"--header", "Authorization: Bearer subnomic_live_agt_…"]
}}}
The endpoint speaks Streamable HTTP only. A client that supports nothing but the older SSE transport cannot connect.
Check what it sees
Before the first prompt, ask the server for its tool list. It holds only the tools the credential’s capabilities allow, so a read-only credential shows no tool that changes anything:
curl -s https://app.subnomic.com/mcp \
-H "Authorization: Bearer $SUBNOMIC_AGENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Then try questions the read tools answer:
- “Which pods in
shopare restarting?” usescrashloop_report: each pod with its restart count and last exit code. - “Why is
checkoutfailing?” usesinvestigate_resource: status, events, restart and OOM signals and recent logs in one report. - “What changed before it broke?” uses
rollout_historyandrecent_changes.
Each call appears on the credential’s page in the console with its tool, outcome and duration; the newest 300 are kept there.
Letting it change things
resource.write adds restart, scale, set-image, apply and drain; resource.delete adds delete. An MCP call has nobody to ask, so a guardrail that requires approval refuses it outright, and a rule that denies refuses it too. Write the rules before you tick the box:
# target pattern action kube ^kubernetes\.delete\b.*\bns=prod\b deny kube ^kubernetes\.scale\b.*\bns=prod\b require_approval
With those two, the agent can restart a workload in prod but cannot delete or scale one there. Changes land in the activity log, attributed to the agent. Rules are in Guardrails.
When it does not work
| What you see | What it means |
|---|---|
| Every call fails after it worked | The credential expired or was revoked. Mint a new one. |
| A tool you expected is missing | The credential does not hold its capability. The tool list follows the capabilities; use a credential that has it. |
| The cluster is not in the target list | It was not picked as a target for this credential, so the agent cannot see it. Use a credential that names it. |
| “agent is offline” | The Kubernetes agent is not connected. Check its pod is running. |
| 403 from the API server | The agent’s ServiceAccount has no RBAC for that resource. |
| A change is refused | A guardrail denied it or requires approval, which an MCP call cannot give. |
Running an open-source MCP server against your own kubeconfig instead? How the common ones connect and what limits them is in Kubernetes MCP servers compared.