Skip to content

MCP: хаб как инструменты ИИ-агента ​

Включается в «О системе»

MCP работает, если в «О системе» → «Экспериментальные функции» включён «MCP для ИИ-агентов» (по умолчанию выключен; выключенный отвечает 403 любому токену).

Хаб — сервер MCP (Model Context Protocol): Claude Code, Claude Desktop, Cursor и другие агенты видят nkt как набор инструментов — хосты, находки, конвейеры, сценарии, переносы, Traffic Fly, кластеры — и сами вызывают их по ходу задачи («почему упал web-2», «перенеси forgejo на web-3 и переключи маршрут»).

Адрес — POST /api/mcp (транспорт Streamable HTTP, ответ одним JSON). Для клиентов, которые запускают сервер командой, есть мост nkt mcp.

Доступ — только по API-токену ​

MCP работает с API-токеном, а не со входом в интерфейс. Каждый инструмент — вызов того же API хаба под тем же токеном, поэтому права агента — права токена, без отдельных правил:

  • токен чтения видит только инструменты чтения (хосты, находки, службы, контейнеры, оповещения, конвейеры, задания, сценарии, переносы, кластеры, карта и статус Traffic Fly);
  • токен администратора получает и действия: запуск сценария, выкладку, перенос стека, Traffic Fly, манифесты в кластеры, службы и контейнеры, бан адресов;
  • токен по правам — только выбранные действия с потолками ресурсов (Токен по правам): агент видит только разрешённые инструменты, выкладка и машины — в потолках;
  • предел по хостам и группам действует как в API: чужие хосты недоступны, общая карта Traffic Fly — только токену без предела;
  • список адресов, срок и nkt-edge — как у любого вызова с токеном.

Действия — без подтверждения

С токеном администратора агент выполняет действия сразу, человек их не подтверждает: так задумано, чтобы агент мог довести задачу до конца. Для агента, которому вы не доверяете всё, выдайте токен чтения или токен по правам: только нужные действия, свои объекты и потолки CPU, памяти, диска и машин. Всё, что агент сделал, есть в журнале действий хаба под именем token:<имя токена>.

Встроенный ИИ хаба (разбор находок, ИИ в редакторе сценариев, ассистент) по-прежнему ничего не запускает сам: сценарий из ответа ассистента выполняется, только когда вы нажмёте «Выполнить». Без человека действия выполняет только MCP — с токеном администратора или токеном по правам (в его пределах).

Инструменты ​

ИнструментРольЧто
list_hostsчтениехосты: статус, версия, проблемы
host_overview, host_findings, host_services, host_containersчтениеразделы хоста (host_id; машина хаба — -1)
list_alertsчтениеоповещения новее номера after
list_pipelines, get_pipelineчтениеконвейеры и последняя выкладка; описание конвейера (секреты — @secret)
list_pipeline_examplesчтениеготовые описания из примеров (без key — список, с key — текст)
job_status, job_logчтениезадание хаба и его журнал
list_scripts, get_scriptчтениесохранённые сценарии
list_migrations, list_clustersчтениеучёт переносов, кластеры
fly_map, fly_statusчтение, без пределакарта и состояние Traffic Fly
check_scriptадминистратор«Проверить» для текста сценария, ничего не меняет
run_scriptадминистраторзапуск сценария (dry_run; dry_first — сухой прогон, при успехе выполнение; values — ответы на вопросы)
deploy_pipeline, dry_run_pipelineадминистраторвыкладка; сухой прогон сохранённого конвейера или текста описания (content)
create_pipeline, update_pipeline, remove_pipelineадминистраторсоздать конвейер из описания, заменить описание (новая версия, в ответе дифф), удалить со стеком (токену по правам — действие «создание конвейеров», только compose на своих хостах и только свои)
pipeline_powerадминистраторостановить выкладку или поднять ту же версию (action: stop / start)
create_vm, vm_powerадминистратормашина на хосте из облачного образа; включить, выключить, погасить (токену по правам — свои, в потолках)
migrate_preview, migrate_stack, migration_actionадминистраторплан переноса, перенос, откат / удаление старой копии
fly_apply, fly_opsадминистратор, без пределаприменить карту, точечные правки целей
manifest_diff, manifest_applyадминистраторманифест в кластеры
device_snapshot, device_findings, device_configчтениехост плагина (MikroTik, Windows…): состав, находки, версии конфигурации (fresh — прочитать с устройства)
device_action, device_execадминистратордействие типа хоста плагина (перезагрузка, обновление…) и команда на его языке (RouterOS, PowerShell); dry_run — только сказать, что было бы
service_action, container_actionадминистраторstart / stop / restart служб и контейнеров
fail2ban_banадминистраторбан / разбан адресов на хостах

Плюс инструменты подключённых плагинов: <имя>_<операция> — операции чтения любому токену, остальные — с действием «плагин ИМЯ». Какие именно, с аргументами и доступом, — «Плагины» → плагин → «Для агентов» (там же «Скачать JSON» в формате tools/list).

У инструментов есть подсказки readOnlyHint и destructiveHint: клиенты, которые их учитывают, сами спросят вас перед опасным вызовом.

Задания. Длинные операции (сценарий, выкладка, перенос, Traffic Fly) возвращают job_id. С аргументом "wait": true инструмент ждёт конца задания (по умолчанию до 10 минут, timeout — до часа) и возвращает итог и хвост журнала — агенту не нужно опрашивать самому.

Пример: задание с ожиданием ​

Агент запускает сухой прогон сохранённого сценария и ждёт итога одним вызовом:

json
{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{
  "name":"run_script",
  "arguments":{"script_id":4,"dry_run":true,
    "values":{"param:FROM":"web1","param:TO":"web2"},"wait":true,"timeout":900}}}

Ответ приходит, когда задание закончилось (или вышло время — тогда "timed_out": true и job_id, чтобы спросить позже через job_status):

json
{"jsonrpc":"2.0","id":7,"result":{"isError":false,"content":[{"type":"text",
  "text":"{\"job_id\":123,\"status\":\"succeeded\",\"succeeded\":true,\"log\":[\"…\"]}"}]}}

В log — последние 200 строк журнала задания. Задание, завершившееся ошибкой, приходит с "isError": true и текстом ошибки — агент видит, что пошло не так, и может прочитать журнал целиком через job_log.

Пример работы агента ​

Просьба в Claude Code: «почему на web-2 падает выкладка app и что с этим делать?». Агент сам вызывает инструменты:

  1. list_hosts — находит web-2 и его host_id;
  2. list_pipelines — конвейер app и его последнюю выкладку;
  3. job_log — журнал упавшего задания: «порт 8080 занят»;
  4. host_containers — кто держит 8080 на web-2;

и отвечает с причиной и исправлением. С токеном чтения на этом всё; с токеном администратора агент может сам остановить лишний контейнер (container_action) и перезапустить выкладку (deploy_pipeline с "wait": true) — без подтверждения, всё в журнале действий как token:<имя>.

Пример: агент создаёт конвейер ​

Просьба: «подними umami на web1 с доменом stats.example.com». Агент:

  1. list_pipeline_examples → list_pipeline_examples с "key":"umami" — готовое описание;
  2. правит в нём хост, домен и env: (пароли оставляет generate: — их создаст хаб);
  3. dry_run_pipeline с "content" и "wait": true — хосты, порты, образы, сайт; ошибки — правит и повторяет;
  4. create_pipeline — конвейер создан, значения env: ушли в зашифрованный .env, в описании — @secret;
  5. deploy_pipeline с "wait": true — итог и журнал.

Дальше правка — get_pipeline и update_pipeline (в ответе дифф, в истории версий конвейера — версия от token:<имя>), удаление — remove_pipeline.

Пример: токен по правам ​

Токен на основе заготовки «Агент: compose с потолками»: из действий оставлены «выкладка, откат, сухой прогон» и «создание конвейеров», конвейеры app и blog, хост web1, потолки — 2 CPU и 2048 МБ суммой, 1 CPU и 512 МБ на сервис, 10 действий в час. Агент с ним видит в tools/list инструменты чтения, deploy_pipeline, dry_run_pipeline, create_pipeline, update_pipeline и remove_pipeline — остальных действий в списке нет, а вызов их отвечает unknown or not allowed tool.

  • create_pipeline — только compose и только на web1; созданный конвейер — его: выкладывать, править и удалять можно, хотя его нет в списке app, blog; update_pipeline для app (создан не им) — конвейер app создан не этим токеном;

  • deploy_pipeline для app — выкладка; сервисам без своих limits хаб ставит потолок на сервис (1 CPU, 512 МБ) в копии compose-файла, которая едет на хост;

  • стек не влез в остаток — задание заканчивается ошибкой вида app@web1: нужно 1.50 CPU, у токена свободно 0.50 из 2.00;

  • сервис с privileged, сетью хоста или путём хоста вне каталога стека — сервис runner: privileged — токену с потолками нельзя (выходит за стек);

  • конвейер не из списка — отказ с его именем, 11-е действие за час — токен исчерпал предел действий в час (10) — повторите позже.

Ошибки приходят в ответе инструмента с "isError": true — агент видит причину и может подобрать меньшие limits сам. Сколько токен уже занял, — в окне токена («Занято»).

Claude Code ​

sh
claude mcp add --transport http nkt https://hub.example.com/api/mcp \
  --header "Authorization: Bearer nkt_…"

Язык ответов хаба (ошибки, журналы заданий) — заголовок X-NKT-Lang: ru или en; мост nkt mcp ставит его по локали.

nkt mcp: мост stdio ​

Клиенты вроде Claude Desktop запускают MCP-сервер командой. Мост nkt mcp пересылает сообщения со stdin на хаб и ответы — в stdout. Адрес и токен — только из окружения (аргументы видны в списке процессов):

json
{
  "mcpServers": {
    "nkt": {
      "command": "/usr/local/bin/nkt",
      "args": ["mcp"],
      "env": {
        "NKT_HUB_URL": "https://hub.example.com",
        "NKT_API_TOKEN": "nkt_…"
      }
    }
  }
}

У хаба самоподписанный сертификат — NKT_HUB_CA=/путь/к/cert.pem. Бинарник nkt подойдёт любой той же версии — машине с агентом хаб и служба не нужны.

С локальной моделью ​

Модель хаба для MCP не нужна: думает модель агента, хаб только даёт инструменты. С локальной моделью подойдёт любой MCP-клиент, который умеет работать с Ollama или OpenAI-совместимым адресом, — например Cline или Continue в VS Code, Goose, Open WebUI. Во многих из них MCP-сервер описывается тем же блоком mcpServers, что у Claude Desktop выше (с мостом nkt mcp), или адресом https://хаб/api/mcp с заголовком Authorization; точное место настройки — в документации клиента. Модели агента нужен вызов инструментов — те же советы по моделям, что для ассистента.

Проверка руками ​

Готовые команды с адресом вашего хаба — в окне токена: «О системе» → «API-токены» → токен → «Примеры MCP» (с секретом — сразу после создания токена, потом секрет не показывается).

Какие инструменты видит токен (для токена по правам — только разрешённые):

sh
curl -s -H 'Authorization: Bearer nkt_…' -H 'Content-Type: application/json' \
  https://hub.example.com/api/mcp \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

Вызов инструмента:

sh
curl -s -H 'Authorization: Bearer nkt_…' -H 'Content-Type: application/json' \
  https://hub.example.com/api/mcp \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"list_hosts","arguments":{}}}'