Files
netbox/README-NETBOX-MCP.md
T

94 lines
7.8 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` на хосте).
- Внутри 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, а тут 6.0.4.
## История изменений
### 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).
- [ ] (Опция) Включить plugin discovery (`ENABLE_PLUGIN_DISCOVERY=true`) и `PLUGIN_WRITE_RULES` для плагинов (netbox-dns и др.), после отладки core.
- ~~(Отклонено) HTTP-транспорт для внешних клиентов~~ — не планируется, интеграция только через Hermes (stdio).