关于 Mcp Kubernetes Ro
mcp-kubernetes-ro 是一个只读的 Kubernetes MCP 服务,供 AI 助手查看集群资源、Pod 日志和 API 资源信息。它读取本地 kubectl 配置,但无需安装 kubectl 二进制文件,并通过禁止破坏性操作和隐藏 Secret 值来保障安全。
主要功能
- 01列出与查看 Kubernetes 资源详情
- 02获取 Pod 日志并支持 grep 与时间过滤
- 03列出 API 资源与上下文
- 04Base64 编码与解码
- 05可按资源类型禁用访问,如 Secret
适用场景
- 01让 AI 助手协助排查集群中 Pod 的运行问题
- 02在不授予写权限的前提下查看资源状态
- 03查看节点与 Pod 的 CPU 和内存用量
MCP 相关
该项目是一个 MCP 服务,向 MCP 客户端暴露只读的 Kubernetes 查询工具,包括资源列表、日志获取和指标查询。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
我们还没有获取到这个服务的安装包或远程地址,请按项目 README 中的说明安装。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Kubernetes 只读 MCP 服务
mcp-kubernetes-ro 是一个 模型上下文协议(MCP) 服务,为 AI 助手提供对 Kubernetes 集群的只读访问权限。它支持 AI 模型列出资源、获取资源详情、检索 Pod 日志、发现 API 资源,以及执行 base64 编码和解码操作,同时通过只读访问确保安全。
该服务使用本地的 kubectl 配置(即使无需安装 kubectl),并提供安全的 Kubernetes 集群只读接口,既能防止任何破坏性操作,又支持全面检查和排查集群问题。
功能
- 无需
kubectl:MCP 服务使用本地的kubectl配置连接 Kubernetes 集群,但不使用其二进制文件,因此即使机器上未安装kubectl也能正常工作。 - 资源列表:按类型列出任意 Kubernetes 资源,并可选择按标签、字段和命名空间筛选
- 资源详情:获取特定 Kubernetes 资源的完整详情
- Pod 日志:检索 Pod 日志,并支持高级筛选选项,包括 grep 模式、时间筛选和之前的日志
- 容器发现:列出 Pod 中的容器,以便有针对性地访问日志
- API 发现:发现可用的 Kubernetes API 资源及其功能
- Base64 实用工具:对 Kubernetes 密钥和配置进行 base64 编码和解码
- 多种传输模式:支持 stdio、服务器发送事件(SSE)和无状态 Streamable HTTP 通信
- 只读安全性:全面禁止破坏性操作,同时保留完整的检查能力
- 资源访问控制:禁用对特定 Kubernetes 资源类型(例如 Secrets)的访问,防止 AI Agent 查询敏感数据
- 密钥值不会进入对话:工具输出会隐藏密钥值。Agent 需要密钥值时,它会被直接写入文件(stdio),或加密后发送到只有你的机器持有的密钥(远程传输)。请参阅密钥值
- 命名空间支持:可操作特定命名空间或集群范围的资源
- 高级筛选:支持标签选择器、字段选择器和分页
- 单命令上下文:可为单个命令指定不同的 Kubernetes 上下文
- 环境变量支持:自动检测 KUBECONFIG 环境变量
- 端口转发(可选启用):建立到 Pod 端口的隧道连接以进行调试,并支持每个会话转发多个端口
- 启动时连接检查:启动时自动验证集群连接和基本权限
安装
可以从 releases 页面获取预构建二进制文件。
或者,你可以在 macOS 或 Linux 上使用 Homebrew 安装:
brew install patrickdappollonio/tap/mcp-kubernetes-ro
也可以将其用作 NPM 包:只需确保向 AI Agent 提供配置:
npx -y @patrickdappollonio/mcp-kubernetes-ro
最后,Docker 用户可以使用 GitHub Container Registry 中的预构建镜像:
docker pull ghcr.io/patrickdappollonio/mcp-kubernetes-ro:latest
编辑器配置
将以下配置添加到编辑器的设置中,以使用 mcp-kubernetes-ro:
{
"mcpServers": {
"kubernetes-ro": {
"command": "mcp-kubernetes-ro",
"args": [
// Uncomment and modify as needed:
// "--kubeconfig=/path/to/kubeconfig",
// "--namespace=default",
// "--transport=stdio",
// "--port=8080",
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets",
// "--always-start"
],
"env": {
// Set KUBECONFIG environment variable if needed:
// "KUBECONFIG": "/path/to/kubeconfig",
// Set MCP_KUBERNETES_RO_DISABLED_TOOLS environment variable if needed:
// "MCP_KUBERNETES_RO_DISABLED_TOOLS": "get_logs,decode_base64",
// Or use generic DISABLED_TOOLS environment variable:
// "DISABLED_TOOLS": "get_logs,decode_base64",
// Disable access to specific resource types:
// "MCP_KUBERNETES_RO_DISABLED_RESOURCES": "secrets,configmaps",
// Skip startup connectivity check via environment variable:
// "MCP_KUBERNETES_RO_ALWAYS_START": "true"
}
}
}
}
你可以像上面那样直接通过 $PATH 使用 mcp-kubernetes-ro,也可以提供二进制文件的完整路径(例如,/path/to/mcp-kubernetes-ro)。
你还可以将其用作 npx 包,简化安装流程:
{
"mcpServers": {
"kubernetes-ro": {
"command": "npx",
"args": [
"-y",
"@patrickdappollonio/mcp-kubernetes-ro"
// Uncomment and modify as needed:
// "--kubeconfig=/path/to/kubeconfig",
// "--namespace=default",
// "--transport=stdio",
// "--port=8080",
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets"
],
"env": {
// Set KUBECONFIG environment variable if needed:
// "KUBECONFIG": "/path/to/kubeconfig",
// Set MCP_KUBERNETES_RO_DISABLED_TOOLS environment variable if needed:
// "MCP_KUBERNETES_RO_DISABLED_TOOLS": "get_logs,decode_base64",
// Or use generic DISABLED_TOOLS environment variable:
// "DISABLED_TOOLS": "get_logs,decode_base64",
// Disable access to specific resource types:
// "MCP_KUBERNETES_RO_DISABLED_RESOURCES": "secrets,configmaps"
}
}
}
}
以下是利用 Docker 镜像的方法:
{
"mcpServers": {
"kubernetes-ro": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e", "KUBECONFIG=/root/.kube/config",
"-v", "/path/to/kubeconfig:/root/.kube/config",
// Environment variables must be passed with -e, before the image name:
// "-e", "MCP_KUBERNETES_RO_DISABLED_TOOLS=get_logs,decode_base64",
// "-e", "MCP_KUBERNETES_RO_DISABLED_RESOURCES=secrets,configmaps",
"ghcr.io/patrickdappollonio/mcp-kubernetes-ro"
// Place additional flags here, like:
// "--disabled-tools=get_logs,decode_base64",
// "--disabled-resources=secrets"
]
},
}
}
请注意,你需要将 kubeconfig 文件挂载到容器中,并将 KUBECONFIG 环境变量设置为已挂载文件的路径,或者使用 --kubeconfig 标志设置路径。此配置中的 "env" 块仅适用于 docker 命令本身,不适用于容器内的服务,因此请像上面那样在 args 中使用 -e 传递环境变量。
容器无法向你的磁盘写入文件,因此镜像默认启用 --encrypted-secret-access:Secret 值将通过 get_secret_encrypted 获取,而不是通过 save_secret_to_file 获取,即使使用 stdio 也如此。请参阅Secret 值。
先决条件
- 有效的 Kubernetes 配置文件(通常为
~/.kube/config) - 有效的凭据和集群访问权限(不需要 kubectl 二进制文件)
- 适用于读取操作的 RBAC 权限
- Metrics Server(指标工具所必需):要使用指标功能(
get_node_metrics、get_pod_metrics),必须在集群中安装 metrics-server。若不可用,这些工具将返回错误消息。
可用的 MCP 工具
默认提供 11 个工具,启用端口转发后还会额外提供 3 个工具。可用的 Secret 工具取决于传输方式;--insecure-secret-access 会将其移除,使工具数量变为 10 个(请参阅Secret 值):
list_resources:按类型列出任意 Kubernetes 资源,可选筛选条件,并按创建时间从新到旧排序。默认省略metadata.managedFields,除非设置include_managed_fields=trueget_resource:获取特定资源的详情。默认省略metadata.managedFields,除非设置include_managed_fields=true。Secret 值会隐藏get_logs:获取 Pod 日志,支持高级筛选选项,包括 grep 模式、时间筛选和先前日志get_pod_containers:列出 Pod 中可用于访问日志的容器list_api_resources:列出可用的 Kubernetes API 资源及其详情(类似于 kubectl api-resources)list_contexts:列出 kubeconfig 文件中的可用 Kubernetes 上下文get_node_metrics:获取节点指标(CPU 和内存使用情况)get_pod_metrics:获取 Pod 指标(CPU 和内存使用情况)encode_base64:将文本数据编码为 base64 格式decode_base64:将 base64 数据解码为文本格式save_secret_to_file(仅限 stdio):将一个 Secret 值写入仅所有者可访问的文件;默认写入私有临时文件夹,不返回该值get_secret_encrypted(SSE、Streamable HTTP 或--encrypted-secret-access):将一个 Secret 值加密后返回,使用你提供的公钥,并附带可在你的机器上解密该值的命令start_port_forward(可选启用):启动到 Pod 的端口转发,支持一个或多个端口映射stop_port_forward(可选启用):按 ID 停止活动的端口转发会话list_port_forwards(可选启用):列出所有活动的端口转发会话
工具管理
禁用工具
你可以使用 --disabled-tools 标志或 MCP_KUBERNETES_RO_DISABLED_TOOLS / DISABLED_TOOLS 环境变量禁用特定工具。该标志可重复使用,并接受以逗号分隔的值:
# Comma-separated
mcp-kubernetes-ro --disabled-tools=get_logs,decode_base64
# Repeated flags
mcp-kubernetes-ro --disabled-tools=get_logs --disabled-tools=decode_base64
# Using environment variable
export MCP_KUBERNETES_RO_DISABLED_TOOLS=get_logs,decode_base64
mcp-kubernetes-ro
标志和环境变量中的值会合并。如果未设置 MCP_KUBERNETES_RO_DISABLED_TOOLS 环境变量,则会使用 DISABLED_TOOLS 作为备用值。
禁用工具后,它不会注册到 MCP 服务中,也不会出现在可用工具列表里。系统会向 stderr 记录一条消息,说明跳过了哪些工具。
可禁用的工具名称:
list_resourcesget_resourceget_logsget_pod_containerslist_api_resourceslist_contextsget_node_metricsget_pod_metricsencode_base64decode_base64save_secret_to_file(仅限 stdio)get_secret_encrypted(仅限 SSE、Streamable HTTP 或--encrypted-secret-access)start_port_forward(仅在启用端口转发时)stop_port_forward(仅在启用端口转发时)list_port_forwards(仅在启用端口转发时)
禁止访问特定资源
你可以使用 --disabled-resources 标志或 MCP_KUBERNETES_RO_DISABLED_RESOURCES 环境变量,阻止 AI Agent 查询特定类型的 Kubernetes 资源。这对于禁止访问 Secret 等敏感资源尤其有用。
资源可以按名称(单数、复数、kind 或简称)指定,也可以指定完整的 group/version/resource 三元组。core 关键字是 Kubernetes 核心 API 组的别名。所有名称都会在启动时根据集群的发现 API 进行解析,因此可以使用单数名称、kind 名称和简称:
# By resource name (resolved via the cluster's discovery API)
mcp-kubernetes-ro --disabled-resources=secrets
# Singular, kind, and short names all work
mcp-kubernetes-ro --disabled-resources=secret # singular
mcp-kubernetes-ro --disabled-resources=Secret # kind
mcp-kubernetes-ro --disabled-resources=cm # short name for configmaps
# Full group/version/resource format
mcp-kubernetes-ro --disabled-resources=core/v1/secrets
# Multiple resources (comma-separated or repeated flags)
mcp-kubernetes-ro --disabled-resources=secrets,configmaps
mcp-kubernetes-ro --disabled-resources=secrets --disabled-resources=configmaps
# Non-core API groups
mcp-kubernetes-ro --disabled-resources=apps/v1/deployments
# Using environment variable
export MCP_KUBERNETES_RO_DISABLED_RESOURCES=secrets,configmaps
mcp-kubernetes-ro
通过 list_resources 或 get_resource 查询已禁用的资源时,服务会返回明确的错误:
access to resource "secrets" (core/v1/secrets) is disabled by configuration and cannot be queried
已禁用的资源也会从 list_api_resources 的输出中隐藏,因此 AI Agent 不会发现这些资源可用。
如果无法根据集群解析资源名称(例如名称拼写错误或 CRD 不存在),服务将拒绝启动并提供详细错误,以确保禁用的资源始终生效。
Secret 值
工具输出会保留在对话历史记录和 AI 客户端日志中。Secret 的值仅经过 Base64 编码,这只是一种编码,并非加密,因此通过工具返回这些值会使其以明文形式可读。
默认情况下,get_resource 会隐藏所有 Secret 值,只显示其大小,例如 "password": "[redacted: 16 bytes]"。它还会移除 kubectl.kubernetes.io/last-applied-configuration 注解;如果 Secret 是通过 kubectl apply 创建的,该注解会包含 Secret 的完整副本。list_resources 返回元数据(title_only=false)时,也会移除该注解。
当 Agent 需要某个值(例如在脚本中使用)时,会通过当前传输方式对应的 Secret 工具获取该值。服务说明会向 Agent 解释相关步骤。
stdio:save_secret_to_file
服务运行在你的计算机上,因此会将值直接写入文件,并且只返回路径和大小:
{
"name": "db-credentials",
"key": "password",
"namespace": "prod"
}
默认情况下,文件会写入系统临时目录中新建的文件夹,例如 /tmp/mcp-kubernetes-ro-secret-1234567/password。只有你可以打开该文件夹(0700)和文件(0600),并且该文件夹位于任何项目之外,因此不会被意外提交。若要使用其他位置,请传入绝对 path。现有文件和符号链接绝不会被覆盖。
Agent 会将该文件传递给脚本,例如 DB_PASSWORD="$(cat /tmp/mcp-kubernetes-ro-secret-1234567/password)" ./migrate.sh,并会收到提示:脚本不再需要该文件时应将其删除。服务不会替你删除文件。
SSE、Streamable HTTP 和 Docker:get_secret_encrypted
远程服务或容器中的服务无法写入你的磁盘,因此该值会加密到一个只有你的设备持有密钥的密钥对。此工具用于替代 save_secret_to_file,适用于 SSE 和 Streamable HTTP 传输;设置 --encrypted-secret-access 时,也适用于 stdio。Docker 镜像默认启用此选项。Agent 会使用 macOS 和大多数 Linux 发行版自带的 openssl 执行以下步骤,因此通常无需安装任何东西:
- 创建一次性密钥对:
(umask 077; openssl genrsa -out /tmp/k8s-secret-key.pem 4096) - 输出公钥:
openssl rsa -in /tmp/k8s-secret-key.pem -pubout - 使用公钥、私钥路径和输出路径调用
get_secret_encrypted。服务端使用 RSA-OAEP 加密该值,并返回decrypt_command。超过一个 RSA 块大小的值会拆分为多个块。 - 运行
decrypt_command。它会以仅所有者可访问的权限将该值写入输出路径,拒绝覆盖已有文件,并在成功解密后删除私钥。系统会告知 Agent,在脚本不再需要解密后的文件时将其删除。
对话中始终只会包含公钥和加密后的数据块。没有私钥就无法还原该值,而私钥始终不会离开你的设备,并会在使用后删除。服务端不保留任何状态,因此这适用于多个无状态副本。
此方式的保护范围
这些工具可避免 Secret 值出现在对话历史和客户端日志中。但它们无法阻止拥有 shell 访问权限的 Agent 之后读取文件,例如使用 cat。服务端指令会告知 Agent 不要这么做,但这只是指导,并非强制措施。若要彻底阻止 Agent 访问 Secret,请使用 --disabled-resources=secrets,这也会让 Secret 工具拒绝所有请求。
恢复旧行为:--insecure-secret-access
--insecure-secret-access(或 MCP_KUBERNETES_RO_INSECURE_SECRET_ACCESS=true)会让 get_resource 按存储时的原样返回 Secret 值,并移除两个 Secret 工具。之后 Agent 读取的每个值都会以可读形式留在对话历史和客户端日志中。启用此选项时,服务端会在启动时打印警告。
运行模式
标准模式(stdio)
默认情况下,mcp-kubernetes-ro 以 stdio 模式运行,适合与通过标准输入/输出通信的编辑器和其他工具集成。
mcp-kubernetes-ro
服务器发送事件(SSE)模式
此外,你也可以将 mcp-kubernetes-ro 作为支持 SSE 的 HTTP 服务运行,用于 Web 集成:
mcp-kubernetes-ro --transport=sse --port=8080
在 SSE 模式下,服务端会监听指定端口(默认值:8080),并通过服务器发送事件在 HTTP 上提供相同的 MCP 工具。这适用于 Web 应用,或不便使用 stdio 通信的环境。
Streamable HTTP 模式
对于需要在负载均衡器后进行水平扩展的部署,可使用 Streamable HTTP 传输运行服务端:
mcp-kubernetes-ro --transport=streamable-http --port=8080
在此模式下,服务端会在 /mcp 提供单一 MCP 端点,并在协议层无状态运行——无需 Mcp-Session-Id,任何请求都可由任意副本处理。这意味着你可以在普通的轮询负载均衡器后部署多个实例,无需粘性会话或共享会话存储。
关于端口转发的说明: 端口转发会话保存在进程内,无法在副本间共享。如果同时启用
--enable-port-forwarding和--transport=streamable-http,请只运行一个副本;否则,在一个副本上启动的会话将无法被其他副本看到。
配置选项
以下命令行标志可用于配置 MCP 服务:
Kubernetes 配置
--kubeconfig=PATH:kubeconfig 文件的路径(默认为KUBECONFIG环境变量指定的路径,其次为~/.kube/config)--namespace=NAME:操作的默认命名空间(默认为当前命名空间)
传输选项
--transport=TYPE:传输类型:stdio、sse或streamable-http(默认值:stdio)--port=PORT:基于 HTTP 的传输所用端口(默认值:8080,仅在使用--transport=sse或--transport=streamable-http时使用)
工具和资源管理
--disabled-tools=NAMES:要禁用的工具名称,可重复指定并用逗号分隔(可选)--disabled-resources=RESOURCES:要屏蔽的资源类型,可重复指定并用逗号分隔(可选)。接受资源名称(secrets、deploy、cm)或完整规格(core/v1/secrets、apps/v1/deployments)MCP_KUBERNETES_RO_DISABLED_TOOLS:用于指定禁用工具的环境变量(与标志值合并,回退到DISABLED_TOOLS)MCP_KUBERNETES_RO_DISABLED_RESOURCES:用于指定禁用资源的环境变量(与标志值合并)
Secret 访问
--encrypted-secret-access:即使使用 stdio,也提供get_secret_encrypted,而不是save_secret_to_file,适用于服务无法写入你的磁盘的情况。Docker 镜像中默认启用MCP_KUBERNETES_RO_ENCRYPTED_SECRET_ACCESS:用于设置相同选项的环境变量(设为true、1或yes)--insecure-secret-access:按存储时的形式从get_resource返回 Secret 值,并禁用 Secret 工具;优先于--encrypted-secret-access(默认禁用,不推荐;参见 Secret 值)MCP_KUBERNETES_RO_INSECURE_SECRET_ACCESS:用于设置相同选项的环境变量(设为true、1或yes)
端口转发
--enable-port-forwarding:启用端口转发工具(默认禁用)MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING:特定于应用的环境变量(设为true、1或yes)ENABLE_PORT_FORWARDING:通用环境变量(设为true、1或yes)
Context 配置
该服务支持按命令设置 context。这让你在同一个 $KUBECONFIG 文件中使用多个 Kubernetes 集群或 context 时拥有更高的灵活性。
配置优先级:
- 命令级 context:在各个工具调用中使用
context参数 - kubeconfig 默认值:使用 kubeconfig 文件中指定的当前 context
Kubeconfig 解析优先级:
- 命令行标志:
--kubeconfig参数 - 环境变量:
KUBECONFIG环境变量 - 默认路径:
~/.kube/config - 集群内配置:在 Kubernetes Pod 内运行时自动检测
示例:
{
"resource_type": "pods",
"namespace": "default",
"context": "production-cluster"
}
这种方式可以让你:
- 在同一会话中为不同操作使用不同的 context
- 按命令切换 context,无需重启服务
- 与现有 kubeconfig 设置保持兼容
工具使用文档
列出资源
按类型列出任意 Kubernetes 资源,可选择筛选,并按创建时间从新到旧排序。
参数:
resource_type(必需):要列出的资源类型——使用复数形式(例如,'pods'、'deployments'、'services')api_version(可选):资源的 API 版本(例如,'v1'、'apps/v1')namespace(可选):目标命名空间(集群级资源留空)context(可选):要使用的 Kubernetes context(默认为 kubeconfig 中的当前 context)label_selector(可选):用于筛选资源的标签选择器(例如,'app=nginx,version=1.0')field_selector(可选):用于筛选资源的字段选择器(例如,'status.phase=Running')limit(可选):要返回的资源数量上限(默认返回全部)continue(可选):用于分页的继续令牌(来自先前的响应)
示例:
{
"resource_type": "pods",
"namespace": "default",
"context": "production",
"label_selector": "app=nginx"
}
获取资源
获取指定资源的详细信息及完整配置。对于 Secret,除非设置了 --insecure-secret-access,否则值会被隐藏,只显示其大小;请参阅Secret 值。
参数:
resource_type(必需):要获取的资源类型name(必需):资源名称api_version(可选):资源的 API 版本(例如,'v1'、'apps/v1')namespace(可选):目标命名空间(命名空间级资源必需)context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)
示例:
{
"resource_type": "deployment",
"name": "nginx-deployment",
"namespace": "default",
"context": "production"
}
获取日志
获取 Pod 日志,支持高级筛选选项,包括 grep 模式、时间筛选和之前的日志。
参数:
namespace(必需):Pod 命名空间name(必需):Pod 名称container(可选):容器名称(多容器 Pod 必需)context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)max_lines(可选):要获取的最大行数grep_include(可选):仅包含与这些模式匹配的行(逗号分隔)。作用类似 grep:包含含有任一模式的行grep_exclude(可选):排除与这些模式匹配的行(逗号分隔)。作用类似 grep -v:排除含有任一模式的行use_regex(可选):是否将 grep 模式视为正则表达式,而非字面字符串since(可选):返回此时间之后的新日志。支持 "5m"、"1h"、"2h30m"、"1d" 等时长,或 "2023-01-01T10:00:00Z" 等绝对时间previous(可选):返回上一个已终止容器实例的日志(类似 kubectl logs --previous)
示例:
{
"namespace": "default",
"name": "nginx-pod-12345",
"container": "nginx",
"context": "production",
"max_lines": "100",
"grep_include": "error,warning",
"since": "5m"
}
获取 Pod 容器
列出 Pod 中的容器,以便访问日志。
参数:
namespace(必需):Pod 命名空间name(必需):Pod 名称context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)
示例:
{
"namespace": "default",
"name": "nginx-pod-12345",
"context": "production"
}
列出 API 资源
列出可用的 Kubernetes API 资源及其详细信息(类似 kubectl api-resources)。
参数:
- 无必需参数
示例:
{}
列出上下文
列出 kubeconfig 文件中的可用 Kubernetes 上下文。此功能可用于查找其他工具的 context 参数可使用哪些上下文。
参数:
- 无必需参数
示例:
{}
示例响应:
{
"contexts": [
{
"name": "production",
"cluster": "prod-cluster",
"user": "prod-user",
"namespace": "default",
"current": true
},
{
"name": "staging",
"cluster": "staging-cluster",
"user": "staging-user",
"namespace": "staging",
"current": false
}
],
"count": 2
}
获取节点指标
从指标服务获取节点指标(CPU 和内存使用情况)。结果按时间戳排序(最新的在前),以确保排序和分页结果一致,因为内置指标服务端点不支持基于游标的分页。
参数:
node_name(可选):要获取指标的特定节点名称。如果未提供,则返回所有节点的指标。context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)limit(可选):要返回的最大节点指标数。如果未提供,则返回所有可用指标。continue(可选):用于分页的延续令牌(来自之前的响应)。
错误处理:
- 如果指标服务不可用,则返回错误消息
- 检测常见的指标服务错误并提供具体指导
示例:
{
"node_name": "worker-node-1",
"context": "production",
"limit": 5
}
示例响应(单个节点):
{
"kind": "NodeMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "worker-node-1",
"creationTimestamp": "2023-01-01T12:00:00Z"
},
"timestamp": "2023-01-01T12:00:00Z",
"window": "10.062s",
"usage": {
"cpu": "137m",
"memory": "1368128Ki"
}
}
示例响应(带分页的列表):
{
"kind": "NodeMetricsList",
"apiVersion": "metrics.k8s.io/v1beta1",
"count": 5,
"items": [
{
"kind": "NodeMetrics",
"metadata": { "name": "node-1" },
"timestamp": "2023-01-01T12:00:00Z",
"usage": { "cpu": "137m", "memory": "1368128Ki" }
}
],
"continue": "eyJvZmZzZXQiOjUsInR5cGUiOiJub2RlIiwibmFtZXNwYWNlIjoiIn0="
}
获取 Pod 指标
从 metrics server 获取 Pod 指标(CPU 和内存使用量)。结果按时间戳排序(最新的在前),以确保排序和分页一致,因为内置的 metrics server 端点不支持基于 needle 的分页。
参数:
namespace(可选):要获取 Pod 指标的命名空间。如果未提供,则返回所有命名空间中所有 Pod 的指标。pod_name(可选):要获取指标的特定 Pod 名称。如果指定,则必须提供namespace。context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)limit(可选):要返回的 Pod 指标的最大数量。如果未提供,则返回所有可用指标。continue(可选):用于分页的继续令牌(来自先前的响应)。
错误处理:
- 如果 metrics server 不可用,则返回错误消息
- 检测常见的 metrics server 错误并提供具体指导
- 指定
pod_name时,验证是否提供了namespace
分页说明:
- 继续令牌与上下文相关;如果命名空间上下文发生变化,则会重置
- 实施客户端分页,以确保排序和筛选一致
示例(特定 Pod):
{
"namespace": "kube-system",
"pod_name": "metrics-server-557ff575fb-9dcl4",
"context": "production"
}
示例(带分页):
{
"namespace": "kube-system",
"context": "production",
"limit": 10,
"continue": "eyJvZmZzZXQiOjEwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ=="
}
示例响应(单个 Pod):
{
"kind": "PodMetrics",
"apiVersion": "metrics.k8s.io/v1beta1",
"metadata": {
"name": "metrics-server-557ff575fb-9dcl4",
"namespace": "kube-system",
"creationTimestamp": "2023-01-01T12:00:00Z"
},
"timestamp": "2023-01-01T12:00:00Z",
"window": "18.888s",
"containers": [
{
"name": "metrics-server",
"usage": {
"cpu": "8020419n",
"memory": "48164Ki"
}
}
]
}
示例响应(带分页的列表):
{
"kind": "PodMetricsList",
"apiVersion": "metrics.k8s.io/v1beta1",
"namespace": "kube-system",
"count": 10,
"items": [
{
"kind": "PodMetrics",
"metadata": { "name": "pod-1", "namespace": "kube-system" },
"timestamp": "2023-01-01T12:00:00Z",
"containers": [
{
"name": "container-1",
"usage": { "cpu": "8020419n", "memory": "48164Ki" }
}
]
}
],
"continue": "eyJvZmZzZXQiOjIwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ=="
}
Base64 编码
将文本数据编码为 base64 格式。
参数:
data(必需):要编码的文本数据
示例:
{
"data": "username:password"
}
Base64 解码
将 base64 数据解码为文本格式。
参数:
data(必需):要解码的 base64 数据
示例:
{
"data": "dXNlcm5hbWU6cGFzc3dvcmQ="
}
端口转发(选择启用)
默认情况下,禁用端口转发,因为它超出了只读操作的范围。虽然它不会修改任何集群状态(不会创建、更新或删除资源),但会在本地计算机与 Pod 端口之间建立活动网络隧道。这意味着流量可以通过这些隧道传输,并与正在运行的应用交互,例如访问 HTTP 端点、连接数据库,或在目标服务中触发副作用。因此,必须显式启用端口转发。
使用 --enable-port-forwarding 标志启用,或将 MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING 环境变量设为 true。
警告
端口转发可以将流量转发到 kubeconfig 凭据有权访问的集群中任意 Pod,包括基础设施 Pod。如果 Kubernetes API server 本身作为 Pod 运行(例如,在自托管或某些托管环境中),AI Agent 理论上可以将流量转发到该 Pod。虽然仅靠端口转发不会授予额外权限——你仍需要有效凭据和 RBAC 权限才能向 API server 进行身份验证——但如果其他本地工具或脚本发现了暴露在本地端口上的 API server,可能会导致意外交互。请务必检查 RBAC 策略,并考虑在启用端口转发的同时使用
--disabled-resources,以限制 AI Agent 可发现和访问的目标。
警告
在远程服务上以 SSE 模式(
--transport=sse)或 Streamable HTTP 模式(--transport=streamable-http)运行时,转发的端口会绑定到服务的本地接口,而不是你的工作站。这意味着localhost:<local_port>指的是运行mcp-kubernetes-ro的计算机。要从工作站访问转发的服务,必须暴露这些端口,例如通过 SSH 隧道(ssh -L <local_port>:localhost:<local_port> user@remote-host)或其他网络配置。在 stdio 模式下不会出现此问题,因为服务会与编辑器一同在本地运行。使用 Streamable HTTP 时,启用端口转发后还应仅运行一个副本——会话状态保存在进程内,不会在副本之间共享。
启用后,会提供三个额外工具:
启动端口转发
与 Kubernetes Pod 建立端口转发会话。支持在单个会话中转发多个端口。每个端口映射都会将一个本地端口转发到 Pod 上的一个端口。将 local_port 设置为 0(或省略),系统便会自动分配一个空闲本地端口。
参数:
namespace(必需):Pod 命名空间pod(必需):Pod 名称ports(必需):端口映射数组,每项包含:pod_port(必需):要转发到的 Pod 端口(1-65535)local_port(可选):要监听的本地端口(设置为0或省略则自动分配)
context(可选):要使用的 Kubernetes 上下文(默认为 kubeconfig 中的当前上下文)
示例(单个端口,自动分配):
{
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080 }
]
}
示例(多个端口,指定本地端口):
{
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 },
{ "pod_port": 5432, "local_port": 15432 }
]
}
响应示例:
{
"id": "pf-1",
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 },
{ "pod_port": 5432, "local_port": 15432 }
],
"started_at": "2025-01-15T10:30:00Z"
}
停止端口转发
根据 ID 终止处于活动状态的端口转发会话。
参数:
id(必需):端口转发会话 ID(例如,"pf-1")
示例:
{
"id": "pf-1"
}
响应示例:
{
"id": "pf-1",
"stopped": true
}
列出端口转发
列出所有处于活动状态的端口转发会话及其端口映射和元数据。无需参数。
示例:
{}
响应示例:
{
"count": 2,
"port_forwards": [
{
"id": "pf-1",
"namespace": "default",
"pod": "my-app-pod-abc123",
"ports": [
{ "pod_port": 8080, "local_port": 18080 }
],
"started_at": "2025-01-15T10:30:00Z"
},
{
"id": "pf-2",
"namespace": "monitoring",
"pod": "grafana-xyz789",
"ports": [
{ "pod_port": 3000, "local_port": 13000 }
],
"started_at": "2025-01-15T10:35:00Z"
}
]
}
端口转发行为
- 自动清理:如果目标 Pod 被删除或连接断开,端口转发会话会自动移除。之后调用
list_port_forwards将不再显示已终止的会话。 - 正常关闭:停止 MCP 服务时(通过
SIGINT或SIGTERM),所有处于活动状态的端口转发会话都会终止。 - 会话 ID:每个会话都会获得一个唯一且递增的 ID(例如,
pf-1、pf-2)。使用此 ID 调用stop_port_forward可终止指定会话。 - 多个会话:可以同时运行多个端口转发会话,每个会话可指向不同的 Pod 或端口。
使用端口转发配置编辑器
{
"mcpServers": {
"kubernetes-ro": {
"command": "mcp-kubernetes-ro",
"args": [
"--enable-port-forwarding"
],
"env": {
// Or use the environment variable instead of the flag:
// "MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING": "true"
}
}
}
}
示例
基本用法示例
# Start with default kubeconfig and context
mcp-kubernetes-ro
# Start with specific kubeconfig
mcp-kubernetes-ro --kubeconfig ~/.kube/config
# Start with KUBECONFIG environment variable
export KUBECONFIG=~/.kube/config
mcp-kubernetes-ro
# Start with specific namespace
mcp-kubernetes-ro --namespace kube-system
# Start in SSE mode
mcp-kubernetes-ro --transport=sse --port=3000
# Start with port forwarding enabled
mcp-kubernetes-ro --enable-port-forwarding
# Start with port forwarding via environment variable
export MCP_KUBERNETES_RO_ENABLE_PORT_FORWARDING=true
mcp-kubernetes-ro
高级配置示例
# Production cluster with specific kubeconfig
mcp-kubernetes-ro \
--kubeconfig ~/.kube/prod-config \
--namespace monitoring
# Development setup with SSE mode using environment variable
export KUBECONFIG=~/.kube/dev-config
mcp-kubernetes-ro \
--transport=sse \
--port=8080
# Using per-command context (specify context in tool calls)
# Context is now specified at the tool level, not globally
# Disable specific tools for security or performance reasons
mcp-kubernetes-ro --disabled-tools=get_logs,decode_base64
# Disable metrics tools when metrics server is not available
mcp-kubernetes-ro --disabled-tools=get_node_metrics,get_pod_metrics
# Prevent AI agents from reading Secrets and ConfigMaps
mcp-kubernetes-ro --disabled-resources=secrets --disabled-resources=configmaps
# Lock down a production environment: no logs, no secrets, no base64 decoding
mcp-kubernetes-ro \
--kubeconfig ~/.kube/prod-config \
--disabled-tools=get_logs,decode_base64 \
--disabled-resources=secrets
# Use environment variables for disabled tools and resources
export MCP_KUBERNETES_RO_DISABLED_TOOLS=get_logs,decode_base64
export MCP_KUBERNETES_RO_DISABLED_RESOURCES=secrets
mcp-kubernetes-ro
使用场景
集群故障排查
- 列出各命名空间中故障的 Pod
- 获取详细的资源配置
- 检索 Pod 日志以进行调试
- 发现可用的 API 资源
资源发现
- 按类型探索集群资源
- 查找带有特定标签的资源
- 了解资源之间的关系
- 确定资源配置
安全与合规
- 只读访问可防止意外更改
- 检查配置,无需承担修改风险
- 审计资源状态和设置
- 安全地探索生产集群
AI 辅助运维
- 让 AI 助手帮助诊断集群问题
- 获取针对资源问题的智能建议
- 自动分析日志并识别模式
- 使用自然语言查询 Kubernetes 资源
AI 助手注意事项
虽然此 MCP 服务提供了用于检查 Kubernetes 集群的全面工具,但某些 AI 助手可能受到限制或策略约束,无法使用某些工具组合,即使这些组合在技术上可用:
潜在限制
- Secret 访问:出于凭据处理方面的安全策略,某些 AI 助手可能会拒绝检索或处理 Kubernetes Secret 值,即使是通过
save_secret_to_file或get_secret_encrypted也不例外 - 敏感数据:无论用户权限或工具是否可用,AI 模型都可能内置限制,禁止在聊天界面中披露敏感信息
- 安全实践:某些 AI 助手会优先遵循安全最佳实践,而非技术能力,因此可能拒绝可能暴露敏感数据的操作
解决方法
如果 AI 助手因安全原因拒绝使用可用工具:
-
直接使用 CLI:对于敏感操作,直接使用
kubectl,只需让 AI 提供要运行的命令即可,例如:kubectl get secret <secret-name> -n <namespace> -o yaml echo "<base64-data>" | base64 -d -
手动使用工具:如果以编程方式使用 MCP 服务,请直接调用工具,而不是通过 AI 助手调用
-
文档:考虑其中的安全影响——AI 拒绝可能确实是在保护你,避免意外泄露凭据
设计理念
这种行为体现了不同的安全理念:
- 基于工具:如果你拥有工具和权限,就应该能够使用它们
- AI 安全:优先防止意外泄露,而非发挥技术能力
这两种观点都有道理。在设计涉及敏感数据检索的工作流时,应考虑这一限制。
启动时的连接检查
MCP 服务会在启动时自动检查连接,以确认能否成功连接到 Kubernetes 集群。检查内容包括:
- API 服务器可达性:确认 Kubernetes API 服务器可以访问并正常响应
- 身份验证:确认你的凭据有效且已被集群接受
- API 发现:测试服务器能否发现可用的 API 资源
- 基本权限:验证你至少拥有命名空间的读取权限(基本 RBAC 检查)
你会看到的内容
成功启动后,你会看到类似以下的输出:
Testing connectivity to Kubernetes cluster...
✓ Successfully connected to Kubernetes cluster (version: v1.28.0)
连接问题排查
如果连接检查失败,你会看到详细的错误消息。常见问题包括:
- kubeconfig 无效:检查 kubeconfig 文件是否存在且格式正确
- 集群无法访问:确认可以从你的网络访问集群端点
- 身份验证失败:确保凭据尚未过期且有效
- 权限不足:确认你至少拥有读取基本集群资源的权限
连接检查的超时时间为 10 秒,以避免因集群无响应而一直等待。
跳过连接检查(--always-start)
如果通过 OIDC 浏览器流程或其他机制授予凭据,且 MCP 服务进程启动时令牌尚未生效,请使用 --always-start 标志(或 MCP_KUBERNETES_RO_ALWAYS_START=true 环境变量)完全跳过启动时的连接检查:
mcp-kubernetes-ro --always-start
使用 --always-start 时,服务会立即启动,不会连接集群。连接检查实际上会延后:首次调用工具时,服务才会尝试正常连接集群。如果届时无法访问集群或凭据已过期,工具会向 AI 返回结构化错误消息,指示其不要自动重试,并提示你重新进行身份验证。
通过 --disabled-resources 配置的资源过滤器也会延后处理:名称解析会在首次调用工具时进行,而非启动时,因此启动服务时无需连接集群。
安全注意事项
- 只读访问:该服务仅支持对集群进行读取操作(
get、list、watch)。它唯一的写入操作是在 stdio 模式下由save_secret_to_file创建新的本地文件 - 资源访问控制:使用
--disabled-resources阻止 AI Agent 查询特定资源类型(例如 Secrets) - 默认隐藏 Secret 值:除非设置了
--insecure-secret-access,否则工具输出中不会显示 Secret 值。请参阅 Secret 值 - 本地身份验证:使用现有的 kubectl 配置和凭据
- 不执行破坏性操作:无法创建、更新或删除资源
- 命名空间隔离:遵循 kubeconfig 中的 RBAC 权限
- 安全通信:支持 stdio、SSE 和 Streamable HTTP 传输方式(后两种可通过反向代理使用 HTTPS 提供服务)
指标实现细节
错误检测与处理
指标工具(get_node_metrics 和 get_pod_metrics)包含完善的错误检测机制,用于判断指标服务器是否可用:
- 自动检测:检测指标服务器是否未安装或未响应
- 实用的错误消息:指标服务器缺失时提供具体的安装命令
- 常见错误模式:识别各种指标服务器错误情况:
- 找不到
metrics-server服务 metrics.k8s.ioAPI 组不可用- “server could not find the requested resource”错误
- “no metrics available”情况
- 找不到
分页实现
由于内置指标服务器端点不支持基于 needle 的分页,并且为了让 AI 工具能够安全地仅请求所需数据(这在上下文窗口较小时尤其有用),这两个指标工具都实现了客户端分页,以确保结果一致。
- 排序:分页前按时间戳对所有结果排序(最新的排在前面)
- Continue 令牌:包含以下内容的 Base64 编码 JSON 令牌:
offset:结果集中的当前位置type:资源类型("node" 或 "pod")namespace:上下文命名空间(用于 pod 指标)
- 上下文感知:命名空间上下文发生变化时,分页状态会重置
- 令牌格式:
eyJvZmZzZXQiOjEwLCJ0eXBlIjoicG9kIiwibmFtZXNwYWNlIjoia3ViZS1zeXN0ZW0ifQ==
资源检索策略
- 先获取后筛选:始终从服务器检索所有可用指标,然后应用客户端筛选和分页
- 排序一致:确保分页请求之间的结果可预测
- 命名空间范围限定:提供命名空间时,自动将 pod 指标限定在指定命名空间内
错误处理
该服务针对常见问题提供详细的错误消息:
- 无效的资源类型或 API 版本
- 缺少必需参数
- RBAC 权限错误
- 网络连接问题
- 格式错误的 kubeconfig 文件
- 指标服务器不可用(并提供安装指导)
限制
- 需要本地 kubectl 配置
- 仅支持只读访问(不支持写入操作)
- 仅限于 kubeconfig 凭据可访问的资源
- 不支持实时日志流(仅支持静态检索)
- 除 API 资源外,不支持发现自定义资源定义
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。