API ВЕГА
English

rustunifimcp

Корпоративный MCP-сервер для UniFi Network — тщательно отобранные инструменты, ограниченный доступ и контроль изменений с аудитом

проект mechub — автономная автоматизация сетевой безопасности

Неофициальный проект сообщества. Это независимый проект сообщества, не связанный с Ubiquiti Inc. и не одобренный компанией. Названия продуктов и товарные знаки используются только для обозначения систем, с которыми взаимодействует программное обеспечение.


rustunifimcp — представитель UniFi Network в семействе MCP-серверов mechub. Он

делает для UniFi то же, что rustjunosmcp

делает для Junos, а rustpanosmcp

— для PAN-OS: предоставляет тщательно отобранный, ограниченный и аудируемый MCP-интерфейс к API управления одного вендора.

Сервер создан на базе mecmcp: в нём нет собственного кода для аутентификации, транспорта, аудита, политик, инвентаризации или контроля изменений. Всё это обеспечивает

mecmcp — общая основа на Rust.

В этом документе описаны модель ресурсов UniFi, доступные инструменты и рабочие процессы. Ничего лишнего.

UniFi — первый в семействе вендор, у которого вообще нет промежуточной конфигурации: нет области для подготовки изменений, фиксации или проверки на устройстве. В Junos и PAN-OS есть промежуточная конфигурация и фиксация; в Proxmox и Security Director — семантика серверных задач, к которой можно привязать согласование. UniFi применяет изменения через REST API сразу к рабочей конфигурации, и больше ничего не предлагает. Поэтому именно на UniFi проверяется, можно ли применять mecmcp-changeset не только к двум вендорам, для которых он был создан.

Статус

Сервер ежедневно используется в инфраструктуре сопровождающего проекта (альфа-версия). Зависимость от прежнего сервера устранена.

rustunifimcp v0.6.2 предоставляет полный набор возможностей — чтение данных, рабочие процессы, операционные действия и контроль изменений. Сервер работает в LXC 981 через TLS с контролем двух лиц.

Регистрация unifi-mcp-legacy удалена; запросы больше не направляются к серверу на Python.

LXC 980 не меняли — он по-прежнему работает. На нём установлены метки

notmechub;protected, и он никогда не принадлежал нам для внесения изменений: устранение зависимости не означало, что нужно что-либо делать с контейнером. Он остаётся резервным вариантом для отката: повторная регистрация вернёт прежний интерфейс. Останавливать или удалять его — отдельное решение владельца.

КонтейнерНазначениеКонечная точка
981 prod-unifimcpиспользуемый ежедневно лабораторный контейнер, контроль двух лиц, TLShttps://prod-unifimcp.example.org:30033/mcp
622 test-twoperson-unifiтестовый стенд, контроль двух лицhttp://test-twoperson-unifi.example.org:30033/mcp
623 test-labmode-unifiтестовый стенд, --lab-modehttp://test-labmode-unifi.example.org:30033/mcp

Сравнение с прежним интерфейсом описано в

docs/PARITY-AUDIT.md: из 33 прежних инструментов, использовавшихся в рассматриваемый период, 31 реализован и проверен на действующем контроллере. Ещё один реализован, но не проверен (execute_port_action, доступен как unifi_device_action action=port_action): он выполняет только перезапуск питания PoE, требует параметр --allow-direct-commit и не проверялся на действующем оборудовании, поскольку это нарушило бы работу занятого порта коммутатора. Один инструмент остался нереализованным (set_device_port_overrides): для него не удалось подтвердить маршрут записи в версии 10.5.67.

ДокументОписание
PLAN.mdЭтапы и два переключения на новую систему — краткий обзор
docs/HOW-TO-SETUP-LXC.mdСоздание Proxmox LXC для rustunifimcp с нуля
docs/HOW-TO-SETUP-DOCKER.mdЗапуск rustunifimcp в Docker с контролем двух лиц и в лабораторном режиме
docs/superpowers/specs/2026-08-26-rustunifimcp-cutover-design.mdПроектирование сборки и переключения: топология развёртывания, доверие к контроллеру, подробности этапов и риски
docs/superpowers/specs/2026-07-24-rustunifimcp-design.mdИсходный проект; по-прежнему является основным источником сведений о наборе инструментов, маркировке API и адаптации контроля изменений

Минимальная поддерживаемая версия контроллера

Минимальная поддерживаемая версия: UniFi Network Application 10.5.67 / UniFi OS Server 5.1.37

Для работы сервера требуется контроллер UniFi Network версии не ниже 10.5.67 (Network Application) или 5.1.37 (UniFi OS Server). В этих версиях учтены исправления уязвимостей 2026 года с оценкой CVSS 10 (SAB-062, SAB-064, SAB-066/067), необходимые проекту для безопасного доступа к API.

Минимальная версия проверена на тестовых стендах rustunifimcp и с помощью наборов тестовых данных. При работе с более старой версией контроллера некоторые конечные точки могут отсутствовать, а изменения API могут не обрабатываться.

Что заменяет этот сервер

В домашней лаборатории используется enuno/unifi-mcp-server (Python / FastMCP). Это функциональный клиент API, но у него есть две проблемы, которые призван решить этот проект.

Слишком много инструментов. Реестр автоматически добавляет все публичные асинхронные функции из src/tools/ с помощью рефлексии: 205 функций из 37 модулей превращаются примерно в 270 инструментов MCP. Это число никто не выбирал. Цель rustunifimcp — 22 инструмента: типизированные примитивы чтения на основе перечисления ресурсов, жизненный цикл контроля изменений, ограниченные операционные действия и четыре полноценных рабочих процесса. Каждый из этих 22 инструментов выполняет свою задачу от начала до конца: ни один не рекламируется как доступный, чтобы затем отказывать при каждом вызове или возвращать пустой результат.

Отсутствие защиты на уровне MCP. Сервер использует обычный HTTP без токена Bearer, областей доступа, журнала аудита и ограничения частоты запросов. Любой, кто может подключиться к порту, получает неограниченный доступ на запись к контроллеру. rustunifimcp использует полноценный уровень безопасности mecmcp.

Каталог инструментов

Примитивы чтения — это сокращённый интерфейс, доступный через unifi_list_resources и unifi_get_resource. Каждый kind перед передачей модели обрабатывается по списку разрешённых полей или правилам сканирования, описанным в rustunifimcp-core::redact; подробнее — в разделе «Ключевые особенности проекта» ниже.

ИнструментПримечания
unifi_list_resourceskind = station | device | network | wlan | port_profile | dhcp_reservation | firewall_policy | firewall_zone | firewall_group | firewall_rule | port_forward | static_route | traffic_route | radius_profile
unifi_get_resourcekind, id
unifi_query_statssubject = site | device | station | wlan | flow | event, а также временной интервал
unifi_searchПолнотекстовый поиск по станциям, устройствам и сайтам
unifi_list_sites

firewall_rule, port_forward и static_route (MEC-509) — это прежний набор правил брандмауэра без зон, правила перенаправления портов и статические маршруты. Пока они доступны только для чтения: для них нет маршрута записи через unifi_stage_change. Значение subject=event позволяет обращаться к журналу событий контроллера.

unifi_backup_action (MEC-516) поддерживает действия list и trigger: list возвращает резервные копии, сохранённые контроллером, — не более 100 записей с маркером truncated, как и другие инструменты, возвращающие списки. trigger запускает создание новой резервной копии.

Действия download и validate не предлагаются вовсе (MEC-505: они удалены из перечисления действий, а не показываются пользователю с последующим отказом). Для обоих действий потребовалось бы передавать файл .unf, а не JSON; сервер пока этого не поддерживает.

Действие restore навсегда запрещено: восстановление резервной копии перезаписывает всю конфигурацию, поэтому его следует выполнять через жизненный цикл набора изменений.

Запуск в Docker (stdio)

Вызов через stdio, удобный для каталога инструментов, заменяет HTTP-команду CMD образа на --transport stdio. Поместите controllers.json (пример структуры:

packaging/examples/controllers.example.json)

и файл с ключом API контроллера в каталог etc/. Для наборов изменений и ключа HMAC аудита контейнеру потребуется доступный для записи каталог state/. Владельцем обоих каталогов и файлов должен быть пользователь с UID/GID 65532:65532, права доступа к файлам должны быть 0600:

"api_key_file": "/etc/unifimcp/api.key"

etc/api.key -> the controller API key

sudo chown -R 65532:65532 etc state sudo chmod 0700 etc state sudo chmod 0600 etc/controllers.json etc/api.key

docker run --rm -i
-v "$PWD/etc:/etc/unifimcp:ro"
-v "$PWD/state:/var/lib/unifimcp"
ghcr.io/mechubsec/rustunifimcp:latest
--transport stdio">

mkdir -p etc state
# etc/controllers.json  -> "api_key_file": "/etc/unifimcp/api.key"
# etc/api.key           -> the controller API key
sudo chown -R 65532:65532 etc state
sudo chmod 0700 etc state
sudo chmod 0600 etc/controllers.json etc/api.key

docker run --rm -i \
  -v "$PWD/etc:/etc/unifimcp:ro" \
  -v "$PWD/state:/var/lib/unifimcp" \
  ghcr.io/mechubsec/rustunifimcp:latest \
  --transport stdio

stdio не передаёт сведения о вызывающей стороне, поэтому подтверждение наборов изменений и инструменты прямого применения изменений недоступны. Для контроля изменений с участием двух человек используйте настройку streamable-HTTP из раздела

docs/HOW-TO-SETUP-DOCKER.md.

Ключевые особенности архитектуры

Три интерфейса API, каждый с собственной маркировкой. Поддерживаемый Integration API от UniFi значительно уже, чем реальные возможности контроллера. Поэтому в сервере сохранены закрытые маршруты /api/s/ и /v2/api/, но в коде у каждой конечной точки указан соответствующий тег. Доступ к закрытым маршрутам разрешается только при явном включении флага allow_private_api для конкретного контроллера в controllers.json, а не на основе области действия токена. Конфигурация, использующая только поддерживаемые возможности, полностью работоспособна, и обновление контроллера не сможет незаметно её нарушить.

Контроль изменений реализован с учётом реальных ограничений. В UniFi нет конфигурации-кандидата и операции фиксации изменений. Поэтому жизненный цикл набора изменений реализован с помощью сохранения исходного состояния на стороне клиента, локальной проверки, последовательного применения и отката с максимально возможными усилиями — именно это и указано в описаниях инструментов. Подтверждение набора изменений в UniFi не обеспечивает семантику фиксации с последующим подтверждением, и сервер не создаёт такого впечатления.

Для вызова unifi_approve_change_set требуется подтверждение человека. Сервер передаёт в mecmcp значение actor_type из токена вызывающей стороны. mecmcp отклоняет все запросы на подтверждение от agent и вызовы без указания вызывающей стороны (stdio); подтвердить изменение может только вызывающая сторона с actor_type: human. Создайте токен подтверждающего с помощью команды rustunifimcp token add ... --actor-type human. Значение actor_type — это утверждение оператора, заданное при создании токена, а не подтверждённый сервером факт. Если передать LLM-агенту токен с меткой human, эта проверка перестанет выполнять свою функцию.

Несколько контроллеров. Сведения о контроллерах хранятся в реестре, а не в переменных среды. Благодаря этому один экземпляр сервера может работать с несколькими контроллерами, а область действия токена можно ограничить выбранным подмножеством.

В HTTP по умолчанию действуют ограничения. По умолчанию ограничиваются частота запросов с одного IP-адреса и по одному токену, количество одновременных сессий и размер тела запроса (LimitsConfig::default()). Для настройки каждого ограничения предусмотрен флаг CLI (см. rustunifimcp --help), поэтому оператору не нужно создавать отдельную версию проекта. Неаутентифицированные конечные точки /healthz (проверка работоспособности процесса) и /readyz (проверки зависимостей не настроены, поэтому состояние «готов» соответствует состоянию «работает») доступны всегда. Конечная точка /metrics по умолчанию отключена (--enable-metrics); при включении она доступна только для обращений с loopback-адресов.

Лицензия

Лицензия MIT.