Skip to main content
Glama

nautobot-mcp

CI Python License

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.

Конфигурация

Переменная

По умолчанию

Назначение

NAUTOBOT_URL

Базовый URL, например http://nautobot.example.com:8080

NAUTOBOT_TOKEN

API-токен

NAUTOBOT_ALLOW_WRITE

false

Главный переключатель для create/update/delete

NAUTOBOT_VERIFY_SSL

true

Проверка TLS

NAUTOBOT_TIMEOUT

30

Таймаут на запрос (секунды)

NAUTOBOT_CACHE_DIR

./var

Где хранятся исходники схем и индекс

NAUTOBOT_MAX_PAGE

1000

Потолок для пагинации fetch_all

Только для контейнера, читаются точкой входа, а не сервером:

Переменная

По умолчанию

Назначение

MCP_TRANSPORT

streamable-http

Транспорт, который обслуживает контейнер (stdio для контейнера, запускаемого клиентом)

MCP_HOST

0.0.0.0

Адрес привязки для HTTP-транспортов

MCP_PORT

8000

Порт привязки для HTTP-транспортов

NAUTOBOT_AUTO_INDEX

true

Строить отсутствующий индекс схемы при запуске вместо отказа от работы

Регистрация у клиента

{
  "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 не всегда надёжно отделяется от значения.

Инструменты

Инструмент

Назначение

nautobot_search_schema

Поиск моделей по имени, описанию или имени поля

nautobot_describe_model

Поля, обязательные поля, цели FK, фильтры, действия

nautobot_list_apps

Пространства имён приложений (ядро и плагины), версии, состояние индекса

nautobot_plan_create

Упорядоченные предпосылки для создания объекта

nautobot_resolve

Человеческое имя → UUID, ограничено ссылающейся моделью

nautobot_list / nautobot_get

Чтение любой модели, урезанной или спроецированной

nautobot_create / nautobot_update / nautobot_delete

Запись с ограничениями

nautobot_graphql

Произвольные GraphQL-запросы

nautobot_graphql_schema

Интроспекция, по одному типу за раз

nautobot_model_actions

Не-CRUD конечные точки (trace, napalm, notes, …)

nautobot_call

Любая REST-конечная точка — плагины, массовые операции, пользовательские действия

nautobot_refresh_schema

Повторная загрузка схем и пересборка индекса

Ссылки на модели прощают ошибки: 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, поэтому пересборка индекса делает их доступными для всех инструментов.

Тесты

pytest

82 теста запускаются на фикстурах, вырезанных из живой схемы, с 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 assembly
A
license - permissive license
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

  • A
    license
    A
    quality
    D
    maintenance
    Enables 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.
    9
    16
    Apache 2.0
  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables 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.
  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables 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.
    13
    MIT

View all related MCP servers

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…

View all MCP Connectors

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/shamalawy/nautobot-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server