mcpField
U
UniFi Gateway

UniFi Gateway

本地服务
pete-builds.github.io云与基础设施263 天前更新

关于 UniFi Gateway

UniFi Gateway 是面向自托管 UniFi 环境的 MCP 服务,适合管理网络、Protect 和 Access 的运维人员。它以默认安全机制为核心,提供变更预览、审计记录和失败回滚,并可通过一个实例管理多个站点。

主要功能

  1. 01网络、Protect 与 Access 管理
  2. 02破坏性操作支持 dry-run
  3. 03复合操作失败时回滚
  4. 04JSONL 审计日志与重放 CLI
  5. 05多控制器与只读模式

适用场景

  1. 01预览网络配置变更再执行
  2. 02为部分失败的配置流程回滚
  3. 03审查并重放控制器操作记录

MCP 相关

该服务向 MCP 客户端开放 UniFi Network 工具,并可选启用 Protect 和 Access。支持 stdio 与 Streamable HTTP 传输。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"pete-builds-unifi": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"STUB_MODE",
"-e",
"UNIFI_HOST",
"-e",
"UNIFI_API_KEY",
"-e",
"UNIFI_SITE",
"-e",
"UNIFI_VERIFY_SSL",
"-e",
"MCP_UNIFI_CONTROLLERS_FILE",
"-e",
"MCP_UNIFI_MODULES_ENABLED",
"-e",
"UNIFI_ACCESS_HOST",
"-e",
"UNIFI_ACCESS_API_KEY",
"-e",
"UNIFI_ACCESS_PORT",
"-e",
"MCP_UNIFI_AUDIT_SINK",
"-e",
"MCP_UNIFI_AUDIT_PATH",
"ghcr.io/pete-builds/mcp-unifi:0.27.0"
],
"env": {
"STUB_MODE": "<STUB_MODE>",
"UNIFI_HOST": "<UNIFI_HOST>",
"UNIFI_API_KEY": "<UNIFI_API_KEY>",
"UNIFI_SITE": "<UNIFI_SITE>",
"UNIFI_VERIFY_SSL": "<UNIFI_VERIFY_SSL>",
"MCP_UNIFI_CONTROLLERS_FILE": "<MCP_UNIFI_CONTROLLERS_FILE>",
"MCP_UNIFI_MODULES_ENABLED": "<MCP_UNIFI_MODULES_ENABLED>",
"UNIFI_ACCESS_HOST": "<UNIFI_ACCESS_HOST>",
"UNIFI_ACCESS_API_KEY": "<UNIFI_ACCESS_API_KEY>",
"UNIFI_ACCESS_PORT": "<UNIFI_ACCESS_PORT>",
"MCP_UNIFI_AUDIT_SINK": "<MCP_UNIFI_AUDIT_SINK>",
"MCP_UNIFI_AUDIT_PATH": "<MCP_UNIFI_AUDIT_PATH>"
}
}
}
}
启动命令docker run -i --rm -e STUB_MODE -e UNIFI_HOST -e UNIFI_API_KEY -e UNIFI_SITE -e UNIFI_VERIFY_SSL -e MCP_UNIFI_CONTROLLERS_FILE -e MCP_UNIFI_MODULES_ENABLED -e UNIFI_ACCESS_HOST -e UNIFI_ACCESS_API_KEY -e UNIFI_ACCESS_PORT -e MCP_UNIFI_AUDIT_SINK -e MCP_UNIFI_AUDIT_PATH ghcr.io/pete-builds/mcp-unifi:0.27.0
需要配置的环境变量
STUB_MODEWhen true, the server returns realistic mock data and requires no UniFi hardware. Defaults to true so the image is functional out of the box.
UNIFI_HOSTIP address or hostname of the UniFi OS gateway (UCG-Fiber, UDM Pro, etc). Required when STUB_MODE=false and MCP_UNIFI_CONTROLLERS_FILE is unset.
UNIFI_API_KEY密钥Local API key generated under Settings -> Control Plane -> Integrations on the gateway. Required when STUB_MODE=false and MCP_UNIFI_CONTROLLERS_FILE is unset.
UNIFI_SITEUniFi controller site name. Defaults to 'default'.
UNIFI_VERIFY_SSLWhether to verify the gateway's TLS certificate. Defaults to false because most home gateways use a self-signed cert.
MCP_UNIFI_CONTROLLERS_FILEPath to a YAML file describing multiple named controllers for multi-site management. When set, the legacy UNIFI_HOST / UNIFI_API_KEY env vars are ignored. Each entry needs name, host, api_key, and optionally port, site, verify_ssl.
MCP_UNIFI_MODULES_ENABLEDComma-separated list of modules to load. Known values: 'network', 'protect', 'access'. Defaults to 'network'. Set to 'network,protect,access' to enable Protect and Access tools alongside Network. Access currently ships read-only; door unlocks and credential issuance require session-token auth and are deferred.
UNIFI_ACCESS_HOSTUniFi Access hub IP or hostname. Required when the access module is enabled and STUB_MODE=false. Often the same host as UNIFI_HOST.
UNIFI_ACCESS_API_KEY密钥UniFi Access API key. Separate from the Network API key; generated on the Access controller's developer settings. Required when the access module is enabled and STUB_MODE=false.
UNIFI_ACCESS_PORTHTTPS port for the Access hub. Defaults to 12445 (the direct Access app port).
MCP_UNIFI_AUDIT_SINKAudit log sink. One of 'file' (default), 'stdout', or 'syslog'. Every tool call is recorded to a JSONL stream with secrets scrubbed.
MCP_UNIFI_AUDIT_PATHPath for the audit log file when MCP_UNIFI_AUDIT_SINK=file. Defaults to audit.jsonl in the process CWD.

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

安装包
ocighcr.io/pete-builds/mcp-unifi:0.27.0

工具

还没有获取到工具列表

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

详细介绍

mcp-unifi

以安全为先的自托管 UniFi MCP 服务。支持试运行预览、JSONL 审计日志和复合回滚。涵盖 Network、Protect 和 Access。

CI Coverage cosign MCP License: MIT

这是一个围绕以下假设构建的 MCP 服务:由大模型驱动的基础设施调用需要防护措施。每个具有破坏性的工具都接受 dry_run=True,并返回预测的变更集,而不执行写入。复合工具(create_iot_network、create_guest_network、provision_homelab_service、provision_camera)会记录操作前的状态,并在部分失败时回滚已应用的步骤。每次调用——无论是试运行还是真正执行——都会写入 JSONL 审计日志,并清除其中的机密信息;随附的 mcp-unifi-replay CLI 可将日志重新应用到新的控制器。

除安全基础设施外,还提供用于设备、AP 无线电调优、VLAN、WLAN、防火墙、交换机端口、端口转发、DHCP 保留、AP 组、可观测性、威胁管理 / IDS-IPS、蜜罐和 Teleport VPN 的 Network 工具,以及可选启用的 Protect(摄像头、运动事件、智能检测、录制配置)和 Access(门、凭证、访客、门禁卡事件、集线器 / 读卡器)。每个工具都接受 controller 参数,因此一个服务实例即可管理多个 UniFi 站点。支持 stdio(Claude Desktop、uvx、.dxt)和 Streamable HTTP(Docker、Helm)。完整且始终保持最新的工具列表见自动生成的工具清单。适用于运行 UniFi Network 9.x 或更高版本的任何 UniFi OS 网关(UDM、UDM Pro、UDM SE、UCG-Fiber、UCG-Ultra、UDR、UDW、UniFi OS Server),并使用通过 Settings → Control Plane → Integrations 获取的本地 API 密钥进行身份验证。已在运行 UniFi OS 5.1.33、搭载 UniFi Network 10.6.101 的 UCG-Fiber 上验证(2026-09-13)。防火墙读取同时涵盖旧版规则集(list_firewall_rules)和基于区域的防火墙(list_firewall_policies、list_firewall_zones),且 audit_open_ports 会同时检查两者,因此已迁移到区域的站点不会被误报为没有防火墙。旧版防火墙写入操作(create_firewall_rule 及相关工具)通过 /rest/firewallrule 执行;区域策略写入操作(create_firewall_policy、update_firewall_policy、delete_firewall_policy)仅通过官方 Integration API 执行;在基于区域的站点上,配置复合工具会创建区域策略,而非旧版规则(ADR 0009)。网络和 WLAN 写入操作会在请求可完全映射到官方 Integration API 时通过该 API 执行,否则回退到私有 API;UNIFI_WRITE_API=private 会让所有写入操作都使用私有 API(ADR 0008)。无需 Site Manager 或云账户。

安装

支持四种方式。请选择与你运行 Claude 的方式相匹配的一种。

Docker

长期运行的容器,通过端口 3714 提供 Streamable HTTP。最适合家庭实验室和多客户端配置。

HTTP 传输在没有 bearer token 时不会启动,因此请提供一个:

export MCP_UNIFI_TOKEN=$(openssl rand -hex 32)
docker run --rm -p 3714:3714 \
  -e STUB_MODE=true \
  -e MCP_UNIFI_AUTH_TOKENS="$MCP_UNIFI_TOKEN" \
  ghcr.io/pete-builds/mcp-unifi:latest

客户端随后发送 Authorization: Bearer $MCP_UNIFI_TOKEN。仅在回环地址上进行临时本地测试时,可使用 -e MCP_UNIFI_AUTH_REQUIRED=false 完全跳过身份验证;切勿在其他设备可访问的网络接口上使用,因为每个连接的客户端都将获得与管理员等效的控制器访问权限。

Claude Desktop (.dxt) — 一键安装

从最新版本下载 mcp-unifi-<version>.dxt 并双击。通过 Claude Desktop 内置的界面进行配置。安装包内含 Python 运行时,无需单独安装。使用 stdio 传输。

Helm
helm repo add mcp-unifi https://pete-builds.github.io/mcp-unifi/
helm install unifi mcp-unifi/mcp-unifi \
  --set unifi.host=192.168.1.1 \
  --set unifi.apiKey=<your-local-api-key> \
  --set auth.tokens=$(openssl rand -hex 32)

该 chart 的 auth.required: true,而 auth.tokens: "",因此必须先设置 token(或使用 --set auth.required=false;这仅适用于可信的单租户集群),Pod 才会启动。

uvx / pipx

直接从 GitHub 仓库快速运行一次性任务。使用 stdio 传输。

uvx --from git+https://github.com/pete-builds/mcp-unifi mcp-unifi

在 URL 末尾追加 @v0.5.0-rc.2(或任何标签)即可固定到指定版本。

各安装方式的完整指南请参阅文档网站。

设计

  • 只读模式。 MCP_UNIFI_READONLY=true 会从结构上阻止服务进行任何更改:修改类工具会从 tools/list 中隐藏,并在 tools/call 时遭到拒绝,因此调用被隐藏工具时只会收到常规错误信封,而不会执行写入操作。工具的分类在注册时逐个声明(@audited("list_networks", mutates=False)),绝不根据工具名称推断——十二个修改类工具(包括 confirm_destructive_action)的名称都没有 create_/update_/delete_/set_ 前缀。如果工具未声明分类,注册就会失败,因此新工具无法默认变为可调用状态。这是在只读 UniFi API 密钥之上的纵深防御,而非其替代方案。
  • 安全机制。 每个具有破坏性的工具都接受 dry_run=True,并会返回预测的变更集,而不执行写入。组合工具(create_iot_network、create_guest_network、provision_homelab_service、provision_camera)会捕获变更前状态,并在部分失败时回滚已应用的步骤。每次工具调用都会写入 JSONL 审计日志,并清除其中的机密信息;随附的 mcp-unifi-replay CLI 可将日志重新应用到全新的控制器。
  • 单一镜像,多控制器。 一个容器即可同时运行 Network、Protect 和 Access。同一进程通过 controller 参数和 YAML 控制器文件(MCP_UNIFI_CONTROLLERS_FILE)并行管理多个 UniFi 站点。无需为每个控制器单独运行一个进程。
  • 优先使用 API 密钥进行身份验证。 使用 Settings → Control Plane → Integrations 中的本地 API 密钥,访问 /proxy/network/api 端点。不存储用户名和密码,无需云账户,也不依赖 Site Manager。
  • 多渠道分发。 提供 Docker、适用于 Claude Desktop 的 .dxt 一键安装包、Helm chart 和 uvx。已列入官方 MCP Registry。容器镜像使用 cosign(无密钥 OIDC)签名,每个版本都附带 CycloneDX SBOM。
  • Network + Protect + Access。 Network 默认启用;Protect 和 Access 通过 MCP_UNIFI_MODULES_ENABLED=network,protect,access 选择启用。Access 默认只读(门禁解锁和凭证签发需要会话令牌身份验证,因此暂不提供)。UniFi Drive 不在范围内。

快速开始

最快的冷启动方式:使用 Docker + Claude Code 并启用 stub 模式,无需硬件。

  1. 启动容器。默认启用身份验证,因此请先生成令牌:

    export MCP_UNIFI_TOKEN=$(openssl rand -hex 32)
    docker run -d --rm -p 3714:3714 \
      -e STUB_MODE=true \
      -e MCP_UNIFI_AUTH_TOKENS="$MCP_UNIFI_TOKEN" \
      --name mcp-unifi ghcr.io/pete-builds/mcp-unifi:latest
    
  2. 将其注册到 Claude Code,并传入令牌:

    claude mcp add --transport http --scope user unifi http://localhost:3714/mcp \
      --header "Authorization: Bearer $MCP_UNIFI_TOKEN"
    
  3. 验证连接:

    claude mcp list
    
  4. 在 Claude Code 会话中,提问:“列出我的 UniFi 设备”。你将收到两个 stub 设备。

  5. 准备好连接到实际网关时,关闭 stub 模式:

    docker run -d --rm -p 3714:3714 \
      -e STUB_MODE=false \
      -e UNIFI_HOST=192.168.1.1 \
      -e UNIFI_API_KEY=<your-local-api-key> \
      -e MCP_UNIFI_AUTH_TOKENS="$MCP_UNIFI_TOKEN" \
      --name mcp-unifi ghcr.io/pete-builds/mcp-unifi:latest
    

在网关的 Settings → Control Plane → Integrations → Create API Key 下生成 API 密钥。

配置

所有配置均从环境变量读取(存在 .env 时也会读取)。最常用的六个变量:

变量默认值说明
STUB_MODEtrue设为 false 时,必须配置真实模式下的控制器。
UNIFI_HOST(空)网关 IP 或主机名。真实模式下必填。
UNIFI_API_KEY(空)本地 API 密钥。真实模式下必填。
MCP_UNIFI_READONLYfalse设为 true 时,隐藏并拒绝会修改数据的工具。请参阅安全指南。
MCP_UNIFI_MODULES_ENABLEDnetwork设置为 network,protect,access 以启用全部三个模块。
MCP_UNIFI_CONTROLLERS_FILE(未设置)包含命名控制器的 YAML 文件,用于多站点配置。
MCP_UNIFI_OTEL_ENABLEDfalse可选的 OpenTelemetry 跟踪,每次工具调用对应一个 span。默认关闭,且 SDK 不是依赖项。请参阅运维。
UNIFI_API_KEY_FILE(未设置)从文件(Docker 或 Kubernetes 密钥挂载)读取 API 密钥,而不是从 UNIFI_API_KEY 读取。如果两者都设置,则优先使用此项,并默认启用 TLS 验证。
UNIFI_ACCESS_API_KEY_FILE(未设置)UNIFI_ACCESS_API_KEY 的文件形式。
UNIFI_OS_PASSWORD_FILE(未设置)UNIFI_OS_PASSWORD 的文件形式。
MCP_UNIFI_AUTH_TOKEN_FILE(未设置)包含一个 bearer 令牌(或完整的 MCP_UNIFI_AUTH_TOKENS 语法)的文件。会与 MCP_UNIFI_AUTH_TOKENS 定义的内容合并。
MCP_UNIFI_CLIENT_ID(未设置)MCP_UNIFI_AUTH_TOKEN_FILE 中裸令牌对应的客户端名称。
UNIFI_PINNED_CERT(未设置)mcp-unifi-pin-cert 提取的控制台自身证书(PEM)路径。设置后,服务仅接受此控制器提供的该证书。见下文。

完整的环境变量参考和多站点 YAML 架构请参阅配置文档。

基于文件的密钥

每个密钥都有对应的 _FILE 变量,可用于 Docker 和 Kubernetes 密钥挂载。本版本不会弃用环境变量形式,它仍可正常使用;文件形式为可选配置,并包含更严格的默认设置,因此使用 api_key_file 配置的控制器会验证网关的 TLS 证书,除非你设置 verify_ssl: false。在控制器 YAML 中:

- name: lan
  host: 192.168.1.1
  api_key: <inline key>            # verify_ssl stays false: self-signed console on a LAN
- name: datacenter
  host: unifi.example.com
  api_key_file: /run/secrets/unifi_api_key   # verify_ssl defaults to true here

密钥文件缺失、为空或不可读时,服务会在启动时失败,并提示控制器名称和字段,但绝不会泄露文件内容。每次启动时,对于仍使用环境变量形式或关闭了 TLS 验证的控制器,服务都会各记录一行日志。这项警告是分阶段推进计划(可选启用,然后警告,最后在某个主要版本中切换)的第一步,相关计划记录在 ADR 0007 中;目前不会拒绝任何配置。docker-compose.yml 展示了密钥挂载方式。

证书固定

UniFi 控制台提供的自签名证书,其名称列表中不包含你连接时使用的地址,因此普通的 TLS 验证永远无法通过,verify_ssl 默认关闭。固定证书无需 CA 即可弥补这一缺口:记录一次控制台的证书,此后服务只接受该证书,不接受其他任何证书。

mcp-unifi-pin-cert 192.168.1.1 --out /etc/mcp-unifi/pins/home.pem
# prints the SHA-256 fingerprint; compare it against the console before trusting it
ssh [email protected] 'openssl x509 -in /data/unifi-core/config/unifi-core.crt -noout -fingerprint -sha256'
# the same fingerprint read on the console itself, over a channel the pin does not depend on

然后在 YAML 中为控制器设置 pinned_cert: /etc/mcp-unifi/pins/home.pem,或在单控制器环境变量形式中设置 UNIFI_PINNED_CERT。固定证书的控制器会对每个连接都依据该证书进行验证,如果控制台提供了其他任何证书,则直接失败;没有回退机制。如果固件更新重新生成了控制台证书,请求会失败并给出提示信息,其中会列出重新固定的命令,你在核对新指纹后使用 --force 重新运行该命令。服务绝不会自行获取并信任证书:引导过程始终是这条显式命令。传入 --expect-fingerprint,使其拒绝与控制台上读取到的指纹不匹配的证书。在容器中,以只读方式挂载该固定证书(compose 文件中显示了挂载位置)。

它是如何构建的

工具集周边的工程脚手架(当前数量见工具清单),以防你想知道是什么在支撑它:

测试纪律。 约 880 个测试,涵盖单元测试、集成测试和基于属性的测试(Hypothesis)——当前数量见 pytest --collect-only。HTTP 使用 respx 进行 mock,因此测试不会打到真实的控制器。CI 中覆盖率以 80% 分支覆盖率为门槛;当前下限为 90%。

代码质量门禁。 Ruff(pycodestyle、pyflakes、isort、flake8-bugbear、pyupgrade、simplify、flake8-bandit 安全规则集、comprehensions)加上 mypy strict(禁止隐式 Any、标记不可达代码、标记未使用的 ignore)。Pre-commit 钩子运行 lint、format、types,并重新生成工具清单并做漂移检查,因此坏代码永远到不了 CI。

CI 流水线(5 个门禁任务)。 每个 PR 依次运行 lockfile 漂移检查 → lint + 类型检查 → 测试 + 覆盖率 → 多架构 Docker 构建 → Trivy 文件系统和镜像扫描(HIGH/CRITICAL 会导致构建失败)。每一项都作为下一项的门禁。

发布流水线。 推送 git tag vX.Y.Z 会触发多架构(linux/amd64 + linux/arm64)Docker 构建、通过 sigstore OIDC 进行 cosign 无密钥签名、SLSA 构建来源证明、通过 Syft 生成并附加到 GitHub release 的 CycloneDX SBOM、用于 Claude Desktop 一键安装的 .dxt 包、以 vX.Y.Z / X.Y / latest 标签推送到 GHCR,以及自动更新 main 分支上示例 docker-compose.yml。

依赖卫生。 通过 pip install --require-hashes 进行哈希固定。自定义 CI 步骤验证 requirements.in 中每个固定的依赖都与 requirements.lock 匹配,因此没人能在不更新另一个的情况下只升级一个。Dependabot 自动合并安全的补丁。基础镜像以 digest 固定,而非以 tag 固定。

容器加固。 以非 root UID 1000 运行,无 shell,无主目录。通过 Docker / Helm 强制只读根文件系统。/tmp 是 16MiB 的 tmpfs。设置了 no-new-privileges。丢弃所有 Linux capabilities。专用的 /health 端点避免 streamable-HTTP 传输在每次 Docker 健康检查时记录 406 噪音。

安全态势。 HTTP 传输上使用 Bearer token 认证,默认安全(没有 token 就拒绝启动)。审计日志记录每次调用中经过认证的 client_id,并对 api_key、passphrase、password、secret、token 子串匹配进行密钥擦除。API key 包装在 pydantic SecretStr 中。SECURITY.md 提供私密披露路径。

分发渠道。 GHCR(已签名的多架构)、Smithery(已注册)、MCP Registry(已列出)、Helm chart(Secret/Deployment/Service/Ingress/NetworkPolicy 模板)、.dxt 包、uvx / pipx。

文档纪律。 Astro Starlight 站点自动部署到 GitHub Pages。各工具的参考页面由 scripts/generate_tool_manifest.py 通过 FastMCP 内省生成,pre-commit 钩子会重新生成并做漂移检查,因此代码和文档不会出现分歧。CHANGELOG 遵循 Keep a Changelog 格式。

版本纪律。 pyproject.toml、git tag、CHANGELOG 条目、Docker 镜像标签、docker-compose 示例以及 Helm chart 的 appVersion 始终保持一致,因为发布工作流强制要求如此。永远不会出现文档和代码对这个版本是什么意见不一的情况。

开发

克隆、安装开发依赖,并接好 pre-commit 钩子:

git clone https://github.com/pete-builds/mcp-unifi.git
cd mcp-unifi
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]" pre-commit
pre-commit install

Pre-commit 钩子会运行 ruff(lint + format)、mypy strict 和工具 清单生成器。只要 src/mcp_unifi/modules/ 下的任何文件发生变化,清单钩子就会重新生成 docs/site/src/content/docs/tools/,如果磁盘上的 清单与已注册的工具集出现漂移,就会使提交失败。使用 pytest 运行测试。

手动重新生成清单:

python scripts/generate_tool_manifest.py        # write
python scripts/generate_tool_manifest.py --check  # CI-style drift check

文档

许可证

MIT。

评论

支持 Markdown

第一次接触 MCP?

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

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