mcpField
U
UniFi

UniFi

本地服务
github.com云与基础设施03 周前更新

关于 UniFi

UniFi 是面向 AI 助手和 WYRE Conduit 网关的 MCP 服务,用于读取 Ubiquiti UniFi Cloud Site Manager 数据。它涵盖站点、主机、设备、WAN 指标和 SD-WAN,不包含本地控制器 API 与代理端点。

主要功能

  1. 01列出站点、主机和设备
  2. 02查询主机详情
  3. 03读取 WAN 和 ISP 指标
  4. 04查看 SD-WAN 配置与状态
  5. 05支持 stdio 或 HTTP 传输

适用场景

  1. 01查看多个 UniFi 站点的设备
  2. 02检查站点 WAN 健康指标
  3. 03检查 SD-WAN 路由和部署状态
  4. 04向 AI 助手提供 UniFi 数据

MCP 相关

向 MCP 客户端提供 UniFi Cloud Site Manager API 的 9 个专用只读工具。使用 API 密钥,并支持 stdio 和 HTTP 传输。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"wyre-ai-unifi": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"UNIFI_API_KEY",
"-e",
"MCP_TRANSPORT",
"-e",
"AUTH_MODE",
"-e",
"LOG_LEVEL",
"ghcr.io/wyre-ai/unifi-mcp:v1.0.1"
],
"env": {
"UNIFI_API_KEY": "<UNIFI_API_KEY>",
"MCP_TRANSPORT": "<MCP_TRANSPORT>",
"AUTH_MODE": "<AUTH_MODE>",
"LOG_LEVEL": "<LOG_LEVEL>"
}
}
}
}
启动命令docker run -i --rm -e UNIFI_API_KEY -e MCP_TRANSPORT -e AUTH_MODE -e LOG_LEVEL ghcr.io/wyre-ai/unifi-mcp:v1.0.1
需要配置的环境变量
UNIFI_API_KEY密钥UniFi Cloud Site Manager API key (X-API-Key), generated at unifi.ui.com under Settings > API Keys. Documented by Ubiquiti as read-only account-wide.
MCP_TRANSPORTTransport mode for the server. Set to 'stdio' for local CLI use; the image defaults to 'http' for gateway hosting.
AUTH_MODE密钥Credential source: 'env' reads vars locally, 'gateway' expects header injection from the WYRE MCP Gateway.
LOG_LEVELLog verbosity: debug, info, warn, error

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
ocighcr.io/wyre-ai/unifi-mcp:v1.0.1

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

UniFi MCP 服务

适用于 Ubiquiti UniFi Cloud Site Manager API 的 MCP 服务,可供 AI 助手和 WYRE Conduit 网关使用,支持站点、主机、设备、WAN/ISP 健康指标以及 SD-WAN 配置/状态。

范围:仅限 Cloud Site Manager API(有意如此)

UniFi 提供两个不同的 API 接口:

  • 本地单控制器 API(Network Application API,developer.ui.com/network/...)——部署在每位客户自己的控制台/控制器上,需要为每个站点单独配置 API 密钥,且没有中央集成点;它深入涵盖站点级配置,包括客户端、网络/VLAN/DHCP、WLAN/SSID、防火墙规则、端口转发等。
  • Cloud Site Manager API(developer.ui.com/site-manager/...,基础 URL 为 https://api.ui.com)——只需一个 UI.com 账户密钥,即可汇总该账户下所有已接入站点的数据,但提供的读取接口范围窄得多:仅支持站点、主机、设备清单、WAN/ISP 指标以及 SD-WAN 配置/状态。

此连接器仅面向 Cloud Site Manager API,这是上游明确决定的范围——本地单控制器 API 暂不实现,也不会作为备用方案。

**对工具覆盖范围的影响:**Cloud Site Manager API 未提供许多「典型」网络管理连接器会有的功能——没有客户端列表/客户端详情端点(站点的 statistics 中仅包含客户端计数汇总),没有 VLAN/网络/DHCP 配置端点,没有 WLAN/SSID 端点,也没有作为一等操作提供的防火墙规则端点。这些功能都属于本地单控制器 API。此连接器实现了 Cloud Site Manager API 自身已发布 OpenAPI 规范中 10 个专用读取操作路径里的 9 个——详见下文的工具。第 10 个路径是连接器代理端点,在下文单独的小节中介绍——这是有意排除,并非遗漏。

身份验证

UniFi Site Manager 使用与 UI.com 账户绑定的单个静态 X-API-Key 请求头进行身份验证——没有 OAuth 流程、令牌交换,也没有按请求过期机制。请在 unifi.ui.com 的 Settings > API Keys 下生成密钥。

这里有两项不同的声明,置信度刻意有所区别——不要将它们混为一句「只读」声明:

  • **经结构验证(直接检查,结论确定):**此连接器自身的代码不会执行任何修改调用。client.ts 中的每个函数都会调用下文 9 个专用读取操作之一;src/ 中完全没有 POST/PUT/PATCH/DELETE 调用,且连接器代理路径(见下文)未以任何名称被引用。
  • **供应商文档所述,未经独立验证(有意保留限定):**Ubiquiti 自己的入门文档将 Site Manager API 密钥概括为只读(「目前为只读……不能用于修改 UniFi 基础架构」)。但对于连接器代理路径,UI.com 的服务端是否确实会强制执行这一限制——也就是说,UI.com 后端是否会拒绝通过 /v1/connector/consoles/{id}/*path 发送的写入动词,还是这仅仅是文档政策而非硬性技术限制——WYRE 尚未测试。此次评审没有人使用有效密钥发送写入动词来验证这一点,这么做是正确的:那将是针对真实客户基础架构的破坏性测试,未经同意不应进行。不要将此连接器或本 README 理解为已确认底层 API 密钥无法执行写入操作——我们只确认此连接器自身的代码从不尝试写入。

在网关模式下,密钥通过每个请求的 X-UniFi-Api-Key 请求头传入;在本地/stdio 模式下,则从 UNIFI_API_KEY 中读取一次。HTTP 模式还需要已签名的 X-Gateway-S2S 请求头——请参阅配置。

connector-proxy 端点(按设计排除)

实时规范(https://developer.ui.com/site-manager/v1.0.0/openapi.json——通过普通 curl/HTTP GET 直接获取;尽管 developer.ui.com 上的交互式文档页面是无法通过普通 fetch 渲染的 JS SPA,但这个特定的原始 JSON 端点可以正常返回)定义了第 10 个路径,超出了此连接器实现的 9 个路径:/v1/connector/consoles/{id}/*path,包含全部 5 种 HTTP 方法——GET/POST/PUT/PATCH/DELETE(operationIds 为 ConnectorGet/ConnectorPost/ConnectorPut/ConnectorPatch/ConnectorDelete)。这是一个通用反向代理:api.ui.com 会将请求原样转发到目标控制台的本地 API http://127.0.0.1/proxy/[path],从而访问控制台完整的本地 Network/Protect/InnerSpace 接口——也就是此连接器在 Scope 部分中不涵盖的同一套控制器本地 API,只不过是通过云端端点而非直接访问控制台。规范明确说明它会执行实际修改——其 DELETE 示例会删除热点凭证——并且可供标准(非组织)API 密钥使用,范围限于该密钥所有者控制的控制台;使用它不需要组织级密钥。(WYRE 尚未针对此路径发送实际写入请求——参见上文 Authentication 中的保留说明。)

此连接器有意完全排除 connector-proxy 端点,原因与不涵盖控制器本地 API 相同:实现它就意味着通过一个通配符直通工具重新暴露整个本地接口(客户端、VLAN、WLAN、防火墙规则和实际修改操作),违背了将此连接器限定为专用云端读取工具的初衷。此连接器中的任何工具都不会以任何名称调用它。

配置

复制 .env.example,并设置以下变量。

环境变量必填说明
UNIFI_API_KEYstdio 和 AUTH_MODE=env 时必填UniFi Cloud Site Manager API 密钥(X-API-Key)。
MCP_TRANSPORT否stdio(默认)或 http。
AUTH_MODE否gateway(Docker 镜像和 Compose)或 env。Gateway 模式要求每个 /mcp 请求都携带 X-UniFi-Api-Key,且绝不会回退使用 UNIFI_API_KEY。env 仅在 S2S 身份验证成功后使用该变量。未设置时使用 env(stdio 和单租户 HTTP)。
CONDUIT_S2S_SECRETHTTP 必填服务到服务密钥。当此变量为空或为已知占位值(changeme、secret、replace-me、your-s2s-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否设置了有效的 CONDUIT_S2S_SECRET 时使用的绑定地址。未设置时使用 0.0.0.0,与历史绑定地址相同。镜像和 Compose 会在容器内设置 0.0.0.0。未设置密钥时,无论此值为何,监听地址都是 127.0.0.1。
MCP_HTTP_PORT否HTTP 端口。默认值为 8080。
LOG_LEVEL否debug | info(默认)| warn | error。

/health 和 /healthz 无需身份验证,也不会读取凭据。stdio 传输方式不使用 CONDUIT_S2S_SECRET。

HTTP 身份验证

设置 MCP_TRANSPORT=http 和 CONDUIT_S2S_SECRET 后,每个 /mcp 请求都必须包含 X-Gateway-S2S。校验逻辑位于 src/s2s-verify.ts 中的 verifyS2sHeader:标头值为 t=<unix seconds>,v1=<hex>,其中十六进制值是以 CONDUIT_S2S_SECRET 为密钥,对字面字符串 t=<unix seconds> 计算的 HMAC-SHA256(64 个小写十六进制字符)。时间戳与服务器时钟的偏差必须在 300 秒以内。标头缺失或无效时会返回 HTTP 401,且此时尚未读取 UniFi API 密钥。

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-UniFi-Api-Key: $UNIFI_API_KEY" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

在 AUTH_MODE=gateway 模式下,/mcp 还要求提供 X-UniFi-Api-Key。此请求的凭据只能来自该标头。AUTH_MODE=env 模式仍要求提供签名的 X-Gateway-S2S 标头,然后使用环境变量中的 UNIFI_API_KEY。

工具

9 个只读工具,对应 Cloud Site Manager API 已发布规范中的每个专用读取操作(在线规范共有 10 个路径;第 10 个是通用的变更型连接器代理端点,按设计排除在外——请参阅上文“身份验证”)。

站点
  • unifi_list_sites - 列出此 API 密钥所属账户可见的所有站点,并提供元数据(名称、时区、网关 MAC)和汇总统计数据(设备/客户端数量、网络性能)。
主机
  • unifi_list_hosts - 列出与此 API 密钥所属账户关联的所有主机(控制台 / network-server 应用)。
  • unifi_get_host - 按 ID 获取单个主机的详细信息。
设备
  • unifi_list_devices - 列出此账户拥有或具有超级管理员权限的主机所管理的 UniFi 设备,并按主机分组。包含 PII(每台设备的 MAC 地址、IP 地址、用户自定义主机名/备注)——默认需管理员权限。
WAN / ISP 健康状况
  • unifi_get_isp_metrics - 获取所有关联站点的 WAN/ISP 健康状况和流量指标,粒度为 5 分钟或 1 小时。
  • unifi_query_isp_metrics - 获取相同的指标,但限定特定主机/站点组合和时间范围。这是对 UniFi API 的 POST 请求,但属于筛选读取,并非变更操作。
SD-WAN
  • unifi_list_sdwan_configs - 列出所有 SD-WAN 配置(仅 ID/名称/类型)。
  • unifi_get_sdwan_config - 获取单个 SD-WAN 配置的完整拓扑:中心/分支站点、关联网络和路由子网(CIDR)。包含网络拓扑数据——默认需管理员权限。
  • unifi_get_sdwan_config_status - 获取单个 SD-WAN 配置的部署状态,包括每个中心/分支的 WAN IP 和延迟。包含网络拓扑数据——默认需管理员权限。

unifi_list_sites、unifi_list_hosts、unifi_get_host、unifi_get_isp_metrics、unifi_query_isp_metrics 和 unifi_list_sdwan_configs 属于普通读取级别:站点/主机是导航目录,大多数其他工具都需要从中获取站点/主机 ID;WAN 指标则是汇总性能数据,不属于 PII 或拓扑数据。

敏感性

即使这 9 个工具全都只读,此连接器本身仍会暴露两类敏感数据:PII(unifi_list_devices 返回的每台设备的 MAC 地址、IP 地址和用户自定义主机名)以及网络拓扑(unifi_get_sdwan_config/unifi_get_sdwan_config_status 中的 SD-WAN 中心/分支路由和子网)。在 Conduit 接线配置中,这三个工具默认设为 isAdmin: true;其他工具均为普通读取级别。这与“身份验证”部分所述的连接器代理端点无关,也不包含该端点;此处根本没有实现该端点,因此它不属于此连接器的权限级别模型。

开发

npm install
npm run build
npm test
npm run lint   # tsc --noEmit

Docker

该镜像在容器内监听 0.0.0.0(MCP_HTTP_HOST),默认使用 AUTH_MODE=gateway。将端口发布到环回地址,并传入真实的 S2S 密钥。在网关模式下,UniFi API 密钥会随每个请求通过 X-UniFi-Api-Key 传入;不会从环境变量中读取。

docker build -t unifi-mcp .
docker run \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -p 127.0.0.1:8080:8080 \
  unifi-mcp

未设置 CONDUIT_S2S_SECRET 时,Compose 会拒绝启动。网关服务设置了 AUTH_MODE=gateway,不会注入 UNIFI_API_KEY,并发布 127.0.0.1:8080:8080:

CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" docker compose up

单租户 HTTP(AUTH_MODE=env)仍然需要 S2S 密钥,然后使用 UNIFI_API_KEY。它与上述网关 Compose 服务相互独立。

docker run \
  -e CONDUIT_S2S_SECRET="$CONDUIT_S2S_SECRET" \
  -e AUTH_MODE=env \
  -e UNIFI_API_KEY=your-value \
  -p 127.0.0.1:8080:8080 \
  unifi-mcp

不使用密钥的本地 HTTP 仅限开发环境。它绑定到 127.0.0.1 并记录警告。非环回地址的 MCP_HTTP_HOST(包括 0.0.0.0)会被覆盖:

MCP_TRANSPORT=http MCP_ALLOW_INSECURE_DEV=1 npm run start:http

许可证

Apache-2.0

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。