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: Advanced Hasura GraphQL MCP Server
Установка
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 installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables 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.916Apache 2.0
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Hasura GraphQL endpoints to discover schema structures and execute queries or mutations. It provides specialized tools for table introspection, data previewing, and performing data aggregations through natural language.
- AlicenseNot gradedqualityAmaintenanceEnables AI agents to interact with any GraphQL API by introspecting the schema and exposing queries and mutations as MCP tools, with built-in pagination, semantic search, and framework adapters.13MIT
- AlicenseNot gradedqualityDmaintenanceEnables LLMs to interact with GraphQL APIs through schema introspection and query execution.1,5161MIT
Related MCP Connectors
Gateway between LLM agents and world data through eight tools and a bundled endpoint catalog.
SaaS intelligence for AI agents. 5 unified tools cover 1,000+ services with 91-96% token savings.
Provides cloud browser automation capabilities using Stagehand and Browserbase, enabling LLMs to i…
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/shamalawy/nautobot-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server