Как построить MCP-сервер для сетевого оборудования: основа для управления сетями с помощью ИИ
Вторая часть серии из семи статей о том, как дать ИИ-ассистенту возможность безопасно работать с сетевым оборудованием через MCP-сервер. Разбираем архитектуру первой рабочей версии: от инвентаризации устройств до бэкапов конфигураций.
MCP-сервер для сетевого оборудования — это не инструмент для энтузиаста, а разделяемая инфраструктура для команды: он знает, какие устройства существуют, как к ним подключаться и что безопасно читать, а ИИ-ассистент просто вызывает готовые функции.
Зачем сетевому оборудованию свой «переводчик» для ИИ
Представьте, что у вас в команде появился очень умный стажёр. Он умеет формулировать вопросы, анализировать данные и предлагать решения — но он не знает, какие коммутаторы стоят на площадке, как к ним подключиться и какой синтаксис команд поддерживает каждая модель. MCP-сервер (Model Context Protocol) — это именно та прослойка, которая закрывает этот пробел: она берёт на себя знание об оборудовании, способ подключения и набор безопасных операций, а ИИ-модели остаётся только вызывать готовые инструменты с понятными параметрами.
Серия из семи статей, которую ведёт разработчик Uzi Golan, описывает подход к построению такой прослойки для оборудования RAD Data Communications — но принципы вполне универсальны и подходят для любого сетевого парка. В первой части обосновывалось, почему сетевым устройствам нужен MCP-сервер вообще. Во второй, которую мы здесь разбираем, строится первая рабочая версия: минимально полезный сервер, с которым можно уже что-то делать.
Минимально полезный сервер: что он умеет и чего не умеет
Автор задаёт правильную рамку с самого начала: прежде чем писать код, нужно определить, что именно первая версия делает, а что — нет.
Что умеет:
- вести инвентаризацию устройств (добавлять, удалять, обновлять, фильтровать);
- подключаться к оборудованию по SSH (и по telnet там, где SSH недоступен);
- выполнять отложенный список разрешённых команд чтения;
- проверять состояние устройства (идентификация, активные аварии);
- делать бэкапы конфигураций в локальный архив.
Что не умеет (пока):
- записывать конфигурации — для этого нужна модель безопасности с предварительным просмотром и согласованием;
- знать, что означают команды — словари аварий, руководства пользователя, MIB-файлы будут позже;
- работать по SNMP — только CLI;
- обслуживать несколько пользователей одновременно;
- выполнять сложные сценарии, объединяющие несколько слоёв.
Это правильный инженерный подход: не пытаться построить всё сразу, а сделать ядро, которое работает и из недостатков которого видно, что нужно добавлять дальше.
Инвентаризация: первый и главный инструмент
Первый инструмент MCP-сервера — не команда к оборудованию, а реестр устройств. ИИ-модель не может обратиться к оборудованию, пока не знает, что оно существует.
Каждое устройство при добавлении описывается шестью полями: имя (человекочитаемый идентификатор), IP-адрес, семейство оборудования, группа, имя пользователя и пароль. Если какое-то поле пропущено, агент запрашивает все недостающие разом, а не по одному.
Разделение инвентаризации и учётных данных
Это первое и принципиальное архитектурное решение: пароли никогда не хранятся в файле инвентаризации. Инвентарный файл (имя, адрес, семейство, группа) безопасно коммитить в Git и показывать коллегам. Учётные данные живут в отдельном файле .env, который исключён из версионирования и защищён на уровне файловой системы.
Для сетевого инженера это значит: можно спокойно делиться списком оборудования с новым коллегой, не опасаясь, что он получит доступ к паролям. Инвентарный файл — это справочник, а не ключ.
Обновление и удаление
При обновлении устройства меняется только названное поле — частичное обновление, а не перезапись всего объекта. Изменение семейства оборудования считается подозрительным (обычно это ошибка при регистрации) и запрашивается повторно. Удаление устройства требует явного подтверждения, и при этом не удаляет ни бэкапы конфигураций, ни историю операций — только запись из реестра.
Абстракция драйвера: почему это ключевой элемент
Технический центр сервера — абстракция драйвера. Ключевое наблюдение: транспорт (SSH, telnet) и диалект CLI (формат приглашения, навигация по контекстам, именование портов) меняются независимо друг от друга.
Большинство скриптов автоматизации сетевого оборудования сшивают эти два измерения вместе: один скрипт подключается по SSH к конкретному типу устройства и выполняет конкретные команды. Это работает для одного семейства. Когда добавляется второе, скрипт копируется и модифицируется. К третьему семейству возникают три копии, которые постепенно расходятся.
Абстракция драйвера решает эту проблему. Общий диалект живёт в базовом классе, а семейство-специфичные различия — в подклассах, которые переопределяют только то, что отличается.
Что именно различается между семействами
Различия реальны и обнаруживаются в процессе эксплуатации:
- Поведение SSH: для большинства моделей стандартное, но MiNID требует «терпеливого» профиля подключения.
- Именование портов: у SecFlow это
ethernet 3, у ETX-2 —ethernet 0/2, у Megaplex-4100 —ethernet 1/1/1. Одна и та же команда с неправильным именем порта молча вернёт не тот результат. - Модель применения изменений: у большинства — прямая запись, у Megaplex-4100 — модель «кандидат-база данных» с обязательным рецептом (отмена изменений → конфигурация → проверка → коммит → сохранение).
- Постраничный вывод: MiNID выводит
more...и ждёт ввода, остальные — нет.
Инструмент, не учитывающий этих различий, будет работать на одном семействе и молча давать сбой на другом. Абстракция драйвера делает различия явными и тестируемыми — а не спрятанными в разбросанных по коду условиях.
Транспортный слой: Netmiko и принцип «одна сессия на устройство»
Для работы с SSH используется библиотека Netmiko — зрелый инструмент для управления сетевыми сессиями. Она поддерживает десятки платформ: Cisco IOS, Junos, Arista EOS, Huawei VRP и, в частности, собственный тип для оборудования RAD.
Но Netmiko — это только транспорт. MCP-сервер определяет политику: какие команды разрешены, как ограничивается объём данных, что требует подтверждения, что логируется.
Важная деталь: SSH-сессии кэшируются. Подключение к устройству занимает 5–7 секунд, и многие сетевые платформы отказывают в создании новой сессии, пока старая не завершена. Поэтому для каждого устройства поддерживается одна персистентная сессия, которая проверяется на работоспособность после 60 секунд простоя и прозрачно пересоздаётся при необходимости.
Привязка к приглашению, а не к таймеру тишины
Каждое чтение завершается в момент, когда на экране снова появляется приглашение устройства (prompt), а не через фиксированный интервал ожидания. Это звучит как техническая деталь, но на практике критично: SecFlow-1p детерминированно делает паузу более трёх секунд в середине вывода info. Короткий таймер тишины молча обрежет результат — и этот случай уже приводил к тому, что целое поддерево router 1 пропало из вывода.
Детерминированное завершение по приглашению всегда надёжнее вероятностного ожидания по таймеру. В сетевых операциях «надёжнее» — единственный приемлемый вариант.
Инструменты чтения: как ИИ общается с оборудованием
Каждый инструмент следует одной схеме: пользователь формулирует запрос на естественном языке, ИИ-агент вызывает инструмент, инструмент выполняет операцию на устройстве (с подтверждением, если это контакт с оборудованием), и результат возвращается с указанием источника.
Среди основных инструментов первого релиза:
- Управление инвентаризацией — добавление, просмотр, обновление, удаление устройств.
- Проверка доступности — подтверждение, что SSH-сессия может быть установлена, без выполнения команд.
- Выполнение разрешённых команд чтения — только отложенный список допустимых префиксов, без произвольных строк. Навигация по контекстам выполняется автоматически.
- Получение справки CLI — отправка символа
?на устройство и захват справочного вывода, без выполнения каких-либо команд. Это основа для будущего каталога знаний. - Экспорт конфигурации — полный вывод
infoв локальный архив с диффами относительно предыдущих снимков. Бэкапы метятся временем и хешем, архив только добавляется — старые снимки никогда не перезаписываются. - Проверка состояния — идентификация устройства (серийный номер, прошивка, время работы), активные аварии с интерпретацией критичности, проверка связности. Результат — структурированные поля, а не сырой CLI-вывод.
Ограничение данных: не сырой дамп, а нужный объём
Самый важный принцип дизайна инструментов чтения — возвращать нужное количество данных в нужном формате, а не всё, что прислало устройство.
Команда show может вернуть 20 строк на одном семействе и 2000 — на другом. Экспорт конфигурации может занять 15 000 строк. Выбросить это в контекст модели — значит потратить токены, перегрузить рассуждение и получить худший ответ.
Автор описывает три направления фильтрации:
- По области — вернуть меньше, но именно то, что нужно. Список разрешённых команд — это и есть фильтрация по области.
- По форме — вернуть структурированные данные, а не сырой текст. Модель работает со структурными полями быстрее и точнее, чем с текстовым дампом.
- По детализации — вернуть нужный уровень подробности. «Покажи активные аварии» и «покажи полный словарь аварий с описаниями и рекомендациями» — это разные инструменты, и нужные уровни детализации обнаруживаются, когда инженеры задают вопросы, на которые текущие инструменты отвечают плохо.
Для больших наборов данных применяется паттерн «сначала поиск, потом чтение»: первый запрос возвращает компактные результаты с выдержками, а детали запрашиваются отдельно по стабильному идентификатору. Это удерживает контекст модели маленьким и делает источники прослеживаемыми.
Чего сервер ещё не умеет — и почему это важно проговорить
Автор честно перечисляет ограничения, и это заслуживает уважения. Много проектов пытаются казаться более зрелыми, чем они есть.
Нет записи конфигураций. Сервер только читает. Изменение конфигурации требует предварительного просмотра, явного согласования, аудита — целая модель безопасности, которой в первой версии нет.
Нет каталога знаний. Сервер умеет отправлять команды и получать ответы, но не знает, что эти ответы означают. Словари аварий, руководства, MIB-файлы — это отдельная область.
Нет SNMP. Единственный путь к устройству — CLI. SNMP даёт второй канал (идентификация, счётчики интерфейсов, трапы аварий) без открытия SSH-сессии.
Нет мультипользовательского режима. Сервер работает локально через stdio. Для командного использования нужен HTTP-транспорт и контроль доступа.
Нет гарантии оптимальности. Наличие инструментов — это отправная точка. Со временем каждый инструмент потребует доработки фильтрации — это обнаруживается в процессе реальной эксплуатации.
Оценка подхода
То, что описывает Uzi Golan, — не революционная идея, а дисциплинированный инженерный подход к давно назревшей проблеме. Сетевая автоматизация существует уже много лет (Ansible, NAPALM, Netmiko, Nornir), но ИИ-модели добавляют новое измерение: естественный язык как интерфейс, контекстная память и способность к рассуждению. MCP-сервер становится мостом между этими возможностями и реальным оборудованием.
При этом важно не переоценивать зрелость решения. Серия открыто публикуется как рабочий процесс, а не как готовый продукт. Код на GitHub размечен как «только для лабораторного использования» — подключать его к производственному оборудованию автор не рекомендует, и с этим нельзя не согласиться. Промежуточные версии неизбежно будут содержать дыры, которые обнаружатся только при столкновении с реальными сценариями.
Тем не менее сама архитектура — разделение транспорта и диалекта, изоляция учётных данных, отложенные белые списки команд, привязка чтения к приглашению, а не к таймеру — это проверенные временем практики, правильно собранные воедино. Для сетевых инженеров, которые хотят дать своим ИИ-ассистентам структурированный доступ к оборудованию, этот подход стоит внимания. Главное — помнить, что MCP-сервер не заменяет экспертизу, а оборачивает её в формат, который понятен и модели, и аудиту.
Код проекта доступен на GitHub: rad-agent-toolkit.
Следующая часть серии будет посвящена модели безопасности: поэтапным коммитам, аудиту и тому, почему блокирующие механизмы должны жить в коде, а не в промптах.