Logo Craft Homelab Docs Нейросети Хостинг Обучение Контакты
MCP-сервер для AppSec: сканеры, база файндингов и локальные модели на 16 ГБ Трендовые github проекты в нашем телеграм канале. Подпишись →
30 октября 2026 г.

Агент-безопасник в IDE: как устроен MCP-сервер со сканерами и что он умеет

Когда код пишут агенты, его становится больше, а AppSec-команда остаётся прежнего размера. Классическая цепочка выглядит так: разработчик пушит в Git, CI запускает SAST/SCA/DAST, отчёты уходят в агрегатор (ASOC/ASPM), безопасник триажит находки, заводит задачу в трекере, задача возвращается разработчику. Время от появления уязвимости до фикса здесь непредсказуемо: сломался сканер, безопасник в отпуске, нет замены дырявой библиотеке — и уязвимость живёт неделями.

Если просто посадить агента в каждую роль этой цепочки, получится то же самое, только дороже по токенам: агент руководителя создаёт задачу, агент разработчика её берёт, агент в CI сканирует, агент в ASOC триажит, агент безопасника пересылает обратно. Разумнее сократить петлю обратной связи.

Схема с меньшим числом агентов

Рабочий вариант, который проверили на MVP под названием AppSecGate, устроен так:

  • Трекер задач убирается из обработки файндингов. Он передавал неструктурированный текст от человека к человеку, а агентам удобнее обмениваться структурированными данными. Для учёта времени и списания токенов трекер можно оставить.
  • В CI остаётся максимум один автономный агент, который берёт контекст по находкам из ASOC. Его можно убрать совсем и запускать агента вручную со стороны безопасника.
  • ASOC/ASPM превращается в систему для агентов со структурированным API вместо дашбордов для людей.

Главное изменение — shift-left на этап написания кода. Агент разработчика сам запускает сканер, как уже запускает форматтер и юнит-тесты, проверяет результат и пытается исправить. Push при этом не блокируется: если находку не удалось закрыть, она эскалируется на AppSec или лида. Сканировать можно только diff, и это экономит токены, потому что агент и так держит эти файлы в контексте. Весь локальный триаж пишется в базу, так что эффективность подхода можно показать руководству цифрами.

Как устроен MVP

Локальный MCP-сервер работает в Docker-контейнере, запускает сканеры (Semgrep для SAST, Trivy для зависимостей и образов, Gitleaks для секретов), хранит результаты сканирования и триажа в SQLite и отдаёт их агенту по запросу. Центральный сервер для агрегации находок от нескольких агентов запланирован на следующую фазу.

Конфигурация для Cline (cline_mcp_settings.json) выглядит так:

{
  "mcpServers": {
    "appsecgate-jshop": {
      "type": "stdio",
      "command": "/usr/bin/docker",
      "args": [
        "run", "--rm", "-i",
        "--network=none",
        "--read-only",
        "--tmpfs=/tmp:size=100M,mode=1777",
        "--tmpfs=/home/appsecgate/.cache:size=2G,mode=1777",
        "--tmpfs=/home/appsecgate/.appsecgate-mcp:size=100M,mode=1777",
        "--cap-drop=ALL",
        "--security-opt=no-new-privileges:true",
        "-v", "./projects/juice-shop/:/workspace:ro",
        "moondoom/appsecgate-mcp:latest",
        "--transport", "stdio", "--project", "/workspace"
      ],
      "timeout": 600
    }
  }
}

Транспорт stdio означает, что IDE сама поднимает контейнер и общается с ним через stdin/stdout. Сеть контейнеру не нужна, поэтому его можно запустить с --network=none, read-only файловой системой, без capabilities и с исходниками, смонтированными только на чтение. Для отладки состояние лежит в tmpfs и очищается при каждом запуске; в постоянной установке вместо tmpfs нужен volume.

У такой изоляции есть цена:

  • исходники проекта приходится явно пробрасывать в контейнер. В связке VS Code + Continue путь подставляется через переменные окружения, а с Cline (при VS Code из snap) пришлось захардкодить путь;
  • базы правил SAST/SCA не обновляются онлайн. Обходной вариант — --pull=always, чтобы при каждом запуске тянуть свежий образ;
  • постоянные volume могут сломаться при обновлении сервера из-за разных версий схемы БД.

Что происходит при подключении

После старта контейнера агент вызывает initialize, затем tools/list. Описания инструментов попадают в системный промпт и уходят с каждым запросом к модели. Поэтому на запрос «проверить безопасность проекта» модель сразу выбирает инструмент с подходящим описанием.

Это же делает MCP удобным вектором атаки: подключённый сервер с вредоносными описаниями инструментов влияет на поведение агента уже с первого запроса. Модели должны воспринимать тулы как данные, но гарантий нет, и поведение зависит от конкретной модели. Перед первым запросом стоит вручную просмотреть список инструментов в интерфейсе расширения, даже если сервер работает в изоляции.

Поведением агента управляют три вещи:

  1. Системный промпт задаёт общую политику, например «каждую подтверждённую находку исправлять в коде».
  2. Описания инструментов определяют, какие тулы вызывать и как читать их вывод. В MVP описания при настройке агента перевели с русского на английский.
  3. Результаты сканирования: меняя описание правил и критичность категорий, можно задать разное поведение для разных типов уязвимостей.

Прогон на OWASP Juice Shop

MVP собрали за 7 дней, потратив около 210 млн токенов и около 3000 рублей. Тестовая цель — OWASP Juice Shop, клиент — Cline. Агент в режиме планирования проходит предсказуемый путь:

  1. get_config — проверка конфигурации;
  2. scan_project — сканирование и агрегированный результат;
  3. query_findings_db — анализ находок через SQL-доступ к базе. Агент выбирает этот инструмент охотнее альтернатив;
  4. get_fix_context_batch — контекст по срабатываниям, затем правка кода;
  5. verify_fix_batch — проверка исправления или подавление как FALSE_POSITIVE.

На первом шаге агент предложил ничего не исправлять, потому что Juice Shop уязвим намеренно. Пришлось явно сказать, что цель — проверить инструменты и исправить всё.

Последний прогон на deepseek-v4-flash занял около 50 минут и стоил около 15 рублей:

ПоказательЗначение
Обработано находок200
Исправлено56 (8 critical, 45 high, 3 medium)
WONT_FIX27 (учебные данные, публичный ALB)
FALSE_POSITIVE117 (тестовые секреты Gitleaks)
Изменено файлов29, diff +333 / −115
Токены input16,2 млн, из них 15,2 млн — cache reads
Токены output56 тыс.

Для shift-left без хуков хватило правила в AGENTS.md: этот файл читают разные агенты, а rules в Cline, судя по поведению, обрабатываются так же. Перед добавлением правила полезно один раз прогнать сканирование вручную, чтобы агент набрал контекст по инструментам. Модель всё равно может правило проигнорировать.

Проблемы, которые всплыли на прогонах:

  • модель один раз потеряла 20 находок и нашла их только после повторного сканирования;
  • Cline не сжимает контекст до завершения задачи, что раздувает расход токенов;
  • MCP иногда склеивал два дубля в один, и агент тратил шаги на выяснение;
  • при работе с query_findings_db агенту приходилось отдельно узнавать схему таблиц;
  • в сценарии pre-commit агент пометил находки в намеренно испорченном файле как WONT_FIX, решив, что человек изменил код сознательно.

Локальные модели на RTX 4060 Ti 16 ГБ

Стенд: хост на Proxmox VE с i7-13700K и 64 ГБ RAM, обе GPU проброшены в гостевые VM через IOMMU. VM с VS Code, Cline и Docker работает на встроенной Intel UHD 770, headless-VM с ollama — на RTX 4060 Ti 16 ГБ. Контекст 32768 токенов, модели загружены через ollama pull без тюнинга.

Тестовая цель — микропроект на Flask с 8 уязвимостями для Semgrep плюс Dockerfile и requirements.txt для Trivy. Задача агента: просканировать, исправить SAST-находки и эскалировать находки Trivy. По три прогона на модель, так что результаты показывают работоспособность связки, а для сравнения моделей этого мало.

Модельt/sCPU/GPURecallТокеныВремяPass
qwen3.8:27b12,135% / 65%100%314k650 s3/3
gemma4:26b84,021% / 79%87%879k419 s3/3
qwen3-coder:30b58,51% / 99%73%877k451 s2/3
glm-4.7-flash52,01% / 99%73%1,17M772 s2/3
gpt-oss:20b67,80% / 100%47%254k89 s1/3
devstral:24b9,523% / 77%—4,7k25 s0/3
qwen2.5-coder:14b31,00% / 100%—4,2k—0/3

Самая медленная по генерации qwen3.8:27b оказалась самой точной: 100% recall во всех трёх прогонах, 8 из 8 исправлений и меньше всех токенов среди прошедших. gemma4:26b стабильна и быстрее всех среди прошедших, но тратит в 2,8 раза больше токенов и в медиане исправляет 6 из 8. У qwen3-coder:30b recall скачет от 40 до 100%, патчи часто промахиваются после сдвига строк. glm-4.7-flash в одном прогоне дала 100% на 376k токенах, в другом — 20% на 1,8M токенах с тремя ошибками и уходом в петлю. gpt-oss:20b выдала 6 исключений при вызове тулов. devstral:24b и qwen2.5-coder:14b вообще не вызывали инструменты и писали JSON в текст ответа.

Практическое правило из этих цифр: для агентских сценариев смотреть на стабильность работы с инструментами и число токенов на задачу, а скорость генерации учитывать во вторую очередь. Быстрая модель, которая уходит в петлю, сожжёт больше времени, чем медленная, которая с первого раза вызывает нужный тул. При этом модели на 20–30 млрд параметров на одной карте с 16 ГБ уже справляются с триажем, и сканировать крупные проекты можно по цене электричества.

Где это не заменит безопасника

Такой сервер снимает рутину: запуск сканеров, разбор очевидных ложных срабатываний вроде тестовых секретов, типовые исправления по шаблону. Логические уязвимости, архитектура и решения о том, что считать допустимым риском, остаются за человеком. Случай с WONT_FIX на pre-commit показывает, почему: агент легко принимает намерение пользователя за обоснование.

Ниша плотная: от обёрток вроде Semgrep MCP до ASPM-платформ с MCP-интерфейсом (Checkmarx One, BoostSecurity) и AI-native сервисов вроде ZeroPath. MVP повторяется за неделю, так что под свой набор сканеров сервер можно собрать самому.