ocm-mcp-server
GitHub

4. Implementation

What is actually in the code, so you can read it with a map in hand.

Module map #

Module Responsibility
server.py The MCP server. Defines every tool; the only surface the agent sees.
guardrails.py Layer-1 static checks: exact GVK allow-list, namespaces, a Restricted-Pod-Security baseline (no root/privilege-escalation, drop-ALL, seccomp, no host/Secret/arbitrary-SA, volume + Service allow-lists), image pinning, and per-proposal limits. Pure functions, no cluster needed.
ocm.py The OCM API layer: inventory, placement, work, add-on, registration and policy reads, the generic allow-listed reader, and the cordon/uncordon/set_label/accept lifecycle writes, summarized into agent-friendly shapes.
k8s.py Kubernetes client construction: hub context, read-only spoke contexts, the CSR client.
approvals.py Proposal store on disk + Ed25519 approval tokens whose claims bind the content hash, the operation (apply/rollback), and a TTL; ManifestWork, lifecycle-action, and rollback proposals.
tracing.py One OpenTelemetry span and one hash-chained audit line per tool call (optional stderr echo for a SIEM).
metrics.py Optional dependency-free Prometheus /metrics endpoint (OCM_MCP_METRICS_PORT).
filelock.py Advisory file lock behind the atomic proposal writes, the spent-token ledger, and the per-proposal apply lock.
cli.py ocm-mcp: the human side (pending, show, approve, reject, audit, audit-verify, doctor, rotate-secret).
config.py Settings from env, the protected-namespace set, the allowed-kinds set, the readable-resource allow-list, the allowed lifecycle actions, per-proposal limits, and the read-only backstop.

The tools, precisely #

The surface is 35 tools across ten toolsets, but the shape is simple: almost everything is a safe read of the Open Cluster Management API, and only two toolsets can change anything, always through the same gate.

Both write toolsets share one flow: propose runs static guardrails and a hub dry-run and stores the change pending; apply requires an approval token that verifies against the stored proposal's content hash. The work toolset proposes a ManifestWork; the registration toolset proposes an OCM lifecycle action (cordon, uncordon, set_label, accept). Setting OCM_MCP_READ_ONLY=1 disables both write toolsets.

The full list - every tool, its class, its arguments, and the OCM API it touches - is in the Tools and Prompts reference. The server also ships ten MCP prompts (from diagnose_fleet and remediate_with_approval to onboard_cluster, hosted_cluster_health, and policy_compliance_report) that encode the safe workflow as reusable templates. Run ocm-mcp doctor to exercise every read tool against a live hub and print a PASS/EMPTY/SKIP/FAIL table before connecting an agent.

The generic reader is an allow-list #

list_resources and get_resource read any Open Cluster Management type through one interface - but only types on a fixed allow-list (ManagedCluster, Placement, ManifestWork, ManagedClusterAddOn, Klusterlet, and so on). This is deliberately an allow-list, not a deny-list: Secret, ConfigMap, and every other core kind are absent, so the dangerous read cannot be named. A capability that does not exist cannot be prompt-injected into use, and that guarantee does not depend on an operator remembering to set a flag.

The approval token, in code terms #

claims = {id, hash: content_hash, op: "apply" | "rollback", exp: expiry}
token  = base64(claims_json) . base64(Ed25519_sign(private_key, claims_json))

Static guardrail checks (layer 1) #

Inputs are schema-checked first (a malformed manifest is a clean violation, not a crash), then each manifest is rejected on any of:

All violations across all manifests are reported at once, so the agent can fix everything in one revision. The Kyverno layer enforces the same baseline on the hub.

Observability #

Every tool call produces two independent records:

The eval harness scores safety from the audit log, and the agent can read it back via get_audit_trail to write an accurate post-incident report.

Tests #

Next: Guardrails Deep Dive.