ocm-mcp-server
GitHub
v0.6.0 · signed releases with provenance

AgentOps for Kubernetes fleets, done safely.

An MCP server that lets AI agents operate a multi-cluster Kubernetes fleet through an Open Cluster Management hub. The agent never holds a kubeconfig. Every write is policy-checked, human-approved, and traced.

Star us ❤️ →

An agent's tool calls pass through a guardrailed control plane where reads are free, consequential writes need a human signature, and everything is recorded.
  1. AI agent no kubeconfig
  2. MCP server narrow surface
  3. Layer 1 guardrails static checks
  4. Layer 2 Kyverno dry-run admission
  5. Layer 3 approval human, Ed25519
  6. Layer 4 RBAC least privilege
  7. fleet OCM hub

Each gate can refuse on its own. A change reaches the fleet only by satisfying all four.

See it refuse, then see it apply

Recorded live against a real fleet: the privileged :latest shortcut is refused, the pinned proposal is human-signed, applied and verified.

Every answer is the model's own, over the real MCP protocol. The same ten chapters run against Claude, Codex, Gemini and IBM Bob Shell: same server, same fleet, only the agent changes.

Four layers between the model and your clusters

Each one can refuse independently. A request has to satisfy all of them, and the two policy layers are tested against a shared fixture corpus to prove they agree.

LAYER 1

Static guardrails

Dangerous reads cannot be expressed: Secrets and non-OCM kinds are absent from the allow-list, so they are refused before any API call.

LAYER 2

Kyverno admission

An independent second opinion in dry-run. A parity contract asserts it reaches the same verdict as layer 1 on every fixture.

LAYER 3

Human approval

Writes are two-phase. An Ed25519 token, minted by a person out of band, binds the exact content hash and expires.

LAYER 4

Least-privilege RBAC

No Secret reads, no exec, no arbitrary delete — enforced by the hub itself, not by the server asking nicely.

Two writes meet the same four gates: a privileged, unpinned request is refused at layer one and never reaches a cluster, while a compliant one is signed by a person, applied and verified.

Watch the same four gates take two requests. Only one of them reaches a cluster, and a person had to sign for it.

A write is two calls with a person between them

The server holds a public verifier key and nothing else. The signing key stays with the person, on their own terminal, and the token it produces is bound to one content hash, one operation, and an expiry.

A write is two calls with a person between them: propose returns a content hash, a human signs that hash on their own terminal, apply spends the one-time token, and a replay of the same token is rejected.

Almost all of this surface is read

The whole Open Cluster Management API is safe to inspect, so most of the server is readable and free. Only two toolsets can change anything, and only through the gate.

Reads and writes take different paths through the server: read-only tools answer immediately and freely, while writing tools go through propose, a human approval, and a one-time-token apply.
The whole tool surface across ten toolsets, of which only work and registration can change anything. No tool reads Secrets, execs into a pod, or deletes what it did not create.

Two records of every call, with different jobs

The audit log is a safety artifact: append-only, hash-chained, and the thing an incident report is written from. The spans are a debugging one, and nothing safety-related trusts them.

Every tool call leaves two records: a hash-chained audit line, where editing an earlier line visibly breaks the chain, and an optional OpenTelemetry span showing where the time went.

Start here

Why it exists, how it works, and what it refuses to automate — in order.

Run it

Architecture, deployment paths, the full tool surface, and the threat model.

Honest numbers, failures included

The same build, the same fleet and the same scenarios, run by four different agents. Diagnosis and recovery belong to the agent. Safety is the axis this server is answerable for.

Published evaluation results for four agents on the same build and fleet: diagnosis and recovery vary by agent, while safety held on every scenario that reached the guardrails, with zero unsafe writes.

Four agents. One server. The failures too.

The same 22 scripted incidents, the same fleet, the same build (v0.6.0, 37 tools). Only the agent changes. Each row links to the run that produced its numbers.

  1. Codex CLI

    gpt-5.6-sol
    Safety
    19/19
    Diagnosis
    20/22
    Recovery
    8/15
    Time taken
    76 min
  2. Gemini (Antigravity)

    gemini-3.7-flash
    Safety
    22/22
    Diagnosis
    19/22
    Recovery
    8/15
    Time taken
    79 min
    every scenario reached the serverraw JSON
  3. IBM Bob Shell

    bob-default
    Safety
    21/21
    Diagnosis
    17/22
    Recovery
    8/15
    Time taken
    48 min
  4. Claude Code

    sonnet
    Safety
    20/20
    Diagnosis
    14/22
    Recovery
    8/15
    Time taken
    104 min

Not measured is neither a pass nor a failure: the agent made no tool call, so the guardrails were never consulted. How the harness scores