netmiko-mcp
claude-project — netmiko MCP сервер + навык
Готовый к копированию проект, который предоставляет ИИ-агенту доступ только для чтения к маршрутизаторам, коммутаторам и межсетевым экранам через SSH с использованием протокола Model Context Protocol.
Он включает две части и связку между ними:
mcps/mcp_server_netmiko.py— самодостаточный MCP-сервер. Десять инструментов, каждая команда проверяется по заданному оператором списку разрешённых/запрещённых команд, вывод разбирается в JSON с помощьюntc-templates, а также ведётся журнал аудита всех попыток с блокировкой при отказе..claude/skills/netmiko/SKILL.md— навык, который обучает агента, когда использовать эти инструменты, как выглядят диалекты CLI для разных платформ и как читать отказ.
Ничто здесь не записывает данные на устройство. Список разрешений построен по принципу «запрещено всё, что не разрешено» — пустой список не разрешает ничего, а запрет всегда имеет приоритет над разрешением.
Всё, что происходит, попадает в журнал аудита, а netmiko.query_audit_trail позволяет получать ответы в диалоге: «всё, что делалось на SW-CORE-01, по датам», «последние 6 действий», «какие команды были отклонены на этой неделе». Поскольку в этом проекте нет пользовательского интерфейса, этот инструмент — единственный способ прочитать журнал.
Авторы и происхождение
Автор этого проекта — Эд Скрималья — edgardo.scrimaglia@gmail.com, Octupus. Сервер, навык, модель конфигурации и документация — его работа, написанная для агента Niko и упакованная здесь как самостоятельный проект.
Проект начался с форка, и это происхождение признаётся, а не скрывается: отправной точкой была работа Кирка Байерса, и проект значительно её превзошёл. Всё, что здесь сейчас — инвентаризация на основе источника истины, разрешение учётных данных, три варианта развёртывания, постраничный вывод, журнал аудита, навык и эта документация — не пришло из исходного проекта.
Два вышестоящих проекта Кирка Байерса:
Netmiko — многоплатформенная SSH-библиотека, которая непосредственно общается с устройствами.
netmiko_mcp — MCP-сервер, от которого был сделан форк. Одна его часть сохранилась в значительной степени в исходном виде: ядро безопасности (проверка команд, обработка glob-шаблонов, асимметрия разрешений/запретов) — оно было оставлено как точный порт намеренно, чтобы патчи из вышестоящего проекта можно было по-прежнему сравнивать. Это было инженерное решение, а не ограничение для остальной работы.
Related MCP server: MCP-Telecom
О Niko
Этот сервер был написан для Niko — ИИ-агента Neural Intelligence Knowledge Orchestrator, созданного Эдом Скримальей в Octupus. Niko использует набор MCP-серверов — сервер источника истины, этот, Jira, отправка писем, создание файлов и другие — чтобы оператор мог задать вопрос на естественном языке и получить ответ из реальной инфраструктуры: из источника истины — что должно быть правдой, с самих устройств — что есть на самом деле.
Внутри Niko тот же файл работает немного иначе, и это стоит знать, потому что объясняет некоторые моменты в коде:
Серверы работают по HTTP на loopback, по одному порту каждый, объявлены в
mcps/mcp_config.jsonс параметрамиurl/transport/local/env— та же двухосевая конфигурация, описанная ниже, в формате Niko.Установка происходит через приложение, а не копированием файлов: загрузка проверяется, зависимости разрешаются из самого кода, а неудачная установка откатывается, не оставляя половину сервера.
Каждая из этих интеграций — опциональный импорт с запасным вариантом, так что niko никогда не нужно устанавливать. Их четыре, и вот к чему сводится каждый при неудачном импорте:
Импорт | Строка | Запасной вариант для автономного режима |
| 60 |
|
| 68 |
|
| 436 |
|
| 2709 | заглушка, которая возвращает полезную нагрузку без изменений |
Ничего важного для работы вне Niko не теряется: конкурентный обработчик решает проблему «несколько процессов — один файл», которая здесь не возникает, а бюджет списка урезает длинные полезные нагрузки для агента, у которого есть собственный учёт контекста. Один файл, два дома, без форка.
Fedele — это источник истины Niko, поэтому переменные источника истины имеют префикс FEDELE_, даже если они указывают на экземпляр NetBox.
Лицензия
Собственный код этого проекта распространяется по лицензии MIT — см. LICENSE.
Это производная работа, поэтому применяются две лицензии, и оба файла поставляются вместе:
Лицензия | Файл | |
Код, документация и навык этого проекта | MIT | |
Части, перенесённые из | Apache-2.0 |
NOTICE содержит указание авторства и заявление об изменениях, требуемое Apache-2.0 §4(b). Netmiko — обычная зависимость MIT: импортируется, не вендорится, ничего не нужно распространять.
Структура
claude-project/
├── .mcp.json # declares the server (project scope)
├── .env.example # → copy to .env with the SSH credentials
├── .claude/skills/netmiko/
│ └── SKILL.md # one directory per skill, file named SKILL.md
├── mcps/
│ └── mcp_server_netmiko.py # NOT at the root: the server reads ../.env
├── config/netmiko/
│ ├── commands.yml # allow/deny list — without it, a 16-command fallback applies
│ └── inventory.yml # inventory in netmiko_tools format
├── logs/ # netmiko-mcp.log + netmiko-audit.jsonl
├── mcpr/netmiko/ # created on demand (0700): large outputs
├── LICENSE LICENSE-APACHE-2.0 NOTICE
└── pyproject.tomlДва не подлежащих обсуждению правила:
Навык находится в
.claude/skills/<имя>/SKILL.md. Claude Code не читаетskills/netmiko.md: ему нужен каталог и именно такое имя файла.Сервер находится в
mcps/, а не в корне.PARENT_DIR— это родительский каталог каталога, содержащего.py(mcp_server_netmiko.py:62), и именно оттуда берётся.env. Если сервер находится в корне,.envбудет искаться на один уровень выше проекта.
Запуск
uv venv --python 3.12
uv pip install -r <(uv pip compile pyproject.toml) # or: uv sync
cp .env.example .env && $EDITOR .env # SSH credentials
# .mcp.json needs no editing: its paths are project-relative
claude # approve the project serverВнутри сессии: /mcp выводит список 10 инструментов, /skills подтверждает, что навык загружен. Первая проверка, без обращения к сети:
какую политику команд применяет netmiko MCP?
Три варианта
Откуда берётся инвентаризация и откуда берутся учётные данные — это две независимые оси. Именно это даёт три варианта развёртывания на одном сервере — и причина, по которой сервер никогда не нужно модифицировать для перехода между ними: всё решают две переменные окружения.
Инвентаризация | Учётные данные | Что нужно | Когда использовать | |
A — Всё из источника истины | Fedele | Fedele | API-токен + ключ Fernet | Источник истины авторитетен и уже содержит учётные данные устройств |
B — Инвентаризация из источника истины, локальные учётные данные | Fedele или NetBox |
| API-токен | У вас есть источник истины, но нет его плагина учётных данных. Обычная отправная точка |
C — Автономный | локальный YAML |
| ничего внешнего | Лаборатория, изолированная сеть, демо или режим пониженной функциональности при недоступности источника истины |
netmiko.get_metadata сообщает, какой вариант фактически запущен — никогда не полагайтесь на конфигурационный файл:
{
"inventory": {"backend": "fedele", "scope_filter": {"tag": "lab"}, "available": true},
"credential_source": "env",
"device_types_in_inventory": ["cisco_ios", "huawei_vrp", "…"]
}A — Fedele как источник истины, включая учётные данные
Агент запрашивает устройство по имени; сервер разрешает адрес, платформу и учётные данные в источнике истины во время вызова. Никакая информация об инфраструктуре не хранится в этом проекте: добавьте устройство в источник истины, и оно станет доступно при следующем вызове без редактирования файлов и перезапуска.
// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "fedele",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "fedele",
"NETMIKO_MCP_FEDELE_GROUP_SOURCE": "tags", // tags | device_roles | sites
"NETMIKO_MCP_FEDELE_DEVICE_FILTER": "tag=lab", // the scope filter — read the warning
"NETMIKO_MCP_FEDELE_CACHE_TTL": "60"# .env
FEDELE_URL=https://fedele.example.com
FEDELE_TOKEN=<API token>
FEDELE_CREDENTIALS_KEY=<Fernet key of the fedele_credentials plugin>Файлы: ни один не является обязательным. commands.yml рекомендуется — без него применяется встроенная запасная политика. Локальная инвентаризация не используется, и NETMIKO_USERNAME / NETMIKO_PASSWORD не нужны; при credential_source=fedele NETMIKO_SECRET игнорируется — пароль enable также берётся из источника истины.
Как работает поиск учётных данных, три шага:
GET dcim/devices/?name=<name> → device.id
GET plugins/credentials/devicecredentials/?device=<id> → credential id
GET plugins/credentials/networkcredentials/<id>/ → username + encrypted password
decrypted locally with the Fernet keyЧто стоит знать, прежде чем выбирать этот вариант:
Ключ Fernet — это вся граница безопасности. Он расшифровывает пароли устройств в памяти сервера. Относитесь к нему как к самим паролям.
Без
FEDELE_CREDENTIALS_KEYсервер всё равно запускается, но каждый инструмент возвращает одну и ту жеStartup Errorс указанием отсутствующей переменной. Он сообщает об ошибке громко, а не молча.Установите фильтр области видимости. Без
NETMIKO_MCP_FEDELE_DEVICE_FILTERинвентаризация включает всю инфраструктуру, известную источнику истины, а значит, и все устройства, к которым может обратиться агент. Сервер записывает предупреждение, если фильтр отсутствует; фильтр принимает синтаксис запросов, напримерtag=lab&status=active.Устройство без
primary_ip, безplatformили с платформой, не являющейсяdevice_typeNetmiko, исключается из инвентаризации — источники истины также учитывают камеры, считыватели пропусков и шасси. Исключения подсчитываются и сообщаются, так что агент никогда не заявит «это все устройства» на основе подмножества.Есть автоматический выключатель: после транспортной ошибки или 5xx клиент прекращает обращаться к источнику истины на 30 с. Групповая команда для 40 устройств при недоступном источнике истины завершится ошибкой один раз, а не сорок.
B — Источник истины для инвентаризации, учётные данные в .env
Идентично варианту A с одной изменённой переменной:
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",# .env
FEDELE_URL=https://sot.example.com
FEDELE_TOKEN=<API token>
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>Вы получаете динамическую инвентаризацию — ту часть, которая окупает себя — без плагина учётных данных и без ключа Fernet. Для всех устройств используется одна учётная запись службы.
NetBox или любой источник истины в форме NetBox
Бэкенд инвентаризации использует диалект REST NetBox, поэтому сам NetBox работает в этом варианте без изменений:
Что вызывает бэкенд | Что он читает |
| список устройств, отфильтрованный по фильтру области видимости и разбитый на страницы |
| тот, который выбран |
| SSH-хост, маска удалена |
|
|
Укажите FEDELE_URL на экземпляр NetBox (/api добавляется, если вы его опустите) и FEDELE_TOKEN на API-токен NetBox — клиент аутентифицируется с заголовком Authorization: Token …, который ожидает NetBox. Переменные сохраняют префикс FEDELE_; это наследие именования, а не требование продукта.
Единственное требование, которое NetBox не удовлетворяет по умолчанию: platform.name должен быть в точности device_type Netmiko — cisco_ios, arista_eos, huawei_vrp, juniper_junos. Платформа с именем «Cisco IOS 15.2» не является device_type, поэтому все устройства с ней исключаются из инвентаризации. Либо переименуйте платформы в NetBox, либо примите исключения, о которых сообщается.
Учётные данные — это та часть, которую NetBox не покрывает: конечные точки plugins/credentials/… принадлежат плагину Fedele. С обычным NetBox вариант A недоступен — оставайтесь на B.
C — Автономный: вообще без источника истины
Всё находится в этом проекте. Никакой внешний сервис никогда не вызывается.
// .mcp.json → env
"NETMIKO_MCP_INVENTORY_TYPE": "yaml",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
"NETMIKO_MCP_INVENTORY_FILE": "/abs/path/claude-project/config/netmiko/inventory.yml"# .env
NETMIKO_USERNAME=<service account>
NETMIKO_PASSWORD=<password>
NETMIKO_SECRET=<enable password, if any device asks for it>Файлы: inventory.yml обязателен здесь — это единственное место, где существуют устройства. commands.yml остается рекомендованным, но не обязательным. Инвентарь использует формат netmiko_tools — плоское сопоставление имени с данными подключения, а также ключи групп:
CORE-RTR-01:
device_type: cisco_xr # must be a Netmiko device_type, verbatim
host: 192.0.2.11
CORE-SW-01:
device_type: arista_eos
host: 192.0.2.21
core: # a group is a list of device names
- CORE-RTR-01
- CORE-SW-01Файл, поставляемый с этим проектом, содержит пример данных: 12 вымышленных устройств на диапазонах документации RFC 5737, 7 групп и платформы, подобранные так, чтобы были представлены все диалекты CLI, упомянутые в списке разрешений. Замените его на свои собственные данные.
Это конфигурация, с которой поставляется этот проект, и это также режим пониженной функциональности: если система истины (SoT) выходит из строя, две переменные и перезапуск переводят развертывание flavor-A или flavor-B в этот режим. Стоит отрепетировать это до того, как понадобится.
Плата за это — файл устаревает. scripts/export_inventory.py в родительском репозитории регенерирует его из SoT; запускайте его по расписанию. Резервный инвентарь с адресами полугодовой давности хуже, чем полное отсутствие резервной копии, потому что вы узнаете об этом во время работы.
Что остается неизменным во всех трех вариантах
Политика команд, журнал аудита, разбивка вывода на страницы и поверхность инструментов не меняются между вариантами. Контракт, видимый агенту, идентичен, поэтому навыку не нужен вариант для каждого flavor.
commands.yml рекомендован, но не обязателен
Сервер работает и без него. Если файл отсутствует, он не блокирует все команды и не отказывается запускаться: встроенный запасной вариант из 16 команд только для чтения вступает в силу — show version, show ip interface brief, display version и их эквиваленты для Junos/VRP. Это сделано намеренно. Пустая политика блокировала бы каждую команду, в то время как сервер сообщал бы о своем исправном состоянии, что оператор воспринял бы как «устройство отказало», а не «никто не написал политику». Запасной вариант объявляется при запуске, netmiko.get_command_policy сообщает policy_source: "fallback", и каждая аудируемая попытка содержит источник.
Таким образом, файл — это политическое решение, а не шаг установки: запасной вариант позволяет запустить сервер с первой попытки, а commands.yml вы пишете, когда хотите использовать собственную политику вместо консервативной по умолчанию. Чего вы не можете сделать, так это иметь политику, которую вы не выбирали, и не знать об этом — сервер сообщает, какая из них действует, каждый раз, когда его спрашивают.
Файл .mcp.json
.mcp.json в корне проекта объявляет MCP-серверы для этого проекта. Claude Code запрашивает подтверждение при первом обнаружении файла, и файл предназначен для фиксации в репозитории: так вся команда получает один и тот же сервер.
Существуют две другие области видимости для того же определения сервера:
Область | Где находится | Кто видит |
|
| любой, кто открывает проект (после подтверждения) |
|
| каждый проект этого пользователя на этой машине |
|
| только этот пользователь, только в этом проекте |
claude mcp add --scope project netmiko -- /path/to/python /path/to/server.py записывает запись project за вас; редактирование JSON вручную эквивалентно.
Структура файла
{
"mcpServers": { // ← the top-level key. Not "servers", not "mcp".
"netmiko": { // ← the server name; it becomes the tool prefix
... // mcp__netmiko__<tool>
}
}
}Имя сервера не просто косметическое: Claude Code предоставляет каждый инструмент как mcp__<server-name>__<tool-name>. С именем netmiko и инструментом netmiko.get_metadata, который регистрирует сервер, инструмент, который видит Claude, на самом деле называется mcp__netmiko__netmiko.get_metadata. Запустите /mcp, чтобы прочитать точные имена перед тем, как вписать их в список allowed-tools или правило разрешений.
Справочник полей
Поле | Транспорт | Значение |
| оба |
|
| stdio | исполняемый файл для запуска. Абсолютный путь — не полагайтесь на cwd |
| stdio | список аргументов, каждый элемент отдельно |
| stdio | окружение для дочернего процесса. Объединяется поверх унаследованного |
| http/sse | полный URL конечной точки, включая путь |
| http/sse | дополнительные заголовки запроса, обычно |
Значения поддерживают подстановку переменных окружения: ${VAR} и ${VAR:-default}. Полезно для хранения токена вне зафиксированного файла:
"headers": { "Authorization": "Bearer ${NETMIKO_MCP_TOKEN}" }Транспорт 1 — stdio (используется в этом проекте)
Claude Code запускает сервер как дочерний процесс и общается с ним через JSON-RPC по его stdin/stdout. Ничто не слушает порт, ничто не доступно из сети, и время жизни процесса равно времени сессии. Это правильный выбор по умолчанию для сервера, хранящего SSH-учетные данные.
{
"mcpServers": {
"netmiko": {
"type": "stdio",
"command": "${CLAUDE_PROJECT_DIR:-.}/.venv/bin/python",
"args": ["${CLAUDE_PROJECT_DIR:-.}/mcps/mcp_server_netmiko.py"],
"env": {
"NETMIKO_MCP_INVENTORY_TYPE": "yaml",
"NETMIKO_MCP_INVENTORY_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/inventory.yml",
"NETMIKO_MCP_COMMAND_FILE": "${CLAUDE_PROJECT_DIR:-.}/config/netmiko/commands.yml",
"NETMIKO_MCP_CREDENTIAL_SOURCE": "env",
"NETMIKO_MCP_SAVE_OUTPUT_DIR": "${CLAUDE_PROJECT_DIR:-.}/mcpr/netmiko",
"NETMIKO_MCP_AUDIT_LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-audit.jsonl",
"LOG_FILE": "${CLAUDE_PROJECT_DIR:-.}/logs/netmiko-mcp.log",
"LOG_LEVEL": "INFO"
}
}
}
}Две вещи, которые могут укусить:
Никаких жестко заданных путей, и на рабочую директорию полагаться не стоит.
${CLAUDE_PROJECT_DIR:-.}— это то, что позволяет фиксировать файл как есть; следующий раздел рассказывает всю историю, потому что очевидное прочтение этого неверно.Сервер не должен писать в stdout. stdout является каналом протокола, и одна случайная строка там нарушает сессию. Логирование идет в stderr плюс в ротируемый файл по пути
LOG_FILE(5 МБ × 3, создается с правами0600— на уровнеDEBUGэтот файл содержит вывод устройств). Внутри Niko та же переменная обрабатываетсяMCPLogging.
Откуда берется ${CLAUDE_PROJECT_DIR:-.}
Две разные вещи в одной строке: синтаксис и переменная.
Синтаксис. ${VAR} и ${VAR:-default} — это подстановка параметров POSIX («используй VAR; если он не установлен или пуст, используй default»), но здесь не задействована оболочка — JSON-файл никогда через нее не проходит. Claude Code сам реализует подстановку при чтении файла, в полях command, args, env, url и headers. Это соглашение именно этого клиента, а не часть спецификации MCP: другой клиент может его не реализовывать (см. Не-Claude агенты, где пути тогда должны быть литеральными), а у VS Code есть свое написание, ${workspaceFolder}.
Переменная. CLAUDE_PROJECT_DIR устанавливается Claude Code в корень проекта, то же значение, которое получают хуки. Она стабильна — предоставление дополнительных рабочих директорий во время сессии с помощью --add-dir не меняет ее.
Контринтуитивная часть, и причина, по которой :-. не просто украшение: Claude Code устанавливает эту переменную в окружении запускаемого сервера, а не в своем собственном. Однако подстановка происходит до запуска, в окружении Claude Code — где переменная не существует. Голый ${CLAUDE_PROJECT_DIR} поэтому развернулся бы в ничто и оставил /config/netmiko/inventory.yml, абсолютный путь к корню файловой системы.
Таким образом, в .mcp.json с областью видимости project значение по умолчанию — это не запасной вариант для какого-то крайнего случая: это значение, которое используется всегда. До процесса доходит ./config/netmiko/inventory.yml. Единственное исключение — конфигурация MCP, поставляемая плагином — там Claude Code подставляет переменную напрямую, и значение по умолчанию не нужно.
Именно это и связывает серверу руки. Относительное значение разрешалось бы относительно cwd дочернего процесса, а cwd — это выбор клиента, а не проекта. Отсюда resolve_project_path(): каждый относительный путь в настройках привязывается к PARENT_DIR — родительской директории mcps/, тому же корню, откуда берется .env — при загрузке настроек. Сессия, запущенная откуда угодно, находит config/netmiko/, а validate_startup() называет абсолютный файл, когда он отсутствует. ~ по-прежнему означает домашнюю директорию оператора, а не файл внутри проекта.
Переменная все еще полезна так, как задумано в документации, при чтении изнутри сервера (os.environ["CLAUDE_PROJECT_DIR"]), где она установлена. Этому серверу она не нужна: PARENT_DIR выводится из __file__ и, следовательно, не зависит ни от какого клиента — по той же причине HTTP-транспорт, где никто не устанавливает эту переменную, не требует особого обращения.
Источник: Claude Code — MCP, разделы Add a local stdio server и Environment variable expansion in .mcp.json.
Транспорт 2 — HTTP (потоковый HTTP)
Claude Code его поддерживает, как и любой другой MCP-клиент. Это транспорт, который следует использовать, когда сервер работает где-то еще: на другом хосте, в контейнере, в сервисе, используемом несколькими агентами, или агентом, отличным от Claude.
Файл сервера всегда вызывает mcp.run(transport="stdio") под своей защитой __main__, поэтому HTTP обслуживается через CLI FastMCP — без изменения кода:
.venv/bin/fastmcp run mcps/mcp_server_netmiko.py \
--transport http --host 127.0.0.1 --port 8123
# endpoint: http://127.0.0.1:8123/mcp/Переменные NETMIKO_MCP_* больше не являются частью конфигурации клиента: серверный процесс запускается вами, поэтому они принадлежат его окружению (экспорт в оболочке, unit systemd, блок environment: контейнера).
Сторона клиента:
{
"mcpServers": {
"netmiko": {
"type": "http",
"url": "http://127.0.0.1:8123/mcp/",
"headers": {
"Authorization": "Bearer ${NETMIKO_MCP_TOKEN}"
}
}
}
}Или, что эквивалентно, claude mcp add --transport http netmiko http://127.0.0.1:8123/mcp/.
--transport sse и "type": "sse" также работают; SSE — это более старый удаленный транспорт, который сохраняется для клиентов, еще не перешедших на потоковый HTTP.
Безопасность. CLI FastMCP обслуживает это без какой-либо аутентификации: любой, кто имеет доступ к порту, может выполнять команды show на всех устройствах в инвентаре, используя учетные данные из окружения сервера. Привязывайтесь к
127.0.0.1для локального тестирования, а для чего-либо общего используйте обратный прокси-сервер, который завершает TLS и проверяет заголовокAuthorization. Блокheadersвыше — это то, что отправляет клиент; прокси-сервер — это то, что должно это проверять.
Не-Claude агенты
Объект mcpServers, показанный здесь, является фактическим стандартом: Claude Code, Claude Desktop, Cursor и Windsurf все читают одни и те же три поля для stdio (command / args / env) и те же два для удаленного доступа (url / headers). Копирование записи между ними обычно работает как есть.
Известные различия, которые стоит проверить перед копированием:
VS Code использует
mcp.jsonс ключом верхнего уровня"servers"вместо"mcpServers"и требует явного указания"type".Некоторые клиенты не реализуют подстановку
${VAR}; там значение должно быть литеральным, что является аргументом в пользу HTTP-транспорта с прокси, а не токена, вставленного в зафиксированный файл.Агент без какого-либо конфигурационного файла все равно может напрямую общаться с HTTP-конечной точкой — URL и заголовок
Authorizationсоставляют весь контракт.
Блок env
Записи NETMIKO_MCP_* имеют приоритет над любым YAML-конфигурационным файлом. Они установлены явно, потому что вне Niko нет NikoPaths, поэтому значения по умолчанию возвращаются к ~/commands.yml и ~/.netmiko_mcp_tmp.
Каждый путь здесь может быть указан относительно корня проекта: сервер привязывает относительные значения к PARENT_DIR при загрузке настроек, поэтому cwd запущенного процесса никогда не определяет, где находится инвентарь или журнал аудита. Абсолютный путь или ~ используются как есть.
Переменная | По умолчанию | Назначение |
|
|
|
| (поиск netmiko-tools) | путь к инвентаризации, если тип |
|
|
|
|
| что определяет группу: |
| (нет) | фильтр области, |
|
| время жизни кэша SoT, в секундах |
|
| список разрешённых/запрещённых команд |
|
| включает пайпы в командах |
| (нет) | OpenSSH |
|
| одновременные подключения в групповых командах |
|
| буфер для больших выводов |
|
| количество строк, после которого вывод сохраняется в файл вместо возврата в строке |
| (см. родительский README) | аудиторский журнал (JSON, fail-closed). Попросите агента прочитать его с помощью |
|
| путь к YAML-файлу конфигурации, содержащему эти же настройки |
|
| операционный лог: stderr всегда, плюс этот ротируемый файл (5 МБ × 3, |
Учётные данные не задаются здесь. NETMIKO_USERNAME, NETMIKO_PASSWORD,
NETMIKO_SECRET и переменные FEDELE_* читаются из
<project-root>/.env, чтобы они никогда не оказались в зафиксированном JSON-файле.
Приоритет: то, что находится в блоке env, переопределяет .env без предупреждения — определяйте каждую переменную ровно в одном месте.
Все остальные переменные описаны в README родительского репозитория.
Проверка работоспособности
claude mcp list # netmiko: ✓ connectedВнутри сессии /mcp выводит список инструментов, а /skills подтверждает, что навык загружен.
Спросите, какая политика действует, и netmiko.get_command_policy укажет имя файла, который он читает — или сообщит "fallback", что означает, что файл не найден и используются 16 встроенных команд.
Автор: Ed Scrimaglia edgardo.scrimaglia@gmail.com — последнее обновление: 2026-08-18.
Available Tools
10 toolsnetmiko.get_command_policyA
List the commands this server will accept, and where that policy comes from.
CALL THIS AFTER A REFUSAL, BEFORE RETRYING. A Security Error: Command ... is not permitted means the command is outside the operator's policy. Do not guess a
variant and do not abbreviate — read the policy here, pick a command that is
actually allowed, and if nothing fits, tell the user which command was refused
and what the allow list does cover.
Also useful when the user asks what they can run on this deployment.
ANSWERING "which commands are available for Juniper / Huawei / Cisco": the lists
are flat, because the operator writes one policy for the whole estate. Filter it
yourself by dialect — you know the CLIs, and device_types_in_inventory tells
you which platforms are actually present. show route* and show chassis* are
Junos, display * is Huawei VRP and HPE Comware, show ip route is Cisco-style,
and show version happens to work on several. Under the fallback,
allowed_commands_by_platform already carries that split, verbatim and exact —
use it as given instead of re-deriving it. Two rules when you answer:
Never list a command that is not in
allowed_commands. It will be refused.Say when the answer is empty: an allow list written for one vendor covers nothing on another, and that is the operator's doing, not a device fault.
policy_source says who wrote the policy in force:
"file" — the operator's allow/deny list, at
command_file."fallback" — no policy file exists on this deployment, so only a small built-in read-only set runs.
warningexplains it; relay that to the user, because every other refusal follows from it and looks like a device problem otherwise.
How the lists are read (getting this wrong wastes attempts, and every attempt is audited):
Deny wins over allow, always.
The allow list does NOT cover abbreviations:
show versiondoes not permitsh ver. Send full commands.The deny list DOES cover abbreviations of the same word count: a deny on
configurealso blocksconf.*is a glob and only ever appears at the end.cmd*swallows whatever follows;cmd *requires at least one more word and does not matchcmdon its own.Anything the allow list does not name is denied.
Returns:
str: JSON with policy_source, command_file, allowed_commands,
denied_commands, their counts, a rules object,
device_types_in_inventory, and — only under the fallback —
allowed_commands_by_platform and a warning.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It extensively discloses behavior: how the policy lists are read (deny wins, no abbreviations, glob rules), what the return JSON contains, and the meaning of `policy_source` values. This is complete and transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is long but well-structured with clear sections and bullet points. Every sentence adds value, though some content (e.g., repeated warnings about not listing commands not in the allow list) could be slightly more concise. It is front-loaded with the core purpose, making it effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (0 parameters, no output schema provided in structured form), the description is exceptionally complete. It explains the return structure, usage interpretation, edge cases (empty lists, fallback warning), and even includes guidance on how to handle the results. No gaps remain.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema coverage is trivially 100%. The description adds no parameter-level semantics because there are none. Per the guidelines, baseline is 4 for zero-parameter tools, and the description does not need to compensate further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'List the commands this server will accept, and where that policy comes from.' It uses a specific verb (list) and resource (commands policy), and distinguishes itself from sibling tools like netmiko.send_show_command by focusing on policy rather than executing commands.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit when-to-use guidance: 'CALL THIS AFTER A REFUSAL, BEFORE RETRYING.' It also explains what not to do (don't guess or abbreviate) and gives context for alternative scenarios ('when the user asks what they can run'). This is thorough and actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.get_metadataA
Return authoritative metadata about the Netmiko MCP server and its inventory.
MANDATORY — call this tool FIRST on EVERY user message that mentions, asks about, or relates to network devices, routers, switches, firewalls, show commands, device inventory or device groups, before any other netmiko tool and before answering from memory, system prompt, or RAG/FAQ.
It reports which inventory backend is active (Fedele or the local YAML file) and, for the local file, how old it is. That matters: operating from a stale local inventory can send a command to the wrong box.
This tool does NOT reach any network device. For "is the MCP alive" call netmiko.health_check. To actually query a device, use netmiko.send_show_command.
Returns:
str: JSON with version, author, description, inventory, capabilities,
command_policy and tool_routing. command_policy is "file" when the
operator's allow/deny list is in force and "fallback" when no policy file
exists — in that case a warning field says so, only a handful of
read-only commands will be accepted, and you must relay that warning to
the user instead of treating the denials as device failures.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It discloses that the tool does not reach any network device, explains the returned fields (version, author, inventory, command_policy, etc.), and details the meaning of the command_policy field including the warning behavior. This fully compensates for missing annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is longer than average but each sentence adds essential information. It is front-loaded with the core purpose and mandatory call order, then provides behavioral details and return format. While slightly verbose, the structure is logical and the length is justified by the complexity of guidance needed.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the absence of annotations, the presence of an output schema (context signals), and zero parameters, the description fully covers all necessary aspects. It explains when to call, what it returns, the significance of inventory freshness, the command_policy states, and how to handle warnings. There is no missing information for an agent to use this tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has zero parameters, so schema description coverage is 100% trivially. The description does not need to explain parameters. It adds value by detailing the output fields and their significance, which is a bonus. Baseline for zero parameters is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Return authoritative metadata about the Netmiko MCP server and its inventory.' This is a specific verb+resource combination. It distinguishes itself from sibling tools like netmiko.health_check (server aliveness) and netmiko.send_show_command (device queries) by explaining what it does not do.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly demands: 'MANDATORY — call this tool FIRST on EVERY user message that mentions, asks about, or relates to network devices...' It provides concrete context for when to use it (first call for device-related queries) and when not to (e.g., 'This tool does NOT reach any network device. For "is the MCP alive" call netmiko.health_check'). This is exemplary usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.health_checkA
Check whether the Netmiko MCP server itself is responsive and correctly configured.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
This checks the MCP server, NOT any network device and NOT the inventory backend reachability. "¿Está arriba el router X?" is not this tool — that requires actually running a command against the device with netmiko.send_show_command.
Returns:
str: JSON with available, version, inventory_backend,
credential_source and command_policy ("file" or "fallback").
When command_policy is "fallback" a warning field explains that
no policy file exists and only built-in read-only commands run;
report that warning to the user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Since no annotations are provided, the description carries full burden. It discloses that the tool checks the MCP server (not devices or inventory), and documents the return fields including special behavior when command_policy is 'fallback' (warning field, suggesting the agent report it). It does not mention authentication needs, rate limits, or side effects, but for a health-check tool with no destructive potential, these are less critical.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a brief header, an important usage note, a clear exclusion, and a detailed return format. It is not overly long, but the return section could be slightly more concise (e.g., listing the fields without the 'Returns:' prefix). Overall, it earns its sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters, no annotations, and an output schema (which partially covers the return format), the description provides complete context: what the tool checks, what it doesn't check, when to call an alternative first, and the exact return structure with special behavior. This is fully sufficient for an agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, and the schema provides full coverage (100%) of the empty parameter set. The description adds no parameter-level details because there are none, but the baseline of 4 is appropriate given the zero-parameter context and the rich return value description that compensates slightly.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool checks 'whether the Netmiko MCP server itself is responsive and correctly configured.' It distinguishes itself from tools that check network devices or inventory backend reachability by explicitly contrasting with those cases, and provides a language example ('¿Está arriba el router X?') to reinforce the boundary.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description tells the agent to call netmiko.get_metadata FIRST if the user message involves network devices, and clearly states what this tool is NOT for (network device checks, inventory backend reachability). It also explains when to use alternatives like netmiko.send_show_command, providing explicit when-to-use and when-not-to-use guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.list_device_outputsA
List the output files already saved on disk for a device, group, or all devices.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
Outputs land here when save_output=True was used or when a command exceeded save_threshold. Read them with netmiko.read_device_output.
| Name | Required | Description | Default |
|---|---|---|---|
| device_or_group | Yes | A device name, a group name, or 'all'. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must fully disclose behavior. It describes what the tool does (lists files), how outputs are generated (saved when save_output=True or threshold exceeded), and implies reading is a separate step. There are no contradictions, and for a listing tool this level of transparency is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is three sentences long, front-loaded with the core purpose, uses an IMPORTANT callout for critical workflow instruction, and every sentence adds value. No wasted words.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (single parameter, fully described in schema), the presence of an output schema, and clear context about when outputs exist and how to proceed after listing, the description is complete enough for an agent to use correctly without confusion.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%—the single parameter device_or_group is fully described in the schema. The description repeats 'for a device, group, or all devices' but adds no additional meaning beyond what the schema already states. With high coverage, baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'List the output files already saved on disk for a device, group, or all devices.' This provides a specific verb (List) and resource (output files) with clear scope options, distinguishing it effectively from sibling tools like netmiko.read_device_output which reads files.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit guidance: 'If the user message involves network devices, call netmiko.get_metadata FIRST.' It also explains the source of outputs ('save_output=True or exceeded save_threshold') and directs the agent to netmiko.read_device_output for reading. While it doesn't explicitly state when not to use this tool, the context is clear enough for an agent to understand its place in a workflow.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.list_devicesA
List devices from the inventory, without credentials.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
Use this to discover exact device names before running a command. Device names are the only handle the other tools accept — never pass an IP address or a hostname you inferred.
| Name | Required | Description | Default |
|---|---|---|---|
| device_or_group | No | 'all' (default), a group name, or a device name. | all |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It clearly states the operation is a list (read-only) and that it operates 'without credentials,' which is a notable behavioral trait. It does not mention pagination, rate limits, or other potential behaviors, but the simplicity of the tool makes this sufficient.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences plus a short IMPORTANT note. Information is front-loaded: the essential action comes first, followed by critical usage instructions. Every sentence earns its place with no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (one optional parameter with 100% schema coverage, an output schema present, and no annotations needed for a read-only list), the description covers all necessary aspects: purpose, when to use, behavioral trait (without credentials), and relationship to sibling tools. The output format is covered by the output schema, so no further detail is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description reinforces the parameter's purpose ('discover exact device names') but does not add new semantic information beyond what the schema's description already provides ('all, a group name, or a device name'). The emphasis on using exact names is helpful context but not additional parameter semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists devices from the inventory without credentials, with a specific purpose to discover exact device names. It distinguishes from siblings by emphasizing that device names are the only handle other tools accept, and it notes the IMPORTANT prerequisite to call netmiko.get_metadata first.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit usage guidance is provided: 'Use this to discover exact device names before running a command' and 'Device names are the only handle the other tools accept — never pass an IP address or a hostname you inferred.' The IMPORTANT instruction to call netmiko.get_metadata first for network-related messages further clarifies when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.list_groupsA
List every device group defined in the inventory.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
Groups are what netmiko.send_show_command_to_group accepts. Call this before assuming a group name exists — never invent one.
Returns:
str: JSON with groups (list of group-name strings) and count.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description must carry the burden. It discloses the read-only nature (list operation) and the return format (JSON with groups and count), and warns against inventing group names. It does not mention error handling or performance, but for a simple list tool this is adequate.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured: a one-line purpose, a bolded IMPORTANT note, a usage tip, and a returns section. Every sentence adds value, and it is front-loaded with the core purpose.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, an output schema, and a straightforward list operation, the description fully covers usage, prerequisites, and return value. It also clarifies its role in relation to send_show_command_to_group, making it complete in context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so no param info is needed. The description does not add parameter details because there are none; baseline 4 is appropriate for a zero-parameter tool. The output schema already covers the return structure, and the description reinforces it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'List every device group defined in the inventory' — a specific verb and resource. It distinguishes from siblings like list_devices and send_show_command_to_group by focusing on groups, and the tool's role is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicit guidance is given: 'call netmiko.get_metadata FIRST' for network devices, and 'Call this before assuming a group name exists — never invent one.' This sets clear prerequisites and usage timing, effectively preventing misuse without overcomplicating.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.query_audit_trailA
Read the audit trail: what this server was asked to do, and what happened.
Answers questions about PAST activity — "everything done on SW-CORE-01", "the last 6 netmiko actions", "which commands were refused this week", "who touched that switch and with which credential". It reads the audit records only; it never opens a connection and never returns device output.
Every argument is a filter, combined with AND. Leave one empty to not filter on it. Translate what the user asked into these arguments — do not ask for everything and sift through it.
The audit trail rotates daily and this reads the rotated files too, but only
what is still on disk. files_scanned and oldest_available in the response
say how far back the answer actually reaches: if the period the user asked
about is older than that, say so instead of reporting "nothing happened".
matched is how many records satisfied the filters; returned is how many
came back in this call. When they differ, the response is one page — never
report returned as a total.
Calling this tool writes a tool_invocation record of its own — reading the
trail is itself auditable — but those records are hidden from the results by
default, so "the last 6 actions" is about the network and not about your own
questions. audit_queries_hidden says how many were left out.
| Name | Required | Description | Default |
|---|---|---|---|
| tool | No | Full tool name, e.g. 'netmiko.send_show_command'. | |
| event | No | Record type. One of command_attempt (a command was validated), connection_outcome (an SSH attempt finished), tool_invocation (a tool that touches no device was called), credential_resolution (which credential was used). | |
| limit | No | Maximum records to return. Defaults to 50, capped at 500. | |
| order | No | 'desc' (newest first, the default) or 'asc'. | desc |
| since | No | ISO 8601 date or datetime, UTC. '2026-08-17' means from midnight. | |
| until | No | ISO 8601 date or datetime, UTC. | |
| device | No | Exact inventory device name, as netmiko.list_devices returns it. | |
| reason | No | Why a command was allowed or refused, e.g. DENY_MATCH, NO_ALLOW_MATCH. | |
| outcome | No | How an execution ended, e.g. SUCCESS, AUTH_FAILURE, TIMEOUT. Only connection_outcome records carry it. | |
| verdict | No | ALLOWED or DENIED. Only command_attempt records carry it. | |
| summary_by | No | Return counts instead of records, grouped by one of device, tool, outcome, verdict, event, day. Counts are exact over every matching record, not over one page. Use it for "how many" questions so a count does not cost hundreds of records. Combine it with an `event` filter to avoid a large '(absent)' bucket: records of one type do not carry the fields of another. | |
| correlation_id | No | Ties the validation, the credential and the outcome of one single attempt together. Use it to reconstruct what happened in one case. | |
| command_contains | No | Case-insensitive substring of the command, e.g. 'running-config'. | |
| include_audit_queries | No | Include this tool's own invocations. Defaults to False. Set it to True only when the question is about who read the audit trail. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses all behavioral traits: it only reads records, never connects to devices, filters combine with AND, audit trail rotates and reads available files, response fields indicate coverage and pagination, and it records its own invocations which are hidden by default. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured and front-loaded with the core purpose. Each sentence adds unique value: examples of use, filtering rules, disk rotation caveats, response field semantics, and self-auditing behavior. No wasted words; the length is appropriate for the tool's complexity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (14 parameters, no annotations, but has output schema), the description covers all necessary aspects: purpose, usage guidance, filtering, pagination, audit trail rotation, and self-recording. It is sufficiently complete for an agent to invoke correctly without additional help.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema already describes all 14 parameters with complete descriptions (100% coverage). The description adds value beyond the schema by explaining the combined-AND filtering strategy, pagination behavior (matched vs. returned), and the context for include_audit_queries. This is meaningful but not extensive, so a 4 is warranted.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool reads the audit trail of past activity, with examples of questions it answers. It distinguishes itself from siblings like send_show_command and read_device_output by explicitly noting it never opens a connection or returns device output.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives strong guidance on when to use the tool (for past activity, not current state) and how to translate user questions into arguments. It instructs to avoid requesting all records and sifting through them. However, it does not explicitly name sibling alternatives to use instead, leaving the agent to infer from context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.read_device_outputA
Read a previously saved output file for one device, with pagination.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
The response header states the line range and the total line count. When lines remain, a continuation hint gives the offset to use next. Do not report a total based on a page you have not finished reading.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum lines per call. Defaults to 500. | |
| offset | No | 0-indexed line to start from. Defaults to 0. | |
| filename | Yes | Exact filename as returned by netmiko.list_device_outputs. | |
| device_name | Yes | Device whose output directory to read from. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so the description carries the full burden. It describes the pagination mechanism: response header with line range and total line count, continuation hint for next offset, and a warning about premature totals. This is relevant behavioral information beyond the tool name.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise at 4 sentences, with a clear front-loaded purpose and a bolded 'IMPORTANT' warning. No redundant phrasing; every sentence adds value. Could be slightly more structured, but it's efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the existence of an output schema, the description adequately covers the pagination behavior and provides a critical prerequisite (get_metadata). It does not explicitly mention error handling or file existence, but the output schema likely covers return values. The description is sufficiently complete for an agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds value by explaining the pagination behavior (continuation hint) which helps the agent understand how to use the offset and limit parameters effectively. This goes beyond the schema's parameter descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb and resource: 'Read a previously saved output file for one device, with pagination.' This distinguishes it from sibling tools like send_show_command (which sends commands) and list_device_outputs (which lists files).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly instructs to call netmiko.get_metadata FIRST when the user message involves network devices. Also provides guidance on pagination (do not report total based on incomplete pages). Does not explicitly mention alternatives for when not to use this tool, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.send_show_commandA
Connect to one network device over SSH and run a single show command.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
The command is validated against the operator's allow/deny list before execution. A rejection is NOT a bug and NOT something to work around: report it to the user and say which command was refused. Do not retry with an abbreviation — abbreviations are covered by the deny list, not by the allow list.
SYNTAX IS PER-PLATFORM. Netmiko drives 177 base device_types (416 with variants)
from 102 vendors and their CLIs are NOT interchangeable. Check the device's
device_type with netmiko.list_devices first and use that platform's syntax:
Cisco IOS/Arista/Juniper use show ..., Huawei VRP and HPE Comware use
display ..., MikroTik RouterOS uses /system resource print, F5 tmsh uses
list/show with its own grammar. Never translate a command from one family
to another by analogy, and never probe variants to see which one is accepted —
each attempt is audited and may be denied for a different reason.
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Full, un-abbreviated CLI command, e.g. 'show ip interface brief'. | |
| device_name | Yes | Exact device name from the inventory (netmiko.list_devices). | |
| save_output | No | Always write the output to disk and return the filename instead of the content. Useful when you will refer back to it several times. | |
| use_textfsm | No | Parse the output into structured JSON via ntc-templates. Falls back to raw text when no template exists. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description bears full responsibility. It discloses that the command is validated against an allow/deny list, that rejections are expected and not a bug, that syntax is per-platform across 177 base device types, and that probes are audited. This covers behavioral traits beyond the basic function.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is fairly long but well-structured, with a clear first sentence stating purpose, followed by an important prerequisite note, rejection behavior, and platform syntax warnings. Every section earns its place given the complexity, though it could be slightly more concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (4 parameters, 177 device types, output schema exists), the description is remarkably complete. It covers prerequisites, platform variations, rejection handling, and flag usage. The output schema exists, so return values do not need to be described. No gaps in essential context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, establishing a baseline of 3. The description adds value by reinforcing the need for full, un-abbreviated commands and exact device names, and by providing context about platform-specific syntax. While much is already in the schema, the additional warnings about abbreviations and device type checking justify a 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Connect to one network device over SSH and run a single show command', providing a specific verb and resource. It distinguishes from siblings like netmiko.send_show_command_to_group and netmiko.list_devices by focusing on a single device and show command.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear when-to-use guidance: call netmiko.get_metadata FIRST for network device queries, check device_type with netmiko.list_devices first, and warns against probing variants or retrying rejected commands. It explicitly states that rejections are not bugs and must be reported to the user.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
netmiko.send_show_command_to_groupA
Run the same show command concurrently on every device of a group.
IMPORTANT: If the user message involves network devices, call netmiko.get_metadata FIRST.
The command is validated once before any connection is opened, so a denied command reaches no device at all. Per-device failures are returned per device: a partial result is normal and must be reported as partial, never summarised as if every device answered.
A GROUP MAY MIX PLATFORMS. The same command string is sent to every member, so a
group holding both Cisco IOS and Huawei VRP devices will fail on half of them
whatever you send — show version is invalid on VRP, display version is invalid
on IOS. Check device_type across the group with netmiko.list_devices first; if
the group is heterogeneous, issue one netmiko.send_show_command per platform
instead of forcing a single string onto all of them.
| Name | Required | Description | Default |
|---|---|---|---|
| command | Yes | Full, un-abbreviated CLI command. | |
| save_output | No | Save per-device output to disk and return filenames. | |
| use_textfsm | No | Parse each output into structured JSON where possible. | |
| device_or_group | Yes | Group name (netmiko.list_groups) or a single device name. |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses concurrent execution, pre-validation of commands, per-device failure reporting, and the platform heterogeneity risk. No contradictions with structured data.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections, important warnings highlighted, and logical flow. Slightly lengthy but every sentence serves a purpose; could be slightly more concise without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all critical aspects: concurrent execution, validation, partial failure reporting, platform heterogeneity, and prerequisites. Output schema exists so return values are not needed. Sufficient for a complex tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value beyond schema by explaining that the command is validated once before connections and warns about platform mixing for the 'command' parameter. It also reinforces the meaning of 'device_or_group' as linking to list_groups/list_devices.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Run the same show command concurrently on every device of a group.' It specifies the verb (run), resource (show command), and scope (concurrently on every device of a group). This distinguishes it from sibling tool 'netmiko.send_show_command' which targets a single device.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides explicit guidance: call netmiko.get_metadata FIRST when involving network devices, and warns against using with heterogeneous groups—directing to use send_show_command per platform instead. Also explains validation behavior and partial failure handling.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.5- First observed
netmiko.get_command_policy - First observed
netmiko.get_metadata - First observed
netmiko.health_check - First observed
netmiko.list_device_outputs - First observed
netmiko.list_devices - First observed
netmiko.list_groups - First observed
netmiko.query_audit_trail - First observed
netmiko.read_device_output - First observed
netmiko.send_show_command - First observed
netmiko.send_show_command_to_group
TDQS
Scored across 10 tools
Each tool targets a clear resource and action, and the descriptions explicitly define when each should be used. get_metadata and health_check overlap somewhat since both report server configuration details, but their distinct purposes are clearly explained.
Most names follow a consistent verb_noun pattern such as list_devices, send_show_command, and query_audit_trail. health_check is the main deviation, being a noun phrase rather than a verb-led name, but the overall pattern remains predictable.
10 tools is well within the ideal scope for a network automation server. Each tool earns its place by covering a distinct function: metadata, policy, health, inventory, command execution, output retrieval, and auditing.
The tool set covers the full read-only operational workflow: discover devices and groups, check command policy, run show commands individually or to a group, list and read saved outputs, and query the audit trail. There are no obvious dead ends—every inventory and output listing has a corresponding consumption tool.
Maintenance
Related MCP Connectors
Read-only MCP access to a documented IT fleet: state, changes, posture. 15 tools.
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Safe, read-only Postgres and MySQL access for AI agents. Audit log + column-level controls.
Read-only finance and operations controls for AI agents with evidence and safe next actions.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables AI agents to interact with Cisco IOS-XE network devices over SSH using structured tools. Provides read and write capabilities for network management with built-in validation and security.-
- AlicenseAqualityCmaintenanceBridges AI agents with network infrastructure, enabling secure read-only access to multiple vendor routers via SSH for natural language queries and troubleshooting.581MIT
- FlicenseAqualityCmaintenanceEnables LLMs to run read-only show commands on Cisco IOS/IOS-XE and Nexus switches over SSH, with a two-account model for privilege separation and a fail-closed allowlist for safety.25-
- AlicenseNot gradedqualityBmaintenanceProvides read-only, multi-vendor network device interaction, configuration auditing against vendor-guide rules, and safe diffing of proposed changes for AI agents to inspect and analyze network infrastructure without any commit or write capability.1Apache 2.0