AgentStack
MCP verified Apache-2.0 Self-run

Ocm Mcp Server

mcp-sandeepbazar-ocm-mcp-server · by sandeepbazar

An MCP server that lets AI agents operate a multi-cluster Kubernetes fleet through an Open Cluster Management hub, with policy, approval, and audit between the model and your clusters.

No reviews yet
0 installs
1 views
0.0% view→install

Install

$ agentstack add mcp-sandeepbazar-ocm-mcp-server

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets Used
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README — it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-sandeepbazar-ocm-mcp-server)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
today

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming — see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps — measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Ocm Mcp Server? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

🛡️ ocm-mcp-server

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, with policy, approval, and audit between the model and your clusters.

The agent never holds a kubeconfig. Every write is policy-checked, human-approved, and traced.

[](LICENSE) [](pyproject.toml) [](https://modelcontextprotocol.io/) [](https://open-cluster-management.io/) [](https://kyverno.io/) [](https://github.com/sandeepbazar/ocm-mcp-server/actions) [](https://github.com/sandeepbazar/ocm-mcp-server/releases)

[](https://www.linkedin.com/in/sandeepbazar/) [](https://www.youtube.com/@techhorizonhub)

[✨ Why](#why-this-exists)  ·  [🧭 Architecture](#architecture)  ·  [🧰 Toolsets](#toolsets)  ·  [🛠️ Tools](#tools)  ·  [💬 Prompts](#prompts)  ·  [🚀 Quickstart](#quickstart-laptop-15-minutes)  ·  📖 Wiki  ·  [📚 Docs](#documentation)

The whole safe-remediation loop: investigate with free reads, propose a change, get rejected by the guardrails and correct it, wait for a human-signed token, apply, verify, and report from the audit log.


Why this exists

Your team runs many Kubernetes clusters. Sooner or later somebody asks the question: can an AI agent take the 2 a.m. page?

The quickest way to find out is to hand a model kubectl with cluster-admin and watch. In production that experiment ends badly, for three separate reasons:

  • The model is non-deterministic. The same alert can produce a careful diagnosis one

run and a kubectl delete the next.

  • The credentials are real. There is no dry run between the model's decision and your

production cluster.

  • There is no record. When something breaks, you cannot reconstruct what the agent did,

in what order, or on whose authority.

This project starts from a different observation: fleets already have a control point that humans trust every day, the multi-cluster hub. Open Cluster Management (a CNCF project) gives every fleet an inventory (ManagedCluster), a scheduler (Placement), and a delivery channel (ManifestWork). ocm-mcp-server exposes that hub to agents as a small set of typed MCP tools, and puts four independent layers between the model and your clusters:

| # | Layer | Enforced by | What it stops | |---|-------|-------------|---------------| | 1 | Static checks | this server, before anything else | privileged pods, host access, system namespaces, unpinned images, disallowed kinds | | 2 | Policy admission | Kyverno dry-run on the hub | anything your org's policies reject, evaluated inside the ManifestWork envelope | | 3 | Human approval | HMAC token minted by ocm-mcp approve on a trusted terminal | any change reaching a cluster without a person consenting to that exact content | | 4 | Least-privilege RBAC | Kubernetes | everything else; no Secrets, no exec, no deletes outside its own ManifestWorks |

None of these layers live in the system prompt, so none of them can be talked out of.

Architecture

Dangerous capabilities do not exist. Reads flow freely; every change is proposed, policy-checked, human-approved, and audited.

flowchart LR
    A["🤖 AI Agent(any MCP client)"] -->|"typed tool calls"| S["🛡️ ocm-mcp-serverstatic guardrails · audit"]
    S -->|"reads + dry-run + apply"| H["☸️ OCM HubPlacement · ManifestWorkKyverno · RBAC"]
    H --> C1["cluster1"]
    H --> C2["cluster2"]
    H --> C3["cluster3"]
    U["🧑‍💻 Human operatorocm-mcp approve"] -.->|"approval token"| A
    S -.->|"spans"| J["🔍 OpenTelemetry / Jaeger"]

The write path in one sentence: the agent proposes a ManifestWork; static guardrails and a Kyverno dry-run validate it; a human reviews the exact content and mints an approval token bound to its hash; only then does apply deliver it, with every step traced and logged.

Policy admission with Kyverno

The second guardrail layer does not live in this server - it lives in the cluster. Before a proposed change is ever stored, the server does a server-side dry-run create of the ManifestWork on the hub, so the hub's Kyverno validating admission runs against the exact manifests the agent wants to apply. If your organization's policy says no, the proposal is rejected at admission with the policy's own message - the same control that governs every human kubectl apply.

Why Kyverno:

  • Policy as code, no new language. Kyverno is a

CNCF policy engine whose policies are ordinary Kubernetes resources in YAML and CEL - reviewable, versioned, and testable like any manifest. This is the policy-as-code approach the CNCF Kubernetes Policy Management whitepaper (CNCF TAG Security) recommends: keep policy declarative and separate from application code.

  • Enforced by the cluster, not the prompt. Admission control is external to the model and

to this server; it cannot be talked out of the way a system prompt can.

  • The right tool for the job. Kyverno can validate, mutate, generate, and verify images;

here it is used to validate the workloads embedded inside a ManifestWork.

Where it is used here:

  • [deploy/policies/](deploy/policies/) ships three ClusterPolicy objects that foreach

over spec.workload.manifests inside a ManifestWork (block privileged/host access, protect system namespaces, enforce a kind allow-list), scoped by the app.kubernetes.io/managed-by: ocm-mcp-server label so they judge only agent-authored work.

  • make policy-test runs a 12-case offline suite with the kyverno CLI - good, bad, and

human-authored ManifestWorks - needing no cluster and no dependencies. It runs in CI, so a policy regression fails the build before it can reach a hub.

  • Don't start from scratch: the community library

kyverno/policies and the searchable Kyverno Policies catalog are a ready source of validation, Pod Security Standards, and best-practice policies to adopt or take inspiration from.

Toolsets

The surface is 33 tools across ten toolsets. Almost all of it is read: the whole Open Cluster Management API is safe to inspect. Only two toolsets can change anything, and only through the propose -> approve -> apply gate. Every hub-level tool works for any managed spoke - a standalone OpenShift cluster, a HyperShift hosted cluster, or a cloud cluster - because on the hub they are all ManagedClusters.

| Toolset | What it covers | Tools | Writes | |---|---|---|---| | inventory | ManagedClusters, ClusterSets, set bindings, ClusterClaims, ManagedClusterInfo | 6 | - | | observability | cluster health, events, pod logs | 3 | - | | placement | Placements, PlacementDecisions, AddOnPlacementScores | 3 | - | | work | ManifestWork status feedback + the gated deploy flow | 6 | gated | | addons | ClusterManagementAddOns, fleet + per-cluster add-on health | 3 | - | | registration | pending join CSRs + gated cluster lifecycle actions | 3 | gated | | policy | governance compliance + violations rollup (if the add-on is installed) | 2 | - | | hosted-control-planes | HyperShift HostedClusters and NodePools (when the hub hosts them) | 3 | - | | resources | generic get/list over an allow-list of OCM API types | 2 | - | | audit | pending proposals, this server's own audit trail | 2 | - |

Every read tool is annotated readOnlyHint; every write tool is annotated destructiveHint and enforced by the gate. Setting OCM_MCP_READ_ONLY=1 turns off the two writing toolsets entirely, for a strictly-inspection deployment.

> Validate against your own hub in one command: ocm-mcp doctor calls every read > tool against the live hub and prints a PASS / EMPTY / SKIP / FAIL table (writing > nothing), so you can confirm exactly what the server sees before wiring up an agent.

There is deliberately no tool that reads Secrets, execs into pods, or deletes arbitrary resources. The generic reader (list_resources / get_resource) works against an allow-list of OCM types, so Secrets are not restricted - they are simply not expressible. A capability that does not exist cannot be prompt-injected into use.

Tools

Each tool below is annotated with its class: read (free, no gate), propose (stores a pending change, mutates nothing), or apply (delivers an approved change; needs a human token).

inventory - who is in the fleet

  • list_clusters (read) - all managed clusters with availability, version, labels, capacity.
  • get_cluster (read) - full view of one cluster.
  • cluster (string) - managed cluster name.
  • list_cluster_sets (read) - ManagedClusterSets with selector type and member clusters.
  • list_cluster_set_bindings (read) - which ClusterSets a namespace's Placements may target.
  • namespace (string, optional) - limit to one namespace; empty lists all.
  • list_cluster_claims (read) - every cluster's ClusterClaims (id, platform, region, version).
  • get_cluster_info (read) - extended inventory from the hub (OpenShift version, nodes, console URL); needs no spoke access.
  • cluster (string) - managed cluster name.

observability - why a cluster is unhealthy

  • get_cluster_health (read) - hub conditions, unhealthy pods, degraded deployments.
  • cluster (string) - managed cluster name.
  • query_events (read) - recent Kubernetes events, newest first.
  • cluster (string) - managed cluster name.
  • namespace (string, optional) - namespace filter; empty means all.
  • limit (int, optional) - max events (default 40).
  • get_pod_logs (read) - tail a pod's logs (falls back to the previous instance if crashing).
  • cluster (string), namespace (string), pod (string) - target.
  • container (string, optional) - container name; empty picks the default.
  • lines (int, optional) - trailing lines (default 80).

placement - which clusters were chosen, and why

  • list_placements (read) - Placements and how many clusters each selects.
  • namespace (string, optional) - limit to one namespace.
  • get_placement_decision (read) - the clusters a Placement actually selected.
  • placement (string) - Placement name.
  • namespace (string) - the Placement's namespace.
  • list_addon_placement_scores (read) - custom scores prioritizers consume.
  • cluster (string) - managed cluster name.

work - what the hub is delivering, and the gated deploy flow

  • list_manifestworks (read) - ManifestWorks targeting a cluster.
  • cluster (string) - managed cluster name.
  • get_manifestwork (read) - detailed status + per-resource status feedback (the "why not Applied").
  • cluster (string), name (string) - target.
  • list_manifestworkreplicasets (read) - a template fanned across a Placement, with rollout summary.
  • namespace (string, optional) - limit to one namespace.
  • propose_manifestwork (propose) - propose a change as a ManifestWork. Applies nothing.
  • cluster (string) - target cluster.
  • name (string) - short kebab-case ManifestWork name.
  • summary (string) - one or two sentences the human approver reads.
  • manifests_json (string) - JSON array of complete manifests (allowed kinds; namespaced; pinned images).
  • apply_manifestwork (apply) - deliver an approved ManifestWork.
  • proposal_id (string), approval_token (string) - from ocm-mcp approve .
  • rollback_manifestwork (apply) - delete the ManifestWork from an applied proposal (needs a fresh token).
  • proposal_id (string), approval_token (string).

addons - add-on health across the fleet

  • list_cluster_management_addons (read) - fleet-level add-on definitions and install strategy.
  • get_addon_health (read) - per-cluster ManagedClusterAddOn Available / Degraded / Progressing.
  • list_addons_for_cluster (read) - every add-on on one cluster, with install namespace and health.
  • cluster (string) - managed cluster name.

registration - onboarding and cluster lifecycle (gated)

  • list_pending_csrs (read) - pending cluster-join / add-on registration CSRs awaiting approval.
  • propose_cluster_action (propose) - propose a lifecycle action. Applies nothing.
  • cluster (string) - target cluster.
  • action (string) - one of cordon (taint out of scheduling), uncordon, set_label, accept (hubAcceptsClient + approve join CSRs), enable_addon / disable_addon (create/delete a ManagedClusterAddOn).
  • summary (string) - what the human approver reads.
  • params_json (string, optional) - action parameters; set_label needs {"key","value"}, the add-on actions need {"addon"} (+ optional install_namespace).
  • apply_cluster_action (apply) - apply an approved lifecycle action.
  • proposal_id (string), approval_token (string).

policy - governance compliance (optional add-on)

  • list_policies (read) - Policies and per-cluster compliance. Reports clearly if the governance add-on is not installed.
  • namespace (string, optional) - limit to one namespace.
  • list_policy_violations (read) - only the NonCompliant / Pending policy-cluster pairs across the fleet.

hosted-control-planes - HyperShift HCP (when the hub hosts them)

  • list_hosted_clusters (read) - HostedClusters with version and conditions. Reports clearly if HCPs are hosted on a different management cluster.
  • namespace (string, optional) - limit to one namespace.
  • get_hosted_cluster (read) - one HostedCluster in detail, with its NodePools.
  • name (string), namespace (string) - target.
  • list_node_pools (read) - HyperShift NodePools (worker groups), desired vs current replicas.
  • namespace (string, optional), cluster (string, optional) - filters.

resources - generic, allow-listed OCM reads

  • list_resources (read) - list any allow-listed OCM type (identity + conditions).
  • resource (string) - e.g. managedclusters, placements, manifestworks, managedclusteraddons, klusterlets.
  • namespace (string, optional) - for namespaced types.
  • get_resource (read) - get one allow-listed OCM object in full. Never returns a Secret (not on the allow-list).
  • resource (string), name (string) - target.
  • namespace (string, optional) - required for namespaced types.

audit - the record

  • list_pending_proposals (read) - ManifestWorks and cluster actions awaiting approval.
  • get_audit_trail (read) - the last N tool calls from this server's append-only log.
  • last_n (int, optional) - trailing entries (default 30).

Prompts

The server also ships ten MCP prompts - reusable templates that encode the safe workflow so any client can start from a good runbook instead of a blank box.

| Prompt | What it drives | Arguments | |---|---|---| | diagnose_fleet | sweep every cluster and add-on, summarize what is unhealthy and why - reads only | - | | remediate_with_approval | investigate a symptom, propose the smallest safe fix, wait for the human token, apply, verify, report | symptom | | incident_postmortem | write the post-incident report strictly from get_audit_trail, not from memory | - | | why_not_scheduled | explain why a cluster was or was not selected by a Placement, from the live objects | cluster, placement, namespace | | onboard_cluster | accept a pending cluster safely through the approval gate | cluster | | addon_troubleshoot | diagnose a degraded add-on across th

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.