Скилы через MCP
Что такое MCP-скилл
Заголовок раздела «Что такое MCP-скилл»Скилл — это набор инструментов, который воркер получает от MCP-сервера (Model Context Protocol). Скиллы не пишутся под каждую задачу: берётся готовый сервер — Postgres, web-fetch, файловая система — и запускается там, где доступна его цель.
Особенность Nythronix в том, что воркер изолирован по сети (ему доступны только control plane и LLM), а базы, логи и сервисы живут на удалённых машинах за агентами. Поэтому MCP-сервер запускается на машине как подпроцесс агента, а воркер обращается к нему через control plane:
воркер (MCP-клиент) │ HTTP JSON-RPC, один вызов = один запрос/ответ ▼control plane /api/agents/:id/mcp/:server/… (релей, токен воркера, аудит) │ по WebSocket-соединению агента ▼агент на машине → MCP-сервер на loopback → цель (локальная БД, файлы, сервис)Ничего открывать наружу не нужно: агент и так держит исходящее соединение с control plane, а MCP-сервер ходит к цели по сети самой машины.
Собственные инструменты воркера — память (remember / read_history) и запуск shell с подтверждением (run_shell) — остаются внутри воркера и через MCP не проходят. Подробнее о них в разделе Воркеры и каналы.
Как скилы обнаруживаются и подключаются
Заголовок раздела «Как скилы обнаруживаются и подключаются»Схема защиты — каталог на машине ограничивает control plane. Control plane никогда не отправляет агенту команду запуска; он передаёт только имя скилла и параметры. Соответствие имени и команды хранится у владельца машины в файле /etc/nythronix/mcp-catalog.json:
[ { "name": "postgres", "port": 9912, "params": ["db_uri"], "read_only": true, "command": ["mcp-proxy", "--stateless", "--host", "127.0.0.1", "--port", "$PORT", "--", "postgres-mcp", "--access-mode", "restricted", "$db_uri"] }]В command подстановка $PORT заменяется портом записи, $<param> — значением объявленного параметра, которое пришло с control plane. Скомпрометированный или чужой control plane может включить лишь то, что владелец уже внёс в каталог — тот же принцип, что и с локальным ограничением sudo.
Дальше цепочка такая:
- Агент при подключении объявляет control plane свой каталог (имена, параметры, признак
read_only; сами команды не передаются) и список уже запущенных серверов. - Администратор в разделе Админ → Агенты открывает у машины панель Скилы, включает нужные записи каталога, заполняет параметры и нажимает Сохранить. Control plane отправляет агенту желаемый набор; агент запускает, останавливает или перезапускает подпроцессы, чтобы привести состояние в соответствие, и сохраняет применённый набор локально — после перезагрузки машины скиллы поднимаются сами. Если агент офлайн, набор можно править, он применится при переподключении. Изменение фиксируется в аудите как
admin.agent.mcp_config_set. - Воркер при старте обходит машины организации, забирает у каждой список серверов и загружает их инструменты под именами
<машина>__<сервер>__<инструмент>, напримерnyx-db__postgres__execute_sql.
Для машин без каталога поддерживается прежний формат /etc/nythronix/mcp-servers.json с готовыми командами; его записи стартуют при загрузке агента.
Пресеты и фильтры
Заголовок раздела «Пресеты и фильтры»Поле скилы у воркера (в интерфейсе — «скилы, напр. postgres (пусто = все)») ограничивает, какие серверы он загружает. Это список имён скилл-серверов через пробел или запятую, допускаются glob-шаблоны, регистр не важен. Пустое значение, all или * означают «все скиллы». Воркер с пресетом postgres получит только инструменты Postgres и пропустит остальные серверы: меньше инструментов — точнее работает модель и меньше поверхность привилегий. Пресет можно указать и при создании канала.
Подтверждение и аудит изменяющих инструментов
Заголовок раздела «Подтверждение и аудит изменяющих инструментов»Инструмент считается безопасным и выполняется без вопросов, если сервер в каталоге помечен read_only: true или сам инструмент объявляет readOnlyHint. Всё остальное — в том числе инструменты без явной аннотации — перед вызовом попадает в канал карточкой «нужно подтверждение» с блоком «Скил, который выполнится» и аргументами. Отклонённый вызов до машины не доходит: воркер получает ответ «не выполнено» и меняет план.
Готовые серверы часто не проставляют readOnlyHint на каждый инструмент, поэтому владелец машины один раз объявляет read_only на весь сервер (например, для Postgres в режиме restricted), и лишние запросы подтверждения исчезают.
Каждый выполненный вызов инструмента control plane записывает в аудит как agent.mcp.call с указанием организации, инициатора, машины, сервера и инструмента — включая автоматически выполненные вызовы read-only серверов. Отклонённый вызов виден только как chat.approval.decided.
Изоляция
Заголовок раздела «Изоляция»- Отдельный процесс. Каждый MCP-сервер — дочерний подпроцесс агента на loopback. При отключении скилла или падении агента подпроцесс завершается вместе с ним.
- Без root. Перед запуском агент понижает привилегии подпроцесса до пользователя
nyx-worker— того же, под которым выполняются команды воркера. Если агент сам запущен не от root, понижение не выполняется. - Ограниченный выход в сеть. Скрипт
deploy/host/skills-egress.sh(и его systemd-юнитnyx-skills-egress.service) перенаправляет исходящие соединения пользователяnyx-workerна порт 443 в локальный SNI-фильтр: разрешённые домены проходят, остальные обрываются. TLS при этом остаётся сквозным. Соединение самого агента с control plane и локальные цели (Postgres на 5432, loopback) не затрагиваются.
ALLOW="example.com api.github.com" ./skills-egress.sh up./skills-egress.sh statusДля внешних сервисов есть готовый образ deploy/docker/Dockerfile.skills-host: контейнер с агентом, mcp-proxy, mcp-server-fetch и встроенным фильтром выхода, который регистрируется в control plane как отдельная машина skills-host. Ему нужна capability CAP_NET_ADMIN, а разрешённые домены задаются переменной SKILLS_ALLOW.
Примеры
Заголовок раздела «Примеры»Postgres. На машине с базой установите mcp-proxy и postgres-mcp, добавьте запись postgres из примера выше в каталог, перезапустите агент. В админке включите скилл, укажите db_uri с учётной записью только для чтения и сохраните. Воркер с пресетом postgres получит около девяти инструментов (execute_sql, list_schemas, explain_query, analyze_db_health и другие) и будет выполнять SQL-запросы без подтверждений, при этом каждый вызов останется в аудите.
Web. На хосте скиллов запись fetch (mcp-proxy --stateless … -- mcp-server-fetch) даёт инструмент fetch для загрузки страниц. Держите её с read_only: false и ограничьте домены через skills-egress.sh: запрос к разрешённому домену вернёт содержимое, к любому другому — ошибку, даже после подтверждения оператором.
Большинство MCP-серверов говорят только по stdio; адаптер mcp-proxy --stateless превращает их в HTTP-сервис, который умеет проксировать control plane.