关于 Nutanix Prism Central
Nutanix Prism Central 是 Nutanix 官方 Prism Central v4 API MCP 服务的多租户 HTTP 桥接层。它按租户凭据启动上游 stdio 进程,并有意仅开放只读操作。
主要功能
- 01按租户建立上游 MCP 会话
- 02Streamable HTTP 接口
- 03只读 Prism Central 操作
- 04凭据请求头映射至子进程
- 05空闲租户进程回收
- 06API 操作发现工具
适用场景
- 01读取不同租户的 Prism Central 数据
- 02将 HTTP 网关连接到仅支持 stdio 的上游服务
- 03发现操作架构和权限
MCP 相关
该桥接层将 MCP 工具列表与调用转发至 Nutanix 官方上游服务,并保持工具名称不变。它通过 Streamable HTTP 提供上游 stdio 会话,并强制启用只读模式。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
docker run -i --rm -e PORT -e IDLE_EVICT_MS -e SPAWN_TIMEOUT_MS ghcr.io/wyre-technology/nutanix-mcp:v1.0.0PORTPublic listen port for the bridge (POST /mcp, GET /health)IDLE_EVICT_MSIdle tenant timeout before an upstream child is evicted (ms)SPAWN_TIMEOUT_MSHow long to wait for a spawned child to answer the MCP handshake (ms)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
ghcr.io/wyre-technology/nutanix-mcp:v1.0.0stdio工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
nutanix-mcp
基于 nutanix/ntnx-api-mcp-server 构建的多租户 Streamable HTTP 桥接服务。该服务是 Nutanix 官方的 Prism Central v4 API MCP 服务,旨在让 WYRE conduit 网关能够通过 HTTP 标头转发各租户的 Nutanix 凭据。
上游版本固定:Nutanix 的服务目前处于技术预览阶段,此处固定使用标签
v0.8(Apache-2.0)。请参阅更新上游版本固定项。
原因
上游服务仅支持 stdio(nutanix-mcp serve-stdio 是其唯一的服务模式),并在进程启动时从环境变量读取 Prism Central 凭据——每个进程只能服务一个租户。我们的网关支持多租户:每个请求都会通过 HTTP 标头携带发起请求的组织凭据,供应商容器必须将这些标头转换为上游可识别的形式。
由于上游没有可供代理的 HTTP 模式,此桥接服务会通过 stdio 为每个租户子进程建立一个 MCP 客户端会话,再通过 Streamable HTTP 提供服务:
- 在
:8080上监听POST /mcp和GET /health。启动时必须提供真实的CONDUIT_S2S_SECRET。每个/mcp请求都必须携带由该密钥生成的有效X-Gateway-S2S签名。 - 对每个
/mcp请求,检查其是否包含X-Nutanix-Pc-*凭据标头(见下文),否则返回 401。这些标头是唯一的 Prism Central 凭据来源。 - 按凭据元组的哈希值作为键,为每个凭据元组按需启动一个
nutanix-mcp serve-stdio子进程,设置租户的PC_*环境变量,并通过 stdio 为其连接 MCP 客户端。 - 在
/mcp上通过 v2 SDK 的createMcpHandler(factory, { legacy: 'stateless' })同时支持两个协议时期:2025 年协议的initialize握手客户端(当前的 conduit 网关)和现代 2026-07-28 信封客户端。tools/list和tools/call会转发到租户的子进程会话。 - 闲置 60 分钟后逐出子进程(
IDLE_EVICT_MS)。
工具名称保持不变:上游的 24 个工具——20 个 {namespace}_execute 工具(aiops、clustermgmt、datapolicies、dataprotection、files、iam、licensing、lifecycle、microseg、monitoring、multidomain、networking、objects、opsmgmt、prism、security、storage、tenancy、vmm、volumes),以及 4 个发现工具(listOperations、getOperationSchema、getCodeSample、getOperationPermissions)。
v1 中仅支持只读——这是有意为之
每个子进程都会以 READ_ONLY_MODE=true 启动(这也是上游的默认值):上游会在非 GET 操作到达 Prism Central 之前将其全部拒绝。此桥接服务的 v1 采用只读模式,是有意作出的整体部署决策。要支持写入,必须对 src/credentials.ts 中的 credentialsToChildEnv() 进行经过审查且带版本控制的更改,而不是简单地切换配置。
凭据约定
网关会在每个 /mcp 请求上转发以下标头;桥接服务会将其映射到上游子进程的环境变量中。conduit 的供应商配置必须与此表完全一致。
| 标头 | 子进程环境变量 | 必填 | 备注 |
|---|---|---|---|
X-Nutanix-Pc-Host | PC_HOST | 是 | Prism Central IP 或 FQDN |
X-Nutanix-Pc-Port | PC_PORT | 否 | 上游默认值为 9440。上游的特殊行为:任何非 9440 端口都会使其使用 http:// 而非 https:// |
X-Nutanix-Pc-Username | PC_USERNAME | 需提供密码 | Basic 身份验证凭据对 |
X-Nutanix-Pc-Password | PC_PASSWORD | 需提供用户名 | Basic 身份验证凭据对 |
X-Nutanix-Pc-Api-Key | PC_API_KEY | 可选 | 作为 X-ntnx-api-key 请求标头发送给 PC;如果两种身份验证方式均已设置,上游会优先使用此项 |
X-Nutanix-Pc-Insecure | PC_INSECURE | 否 | "true"/"false"——跳过 TLS 验证(默认值为 false) |
**有效性规则:**必须提供 pcHost,并且必须提供 apiKey 或 username+password。其他任何情况都会返回包含 JSON-RPC 错误正文的 HTTP 401。
此外,每个子进程都会被强制设置为 READ_ONLY_MODE=true(见上文)。
API 规格文件(在构建时预先打包)
上游根据 YAML API 规格文件构建工具接口,而不是从实时 PC 获取。nutanix-mcp init 会下载这些文件——如果没有 PC 凭据,它会以 latest_release 模式调用公开的 developers.nutanix.com 命名空间 API(无需访问 PC;已通过实测验证:20 个命名空间)。Docker 构建会运行一次 init,并将文件打包到镜像的 /opt/nutanix-mcp/artifacts 中,供所有租户子进程以只读方式共享。由此带来的影响:
- 即使没有可访问的 PC,
tools/list和发现工具也能正常工作——只有{namespace}_execute调用会访问 Prism Central。 - 文件版本是构建镜像时最新的公开发行版,而不是租户 PC 的确切版本(上游的
pc_compatible模式需要在启动子进程时访问实时 PC)。对于只读的 v1 接口,这是合理的取舍:共享文件,加快租户启动速度。
配置
复制 .env.example。将该文件中的 CONDUIT_S2S_SECRET 留空,只在运行环境中设置真实值。
| 环境变量 | 默认值 | 说明 |
|---|---|---|
CONDUIT_S2S_SECRET | 空(拒绝启动) | 服务间密钥。如果此值为空或为已知占位值(changeme、secret、replace-me、your-s2s-secret、replace-with-a-real-secret 及其他示例值),HTTP 服务端会记录错误并以非零状态退出。使用 openssl rand -hex 32 生成密钥。未设置此值时,Compose 不会启动。此值绝不会写入日志。 |
MCP_ALLOW_INSECURE_DEV | 未设置 | 仅用于本地开发时,将其精确设置为 1,即可在没有 CONDUIT_S2S_SECRET 的情况下启动 HTTP。进程会记录警告、跳过 X-Gateway-S2S,并且仅绑定到 127.0.0.1。如果 MCP_HTTP_HOST 不是回环地址,则拒绝启动。已知占位密钥仍会导致拒绝启动。 |
MCP_HTTP_HOST | 设置真实密钥时为 0.0.0.0 | 绑定地址。配置了密钥时会采用此值,包括未设置时的情况(历史默认行为是容器绑定到 0.0.0.0)。镜像和 Compose 会在容器内将其设为 0.0.0.0。未设置密钥时,MCP_ALLOW_INSECURE_DEV=1 仅绑定到 127.0.0.1。 |
PORT | 8080 | 公共监听端口(备用值为 MCP_HTTP_PORT)。 |
NUTANIX_MCP_DIR | /opt/nutanix-mcp | 上游代码检出目录(venv 和文件)。 |
NUTANIX_MCP_BIN | $NUTANIX_MCP_DIR/.venv/bin/nutanix-mcp | 桥接服务启动的上游控制台脚本。 |
ARTIFACTS_DIR | $NUTANIX_MCP_DIR/artifacts | 预先打包的 YAML API 规格文件。 |
CHILD_LOG_DIR | /tmp/nutanix-mcp-logs | 可写目录,用于存放上游各进程的日志文件。 |
IDLE_EVICT_MS | 3600000 | 租户空闲超时时间(60 分钟)。 |
SPAWN_TIMEOUT_MS | 60000 | 等待子进程响应 MCP 握手的最长时间。 |
/health 和 /healthz 不需要身份验证,也不会读取凭据。
HTTP 身份验证
设置 CONDUIT_S2S_SECRET 后,每个 /mcp 请求都必须包含 X-Gateway-S2S。验证逻辑位于 src/s2s-verify.ts 的 verifyS2sHeader 中:标头值为 t=<unix seconds>,v1=<hex>,其中 hex 是以 CONDUIT_S2S_SECRET 为密钥、对字面字符串 t=<unix seconds> 计算得到的 HMAC-SHA256 值(64 个小写十六进制字符)。时间戳必须在服务器时钟的 300 秒范围内。缺少或无效的标头会导致 HTTP 401,且此时尚未读取 Prism Central 凭据。
使用服务器进程所用的同一个 CONDUIT_S2S_SECRET 进行签名。本地开发会在 shell 中导出该值;对此请求应复用该值,而不是另行生成。
TS=$(date +%s)
SIG=$(printf 't=%s' "$TS" | openssl dgst -sha256 -hmac "$CONDUIT_S2S_SECRET" -hex | awk '{print $NF}')
curl -sS http://127.0.0.1:8080/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H "X-Gateway-S2S: t=${TS},v1=${SIG}" \
-H 'X-Nutanix-Pc-Host: pc.example.com' \
-H 'X-Nutanix-Pc-Api-Key: fake' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-03-26","capabilities":{},"clientInfo":{"name":"dev","version":"0"}}}'
此桥接服务采用网关模式。/mcp 还要求提供 X-Nutanix-Pc-Host,以及 X-Nutanix-Pc-Api-Key 或 X-Nutanix-Pc-Username 和 X-Nutanix-Pc-Password 两者。这些标头是该请求唯一的凭据来源。进程环境中的 PC_* 值不会用作备用凭据。
本地开发
# 1. Get the upstream at the pinned tag with a venv + artifacts
git clone --branch v0.8 --depth 1 https://github.com/nutanix/ntnx-api-mcp-server ../ntnx-api-mcp-server
cd ../ntnx-api-mcp-server
uv venv .venv && uv pip install .
ARTIFACTS_DIR=$PWD/artifacts .venv/bin/nutanix-mcp init # no PC creds needed
cd -
# 2. Build and run the bridge against it
npm ci && npm run build && npm test
# HTTP refuses to start until CONDUIT_S2S_SECRET is a real value.
# Export it so this shell keeps the same secret for the server, the
# signing request above, and the Docker commands below.
export CONDUIT_S2S_SECRET="$(openssl rand -hex 32)"
NUTANIX_MCP_DIR=../ntnx-api-mcp-server node dist/index.js
# Alternative: local HTTP only, without a service-to-service secret (always
# binds 127.0.0.1). A non-loopback MCP_HTTP_HOST makes this exit. The empty
# assignment applies only to this process; the exported secret stays in the shell.
MCP_ALLOW_INSECURE_DEV=1 CONDUIT_S2S_SECRET= \
NUTANIX_MCP_DIR=../ntnx-api-mcp-server node dist/index.js
# 3. Smoke it (health is unauthenticated; /mcp needs X-Gateway-S2S — see above)
curl -s localhost:8080/health
或者构建镜像(镜像会打包所有内容,包括 stdio 冒烟测试;如果 serve-stdio 无法响应 tools/list,构建就会失败)。镜像会在容器内监听 0.0.0.0,并且在没有有效的 CONDUIT_S2S_SECRET 时仍会拒绝启动。将端口发布到回环地址。Prism Central 凭据会随每个请求通过 X-Nutanix-Pc-* 标头传入。
docker build --platform linux/amd64 -t ghcr.io/wyre-ai/nutanix-mcp:dev .
# Pass the exported secret. An empty value makes the container exit.
docker run --rm \
-e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
-p 127.0.0.1:8080:8080 \
ghcr.io/wyre-ai/nutanix-mcp:dev
未设置 CONDUIT_S2S_SECRET 时,Compose 会拒绝启动。网关服务会发布 127.0.0.1:8080:8080,且不会注入 PC_HOST、PC_USERNAME、PC_PASSWORD、PC_API_KEY 或 env_file。请使用已导出的密钥,以确保后续的签名请求与容器匹配:
docker compose up
升级上游固定版本
上游固定为经过审查的 Dockerfile 中的标签 v0.8(NUTANIX_MCP_REF)——绝不使用 main(NSA MCP 指南/车队安全基线)。升级步骤:
- 审查当前固定版本与新标签之间的上游差异(工具范围、凭据处理、
READ_ONLY_MODE语义)。 - 修改
Dockerfile中的NUTANIX_MCP_REF和本 README 中的标签。 - 在本地运行
docker build——构建时的冒烟测试会验证 venv 入口点可运行,且 stdio 工具范围仍能正常响应(如果命名空间发生变化,请更新预期的工具数量)。 - 以
feat:/fix:PR 的形式合并,以便 semantic-release 发布版本。
许可证
Apache-2.0。捆绑的 ntnx-api-mcp-server 由 Nutanix 以 Apache-2.0 许可发布。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。