mcp-unifi
mcp-unifi
MCP-сервер для управления UniFi-шлюзом, размещенным на собственном хостинге. Включает пятнадцать инструментов для работы с устройствами, сетями/VLAN, WiFi SSID (полный CRUD), правилами брандмауэра (полный CRUD), профилями портов коммутатора, подключенными клиентами, а также инструмент create_iot_network для создания изолированной IoT-подсети (VLAN, SSID и правило брандмауэра) одним вызовом с автоматическим откатом при частичном сбое.
Построен на базе FastMCP с использованием потокового HTTP-транспорта. Взаимодействует с UCG-Fiber, UDM Pro или любым другим шлюзом UniFi OS через локальный API-ключ. Учетная запись Site Manager / облачный аккаунт не требуются.
Каждый инструмент возвращает JSON. Ошибки возвращаются в виде структурированного объекта {"error": "...", "stub_mode": bool}, поэтому цикл MCP никогда не завершается аварийно из-за сбоев шлюза.
Зачем это нужно
Большинство задач по автоматизации UniFi сегодня требуют кликов в интерфейсе контроллера, написания хрупких одноразовых скриптов или использования тяжеловесных сторонних SDK. mcp-unifi предоставляет любому MCP-совместимому клиенту (Claude Code, Claude Desktop, пользовательские агенты) компактную, сфокусированную и типизированную поверхность для операций, которые вы действительно выполняете каждую неделю: создание IoT VLAN, добавление правила брандмауэра, аудит SSID, просмотр принятых устройств.
Составной инструмент create_iot_network превращает 15-шаговый процесс в интерфейсе в один вызов инструмента.
Быстрый старт
Загрузите опубликованный образ и запустите его:
docker run --rm \
-p 3714:3714 \
-e STUB_MODE=true \
ghcr.io/pete-builds/mcp-unifi:0.2.0Сервер по умолчанию запускается в режиме заглушки (stub mode), который возвращает реалистичные фиктивные данные и не требует оборудования UniFi. Зарегистрируйте его в Claude Code:
claude mcp add unifi --transport http --scope user --url http://localhost:3714/mcpЗатем попросите Claude Code «перечислить мои устройства UniFi», и вы увидите два фиктивных устройства.
Чтобы подключиться к реальному шлюзу, передайте учетные данные и отключите режим заглушки:
docker run --rm \
-p 3714:3714 \
-e STUB_MODE=false \
-e UNIFI_HOST=192.168.1.1 \
-e UNIFI_API_KEY=<your-local-api-key> \
ghcr.io/pete-builds/mcp-unifi:0.2.0Сгенерируйте API-ключ в разделе Settings → Control Plane → Integrations на шлюзе.
Справочник инструментов
Инструмент | Сигнатура | Что делает |
|
| Список принятых шлюзов, точек доступа и коммутаторов с состоянием, временем работы и информацией по радиоканалам. |
|
| Список всех настроенных сетей/VLAN (подсеть, диапазон DHCP, ID VLAN). |
|
| Создание новой сети с тегом VLAN. |
|
| Изменение полей существующей VLAN. |
|
| Удаление VLAN. |
|
| Список всех WiFi SSID. |
|
| Создание нового SSID, привязанного к конкретной VLAN. |
|
| Изменение полей существующего SSID (имя, пароль, hide_ssid и т.д.). |
|
| Удаление WiFi SSID. |
|
| Список всех правил брандмауэра. |
|
| Создание правила брандмауэра. |
|
| Удаление правила брандмауэра. |
|
| Список профилей портов коммутатора (режим PoE, нативная VLAN, пересылка). |
|
| Список подключенных беспроводных и проводных клиентов (MAC, имя хоста, IP, сигнал/качество, порт AP или коммутатора, время работы). |
|
| «В один клик»: VLAN + SSID + правило изоляции, с откатом при сбое. |
Каждый инструмент возвращает JSON-строку. Ошибки возвращаются в виде структурированного объекта {"error": "...", "stub_mode": bool}, чтобы Claude мог отобразить сбой, не прерывая цикл MCP.
Режим заглушки (Stub) против реального режима
Режим | Когда использовать | Поведение |
Stub ( | Разработка, демонстрации, настройка потоков Claude до получения оборудования | Машина состояний в памяти, инициализированная одним шлюзом, одной точкой доступа, одной сетью, одним SSID, одним правилом брандмауэра, двумя профилями портов. Создание/изменение/удаление сохраняются в течение жизни контейнера. Сбрасывается при перезапуске. |
Real ( | Продакшн с UCG-Fiber/UDM/другим шлюзом UniFi OS | Взаимодействие по HTTPS со шлюзом с использованием вашего локального API-ключа. Требуются |
Переключение режимов — это изменение конфигурации, а не кода. Те же одиннадцать инструментов, те же форматы ответов.
Конфигурация
Вся конфигурация считывается из переменных окружения (и файла .env, если он присутствует). Конфигурация проверяется библиотекой Pydantic при запуске; при наличии неверных значений процесс завершается с понятным сообщением.
Переменная | Тип | По умолчанию | Обязательно | Примечания |
| bool |
| нет | Если |
| string |
| только в реальном режиме | IP или имя хоста шлюза (без схемы). |
| int |
| нет | HTTPS-порт шлюза. |
| string |
| нет | Идентификатор сайта контроллера. |
| string |
| только в реальном режиме | Локальный API-ключ из Settings → Control Plane → Integrations. |
| bool |
| нет | Установите |
| string |
| нет | Должен содержать литеральный плейсхолдер |
| int (2-254) |
| нет | Смещение первого DHCP-адреса в IoT /24. |
| int (2-254) |
| нет | Смещение последнего DHCP-адреса в IoT /24. |
| string |
| нет | Адрес привязки. |
| int |
| нет | Порт прослушивания. |
| enum |
| нет | Один из |
| enum |
| нет |
|
Полный пример находится в .env.example.
Настройка MCP-клиента
Claude Code
claude mcp add unifi --transport http --scope user --url http://<host>:3714/mcpClaude Desktop
Добавьте следующее в ваш claude_desktop_config.json:
{
"mcpServers": {
"unifi": {
"transport": "streamable-http",
"url": "http://<host>:3714/mcp"
}
}
}Общая конфигурация
Потоковый HTTP по адресу http://<host>:3714/mcp. Может подключиться любой MCP-клиент, поддерживающий потоковый HTTP-транспорт (спецификация 2025-03-26+).
Архитектура
+---------------------+ Streamable HTTP +---------------------+
| MCP Client | --------------------------> | mcp-unifi |
| (Claude Code, etc) | <-------------------------- | (FastMCP server) |
+---------------------+ +----------+----------+
|
| HTTPS + X-API-Key
v
+----------+----------+
| UniFi OS Gateway |
| /proxy/network/... |
+---------------------+Сервер представляет собой легкий асинхронный прокси: он переводит вызовы инструментов MCP в REST-запросы к контроллеру UniFi, формирует ответы и возвращает JSON. Он не хранит состояние, не обращается к облачным сервисам и не аутентифицирует входящие MCP-соединения (запускайте его в доверенной локальной сети).
Заметки по безопасности
UNIFI_API_KEYхранится только в переменных окружения контейнера. Он никогда не логируется, не возвращается в ответах MCP и не записывается на диск этим сервером.Пароли WLAN очищаются (
[REDACTED]) при выходе из ответа любого инструмента, даже в режиме заглушки.Контейнер работает под UID 1000, без оболочки (shell), без домашней директории, с файловой системой root в режиме только для чтения (
/tmp— этоtmpfs) иno-new-privileges.Базовый образ закреплен по дайджесту. Python-зависимости устанавливаются с помощью
pip --require-hashesиз заблокированного хешами файлаrequirements.lock.Опубликованный образ является мультиархитектурным (amd64/arm64) с аттестацией происхождения сборки и SBOM через
docker/build-push-action.Сам MCP-сервер не аутентифицируется. Размещайте его за границей доверенной локальной сети, обратным прокси с аутентификацией или ACL Tailscale.
Отчеты об уязвимостях см. в SECURITY.md.
Разработка
Требуются Python 3.13+ и Docker.
# Clone + install dev deps
git clone https://github.com/pete-builds/mcp-unifi.git
cd mcp-unifi
python -m venv .venv && source .venv/bin/activate
pip install --require-hashes -r requirements-dev.lock
pip install -e . --no-deps
# Run the test suite (101 tests, ~95% coverage)
pytest
# Lint and format
ruff check src tests
ruff format src tests
# Type check (mypy strict)
mypy src/mcp_unifi
# Run the server locally in stub mode
python -m mcp_unifi.server
# Or build the image yourself instead of pulling from GHCR
cp docker-compose.example.yml docker-compose.yml
docker compose up --buildТесты
======================= 101 passed in 1.5s =======================
Name Stmts Miss Branch BrPart Cover
-----------------------------------------------------------------
src/mcp_unifi/__init__.py 2 0 0 0 100%
src/mcp_unifi/clients/__init__ 3 0 0 0 100%
src/mcp_unifi/clients/stubs.py 70 1 6 0 99%
src/mcp_unifi/clients/unifi.py 82 0 12 0 100%
src/mcp_unifi/config.py 38 1 8 0 98%
src/mcp_unifi/healthcheck.py 18 1 0 0 94%
src/mcp_unifi/logging_setup.py 33 1 12 2 93%
src/mcp_unifi/models.py 6 0 0 0 100%
src/mcp_unifi/server.py 232 15 70 5 92%
-----------------------------------------------------------------
TOTAL 484 19 108 7 95%CI требует минимум 80% покрытия, линтинг ruff, форматирование ruff, строгий mypy и сканирование Trivy fs+image, которое завершается с ошибкой при обнаружении любой уязвимости уровня HIGH или CRITICAL.
Обновление зависимостей
Файлы requirements.lock и requirements-dev.lock закреплены по хешам. Отредактируйте requirements.in (или requirements-dev.in), затем перегенерируйте:
uv pip compile requirements.in --output-file requirements.lock --generate-hashes --python-version 3.13
uv pip compile requirements-dev.in --output-file requirements-dev.lock --generate-hashes --python-version 3.13Dependabot еженедельно открывает PR для обновлений уровня requirements.in и дайджеста базового образа Docker.
Благодарности
Пути эндпоинтов контроллера UniFi были сверены с проектом sirkirby/unifi-mcp. Этот репозиторий использовался как исследовательский материал для API; код не копировался. Данная реализация является независимой сборкой FastMCP + httpx, следующей проверенному шаблону Forge.
Лицензия
MIT.
Вклад в проект
Приветствуются issues и pull requests. Перед открытием PR:
Убедитесь, что
ruff check,ruff format --checkиmypy src/mcp_unifiпроходят успешно.Добавьте или обновите тесты, поддерживайте покрытие на уровне 80% или выше.
Запустите
pytestлокально и подтвердите прохождение тестов.Обновите
CHANGELOG.mdпод заголовком[Unreleased].
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/pete-builds/mcp-unifi'
If you have feedback or need assistance with the MCP directory API, please join our Discord server