nautobot-mcp
nautobot-mcp
MCP-сервер для Nautobot, созданный для инстансов, чей API слишком велик для перечисления: Nautobot 3.2 поставляет 1 673 операции REST по 477 путям, и каждое установленное приложение добавляет ещё. Этот сервер предоставляет 15 инструментов, управляемых схемой, вместо одного инструмента на конечную точку, поэтому весь API — ядро и плагины — доступен без переполнения контекста агента.
Что делает его рабочим
Шаг сборки, а не разбор во время выполнения. Документ OpenAPI Nautobot весит 18 МБ, а его GraphQL-интроспекция — ещё 10 МБ. Скрипт сборки объединяет их в индекс SQLite размером ~1,1 МБ с таблицей поиска FTS5. Сервер открывает его только для чтения и отвечает на запросы за микросекунды; запуск не зависит от размера API.
Внешние ключи, восстановленные из GraphQL. OpenAPI сам по себе не может описать связи Nautobot — каждое связанное поле сериализуется как идентичный непрозрачный объект:
// dcim.device: device_type, role, status and location are indistinguishable here
"device_type": { "id": {...}, "object_type": {"pattern": "^[a-z]+\\.[a-z]+$"}, "url": {...} }Система типов GraphQL прямо называет цели (device_type → DeviceTypeType), поэтому они объединяются по имени компонента OpenAPI для восстановления 441 типизированного FK-ребра. Именно этот граф делает возможным планирование зависимостей.
Сжатие фильтров. dcim.device предоставляет 250 параметров фильтрации, которые на самом деле представляют собой ~74 базовых поля, умноженных на семейство суффиксов поиска (__ic, __n, __isnull, __gte, …). Индекс хранит базовые поля плюс их наборы суффиксов и описывает словарь один раз.
Related MCP server: mcp-graphql
Установка
uv venv && uv pip install -e ".[dev]"
cp .env.example .env # then set NAUTOBOT_URL and NAUTOBOT_TOKEN
cp .mcp.json.example .mcp.json # optional: for stdio-based clients
python -m nautobot_mcp.schema.build --probeИли пропустите клонирование и запустите в контейнере — см. Docker.
Шаг сборки загружает схемы и записывает var/index.sqlite. Повторно запустите его после установки или обновления приложения Nautobot — или вызовите инструмент nautobot_refresh_schema.
Конфигурация
Переменная | По умолчанию | Назначение |
| — | Базовый URL, например |
| — | API-токен |
|
| Главный переключатель для create/update/delete |
|
| Проверка TLS |
|
| Таймаут на запрос (секунды) |
|
| Где хранятся исходники схем и индекс |
|
| Потолок для пагинации |
Только для контейнера, читаются точкой входа, а не сервером:
Переменная | По умолчанию | Назначение |
|
| Транспорт, который обслуживает контейнер ( |
|
| Адрес привязки для HTTP-транспортов |
|
| Порт привязки для HTTP-транспортов |
|
| Строить отсутствующий индекс схемы при запуске вместо отказа от работы |
Регистрация у клиента
{
"mcpServers": {
"nautobot": {
"command": "/path/to/nautobot-mcp/.venv/bin/python",
"args": ["-m", "nautobot_mcp"],
"env": {
"NAUTOBOT_URL": "http://nautobot.example.com:8080",
"NAUTOBOT_TOKEN": "...",
"NAUTOBOT_CACHE_DIR": "/path/to/nautobot-mcp/var"
}
}
}
}HTTP-транспорты также доступны: python -m nautobot_mcp --transport streamable-http --port 8000.
Docker
cp .env.example .env # then set NAUTOBOT_URL and NAUTOBOT_TOKEN
docker compose up -d # or: make docker-upПервый запуск строит индекс схемы для вашего инстанса и сохраняет его на томе index; последующие запуски используют его повторно. Сервер слушает 127.0.0.1:8000/mcp.
Индекс не встроен в образ и не может быть встроен: он создаётся из схем конкретного инстанса Nautobot, включая все установленные в нём приложения. Пересоберите его после установки или обновления приложения — make docker-index или инструмент nautobot_refresh_schema, который пишет в тот же том.
make docker-index # rebuild the index in place
make docker-logs # follow the server log
make docker-down # stop; VOLUMES=1 also drops the index
docker compose run --rm server index --offline # rebuild from cached sources onlyРегистрация контейнера у клиента
По HTTP укажите клиенту опубликованный порт:
{
"mcpServers": {
"nautobot": { "url": "http://127.0.0.1:8000/mcp" }
}
}Или позвольте клиенту запускать контейнер на каждую сессию через stdio, повторно используя тот же том индекса:
{
"mcpServers": {
"nautobot": {
"command": "docker",
"args": [
"run", "-i", "--rm",
"--env-file", "/path/to/nautobot-mcp/.env",
"-e", "MCP_TRANSPORT=stdio",
"-v", "nautobot-mcp_index:/data",
"nautobot-mcp:latest"
]
}
}
}Всё, что передано после имени образа, идёт напрямую в python -m nautobot_mcp, так что docker run ... nautobot-mcp:latest --transport sse --host 0.0.0.0 --port 8000 тоже работает.
Что предполагает compose-файл
Порт публикуется только на loopback. Раздел Безопасность применяется полностью: это неаутентифицированный прокси, держащий токен с вашими правами, поэтому доступ с другого хоста означает размещение аутентификации перед ним, а не расширение проброса порта.
Запись остаётся выключенной, если в вашем
.envнетNAUTOBOT_ALLOW_WRITE=true.Контейнер укреплён по умолчанию — не-root (uid 1000), read-only корневая файловая система, все capabilities сброшены,
no-new-privileges. Единственный путь для записи — том/data, где находятся индекс и его кэшированные источники.Здоровье — это TCP-соединение, а не MCP-запрос: запрос без сессии к
/mcpзаставляет менеджер сессий выделить транспорт, который никто не освобождает, поэтому проверка протокола каждые 30 секунд приводила бы к утечке сессии на каждую проверку..envчитается compose дословно. Держите комментарии на отдельной строке; завершающий# commentне всегда надёжно отделяется от значения.
Инструменты
Инструмент | Назначение |
| Поиск моделей по имени, описанию или имени поля |
| Поля, обязательные поля, цели FK, фильтры, действия |
| Пространства имён приложений (ядро и плагины), версии, состояние индекса |
| Упорядоченные предпосылки для создания объекта |
| Человеческое имя → UUID, ограничено ссылающейся моделью |
| Чтение любой модели, урезанной или спроецированной |
| Запись с ограничениями |
| Произвольные GraphQL-запросы |
| Интроспекция, по одному типу за раз |
| Не-CRUD конечные точки ( |
| Любая REST-конечная точка — плагины, массовые операции, пользовательские действия |
| Повторная загрузка схем и пересборка индекса |
Ссылки на модели прощают ошибки: dcim.device, device, devices, Device, /dcim/devices/ и DeviceType — всё разрешается, а опечатки получают подсказки (dvice → "Возможно, вы имели в виду: dcim.device?").
Планирование зависимостей
Создание Device на пустом инстансе означает создание четырёх других объектов сначала. nautobot_plan_create("dcim.device") обходит FK-граф, проверяет живой инстанс на предмет уже существующего и возвращает их по порядку:
dcim.manufacturer → dcim.devicetype → dcim.locationtype → dcim.location → extras.role → dcim.deviceОн также обрабатывает ограничение по content-type Nautobot. Role, Status и Tag могут быть назначены только моделям, перечисленным в их content_types. Глобальный подсчёт — неправильный вопрос: инстанс может содержать 20 ролей, в то время как ни одна не применима к Device:
{
"model": "extras.role",
"action": "create", // not "use_existing", despite 20 existing
"content_type_scoped": true,
"by_referrer": { "dcim.device": { "valid_count": 0 } },
"note": "No extras.role is assignable to dcim.device yet. Create one with
content_types including ['dcim.device'] ..."
}Какие модели ограничены таким образом, обнаруживается, а не зашивается: content_types означает "что может здесь находиться" для LocationType и "кто может ссылаться на меня" для Role. Планировщик пробует ограниченный запрос и считает 400 доказательством того, что ограничение не применяется — поэтому модели плагинов ведут себя корректно без дополнительного кода.
Запись
Запись выключена, пока не установлено NAUTOBOT_ALLOW_WRITE=true. Даже тогда мутации двухэтапные: первый вызов возвращает предпросмотр и confirm_token, и вызов повторяется с этим токеном для применения. Токены выводятся из полезной нагрузки, поэтому токен, выданный для одного тела, не может быть воспроизведён для другого. nautobot_update показывает построчный diff; nautobot_delete показывает объект и всё, что на него ссылается.
Безопасность
Этот сервер — неаутентифицированный привилегированный прокси к Nautobot. Он держит API-токен и не выполняет собственной аутентификации: любой клиент, который может до него добраться, действует с полными правами этого токена, никогда не владея самим токеном.
Значения по умолчанию намеренно безопасны — --host привязывается к 127.0.0.1, а NAUTOBOT_ALLOW_WRITE равен false. Рискованная конфигурация — это сочетание не-loopback привязки с включённой записью, что даёт неаутентифицированное создание/обновление/удаление вашего источника истины всему, что может маршрутизировать к порту.
Поток с confirm-токеном — это защита от случайности, а не контроль доступа — любой клиент может прочитать токен из ответа предпросмотра и немедленно подтвердить.
Если сервер должен быть доступен другим хостам, поместите аутентификацию перед ним (обратный прокси с mTLS, шлюз с OAuth или SSH-туннель) и дайте ему токен Nautobot, ограниченный только тем, что нужно агенту. См. SECURITY.md.
Отзывчивость
Один объединённый HTTP/2-клиент используется всеми инструментами; планировщик параллельно выполняет проверки существования.
Ответы урезаются до того, как попадают к агенту. Nautobot не поддерживает разреженные наборы полей (
?fields=отклоняется как неизвестный фильтр), поэтомуurl,natural_slug,notes_url, временные метки и пустые блоки пользовательских полей отбрасываются на стороне клиента, а вложенные связанные объекты сводятся к идентичности. Передайтеfields=[...]для проекции илиfull=trueдля отказа от урезания.
Расширение
Каждый набор инструментов — это модуль, экспортирующий register(server, ctx), перечисленный в tools/__init__.py::TOOLSETS. Регистрация обёрнута так, что каждый инструмент возвращает структурированную ошибку вместо исключения — неперехваченное исключение достигло бы агента как непрозрачное "Error executing tool X".
Конечные точки плагинов не требуют кода: они появляются в /api/swagger.json, поэтому пересборка индекса делает их доступными для всех инструментов.
Тесты
pytest82 теста запускаются на фикстурах, вырезанных из живой схемы, с HTTP, замоканным через respx. Они фиксируют ловушки, найденные при создании: коллизию slug, которая отображает virtualization.vminterface на InterfaceType из DCIM, ограничение content_types, которое молча даёт непригодные планы, и эвристику FK, которая разрешает DynamicGroupMembership.group в auth.Group Django вместо extras.DynamicGroup.
Конфигурация агента
AGENT.md содержит готовый к использованию системный промпт и описание реестра для агента, управляющего этим сервером, включая протокол записи и правило ограничения по content-type, которое чаще всего вызывает сбой создания.
Вклад
Приветствуются issues и pull request'ы. pytest должен проходить, а ruff check / ruff format --check должны быть чистыми; CI проверяет оба на Python 3.11-3.13. Набору не нужен инстанс Nautobot и сеть — он работает на фикстурах схем в tests/fixtures с HTTP, замоканным через respx.
Лицензия
Apache 2.0 — см. LICENSE.
Структура
src/nautobot_mcp/
schema/build.py fuses OpenAPI + GraphQL + content types into the index
schema/index.py read-only query layer (lookup, FTS search, graph)
client.py pooled async HTTP, slimming, error normalisation
depgraph.py creation planning and reference resolution
safety.py write gate, confirm tokens, diffs
tools/ one module per toolset, registered through a guard
server.py MCP server assemblyThis server cannot be deployed
Maintenance
Related MCP Connectors
MCP facade over the Nebelus Construction API. ~48 tools give full agent build parity: create/update/probe agents, edit graphs, attach knowledge and vector stores, wire connectors, set governance policies and locked guardrails, enable grounding-trace, and read deployment wiring. Purpose-built for regulated industries: data residency is enforced per region (EU / GCC-KSA), with PII controls and an audit trail. Agents are created as drafts — no deploy tool is exposed over MCP by design; publishing happens in the Nebelus console.
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
Build and run agents and automations across hundreds of apps using natural language.
- mcp-serverOAuthcom.make
Give your AI agents the tools to build, manage, and run automation workflows.
Related MCP Servers
- AlicenseAqualityFmaintenanceEnables comprehensive interaction with NetBox infrastructure management through both read and write operations. Supports full CRUD operations for devices, IP addresses, sites, racks, and other NetBox objects through natural language commands.917Apache 2.0
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to interact with GraphQL APIs through schema introspection and query execution.676 npm1MIT
- AlicenseAqualityDmaintenanceEnables AI agents to connect to any GraphQL endpoint, introspect schemas, and execute queries or mutations through auto-generated tools.2235 npmMIT
- AlicenseBqualityAmaintenanceGives AI assistants read (and optionally write) access to a NetBox instance, covering DCIM, IPAM, circuits, virtualization, tenancy, and more.10021 npm1MIT