Files
netbox/README-NETBOX-MCP.md
T
hermes 693370446c chore: upgrade all 14 plugins, fix config-diff key, pin netbox base image
- plugin_requirements.txt: pinned ==versions (10 plugins updated vs PyPI)
- Dockerfile-Plugins: FROM netbox:latest -> netbox:v4.6-5.0.2 (reproducible)
- configuration/plugins.py: fix netbox-config-diff -> netbox_config_diff key (required_settings USERNAME/PASSWORD)
- docker-compose.yml: VERSION default v4.6-5.0.1 -> v4.6-5.0.2
- README-NETBOX-MCP.md: fix NetBox version 6.0.4 -> 4.6.10, mark plugins TODO done
- NetBox 4.6.0 -> 4.6.10; all 14 plugins now load (config_diff, secrets, qrcode, floorplan revived)
NOTE: docker-compose.override.yml (housekeeping DB env fix) is gitignored - kept local
2026-09-03 14:33:28 +00:00

125 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# NetBox MCP Server (read-only)
Интеграция NetBox с Hermes Agent через Model Context Protocol (MCP).
## Сервер
- Репозиторий: [skuldgerry/netbox-mcp](https://github.com/skuldgerry/netbox-mcp) — enhanced-версия официального [netboxlabs/netbox-mcp-server](https://github.com/netboxlabs/netbox-mcp-server) с **write-операциями** (72 мутации).
- Установлен: `/opt/netbox-mcp-server` (git clone, ветка main, релиз v1.1.0)
- Python-пакет: `netbox-mcp-server` (запуск через `uv --directory /opt/netbox-mcp-server run netbox-mcp-server`)
- Транспорт: **stdio** (MCP-клиент Hermes сам запускает процесс)
## Конфигурация в Hermes
Файл: `/opt/hermes/.hermes/config.yaml`, секция `mcp_servers`:
```yaml
mcp_servers:
netbox:
command: "uv"
args: ["--directory", "/opt/netbox-mcp-server", "run", "netbox-mcp-server"]
env:
NETBOX_URL: "http://172.19.0.5:8080/" # docker-IP контейнера netbox
NETBOX_TOKEN: "<secret>"
VERIFY_SSL: "false"
LOG_LEVEL: "INFO"
timeout: 120
connect_timeout: 60
```
## Доступ к NetBox
- NetBox работает в docker (контейнер `netbox-netbox-1`, порт `8080` на хосте).
- Версия NetBox: **4.6.10** (Community, netbox-docker `v4.6-5.0.2`), образ `netbox-kupazh:latest` (кастомный, с плагинами), базовый `netboxcommunity/netbox:v4.6-5.0.2`.
- Внутри docker-сети `netbox_default` контейнер доступен по имени `netbox-netbox-1` (IP 172.19.0.5).
- С хоста прямой доступ к API по `127.0.0.1:8080` даёт 403 (ALLOWED_HOSTS/прокси), поэтому MCP-сервер ходит по docker-IP.
- Аутентификация: **v1 API токен** (`Authorization: Token <40-символов>`), т.к. v2-токены в этой кастомной модели имеют ограничение key ≤12 символов и HMAC-дигест — с ними были проблемы в CLI-тестах.
## Инструменты (read-only режим)
| Инструмент | Назначение |
|---|---|
| `netbox_get_objects` | Получить объекты по типу и фильтрам (dcim.device, ipam.ipaddress, ...) |
| `netbox_get_object_by_id` | Детали объекта по ID |
| `netbox_get_changelogs` | История изменений (audit trail) |
| `netbox_search_objects` | Глобальный поиск по типам |
Поддерживаются фильтры: `{'site_id': 1, 'name': 'router'}`, lookup-суффиксы `__ic`, `__in`, `__gte` и др. Параметр `fields` уменьшает объём ответа (токены).
## Учётка / права
- Пользователь: `mcp-ro` (служебный, без пароля, `is_superuser=False`)
- Токен: read-only (`write_enabled=False`), v1, 40 символов
- **ObjectPermission «MCP ReadOnly user»**: действия `['view']` на 117 content types (dcim, ipam, tenancy, virtualization, circuits, extras, wireless). Без ObjectPermission даже чтение даёт 403.
- Намеренно **только чтение**: запись (`write_enabled=True` + ObjectPermission с create/update/delete) включается ПОСЛЕ отладки read-режима (см. ниже).
## Проверка
```bash
# из хоста, stdio-пробе:
cd /opt/netbox-mcp-server && echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"probe","version":"1.0"}}}' | timeout 10 env NETBOX_URL=http://172.19.0.5:8080/ NETBOX_TOKEN=<token> VERIFY_SSL=false uv run netbox-mcp-server
```
Рабочий запрос (пример): `netbox_get_objects('dcim.site', {'limit': 2}, fields=['id','name','slug'])` → 2 сайта («Винный город», «Горизонт»).
## План: включение записи (после отладки)
- [ ] 1. Создать отдельный write-токен (`write_enabled=True`).
- [ ] 2. ObjectPermission с actions `['view','add','change','delete']` на нужные типы (или только нужные).
- [ ] 3. В конфиге Hermes сменить `NETBOX_TOKEN` на write-токен.
- [ ] 4. Проверить на тестовых объектах (site/tag), затем в проде.
> **HTTP-транспорт (внешние клиенты): рассмотрено и отклонено.** Идея запускать MCP-сервер как контейнер в сети netbox_default с `MCP_AUTH_TOKEN` и доступом по localhost для внешних клиентов предлагалась, но не планируется — интеграция только через Hermes (stdio).
## Замечания
- Плагины NetBox (netbox-dns и др.) не включены в discovery (`ENABLE_PLUGIN_DISCOVERY=false`) — при необходимости включить отдельно; их запись управляется `PLUGIN_WRITE_RULES`.
- Многие плагины (netbox_secrets, netbox_qrcode, netbox_floorplan) не загружались — требовали NetBox ≤4.5.99; **после обновления плагинов (2026-09-03) все 14 загружаются** (см. историю изменений).
## История изменений
### 2026-09-03 — Обновление плагинов
Обновлены все 14 установленных плагинов до актуальных версий на PyPI (совместимых с NetBox 4.6), NetBox обновлён с 4.6.0 до 4.6.10 (базовый образ `netboxcommunity/netbox:latest` → зафиксирован `v4.6-5.0.2`).
| Плагин | Было | Стало |
|---|---|---|
| netbox-plugin-prometheus-sd | 1.3.0 | 2.0.0 (устранены N+1 запросы) |
| netbox-lists | 4.0.4 | 4.0.4 (=) |
| netbox-inventory | 2.6.0 | 2.6.1 |
| netbox-interface-synchronization | 4.5.8 | 4.5.8 (=) |
| netbox-documents | 0.8.2 | 0.8.5 |
| netbox-contract | 2.4.5 | 2.4.7 |
| netbox-data-flows | 1.5.2 | 1.5.4 |
| netbox-config-diff | 2.14.2 | 2.15.2 |
| netbox-attachments | 11.2.1 | 11.3.1 |
| netbox-topology-views | 4.5.1 | 4.5.1 (=) |
| netbox-reorder-rack | 1.1.4 | 1.1.4 (=) |
| netbox-secrets | 3.0.2 | 3.1.1 |
| netbox-qrcode | 0.0.20 | 0.0.21 |
| netbox-floorplan-plugin | 0.9.1 | 0.9.2 |
Ключевые результаты:
1. **Исправлена скрытая поломка конфига config-diff**: ключ в `PLUGINS_CONFIG` был `"netbox-config-diff"` (с дефисом) вместо `"netbox_config_diff"` (с подчёркиванием). Новая версия 2.15.2 жёстко требует `USERNAME`/`PASSWORD` (required_settings) — из-за неправильного ключа сборка падала на collectstatic. Ключ исправлен, значения прописаны.
2. **Ожили 4 плагина**: netbox_config_diff, netbox_secrets, netbox_qrcode, netbox_floorplan раньше не загружались (требовали NetBox ≤4.5.99). Обновлённые версии поддерживают 4.6 — теперь **все 14 плагинов активны** (миграции накатаны).
3. **netbox-qrcode**: пропущен 1.0.0 (таргетит NetBox 4.7) — взят 0.0.21 (последний с поддержкой 4.6.x).
4. **Исправлен housekeeping**: в `docker-compose.override.yml` у сервиса не было `DB_HOST`/`DB_NAME`/`DB_USER`/`DB_PASSWORD` — контейнер падал с «connection refused» к postgres. Добавлены переменные (как у netbox). Теперь housekeeping успешно выполняется.
5. **plugin_requirements.txt** теперь с жёсткими пинами `==` (было без версий) — воспроизводимая сборка. Бэкап-тег образа: `netbox-kupazh:pre-upgrade-20260903`.
### 2026-09-03 — Развёртывание и отладка
Развёрнут MCP-сервер (read-only). Ключевые находки при отладке:
1. **v2-токены NetBox 6** — формат `nbt_<key>.<plaintext>` с HMAC-дигестом и pepper. В кастомной модели пользователей поля `username` и `Token.key` ограничены 12 символами, поэтому создание v2-токенов через shell приводило к `"Invalid v2 token"`. Рабочий вариант — **v1-токен** (`Authorization: Token <40 символов>`), создаётся через `Token.objects.create(user=..., version=1, write_enabled=False)` с явным `t.token = <40 символов>`.
2. **ObjectPermission обязателен** — в NetBox 6 доступ к API (даже чтение) контролируется моделью `users.ObjectPermission` (actions `['view']`), а не Django-группами. Без него API отвечает 403 `"You do not have permission to perform this action"`.
3. **Доступ по docker-IP** — с хоста API по `127.0.0.1:8080` даёт 403 (ALLOWED_HOSTS/прокси). MCP-сервер ходит в docker-сеть `netbox_default` по `http://172.19.0.5:8080/` (IP контейнера `netbox-netbox-1`).
4. **config.yaml Hermes** — `hermes config set` пишет значения как строки; для `args` (список) и `VERIFY_SSL` (строка) это ломало запуск: `uv: error: unrecognized subcommand '['` и pydantic ValidationError. Исправлено прямым редактированием YAML (бэкап + python).
5. **76 инструментов** (4 чтения + 72 записи) зарегистрированы, `hermes mcp test netbox` проходит. Write-инструменты в списке есть, но при вызове вернут 403 — запись намеренно отключена (см. план выше).
## TODO (ожидающие задачи)
- [ ] Включить write-режим: write-токен (`write_enabled=True`), ObjectPermission с actions `['view','add','change','delete']` на нужные типы, сменить `NETBOX_TOKEN` в конфиге Hermes, проверить на тестовых объектах (site/tag).
- [x] **Обновление плагинов**: сверить версии с PyPI, пересобрать образ, проверить загрузку. Выполнено 2026-09-03: все 14 плагинов обновлены до свежих версий (совместимых с NetBox 4.6), NetBox 4.6.0 → 4.6.10. Детали в истории изменений.
- [ ] (Опция) Включить plugin discovery (`ENABLE_PLUGIN_DISCOVERY=true`) и `PLUGIN_WRITE_RULES` для плагинов (netbox-dns и др.), после отладки core.
- ~~(Отклонено) HTTP-транспорт для внешних клиентов~~ — не планируется, интеграция только через Hermes (stdio).