Help:13-alpha MCP: Difference between revisions
Mitrofanov (talk | contribs) |
m (Akuzmin moved page Help:Test build MCP to Help:13-alpha MCP without leaving a redirect) |
Revision as of 18:13, 21 May 2026
Архитектура
MCP — открытый стандарт, через который LLM-клиенты (Claude Desktop, Cursor, VS Code, OpenWebUI и др.) вызывают внешние инструменты. Svacer MCP соединяет одно с другим: 8 инструментов поверх публичного REST API Svacer, которые LLM выбирает и вызывает в ответ на обычный текстовый запрос. Вместо ручной последовательности «открыть UI, найти проект, выбрать снимок, применить фильтр» достаточно сформулировать вопрос в чате, например, «сколько критических предупреждений в последнем снимке bash?», и получить ответ. Необходимые вызовы инструментов модель выполняет самостоятельно.

Поток запроса: LLM-клиент отправляет MCP-вызов через STDIO или Streamable HTTP → server.py передаёт его в выбранный инструмент из tools/ → инструмент проверяет параметры и обращается к api_client.py → клиент получает JWT от auth.py (модуль автоматически обновляет токен по истечении срока действия или при ответе 401) → запрос отправляется в Svacer REST API.
Установка
Установка Svacer MCP, подключение клиентов и конфигурация.
Требования
- Python 3.10+
- Доступ к Svacer-серверу: URL + логин/пароль
Режим STDIO
Подходит для настольных клиентов: Claude Desktop, Claude Code, Cursor, VS Code.
git clone https://gitlab.ispras.ru/svacerai/mcp.git && cd mcp
python3 -m venv .venv
.venv/bin/pip install -e .
cp .env.example .env
# Отредактировать .env — указать URL и учётные данные Svacer
# Проверить запуск (сервер ожидает данные на stdin; для выхода — Ctrl+C)
.venv/bin/svacer-mcp
После pip install -e . в окружении становится доступна команда svacer-mcp — её указывают в конфигурации клиентов ниже.
Режим HTTP (Docker)
Подходит для веб-клиентов (OpenWebUI) и удалённого доступа.
Требования: Docker, Docker Compose.
cp .env.example .env
# В .env обязательно задать SVACER_MCP_TOKEN — без него сервер не запускается
echo "SVACER_MCP_TOKEN=$(openssl rand -hex 32)" >> .env
docker compose up -d
# MCP endpoint: http://localhost:8002/mcp
# Клиенты передают заголовок: Authorization: Bearer <SVACER_MCP_TOKEN>
Внешний порт хоста задаётся переменной MCP_PORT (по умолчанию 8002), внутри контейнера сервер всегда слушает порт 8000.
Подключение клиентов
Claude Desktop
Файл конфигурации: ~/.config/Claude/claude_desktop_config.json (Linux) или %APPDATA%\Claude\claude_desktop_config.json (Windows).
Укажите абсолютный путь к svacer-mcp из вашего venv (which svacer-mcp в активированном venv или /path/to/mcp/.venv/bin/svacer-mcp).
{
"mcpServers": {
"svacer": {
"command": "/path/to/mcp/.venv/bin/svacer-mcp",
"env": {
"SVACER_URL": "https://your-svacer.example.com",
"SVACER_LOGIN": "your-login",
"SVACER_PASSWORD": "your-password"
}
}
}
}
Claude Code
claude mcp add svacer \
-e SVACER_URL=https://your-svacer.example.com \
-e SVACER_LOGIN=your-login \
-e SVACER_PASSWORD=your-password \
-- /path/to/mcp/.venv/bin/svacer-mcp
VS Code
Файл .vscode/mcp.json в корне рабочей директории:
{
"servers": {
"svacer": {
"type": "stdio",
"command": "/path/to/mcp/.venv/bin/svacer-mcp",
"env": {
"SVACER_URL": "https://your-svacer.example.com",
"SVACER_LOGIN": "your-login",
"SVACER_PASSWORD": "your-password"
}
}
}
}
Cursor
Файл .cursor/mcp.json в корне проекта или глобально:
{
"mcpServers": {
"svacer": {
"command": "/path/to/mcp/.venv/bin/svacer-mcp",
"env": {
"SVACER_URL": "https://your-svacer.example.com",
"SVACER_LOGIN": "your-login",
"SVACER_PASSWORD": "your-password"
}
}
}
}
OpenWebUI
- Развернуть через Docker (см. «Режим HTTP» выше).
- Открыть Settings → Tools (или Admin Panel → Settings → Tools).
- Добавить сервер:
http://localhost:8002/mcp— если OpenWebUI работает на хосте, снаружи Docker.http://svacer-mcp:8000/mcp— если OpenWebUI развёрнут в той же compose-сети, что иsvacer-mcp(имя берётся изdocker-compose.yml→ service name, порт 8000 — внутренний порт контейнера).
- Тип подключения: MCP (Streamable HTTP).
- В настройках инструмента указать заголовок
Authorization: Bearer <SVACER_MCP_TOKEN>(значение — то же, что в.envсервера). - Сохранить — инструменты появятся в чате.
Конфигурация
| Переменная | По умолчанию | Описание |
|---|---|---|
SVACER_URL
|
https://svacer-demo.ispras.ru
|
URL Svacer-сервера |
SVACER_LOGIN
|
admin
|
Логин |
SVACER_PASSWORD
|
admin
|
Пароль |
SVACER_TIMEOUT
|
30
|
Тайм-аут HTTP-запросов к Svacer, секунды |
SVACER_TRANSPORT
|
stdio
|
Режим транспорта: stdio или http
|
SVACER_HTTP_PORT
|
8000
|
TCP-порт сервера в режиме HTTP (внутри контейнера) |
SVACER_MCP_TOKEN
|
(не задано) | Bearer-токен для клиентов /mcp. Обязателен при SVACER_TRANSPORT=http, в режиме STDIO игнорируется. Генерация: openssl rand -hex 32
|
SVACER_MCP_RESOURCE_URL
|
http://localhost:<HTTP_PORT>
|
Публичный URL MCP-сервера для заголовка WWW-Authenticate (RFC 9728). Задаётся при работе за обратным прокси
|
SVACER_TOOLS
|
(не задано) | Список инструментов через запятую. Если не задано, регистрируются все 8 |
MCP_PORT
|
8002
|
Внешний порт хоста при запуске через docker compose (отображается на внутренний SVACER_HTTP_PORT)
|
Переменные читаются из .env или из окружения. Для STDIO-клиентов их можно указать в секции env конфигурации клиента.
Ограничение набора инструментов
Чтобы запустить сервер с подмножеством инструментов (например, для уменьшения объёма контекста у модели или разграничения доступа), задайте SVACER_TOOLS:
SVACER_TOOLS=get_projects,get_snapshots,get_markers
Допустимые имена: get_projects, get_snapshots, get_warnings, get_markers, get_project_stats, get_project_groups, get_advanced_file_preview, get_diff. Неизвестное имя в списке приводит к ошибке при запуске. Если переменная пустая или не задана, регистрируются все 8 инструментов.
Несколько экземпляров сервера
Параллельный запуск нескольких MCP-серверов поддерживается без ограничений.
- В режиме STDIO каждая запись в конфигурации клиента описывает отдельный процесс — несколько подключений к разным экземплярам Svacer задаются простым перечислением.
- В режиме HTTP запускаются независимые контейнеры на разных хост-портах: например,
MCP_PORT=8002для одного экземпляра иMCP_PORT=8003для другого. Для каждого контейнера задаётся собственныйSVACER_MCP_TOKEN.
Безопасность
- STDIO: сервер не открывает сетевых портов и обменивается данными через стандартные потоки ввода/вывода процесса.
- Streamable HTTP: эндпоинт
/mcpтребует заголовокAuthorization: Bearer <SVACER_MCP_TOKEN>. Запросы без токена или с неверным значением получают ответ401и заголовокWWW-Authenticate: Bearer .... Токен является разделяемым секретом и не заменяет TLS, а дополняет его: при работе за обратным прокси необходимо использовать HTTPS, а сам токен передавать только по защищённому каналу. - Без
SVACER_MCP_TOKENHTTP-сервер не запускается. - Учётные данные
admin/adminпредназначены только для тестового стенда. В рабочем окружении необходимо задать собственные логин и пароль через переменные окружения. - Файл
.envне должен добавляться в систему контроля версий.
Передача токена клиентом
Большинство HTTP-клиентов MCP (OpenWebUI и др.) позволяют задать произвольный заголовок Authorization в настройках инструмента — указывается значение Bearer <токен>. Для ручной проверки:
curl -H "Authorization: Bearer $SVACER_MCP_TOKEN" \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"0"}}}' \
http://localhost:8002/mcp
Инструменты
Справочник по 8 инструментам Svacer MCP. Типичный порядок вызовов: get_projects → get_snapshots → любой из аналитических инструментов.
| Инструмент | Назначение |
|---|---|
get_projects
|
Список проектов с ветками — точка входа |
get_snapshots
|
Снимки конкретной ветки, от нового к старому |
get_project_stats
|
Агрегированные метрики снимка: severity / review / checker |
get_markers
|
Компактный список маркеров с серверной фильтрацией |
get_warnings
|
Полные предупреждения с трассами и историей ревью |
get_diff
|
Сравнение двух снимков: new / missing / modified / matched |
get_advanced_file_preview
|
Фрагмент исходного кода вокруг строки |
get_project_groups
|
Группа проектов по имени или UUID |
get_projects
Список всех проектов с ветками. Точка входа: с этого вызова начинается практически любой сценарий — он возвращает project_id и branch_id, необходимые для последующих запросов.
Параметров нет.
Вызов:
get_projects()
Ответ:
[
{
"project_id": "91630e84-db2f-4d8c-8716-68b7fdf17a66",
"project_name": "bash",
"created": "2021-12-13T13:22:42.122456Z",
"created_by": "admin",
"branches": [
{
"branch_id": "77f66b9e-0453-4ae9-a187-88950b4c4bc4",
"branch_name": "master",
"created": "2021-12-13T13:22:42.394812Z"
}
]
}
]
get_snapshots
Список снимков для конкретной ветки проекта, от нового к старому.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
project_id
|
string (UUID) | да | Из get_projects
|
branch_id
|
string (UUID) | да | Из get_projects
|
name_filter
|
string | нет | Подстрока или regex для фильтра по имени снимка |
Вызов:
get_snapshots(
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66",
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4"
)
Ответ:
[
{
"snapshot_id": "b42cb563-86f4-4f96-900a-7782163327c9",
"name": "Snapshot 2020-03-25 09:09:41 +0300",
"import_time": "2020-03-25T09:09:41.837296Z",
"commit_hash": null,
"markers_count": 297,
"link": "https://svacer-demo.ispras.ru/..."
}
]
get_project_stats
Агрегированные метрики по снимку: общее количество предупреждений, распределение по критичности, по статусу ревью, по детекторам. Наиболее быстрый способ получить общую картину по проекту.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
project_id
|
string (UUID) | да | |
branch_id
|
string (UUID) | да | |
snapshot_id
|
string (UUID) | да |
Вызов:
get_project_stats(
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66",
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4",
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9"
)
Ответ:
{
"total_warnings": 771,
"by_severity": {
"Critical": 1,
"Major": 1,
"Unspecified": 769
},
"by_review_status": {
"Confirmed": 1,
"False Positive": 1,
"Undecided": 767,
"Unclear": 1,
"Won't fix": 1
},
"by_checker": {
"PROC_USE.VULNERABLE": 337,
"UNUSED_FUNC_RES.REWRITE.MINOR": 44,
"UNREACHABLE_CODE": 28,
"DEREF_AFTER_NULL.EX": 27,
"NULL_AFTER_DEREF": 27
}
}
get_markers
Компактный список маркеров с серверной фильтрацией. Основной инструмент для перечисления и обзора: его следует предпочитать get_warnings, когда не требуются развёрнутые поля — трассы и история ревью.
По умолчанию ответ ограничен 30 маркерами и содержит компактный набор полей. Подробнее об ограничении объёма см. раздел Про объём ответа в сценариях.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
project_id
|
string (UUID) | да | |
branch_id
|
string (UUID) | да | |
snapshot_id
|
string (UUID) | да | |
severity
|
string[]
|
нет | Critical, Major, Minor, Unspecified. Фильтр по review.severity, применяется на стороне коннектора
|
review
|
string[]
|
нет | Confirmed, Won't fix, False Positive, Unclear
|
warnClass
|
string[]
|
нет | Идентификатор детектора (DEREF_AFTER_NULL, …)
|
file
|
string[]
|
нет | Подстрока пути к файлу |
traces
|
bool
|
нет | Включить трассы маркеров |
checker_info
|
bool
|
нет | Включить метаданные детектора (CWE, описание) |
review_history
|
bool
|
нет | Включить историю изменений ревью |
comment_history
|
bool
|
нет | Включить комментарии к маркеру |
custom_filter
|
string | нет | Имя или идентификатор сохранённого фильтра из веб-интерфейса Svacer |
limit
|
int | нет | Максимальное количество маркеров в ответе (по умолчанию 30). Значение 0 снимает ограничение
|
fields
|
string[]
|
нет | Список разрешённых полей маркера верхнего уровня. По умолчанию — компактный набор id, warnClass, file, line, msg, function, review. Значение ["*"] возвращает все поля коннектора (id, warnClass, file, line, msg, tool, function, mtid, review, а также traces/checkerInfo/review_history/comments, если они запрошены). Допустим и произвольный список — например, ["id","warnClass"]
|
Вызов:
get_markers(
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66",
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4",
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9",
warnClass=["PROC_USE.VULNERABLE"]
)
Ответ:
{
"total_count": 341,
"returned_count": 30,
"truncated": true,
"filters_applied": {"warnClass": ["PROC_USE.VULNERABLE"]},
"markers": [
{
"id": "e05bb35b-a95e-4eb2-85ae-3101b788f07d",
"warnClass": "PROC_USE.VULNERABLE.TEMP",
"file": "/.build/lib/sh/tmpfile.c",
"line": 160,
"msg": "Use of vulnerable function 'mktemp' at tmpfile.c:160. ...",
"function": "sh_mktmpname",
"review": null
}
]
}
total_count отражает количество маркеров, удовлетворяющих фильтру до применения ограничения; returned_count — количество маркеров, фактически содержащихся в markers. При truncated: true следует либо сузить фильтры (severity, warnClass, file), либо передать limit=0 для получения полного списка. Поля tool и mtid возвращаются только при fields=["*"].
get_warnings
Полные предупреждения с детальной разметкой. Ответ значительно объёмнее, чем у get_markers, поэтому инструмент следует использовать только тогда, когда нужны поля, отсутствующие в компактной форме: traces, review_history, checker_info, comment_history.
Лимит по умолчанию — 30; при включённых traces, review_history или comment_history он автоматически снижается до 8, поскольку такие предупреждения существенно объёмнее.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
project_id
|
string (UUID) | да | |
branch_id
|
string (UUID) | да | |
snapshot_id
|
string (UUID) | да | |
severity
|
string[]
|
нет | Critical, Major, Minor, Unspecified. Фильтр по review.severity, применяется на стороне коннектора
|
review
|
string[]
|
нет | Confirmed, Won't fix, False Positive, Unclear
|
warnClass
|
string[]
|
нет | Идентификатор детектора |
file
|
string[]
|
нет | Подстрока пути к файлу |
traces
|
bool
|
нет | Включить трассы. Активирует режим расширенных полей (лимит по умолчанию — 8) |
checker_info
|
bool
|
нет | Включить метаданные детектора (CWE, описание) |
review_history
|
bool
|
нет | Включить историю ревью. Режим расширенных полей |
comment_history
|
bool
|
нет | Включить комментарии. Режим расширенных полей |
custom_filter
|
string | нет | Имя или идентификатор сохранённого фильтра |
limit
|
int | нет | Максимальное количество предупреждений в ответе. По умолчанию — 30, в режиме расширенных полей — 8. Значение 0 снимает ограничение. Явно заданное limit отменяет автоматическое снижение
|
fields
|
string[]
|
нет | См. описание у get_markers
|
Вызов:
get_warnings(
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66",
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4",
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9",
severity=["Critical"],
review_history=True,
traces=True
)
Ответ:
{
"total_count": 1,
"returned_count": 1,
"truncated": false,
"filters_applied": {"severity": ["Critical"], "traces": true, "review_history": true},
"warnings": [
{
"id": "a3f21c90-1d4e-4b82-9f63-7c8e5d2a1b09",
"warnClass": "DEREF_AFTER_NULL.LOOP",
"file": "/.build/execute_cmd.c",
"line": 3327,
"msg": "Possible null pointer dereference of 'l' after loop exit.",
"function": "select_query",
"review": {"status": "Confirmed", "severity": "Critical"},
"review_history": [{"status": "Confirmed", "changed_by": "admin", "changed_at": "2021-12-13T14:00:00Z"}],
"traces": [{"file": "/.build/execute_cmd.c", "line": 3320, "msg": "Loop starts here; 'l' may exhaust the list."}]
}
]
}
get_diff
Сравнение двух снимков. Категории располагаются под ключом markers: new_markers (появилось в новом снимке), missing_markers (исчезло из нового), modified_markers (тот же идентификатор, изменился контекст), matched_markers (совпало в обоих). Параметры project_id и branch_id не требуются — достаточно UUID снимков.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
base_snapshot_id
|
string (UUID) | да | Старый снимок |
head_snapshot_id
|
string (UUID) | нет | Новый снимок; если не указан, сравнение выполняется с предыдущим по времени |
level
|
int | нет | 0 — только статистика; 1 — статистика и идентификаторы маркеров; 2 — полные маркеры по категориям
|
checker_info
|
bool | нет | Метаданные детекторов для маркеров (только при level >= 2)
|
limit
|
int | нет | Максимальное количество маркеров на каждую категорию при level >= 2. По умолчанию — 20, значение 0 снимает ограничение. Параметр игнорируется при level < 2
|
fields
|
string[]
|
нет | См. описание у get_markers/get_warnings. Применяется к маркерам внутри категорий при level >= 2
|
Вызов (level=0):
get_diff(
base_snapshot_id="72b3df7b-c15a-4e3d-8f92-a041dc6e5b87",
head_snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9",
level=0
)
Ответ (level=0):
{
"stats": {
"context1": {"projectName": "paho.mqtt.c", "snapshotName": "Snapshot 2020-03-20 ..."},
"context2": {"projectName": "paho.mqtt.c", "snapshotName": "Snapshot 2020-03-25 ..."},
"scope": ["NEW", "MISSING", "MATCHED", "MODIFIED"],
"new": 9,
"missing": 12,
"modified": 98,
"matched": 187
}
}
Ответ (level=2) — каждая категория внутри markers оформляется и ограничивается независимо:
{
"stats": {"new": 50, "missing": 5, "modified": 0, "matched": 187},
"markers": {
"new_markers": {
"total_count": 50,
"returned_count": 20,
"truncated": true,
"markers": [
{"id": "a3f21c90-...", "warnClass": "DEREF_AFTER_NULL.LOOP", "file": "...", "line": 3327, "msg": "...", "function": "select_query", "review": null}
]
},
"missing_markers": {"total_count": 5, "returned_count": 5, "truncated": false, "markers": [...]},
"modified_markers": {"total_count": 0, "returned_count": 0, "truncated": false, "markers": []},
"matched_markers": {"total_count": 187, "returned_count": 20, "truncated": true, "markers": [...]}
}
}
Если требуется полное содержимое категории, следует увеличить limit либо запросить нужные идентификаторы отдельным вызовом get_markers. Маркеры внутри категорий проходят ту же компактную обработку, что и в get_warnings: значение fields=["*"] возвращает фиксированный набор полей коннектора, а не произвольные «сырые» поля API.
get_advanced_file_preview
Фрагмент исходного кода из снимка вокруг указанной строки. Параметры project_id и branch_id не требуются — достаточно идентификатора снимка и пути к файлу.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
snapshot_id
|
string (UUID) | да | |
file_path
|
string | да | Путь к файлу в том виде, в котором его возвращают get_markers и get_warnings
|
line
|
int | нет | Центральная строка, нумерация с 1 (по умолчанию 1)
|
before
|
int | нет | Количество строк до центральной (по умолчанию 0)
|
after
|
int | нет | Количество строк после центральной (по умолчанию 99999 — до конца файла)
|
Вызов:
get_advanced_file_preview(
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9",
file_path="/.build/execute_cmd.c",
line=3327,
before=10,
after=10
)
Ответ:
{
"line": 3327,
"content": " for (l = list; l && --reply; l = l->next)\n\t;\n return (l->word->word);\n",
"total_lines": 6082
}
get_project_groups
Получить группу проектов по имени или UUID. Группы объединяют проекты в логические блоки — например, по команде или продукту.
Параметры.
| Имя | Тип | Обязательный | Описание |
|---|---|---|---|
name_or_id
|
string | да | Имя группы или её UUID |
Вызов:
get_project_groups(name_or_id="Linux Tools")
Ответ:
{
"project_group_id": "c4f8a2d1-3b7e-4f90-82ac-1d5e8f2b6c04",
"project_group_name": "Linux Tools",
"projects": [
{"id": "91630e84-db2f-4d8c-8716-68b7fdf17a66", "name": "bash"},
{"id": "d3a17f52-...", "name": "coreutils"}
]
}
projects[].id — это project_id, который далее передаётся в get_snapshots. Группы и проекты — разные сущности; идентификатор группы и идентификатор проекта не взаимозаменяемы.
Примеры сценариев
Приведённые ниже запросы выполнены на демонстрационном стенде svacer-demo.ispras.ru с использованием OpenWebUI и модели qwen3-coder:30b. В любом другом MCP-клиенте с моделью достаточной мощности порядок вызовов будет аналогичным.
Про объём ответа
get_markers, get_warnings и get_diff(level=2) по умолчанию ограничивают объём ответа, чтобы не перегружать контекст модели:
get_markersиget_warnings— 30 маркеров по умолчанию. Если уget_warningsвключеныtraces,review_historyилиcomment_history, лимит снижается до 8, поскольку такие маркеры значительно объёмнее.get_diff(level=2)— 20 маркеров на каждую категорию внутриmarkers(new_markers/missing_markers/modified_markers/matched_markers).
В ответе присутствуют поля total_count, returned_count, truncated. При truncated: true есть два варианта действий: сузить фильтр (severity, warnClass, file) либо явно увеличить limit (значение limit=0 полностью снимает ограничение).
Поле fields определяет, какие ключи маркера возвращаются. По умолчанию применяется компактный набор id, warnClass, file, line, msg, function, review (а также traces/checkerInfo/review_history/comments, если они запрошены логическими флагами и пришли с сервера). Для полного маркера со всеми служебными ключами — fields=["*"]. Для произвольной выборки — список полей верхнего уровня, например fields=["id","warnClass"]. Поле review — объект {status, severity, action}; вложенные ключи в fields не поддерживаются, поэтому объект review запрашивается целиком.
Перечислить все проекты
Какие проекты есть в Svacer?
Цепочка вызовов:
get_projects()
Ответ модели:
В Svacer доступно 6 проектов: bash, openssl, paho.mqtt.c, coturn, zstd, darpa. У каждого — одна ветка
master.
Посмотреть снимки проекта
Какие снимки есть у paho.mqtt.c? Самый свежий когда?
Цепочка вызовов:
get_projects()— найтиproject_idиbranch_idget_snapshots(project_id=..., branch_id=...)
Ответ модели:
У paho.mqtt.c 3 снимка. Самый свежий — «Snapshot 2020-03-25 09:09:41 +0300» (297 маркеров). Предыдущий — 20 марта (306 маркеров).
Поле commit_hash может принимать значение null, если проект не сохраняет хэш коммита в custom_properties. Имена снимков произвольны: одни проекты записывают в имя дату, другие — коммит, третьи — свободный текст.
Сводка по проекту
Что в bash в последнем снимке? Сколько всего предупреждений, есть ли критические, какие топ-детекторы?
Цепочка вызовов:
get_projects()get_snapshots(project_id, branch_id)— взять последний снимокget_project_stats(project_id, branch_id, snapshot_id)
Ответ модели:
В последнем снимке bash содержится 771 предупреждение:
- Критических: 1 (Confirmed)
- Major: 1 (Won't fix)
- Остальные: 769 (Unspecified — не ревьюились)
Топ-детекторы по количеству:
PROC_USE.VULNERABLE— 337UNUSED_FUNC_RES.REWRITE.MINOR— 44UNREACHABLE_CODE— 28DEREF_AFTER_NULL.EX— 27NULL_AFTER_DEREF— 27
Unspecified в by_severity — маркеры без ручного ревью, а не «низкий приоритет». Поле by_checker не сортируется, на большом снимке оно может содержать более 100 ключей — чтобы получить именно топ-N, следует явно сформулировать запрос: «топ-5 детекторов».
Тренд по нескольким снимкам
Как у openssl менялось число предупреждений за последние пять снимков? Покажи таблицей.
Цепочка вызовов:
get_projects()get_snapshots()— взять списокget_project_stats()× 5 — по каждому из последних пяти снимков
Ответ модели:
Снимок Дата Всего 2020-04-30 05:49 30.04.2020 1252 2020-04-30 05:29 30.04.2020 1252 2020-04-30 05:08 30.04.2020 1252 2020-04-30 04:48 30.04.2020 1252 2020-04-30 04:22 30.04.2020 1252
На демонстрационном стенде указанные пять снимков openssl импортированы с интервалом в 20 минут одного дня и полностью идентичны — поэтому динамика отсутствует. На реальном проекте с историей релизов значения будут изменяться.
Найти срабатывания конкретного детектора
Где в bash срабатывает PROC_USE.VULNERABLE? Покажи список — файл, строка, что именно ругается. Достаточно первых десяти.
Цепочка вызовов:
get_projects()get_snapshots()get_markers(warnClass=["PROC_USE.VULNERABLE"])
Ответ модели:
/.build/lib/sh/tmpfile.c:160—mktemp(), race condition. Рекомендуетсяmkstemp()./.build/lib/readline/shell.c:151—getenv(), значение может быть подменено./.build/shell.c:415—getenv()вmain()./.build/lib/readline/complete.c:1516—getenv()./.build/lib/sh/eaccess.c:115—strcat(), рекомендуетсяstrncat(). …
Фильтр warnClass=["PROC_USE.VULNERABLE"] охватывает все подклассы: PROC_USE.VULNERABLE.TEMP, .GETENV, .STRCAT и т. д. — всего 341 маркер. Несколько значений в одном параметре трактуются как логическое «ИЛИ»: severity=["Critical","Major"] возвращает маркеры обеих категорий.
В ответе будет total_count: 341, returned_count: 30, truncated: true — это ожидаемое поведение. Модель видит общий объём по total_count и при необходимости сужает запрос или вызывает get_markers(..., limit=0), чтобы получить полный список.
Сравнить два снимка
Возьми два последних снимка paho.mqtt.c — что между ними изменилось? Сколько новых предупреждений, сколько починили?
Цепочка вызовов:
get_projects()get_snapshots()— два последнихget_diff(base_snapshot_id="72b3df7b-...", head_snapshot_id="b42cb563-...", level=0)
Ответ модели:
Между двумя последними снимками paho.mqtt.c:
- Новых: 12
- Удалённых: 13
- Изменённых: 99
- Совпадающих: 185
Удалено несколько больше, чем добавлено — общая картина практически не изменилась.
Категория modified — маркер, присутствующий в обоих снимках, у которого изменилось окружение (номер строки, контекст функции). Это не новая ошибка. На больших проектах рекомендуется начинать с level=0 для получения статистики, при необходимости использовать level=1 (только идентификаторы маркеров) и затем точечно вызывать get_markers с нужными фильтрами.
level=2 возвращает полные маркеры по категориям, причём каждая категория по умолчанию ограничена 20 маркерами. Категории располагаются внутри markers: new_markers, missing_markers, modified_markers, matched_markers. Структура ответа в JSON: {"markers": {"new_markers": {"total_count": N, "returned_count": ..., "truncated": ..., "markers": [...]}, ...}}. Если требуется полное содержимое категории, следует увеличить limit или выполнить отдельный вызов get_markers по нужным идентификаторам.
Разобрать конкретное предупреждение
В bash есть один подтверждённый критикал — что-то про разыменование указателя. Покажи код вокруг этого места и объясни в чём проблема.
Цепочка вызовов:
get_projects()→get_snapshots()— найти снимок bashget_markers(severity=["Critical"], review=["Confirmed"])get_advanced_file_preview(file_path="/.build/execute_cmd.c", line=3327, before=10, after=10)
Ответ модели:
Маркер
DEREF_AFTER_NULL.LOOPв функцииselect_query(), строка 3327:
for (l = list; l && --reply; l = l->next)
;
return (l->word->word); /* l может быть NULL после выхода из цикла */Если список заканчивается раньше, чем
replyобнуляется,lстанетNULLна последнемl->next, и следующийl->word->word— разыменование нулевого указателя.
file_path должен точно совпадать со значением, возвращённым маркером, включая ведущий префикс /.build/.... Это путь внутри сборочной директории Svacer, а не путь в исходном репозитории; соответствие в репозитории определяется по имени файла.
Для одиночной разметки удобно сразу запрашивать полный маркер с трассами: get_markers(..., severity=["Critical"], review=["Confirmed"], traces=True, checker_info=True). Флаги traces и checker_info указывают серверу включить соответствующие поля в ответ; в выдаче они сохраняются и при значении fields по умолчанию. Значение fields=["*"] требуется лишь в том случае, когда дополнительно нужны tool и mtid — служебные ключи, исключённые из компактного набора.