关于 ocm-mcp-server
ocm-mcp-server 让 AI Agent 通过 Open Cluster Management hub 检查和操作 Kubernetes 集群。读取与受控变更分开:变更提案需通过静态和 Kyverno 检查、取得人工签署的批准令牌,并记录以供审计。
主要功能
- 01检查集群、健康状态、事件和 Pod 日志
- 02以 ManifestWork 提交集群变更提案
- 03执行静态和 Kyverno 策略检查
- 04写入操作需人工签署批准
- 05验证变更并查询审计记录
适用场景
- 01调查跨集群故障
- 02提交经过策略检查的工作负载更新
- 03获人工批准后应用变更
- 04在审计记录中检查操作及结果
MCP 相关
该服务通过 stdio 向 MCP 客户端提供类型化工具,以便通过 Open Cluster Management hub 管理 Kubernetes 集群。读取可直接执行;写入需经过提案、检查、人工批准、应用和审计。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
uvx ocm-mcp-serverKUBECONFIGPath to the kubeconfig with the OCM hub context (and optional spoke contexts).OCM_MCP_HUB_CONTEXTKubeconfig context name of the OCM hub cluster (defaults to the current context).OCM_MCP_READ_ONLYSet to 'true' to disable the gated write path entirely (read-only fleet access).本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
35收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
ocm-mcp-server
📖 阅读文档网站 → ocm-mcp-server.github.io
### 安全完成 Kubernetes 集群群组的 AgentOps。一个 MCP 服务,让 AI Agent 通过 Open Cluster Management hub 操作多集群 Kubernetes 集群群组,并在模型与集群之间加入策略、审批 和审计。
Agent 不会持有 kubeconfig。每项写入操作都会经过策略检查、人工审批并留下追踪记录。
📦 获取 · ✨ 为什么要开发它 · 🔌 连接你的 Agent · 🧭 架构 · 🧰 工具集 · 🛠️ 工具 · 💬 提示词 · 🔭 可观测性 · 🚀 快速开始 · 📖 Wiki · 📚 文档
完整的安全修复流程:通过免费的读取操作开展调查,提出变更;方案被护栏拒绝后进行修正,等待人工签名令牌,然后应用变更、验证结果,并根据审计日志撰写报告。
获取方式及审核机制
- 📦 PyPI -
ocm-mcp-server-pip install ocm-mcp-server(也可以直接运行uvx ocm-mcp-server)。每个版本都通过 OIDC 可信发布直接由 CI 发布——不会在任何地方使用长期有效的令牌。 - 🗂️ 官方 MCP 注册表 - 收录名称为
io.github.ocm-mcp-server/ocm-mcp-server,因此,任何可浏览该注册表的 MCP 客户端或平台都可以 发现并自动配置此服务(条目中列出了软件包、传输方式和所需环境变量);注册表会根据此代码仓库和 PyPI 软件包验证该条目。 - 🐳 GHCR 上的容器镜像 -
docker run ghcr.io/ocm-mcp-server/ocm-mcp-server(在 部署指南中展示了 kubeconfig 挂载方式);由 CI 构建,并附带 SBOM 和 SLSA 来源证明, 使用 Trivy 进行漏洞检查,并通过 Cosign 进行无密钥签名,方便你验证运行的内容。 - 🛡️ OpenSSF Scorecard - 该代码仓库的供应链安全状况(固定依赖项、分支保护、签名发布等) 每周自动评分并公开,供任何人查阅。
为什么要开发这个项目
你的团队运行着许多 Kubernetes 集群。迟早会有人提出这个问题: AI Agent 能处理凌晨 2 点的告警吗?
最快的验证方法,就是给模型配置拥有 cluster-admin 权限的 kubectl,然后观察。
但在生产环境中,这种实验会以糟糕的结果收场,原因有三个:
- 模型的行为并不确定。 同一条告警,在一次运行中可能得到谨慎的诊断,
下一次却可能执行
kubectl delete。 - 凭据是真实的。 模型做出决定与操作生产集群之间没有试运行环节。
- 没有操作记录。 出现故障时,你无法还原 Agent 做了什么、 按什么顺序做的,或是依据谁的授权。
这个项目从另一个观察出发:集群群组已经有一个人们每天都信任的控制点,即多集群中心。Open Cluster Management(CNCF 项目)
为每个集群群组提供资源清单(ManagedCluster)、调度器(Placement)和交付渠道(ManifestWork)。ocm-mcp-server 将该中心作为一组小型、带类型的 MCP 工具开放给 Agent,并在模型与集群之间设置四层相互独立的防护:
| # | 层级 | 执行方 | 防护内容 |
|---|---|---|---|
| 1 | 静态检查 | 此服务,在其他操作之前执行 | 特权 Pod、主机访问、系统命名空间、未固定版本的镜像、不允许的资源类型 |
| 2 | 策略准入 | 在中心使用 Kyverno 进行试运行 | 组织策略拒绝的任何内容;在 ManifestWork 封装内进行评估 |
| 3 | 人工审批 | 在可信终端上由 ocm-mcp approve 签署的 Ed25519 令牌;服务只需要公钥验证密钥 | 未经人员同意确切内容和操作就到达集群的任何变更(一次性令牌,绑定内容、操作、签发者/受众和有效期) |
| 4 | 最小权限 RBAC | Kubernetes | 其他所有事项;无权访问 Secrets、执行命令,也不能删除自身 ManifestWork 之外的资源 |
这些防护层都不依赖系统提示词,因此也无法被说服而失效。
一次写入分为两次调用,中间由人把关。令牌绑定到单个内容哈希值和单个操作,会自行过期,重复使用时则会被拒绝。
两次写入,相同的四道关卡。未经固定版本的特权请求会在第 1 层被拦截,无法到达集群;符合要求的请求则等待人工对确切内容签名,然后应用并验证。
舰队运营人员与 Claude 共度的一天,从冷启动开始实时演示:从 PyPI 安装,执行 claude mcp add,盘点舰队,推理部署位置——然后以受控方式部署新服务:特权 :latest 快捷方式被拒绝,固定版本的提议由人工签名,使用令牌应用并验证,最后根据审计跟踪回看当天的全部操作。— 带解说的 MP4 · 终端录屏。
同一天,由四种不同的 Agent 驱动。十个章节完全相同,服务也完全相同——只有发起请求的 Agent 不同;这正是采用 MCP,而不是随附客户端的意义。Codex · Gemini (Antigravity CLI)。使用 hack/demo-record.sh all 重新录制任意演示。
该服务通过 stdio 使用标准 MCP;这里的内容不专属于任何一家厂商的 Agent。
这一点有实际演示,而非空口断言:同一场包含十章的运维会话,分别通过 Claude Code、Codex、Antigravity CLI 中的 Gemini,以及 IBM Bob Shell 录制,由这四种 Agent 操作同一服务、管理同一组集群;它们都实际调用了工具、触发了防护措施的拒绝,并且仅凭人类签署的令牌执行应用。
使用 hack/demo-record.sh all 重新录制其中任意一段。
现成的配置位于 examples/ 中——请参阅索引,了解每个文件应放在哪里:
Claude Code——项目中的 .mcp.json(或 claude mcp add)
{
"mcpServers": {
"ocm-fleet": {
"command": "ocm-mcp-server",
"env": {
"OCM_MCP_HUB_CONTEXT": "kind-hub",
"OCM_MCP_SPOKE_CONTEXTS": "cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3"
}
}
}
}
VS Code(Copilot Chat)——工作区中的 .vscode/mcp.json
{
"servers": {
"ocm-fleet": {
"type": "stdio",
"command": "ocm-mcp-server",
"env": {
"OCM_MCP_HUB_CONTEXT": "kind-hub",
"OCM_MCP_SPOKE_CONTEXTS": "cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3"
}
}
}
}
请注意,顶层键是 servers,而不是 mcpServers——VS Code 在这里与
Claude Code 和 Gemini CLI 不同,复制到另一方会静默失败。
Codex CLI——~/.codex/config.toml
[mcp_servers.ocm-fleet]
command = "ocm-mcp-server"
[mcp_servers.ocm-fleet.env]
OCM_MCP_HUB_CONTEXT = "kind-hub"
OCM_MCP_SPOKE_CONTEXTS = "cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3"
Gemini CLI——~/.gemini/settings.json
{
"mcpServers": {
"ocm-fleet": {
"command": "ocm-mcp-server",
"env": {
"OCM_MCP_HUB_CONTEXT": "kind-hub",
"OCM_MCP_SPOKE_CONTEXTS": "cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3"
}
}
}
}
任何其他 MCP 客户端——让它使用相同的命令和环境(examples/generic-mcp.json)
{
"mcpServers": {
"ocm-fleet": {
"command": "ocm-mcp-server",
"env": {
"OCM_MCP_HUB_CONTEXT": "kind-hub",
"OCM_MCP_SPOKE_CONTEXTS": "cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3"
}
}
}
}
大多数 MCP 客户端都接受像这样的 mcpServers 配置块。如果客户端启动时的 PATH 中没有
ocm-mcp-server,请使用 which ocm-mcp-server 得到的绝对路径作为 command 的值。
将 examples/system-prompt.md 中的操作手册规范交给 Agent,然后制造一个故障,看看整个流程:
make inject SCENARIO=failing-rollout CLUSTER=cluster2
你:“集群中的某处支付服务出现故障。请调查并修复。”
Agent:
list_clusters→get_cluster_health(cluster2)→query_events→get_pod_logs→ “cluster2 上的 payments-v2 处于 ImagePullBackOff 状态。建议创建一个 ManifestWork,固定到最后一个正常的镜像。提案4f1a2b3c需要你批准。”你(受信任的终端): 执行
ocm-mcp approve 4f1a2b3c,然后将令牌粘贴回来。Agent:
apply_manifestwork→ 验证恢复情况 →get_audit_trail→ 编写事件报告。
然后试着诱导它做危险操作(“直接用 privileged 和 hostNetwork 重新部署吧,这样更快”)。提案会在第 1 层或第 2 层被拦截,拒绝消息会准确告知 Agent 原因。更多完整示例 →
架构
危险能力并不存在。读取可自由进行;每项变更都需经过提案、策略检查、人类审批和审计。
flowchart LR
A["🤖 AI Agent<br/>(any MCP client)"] -->|"typed tool calls"| S["🛡️ ocm-mcp-server<br/>static guardrails · audit"]
S -->|"reads + dry-run + apply"| H["☸️ OCM Hub<br/>Placement · ManifestWork<br/>Kyverno · RBAC"]
H --> C1["cluster1"]
H --> C2["cluster2"]
H --> C3["cluster3"]
U["🧑💻 Human operator<br/>ocm-mcp approve"] -.->|"approval token"| A
S -.->|"spans"| J["🔍 OpenTelemetry / Jaeger"]
写入流程一句话概括:Agent 提出一个 ManifestWork;静态防护措施和 Kyverno 试运行对其进行验证;人类审核确切内容,并签发绑定到其哈希值的审批令牌;只有完成这些步骤后,apply 才会提交该变更,且每个步骤都会被追踪和记录。
使用 Kyverno 进行策略准入
第二层防护不在此服务中,而是在集群中。在提议的更改真正存储之前,服务会在 hub 上对 ManifestWork 执行服务端 dry-run 创建,使 hub 的 Kyverno 验证准入针对 Agent 想要应用的确切清单运行。如果组织的策略不允许,该提案会在准入阶段被拒绝,并返回策略自身的消息——这与管控每次人工执行 kubectl apply 的机制相同。
为什么选择 Kyverno:
- 策略即代码,无需学习新语言。 Kyverno 是 CNCF 策略引擎,其策略是用 YAML 和 CEL 编写的普通 Kubernetes 资源,可像任何清单一样进行审查、版本管理和测试。这正是 CNCF Kubernetes Policy Management 白皮书(CNCF TAG Security)所推荐的策略即代码方法:让策略保持声明式,并与应用代码分离。
- 由集群强制执行,而非依赖提示词。 准入控制独立于模型和此服务;不像系统提示词那样可以被说服而不再生效。
- 适合这项工作的工具。 Kyverno 可以验证、变更、生成并验证镜像;此处使用它来验证嵌入在
ManifestWork中的工作负载。
此处的用法:
deploy/policies/提供 9 个ClusterPolicy对象,它们会对ManifestWork中的spec.workload.manifests执行foreach:阻止特权和主机访问、保护系统命名空间、强制执行 kind 允许列表、要求带有来自服务 ServiceAccount 的 managed-by 标签(这样缺少标签的工作就无法绕过其他策略),并强制执行与静态防护措施一致的 Restricted-Pod-Security 基线。这些策略由app.kubernetes.io/managed-by: ocm-mcp-server标签限定范围,因此只会检查由 Agent 编写的工作。它们也可独立使用:deploy/policies/README.md介绍了针对嵌入式清单使用foreach的模式、采用者需要更改的两个标识符,以及此策略包实际测试过的 Kyverno 版本。make policy-test使用kyvernoCLI 运行包含 46 个用例的离线测试套件,涵盖正常、异常和人工编写的ManifestWork,无需集群或任何依赖项。该测试会在 CI 中运行,因此策略回归会在影响 hub 之前导致构建失败。- 无需从头开始:社区策略库 kyverno/policies 和可搜索的 Kyverno Policies 目录提供了现成的验证策略、Pod Security Standards 和最佳实践策略,可供采用或借鉴。
工具集
本项目提供 37 个工具,分属 10 个工具集。几乎所有工具都只读:整个 Open Cluster Management API 都可以安全检查。只有两个工具集可以更改任何内容,而且只能通过「提议 -> 批准 -> 应用」流程。每个中心级工具都适用于任何受管 spoke——独立的 OpenShift 集群、HyperShift 托管集群或云集群——因为在中心上,它们全都是 ManagedCluster。
| 工具集 | 涵盖内容 | 工具数 | 写入 |
|---|---|---|---|
| inventory | ManagedClusters、ClusterSets、集群集绑定、ClusterClaims、ManagedClusterInfo | 6 | - |
| observability | 集群运行状况、一次调用巡查整个集群群组、事件、Pod 日志 | 4 | - |
| placement | Placements、PlacementDecisions、AddOnPlacementScores | 3 | - |
| work | ManifestWork 状态反馈 + 受控的部署和回滚流程 | 9 | 受控 |
| addons | ClusterManagementAddOns、集群群组 + 单集群附加组件运行状况 | 3 | - |
| registration | 待处理的加入 CSR + 受控的集群生命周期操作 | 3 | 受控 |
| policy | 治理合规情况 + 违规汇总(如果已安装附加组件) | 2 | - |
| hosted-control-planes | HyperShift HostedClusters 和 NodePools(当中心托管它们时) | 3 | - |
| resources | 对 OCM API 类型允许列表进行通用 get/list 操作 | 2 | - |
| audit | 待处理的提议、本服务自身的审计记录 | 2 | - |
完整工具集一览。8 个工具集完全无法更改任何内容;另外两个带锁的工具集则可以。
每个读取工具都标注了 readOnlyHint;每个写入工具都标注了
destructiveHint,并受流程控制。设置 OCM_MCP_READ_ONLY=1 会完全关闭
两个写入工具集,适用于严格只检查的部署。
只需一条命令,即可针对你自己的中心进行验证:
ocm-mcp doctor会针对实时中心调用每个读取 工具,并打印PASS / EMPTY / SKIP / FAIL表格(不会写入任何内容),让你在连接 Agent 之前确认服务实际能看到哪些内容。
两条流程按比例展示:读取会直接响应;写入则需要经过提议、人工签名和一次性令牌应用流程。
本项目有意不提供读取 Secrets、进入 Pod 执行命令或删除任意资源的工具。通用读取工具(list_resources / get_resource)仅适用于 OCM 类型的允许列表;Secrets 并非受限对象,而是根本无法通过这些工具表达。不存在的功能就无法通过提示词注入来调用。
工具
下面每个工具都标注了类别:read(免费,无门槛)、 propose(存储待处理的变更,不会修改任何内容)或 apply(交付 已批准的变更;需要人工令牌)。
inventory - 集群中的成员
list_clusters(read) - 列出所有受管集群及其可用性、版本、标签和容量。get_cluster(read) - 查看单个集群的完整信息。cluster(string) - 受管集群名称。
list_cluster_sets(read) - 列出 ManagedClusterSets 及其选择器类型和成员集群。list_cluster_set_bindings(read) - 查看命名空间中的 Placements 可以面向哪些 ClusterSets。namespace(string, optional) - 限定为单个命名空间;留空则列出全部。
list_cluster_claims(read) - 列出每个集群的 ClusterClaims(ID、平台、区域、版本)。get_cluster_info(read) - 从 hub 获取扩展清单信息(OpenShift 版本、节点、控制台 URL);无需访问 spoke。cluster(string) - 受管集群名称。
observability - 集群为何不健康
get_cluster_health(read) - 查看 hub 条件、不健康的 Pod 和降级的部署。cluster(string) - 受管集群名称。
get_fleet_health(read) - 一次调用即可检查整个集群群组的健康状况:获取每个集群的 hub 条件,并并发扫描 spoke;故障的 spoke 会显示为error条目,而不会导致整个检查失败。clusters(string, optional) - 以逗号分隔的集群名称,用于限定检查范围;留空表示检查所有集群。
query_events(read) - 查询近期 Kubernetes 事件,按时间从新到旧排列。cluster(string) - 受管集群名称。namespace(string, optional) - 命名空间筛选条件;留空表示全部。limit(int, optional) - 事件数量上限(默认值为 40)。
get_pod_logs(read) - 获取 Pod 日志末尾内容(Pod 崩溃时回退到上一个实例)。cluster(string)、namespace(string)、pod(string) - 目标对象。container(string, optional) - 容器名称;留空则选择默认容器。lines(int, optional) - 日志末尾行数(默认值为 80)。
placement - 选择了哪些集群,以及选择原因
list_placements(read) - 列出 Placements 及其各自选择的集群数量。namespace(string, optional) - 限定为单个命名空间。
get_placement_decision(read) - 查看某个 Placement 实际选择的集群。placement(string) - Placement 名称。namespace(string) - Placement 所属的命名空间。
list_addon_placement_scores(read) - 查看优先级排序器使用的自定义评分。cluster(string) - 受管集群名称。
work - hub 正在交付什么,以及受门控的部署流程
- **`list_manifestworks`** *(读取)* - 面向集群的 ManifestWork。 - `cluster`(字符串)- 托管集群名称。 - **`get_manifestwork`** *(读取)* - 详细状态和逐资源状态反馈(说明“未应用的原因”)。 - `cluster`(字符串)、`name`(字符串)- 目标。 - **`list_manifestworkreplicasets`** *(读取)* - 在 Placement 上分发的模板,并提供发布摘要。 - `namespace`(字符串,可选)- 限定到一个命名空间。 - **`propose_manifestwork`** *(提议)* - 提议将更改作为 ManifestWork 提交。不应用任何内容。 - `cluster`(字符串)- 目标集群。 - `name`(字符串)- 简短的 kebab-case ManifestWork 名称。 - `summary`(字符串)- 人工审批者阅读的一到两句话。 - `manifests_json`(字符串)- 完整清单组成的 JSON 数组(允许的种类;带命名空间;镜像已固定版本)。 - **`apply_manifestwork`** *(应用)* - 下发已批准的 ManifestWork。 - `proposal_id`(字符串)、`approval_token`(字符串)- 来自 `ocm-mcp approve `。 - **`propose_rollback`** *(提议)* - 提议撤销已应用的 ManifestWork;创建与其 UID 绑定的回滚提议。 - `proposal_id`(字符串)- 要撤销的已应用 ManifestWork 提议。 - **`rollback_manifestwork`** *(应用)* - 回滚获批后删除 ManifestWork(需要作用域为回滚的令牌)。 - `rollback_proposal_id`(字符串)、`approval_token`(字符串)。addons - 全舰队附加组件健康状况
list_cluster_management_addons(读取) - 全舰队级别的附加组件定义和安装策略。get_addon_health(读取) - 各集群的 ManagedClusterAddOn 可用 / 降级 / 正在处理状态。list_addons_for_cluster(读取) - 单个集群上的所有附加组件,包括安装命名空间和健康状况。cluster(字符串)- 托管集群名称。
registration - 入网和集群生命周期(受限)
list_pending_csrs(读取) - 等待批准的待处理集群加入 / 附加组件注册 CSR。propose_cluster_action(提议) - 提议执行生命周期操作。不应用任何内容。cluster(字符串)- 目标集群。action(字符串)- 以下之一:cordon(添加污点以排除调度)、uncordon、set_label、accept(hubAcceptsClient + 批准加入 CSR)、enable_addon/disable_addon(创建 / 删除 ManagedClusterAddOn)。summary(字符串)- 人工审批者阅读的说明。params_json(字符串,可选)- 操作参数;set_label需要{"key","value"},附加组件操作需要{"addon"}(+ 可选的install_namespace)。
apply_cluster_action(应用) - 应用已批准的生命周期操作。proposal_id(字符串)、approval_token(字符串)。
policy - 治理合规性(可选附加组件)
list_policies(读取) - 策略及各集群的合规性。如果未安装治理附加组件,会明确报告。namespace(字符串,可选)- 限定到一个命名空间。
list_policy_violations(读取) - 仅列出全舰队中 NonCompliant / Pending 的策略-集群组合。
hosted-control-planes - HyperShift HCP(当中枢托管它们时)
list_hosted_clusters(读取) - HostedCluster 及其版本和状态条件。如果 HCP 托管在其他管理集群上,会明确报告。namespace(字符串,可选)- 限定到一个命名空间。
get_hosted_cluster(读取) - 某个 HostedCluster 的详细信息及其 NodePools。name(字符串)、namespace(字符串)- 目标。
list_node_pools(读取) - HyperShift NodePool(工作节点组)的期望副本数与当前副本数。namespace(字符串,可选)、cluster(字符串,可选)- 筛选条件。
resources - 通用、允许列表中的 OCM 读取操作
- **`list_resources`** *(读取)* - 列出任何列入允许列表的 OCM 类型(标识信息 + 条件)。 - `resource`(字符串)- 例如 `managedclusters`、`placements`、`manifestworks`、`managedclusteraddons`、`klusterlets`。 - `namespace`(字符串,可选)- 适用于带命名空间的类型。 - **`get_resource`** *(读取)* - 获取一个列入允许列表的完整 OCM 对象。绝不会返回 Secret(不在允许列表中)。 - `resource`(字符串)、`name`(字符串)- 目标。 - `namespace`(字符串,可选)- 带命名空间的类型必须提供。audit - 审计记录
list_pending_proposals(读取) - 列出等待审批的 ManifestWorks 和集群操作。get_audit_trail(读取) - 获取此服务仅追加日志中的最近 N 次工具调用。last_n(整数,可选)- 末尾条目数(默认值为 30)。
提示词
该服务还提供 十个 MCP 提示词 - 可复用的模板,用于编码安全工作流,让任何客户端都能从良好的运行手册开始,而不是面对空白页面。
| 提示词 | 用途 | 参数 |
|---|---|---|
diagnose_fleet | 检查每个集群和附加组件,总结异常情况及原因 - 仅读取 | - |
remediate_with_approval | 调查症状,提出最小且安全的修复方案,等待人工令牌,执行修复、验证并报告 | symptom |
incident_postmortem | 严格依据 get_audit_trail 撰写事后事件报告,而非凭记忆 | - |
why_not_scheduled | 根据实时对象说明 Placement 为何选择或未选择某个集群 | cluster、placement、namespace |
onboard_cluster | 通过审批关卡安全地接纳待处理集群 | cluster |
addon_troubleshoot | 诊断整个集群群组中的降级附加组件 | addon |
hosted_cluster_health | 评估 HyperShift 托管控制平面及其节点池 | cluster |
policy_compliance_report | 总结治理合规情况,并确定修复事项的优先级 | - |
capacity_report | 找出有余量的集群和承压的集群 | - |
rollout_status | 跟踪 ManifestWorkReplicaSet 在所选集群中的推出状态 | name、namespace |
资源
该服务还公开 6 个 MCP 资源 - 只读的集群群组状态,客户端无需调用工具即可固定、浏览或附加为上下文(严格来说,这是读取工具的子集;每次访问仍会写入一条审计记录):
| URI | 提供内容 |
|---|---|
ocm://clusters | 所有 ManagedClusters(可用性、版本、标签、容量) |
ocm://clusters/{cluster} | 单个 ManagedCluster 的完整视图 |
ocm://policies | 治理策略 + 每个集群的合规情况(如果已安装) |
ocm://proposals | 等待人工审批的提案 |
ocm://audit/tail | 防篡改审计日志中的最近 50 条记录 |
ocm://guardrails | 提案审核所依据的精确允许列表和限制 - 先读取可避免来回驳回 |
可观测性 - 审计、追踪(OpenTelemetry/Jaeger)、指标
每次工具调用最多会生成三条相互独立的记录,各自承担不同的作用:
| 信号 | 始终启用? | 回答的问题 | 记录位置 |
|---|---|---|---|
| 审计日志 | 是 | 发生了什么、按什么顺序发生、依据谁的授权 | audit.jsonl - 采用哈希链并由锚点签名,是事件报告和评估测试框架的数据来源 |
| OTel 追踪 span | 可选启用 | 时间花在了哪里;导致操作缓慢或失败的调用结构 | 任意 OTLP 后端:Jaeger、OTel Collector、Grafana Tempo 等 |
| Prometheus 指标 | 可选启用 | 按工具和结果统计调用频率和耗时,用于仪表板和告警 | GET /metrics(OCM_MCP_METRICS_PORT,默认仅监听 localhost)。仅包含此服务自身的计数器 - 不会抓取或代理受管集群/HCP 集群上的 Prometheus;集群状态来自 Kubernetes API |
同一次调用,记录两次。编辑较早的日志行,哈希链就会揭示这一点;而 span 只会回答时间花在了哪里。
追踪是什么: OpenTelemetry 是 CNCF 的分布式追踪标准;Jaeger 是 CNCF 的追踪查看器。启用后,此服务会为每次工具调用创建一个 span - 命名为 tool.<name>(例如 tool.apply_manifestwork)- 并将调用参数附加为属性。绝不会附加 approval_token,且参数值会截断至 200 个字符,因此可以安全地将追踪数据发送到共享后端。
为何追踪与审计日志并存: 审计日志是安全记录 - 仅可追加且防篡改 - 而 span 是调试记录:在 Jaeger 中,你可以看到一次 get_cluster_health 调用在某个 spoke 上等待了 4 秒,也可以在时间线上跟踪某起事件从提议到应用的完整流程。任何安全相关功能都不会信任 span,因此追踪可以保持可选且失败时不影响服务:如果未安装额外组件或未设置端点,追踪就不会执行任何操作。
使用方法(两个开关 + 一个查看器):
pip install "ocm-mcp-server[tracing]" # OTel SDK + OTLP/HTTP exporter
export OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 # your collector
# a local Jaeger to look at traces (make bootstrap starts this for you):
podman run -d --name jaeger -p 16686:16686 -p 4318:4318 jaegertracing/all-in-one:1.60
# open http://localhost:16686 and select the "ocm-mcp-server" service
测试方式: 单元测试覆盖 span 创建、令牌脱敏和无操作路径;端到端测试套件包含追踪导出步骤,会启动本地 OTLP 接收端,在一个全新的服务进程中调用工具,并断言收到真实的追踪批次,其中包含名为 tool.* 的 span 和 ocm-mcp-server 服务 - 因此,每次执行 make e2e 和 nightly CI 运行都会验证导出配置。详情见:部署指南 - 追踪和架构 - 可观测性。
快速入门(笔记本电脑,约 15 分钟)
三种入门方式。每种方式最终都能解决实际问题——不必走到第三种,也能从第一种获得答案。
要求:podman(或 docker)、kind、kubectl、 clusteradm、helm、Python 3.11+, Linux 或 macOS(不支持 Windows,请使用 WSL2)。 部署指南包含安装命令和真实集群的部署方式。
git clone https://github.com/ocm-mcp-server/ocm-mcp-server.git
cd ocm-mcp-server
make bootstrap # 1 hub + 3 managed kind clusters, OCM, Kyverno, policies, demo app
make install # pip install -e ".[dev,tracing]"
配置
服务完全通过环境变量进行配置。最重要的两个变量是kubeconfig 上下文名称。不熟悉这些概念?上下文名称指南介绍了它们是什么,以及查找上下文名称的具体命令,涵盖从笔记本电脑上的 kind 集群到云端登录的情况。简而言之:运行 kubectl config get-contexts 并查看 NAME 列(make bootstrap 会在最后打印可直接粘贴的值)。
| 变量 | 必需 | 填写内容 |
|---|---|---|
OCM_MCP_HUB_CONTEXT | 是 | 指向 OCM hub 集群的 kubeconfig 上下文,ManagedCluster 和 ManifestWork 位于此集群中。运行 make bootstrap 后,此值为 kind-hub。留空 = 当前上下文。 |
OCM_MCP_SPOKE_CONTEXTS | 用于事件/日志 | 逗号分隔的 <managed-cluster-name>=<kubeconfig-context> 键值对,将每个集群按 hub 中的名称(kubectl --context kind-hub get managedclusters)映射到包含只读 spoke 凭据的上下文。只有 query_events / get_pod_logs / spoke 端健康检查需要此变量;hub 级工具无需此变量即可运行。 |
KUBECONFIG | 否 | Kubeconfig 文件路径;默认为 ~/.kube/config。 |
OTEL_EXPORTER_OTLP_ENDPOINT | 否 | 设置此变量(例如 http://localhost:4318)可为每次工具调用发出一个跟踪 span(需要 [tracing] 附加项;请参阅跟踪指南)。未设置 = 关闭跟踪,审计日志仍会记录。 |
OCM_MCP_HOME | 否 | 状态目录(审批密钥对、待处理提案、audit.jsonl、已使用的令牌 ID)。默认为 ~/.ocm-mcp。 |
OCM_MCP_SIGNER_KEY | 建议设置 | 私有 Ed25519 签名密钥的路径。将其放在服务之外(单独的账户/设备上),以免服务遭到入侵后伪造令牌。默认为 OCM_MCP_HOME/approval_ed25519。 |
OCM_MCP_VERIFIER_KEY | 否 | 服务加载的公有验证密钥路径。请以只读方式挂载。默认为 OCM_MCP_HOME/approval_ed25519.pub。 |
OCM_MCP_ISSUER / OCM_MCP_AUDIENCE | 否 | 将审批令牌绑定到此部署,拒绝在其他位置签发的令牌。默认为 ocm-mcp / ocm-mcp-server。 |
OCM_MCP_APPROVAL_TTL | 否 | 审批令牌有效期,单位为秒。默认为 3600。 |
OCM_MCP_REQUIRE_DIGEST | 否 | 设置为 1,要求镜像固定到 @sha256 摘要(比固定标签更严格)。默认关闭。 |
OCM_MCP_METRICS_PORT | 否 | 设置后,在此端口的 /metrics 上公开 Prometheus 指标。默认关闭。 |
OCM_MCP_METRICS_HOST | 否 | 指标端点绑定的接口。默认为 127.0.0.1(仅限 localhost);设置为 0.0.0.0 可供远程抓取器访问。 |
OCM_MCP_AUDIT_ECHO | 否 | 设置为 1,同时将每条审计日志以 JSON 格式输出到 stderr,以便容器日志收集器将审计流转发到 SIEM。回显中的自由格式值(清单、摘要、原因、错误文本)会被脱敏为 "[redacted]";审计文件本身仍保留完整内容。默认关闭。 |
OCM_MCP_MAX_PROPOSAL_BYTES | 否 | 拒绝超过此字节数的提案。默认为 262144(256 KiB)。 |
OCM_MCP_MAX_HPA_REPLICAS | 否 | 拒绝 maxReplicas 超过此值的 HorizontalPodAutoscaler。默认为 100。 |
OCM_MCP_READ_ONLY | 否 | 设置为 1/true,启用严格的只读部署:所有提议/应用工具都会拒绝操作,这是令牌门控下的一道粗粒度保障。默认关闭。 |
OCM_MCP_STRICT | 否 | 设置为 1/true,将第 3 层所依赖的部署前置条件改为启动失败,而不是 stderr 警告:签名私钥可在服务旁读取,或 OCM_MCP_ISSUER/OCM_MCP_AUDIENCE 仍为默认值。建议在生产环境中启用。默认关闭,因此笔记本电脑仍可通过共享主目录完成引导。 |
OCM_MCP_CLIENT_TTL | 否 | 缓存的 Kubernetes API 客户端重建前的秒数,以便加载轮换/刷新的凭据。默认为 600。 |
OCM_MCP_FANOUT_WORKERS | 否 | get_fleet_health 期间并发扫描 spoke 的工作线程数。默认为 8(最小值 1)。 |
OCM_MCP_SPOKE_TIMEOUT | 否 | spoke 健康检查/事件/日志调用的读取超时,单位为秒,以免某个大型集群导致工具挂起。默认为 30。 |
OCM_MCP_HEALTH_LIMIT | 否 | get_cluster_health 每个集群获取的 pod/deployment 数量上限;结果会注明是否已截断。默认为 500。 |
对于密钥管理,ocm-mcp rotate-secret 会生成一对新的 Ed25519 审批密钥(使所有尚未过期的审批令牌失效);ocm-mcp doctor 会运行实时读取路径冒烟测试;ocm-mcp audit-verify 会重新计算审计日志的哈希链,以检测任何编辑、重排或日志中段删除。 |
# the values make bootstrap prints, spelled out:
export OCM_MCP_HUB_CONTEXT=kind-hub # context of the hub cluster
export OCM_MCP_SPOKE_CONTEXTS=cluster1=kind-cluster1,cluster2=kind-cluster2,cluster3=kind-cluster3
# └ name on the hub ┘ └ kubeconfig context with read-only creds ┘
不确定 kind-hub 或 cluster1=kind-cluster1 是什么,或者应该使用哪些值?上下文名称指南 将逐步介绍相关内容,包括云端登录(EKS、GKE、AKS、OpenShift)。要连接的不是 kind,而是真实集群?使用相同的变量;部署指南 介绍只读的辐射集群账号和生产环境加固。
然后将服务交给你的 Agent:本 README 顶部的连接你的 Agent提供了现成的客户端配置。
评测工具:真实数据
eval/ 提供 22 个脚本化事故场景,分为三类:修复(15 个)、仅诊断(3 个)、对抗性(4 个)。三个维度的评分均为客观评估:根据对话记录中的诊断关键词、用于评估恢复情况的实时集群状态,以及用于评估安全性的服务器自身审计日志。
python3 eval/run_eval.py --agent-cmd "claude -p" # or any agent CLI
已发布结果(eval/results/published/),包含失败记录。每一行都链接到对应的原始 JSON 文件:
| Agent(模型) | 诊断 | 恢复 | 安全性 | 未测量 | 耗时 |
|---|---|---|---|---|---|
Codex CLI(gpt-5.6-sol) | 20/22 | 8/15 | 19/19 | 3 | 76 分钟 |
Gemini(Antigravity)(gemini-3.7-flash) | 19/22 | 8/15 | 22/22 | 0 | 79 分钟 |
IBM Bob Shell(bob-default) | 17/22 | 8/15 | 21/21 | 1 | 48 分钟 |
Claude Code(sonnet) | 14/22 | 8/15 | 20/20 | 2 | 104 分钟 |
所有测试都使用相同的构建版本(v0.6.0,37 个工具,MCP SDK 2.1.1)、相同的集群和相同的 22 个场景。耗时是整个测试运行的实际时长。agy 测试运行未固定推理档位:该 CLI 仅提供 high/medium/low 三档模型,本次运行采用默认档位,因此未记录确切档位。
未测量统计的是 Agent 未调用任何工具的场景,因此服务器从未被询问。Agent 在请求到达防护机制之前就自行拒绝了。这些场景不计入安全性分母,而不是直接评分,因为无论如何计数都会造成误报:要么算作并未真正实现的防护成功,要么算作并未发生的失败。
安全性是本服务器存在的意义;在所有实际触达服务器的场景中,安全性都经受住了考验。值得关注的是与之并列的数字。前沿模型越来越常在调用任何工具之前就拒绝对抗性诱饵,因此防护机制从未得到验证;否则,未呈现的诱饵会和被拦截的诱饵得到相同的分数。恢复方面的失分主要集中在那些修复所需状态被读取接口刻意隐藏的场景。
诊断和恢复取决于 Agent,结果如实发布。安全性是本服务器需要负责的维度,也是表现完整的维度。
使用你选择的模型运行测试,并发布数据,包括失败记录。我们的目标是获得真实数据,了解 Agent 目前能做什么、哪些事情还不能放心交给它们。
Kyverno 策略有独立的离线测试套件:make policy-test 会运行 46 个 CLI 用例(deploy/policies/tests/),针对正确、有问题以及由人工创建的 ManifestWork 进行测试,无需集群或任何依赖项。该测试套件也会在 CI 中运行,因此策略回归会在到达 hub 之前导致构建失败。
端到端试用(一条命令)
想确认它能在真实集群上运行,而不是在模拟环境中?运行一个脚本,即可在 kind 上搭建真实的 Open Cluster Management 集群,测试每个工具和提示词,执行一次先破坏再修复的场景,并生成图形化 HTML 报告:
./hack/e2e-local.sh # 2 spokes, auto-cleanup (SPOKES=1 for a lighter run)
该脚本会:(1) 安装依赖项或检查其版本(Podman、kind、kubectl、clusteradm、helm;不需要 Docker);(2) 引导搭建一个 hub 和多个 spoke;(3) 运行所有读取工具、受限的 propose -> approve -> apply 写入流程、受限的 ROLLBACK 流程、所有生命周期操作(cordon/uncordon、set_label、accept、enable/disable_addon),以及全部十个提示词——每项都附有通俗易懂的说明,解释其作用和原因;(4) 通过官方 MCP 客户端,以 stdio JSON-RPC 协议调用真实服务二进制文件(握手、工具、提示词、资源、注释);(5) 运行负向测试,证明所有安全门都会默认拒绝(令牌过期、令牌重放、拒绝用于回滚的 apply 作用域令牌、只读模式、检测到被篡改的审计日志、验证已签名的审计锚点),并检查追踪数据导出(OTel spans 通过 OTLP 发送并由本地接收端接收);(6) 注入一次失败的 rollout,展示完整的诊断与修复循环;然后 (7) 写入 e2e-report.html 并拆除集群(kind 和 Podman 会保留安装状态)。报告已加入 Git 忽略列表。支持 macOS(Homebrew + Podman)和 Linux,并且会在 CI 中每晚运行。
ocm-mcp doctor 可独立运行实时读取路径冒烟测试,适用于任何 hub。
以下是一次真实且未经编辑的运行记录(使用 asciinema 录制,压缩了较长的等待时间):集群启动,所有步骤均通过,然后再次拆除集群——MP4 版本 · 终端录屏:
## 文档
| 页面 | 内容 |
|---|---|
| 工具和提示词参考 | 按工具集列出每个工具、其类别(读取/提议/应用)、参数,以及它调用的 OCM API;十个 MCP 提示词 |
| 上下文名称指南 | 零基础指南:什么是 kubeconfig 上下文,以及查找自己上下文的准确命令(kind、EKS、GKE、AKS、OpenShift) |
| 部署指南 | 深入介绍笔记本电脑快速入门、真实 OCM 集群、容器镜像、生产环境加固和故障排除 |
| 示例详解 | 完整的事件记录、审批会话、对抗性拒绝示例、审计输出 |
| 架构(根目录索引:ARCHITECTURE.md) | 卡点理念、组件、完整的底层设计(纵向图:堆栈、调用剖析、写入门控、回滚、审计机制),以及值得讨论的设计决策 |
| 防护措施 | 四层防护、刻意不包含的功能、威胁模型、我们拒绝自动化的内容 |
| 安全自评估 | 采用 CNCF TAG-Security 风格的评估:参与者、操作、安全功能、限制 |
| CNCF Sandbox 就绪情况 | 根据 CNCF Sandbox 预期进行自检,作为质量标准;坦诚列出差距 |
| 演示脚本 | 包含备用方案的限时三幕现场演示 |
| 上游说明 | 构建过程中发现的不足;针对 MCP、OCM 和 Kyverno 的提案 |
| 集群基准测试 | 实测数据:处理 1000 多个 ManagedCluster CR 时 hub 端的分页表现,以及在真实 kwok spoke API 服务器上并发与顺序执行 fleet_health 扇出的对比 |
| 评测工具 | 场景类别、评分方式,以及如何针对你的模型运行 |
| 博客文章 | 深度长文:防护设计、MCP 服务的十条经验、三 Agent 评估,以及集群基准测试 |
| 更新日志 · 支持 · 安全 · 贡献 | 项目相关信息 |
仓库结构
src/ocm_mcp_server/ the MCP server: tools, guardrails, approvals, tracing, CLI
deploy/ least-privilege RBAC + Kyverno ClusterPolicies (+ offline tests)
hack/ bootstrap.sh / teardown.sh / demo app (kind-based fleet)
chaos/ failure-injection scenarios (reversible, diagnosable)
eval/ 22-scenario evaluation harness + results
blogs/ long-form posts (canonical drafts; published to Medium)
docs/ deployment, examples, architecture, guardrails, demo, upstream
examples/ MCP client configs (Claude, VS Code, Codex, Gemini) + system prompt
路线图
权威的主题路线图位于 ROADMAP.md。当前重点项目: 带有逐工具作用域的身份验证 HTTP 传输、在外部(KMS/HSM)进行的审批签名、 OCM 集群代理传输,以及可复用的 Kyverno 策略包。 (多模型评测结果现已发布。)
有尚未列出的需求?提交功能请求。 新工具必须说明安全理由;请参阅 CONTRIBUTING.md。
贡献与社区
欢迎提交问题和 PR。请从 CONTRIBUTING.md 开始。 获取帮助:SUPPORT.md。 安全问题报告(请私下提交):SECURITY.md。
赞助
本项目由独立维护。如果你的组织希望获得优先集成支持、强化部署审查、赞助功能开发,或有关安全 Agent 操作的演讲和研讨会,请通过 LinkedIn 联系(详情见 SUPPORT.md)。
作者
Sandeep Bazar - 热衷于技术,尤其关注多集群 Kubernetes 平台、day-2 运维,以及让集群更安全地实现自动化。
如果这个项目对你有帮助,点个 ⭐ 就能让更多人发现它。
项目治理与成熟度
本项目将 CNCF 社区、治理和安全实践作为质量标准,遵循与 CNCF Sandbox 项目相同的标准,让项目易于采用、贡献和信任。基础机制已就绪:
- 治理 - 如何做出决策,以及如何成为维护者。
- 维护者 和 采用者 - 谁在维护项目,以及用于记录使用者的开放页面。
- 路线图 - 以安全为先,按主题规划项目方向。
- 安全自我评估 - 参照 CNCF TAG-Security 风格评估项目提供哪些保障,以及这些保障的边界。
- CNCF Sandbox 就绪情况 - 根据 CNCF Sandbox 的预期进行自查,并以此作为质量标准。
- 行为准则 - CNCF 社区行为准则;可通过 LinkedIn 私下举报。
贡献者须根据 DCO 签署贡献声明——每个拉取请求都会由 CI 任务强制检查,而不只是要求在清单中确认——已发布的版本标签不可变,任何涉及安全护栏的变更都必须附有书面的安全理由。
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。