Help:13-alpha MCP: Difference between revisions
Mitrofanov (talk | contribs) No edit summary |
Mitrofanov (talk | contribs) |
||
| Line 188: | Line 188: | ||
== Инструменты == | == Инструменты == | ||
Справочник по 8 инструментам Svacer MCP. Типичный порядок вызовов: <code>get_projects</code> → <code>get_snapshots</code> → любой из аналитических инструментов. | |||
{| class="wikitable" | |||
!Инструмент | |||
!Назначение | |||
|- | |||
|<code>get_projects</code> | |||
|Список проектов с ветками — точка входа | |||
|- | |||
|<code>get_snapshots</code> | |||
|Снимки конкретной ветки, от нового к старому | |||
|- | |||
|<code>get_project_stats</code> | |||
|Агрегированные метрики снимка: severity / review / checker | |||
|- | |||
|<code>get_markers</code> | |||
|Компактный список маркеров с серверной фильтрацией | |||
|- | |||
|<code>get_warnings</code> | |||
|Полные предупреждения с трассами и историей ревью | |||
|- | |||
|<code>get_diff</code> | |||
|Сравнение двух снимков: new / missing / modified / matched | |||
|- | |||
|<code>get_advanced_file_preview</code> | |||
|Фрагмент исходного кода вокруг строки | |||
|- | |||
|<code>get_project_groups</code> | |||
|Группа проектов по имени или UUID | |||
|} | |||
=== get_projects === | |||
Список всех проектов с ветками. Точка входа: с этого вызова начинается практически любой сценарий — он возвращает <code>project_id</code> и <code>branch_id</code>, необходимые для последующих запросов. | |||
'''Параметров нет.''' | |||
'''Вызов:''' | |||
<code>get_projects()</code> | |||
'''Ответ:''' | |||
<code>[ | |||
{ | |||
"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" | |||
} | |||
] | |||
} | |||
]</code> | |||
---- | |||
=== get_snapshots === | |||
Список снимков для конкретной ветки проекта, от нового к старому. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>project_id</code> | |||
|string (UUID) | |||
|да | |||
|Из <code>get_projects</code> | |||
|- | |||
|<code>branch_id</code> | |||
|string (UUID) | |||
|да | |||
|Из <code>get_projects</code> | |||
|- | |||
|<code>name_filter</code> | |||
|string | |||
|нет | |||
|Подстрока или regex для фильтра по имени снимка | |||
|} | |||
'''Вызов:''' | |||
<code>get_snapshots( | |||
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66", | |||
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4" | |||
)</code> | |||
'''Ответ:''' | |||
<code>[ | |||
{ | |||
"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": "<nowiki>https://svacer-demo.ispras.ru/</nowiki>..." | |||
} | |||
]</code> | |||
---- | |||
=== get_project_stats === | |||
Агрегированные метрики по снимку: общее количество предупреждений, распределение по критичности, по статусу ревью, по детекторам. Наиболее быстрый способ получить общую картину по проекту. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>project_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>branch_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>snapshot_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|} | |||
'''Вызов:''' | |||
<code>get_project_stats( | |||
project_id="91630e84-db2f-4d8c-8716-68b7fdf17a66", | |||
branch_id="77f66b9e-0453-4ae9-a187-88950b4c4bc4", | |||
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9" | |||
)</code> | |||
'''Ответ:''' | |||
<code>{ | |||
"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 | |||
} | |||
}</code> | |||
---- | |||
=== get_markers === | |||
Компактный список маркеров с серверной фильтрацией. Основной инструмент для перечисления и обзора: его следует предпочитать <code>get_warnings</code>, когда не требуются развёрнутые поля — трассы и история ревью. | |||
По умолчанию ответ ограничен 30 маркерами и содержит компактный набор полей. Подробнее об ограничении объёма см. раздел Про объём ответа в сценариях. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>project_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>branch_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>snapshot_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>severity</code> | |||
|<code>string[]</code> | |||
|нет | |||
|<code>Critical</code>, <code>Major</code>, <code>Minor</code>, <code>Unspecified</code>. Фильтр по <code>review.severity</code>, применяется на стороне коннектора | |||
|- | |||
|<code>review</code> | |||
|<code>string[]</code> | |||
|нет | |||
|<code>Confirmed</code>, <code>Won't fix</code>, <code>False Positive</code>, <code>Unclear</code> | |||
|- | |||
|<code>warnClass</code> | |||
|<code>string[]</code> | |||
|нет | |||
|Идентификатор детектора (<code>DEREF_AFTER_NULL</code>, …) | |||
|- | |||
|<code>file</code> | |||
|<code>string[]</code> | |||
|нет | |||
|Подстрока пути к файлу | |||
|- | |||
|<code>traces</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить трассы маркеров | |||
|- | |||
|<code>checker_info</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить метаданные детектора (CWE, описание) | |||
|- | |||
|<code>review_history</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить историю изменений ревью | |||
|- | |||
|<code>comment_history</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить комментарии к маркеру | |||
|- | |||
|<code>custom_filter</code> | |||
|string | |||
|нет | |||
|Имя или идентификатор сохранённого фильтра из веб-интерфейса Svacer | |||
|- | |||
|<code>limit</code> | |||
|int | |||
|нет | |||
|Максимальное количество маркеров в ответе (по умолчанию <code>30</code>). Значение <code>0</code> снимает ограничение | |||
|- | |||
|<code>fields</code> | |||
|<code>string[]</code> | |||
|нет | |||
|Список разрешённых полей маркера верхнего уровня. По умолчанию — компактный набор <code>id, warnClass, file, line, msg, function, review</code>. Значение <code>["*"]</code> возвращает все поля коннектора (<code>id, warnClass, file, line, msg, tool, function, mtid, review</code>, а также <code>traces</code>/<code>checkerInfo</code>/<code>review_history</code>/<code>comments</code>, если они запрошены). Допустим и произвольный список — например, <code>["id","warnClass"]</code> | |||
|} | |||
'''Вызов:''' | |||
<code>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"] | |||
)</code> | |||
'''Ответ:''' | |||
<code>{ | |||
"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 | |||
} | |||
] | |||
}</code> | |||
<code>total_count</code> отражает количество маркеров, удовлетворяющих фильтру до применения ограничения; <code>returned_count</code> — количество маркеров, фактически содержащихся в <code>markers</code>. При <code>truncated: true</code> следует либо сузить фильтры (<code>severity</code>, <code>warnClass</code>, <code>file</code>), либо передать <code>limit=0</code> для получения полного списка. Поля <code>tool</code> и <code>mtid</code> возвращаются только при <code>fields=["*"]</code>. | |||
---- | |||
=== get_warnings === | |||
Полные предупреждения с детальной разметкой. Ответ значительно объёмнее, чем у <code>get_markers</code>, поэтому инструмент следует использовать только тогда, когда нужны поля, отсутствующие в компактной форме: <code>traces</code>, <code>review_history</code>, <code>checker_info</code>, <code>comment_history</code>. | |||
Лимит по умолчанию — 30; при включённых <code>traces</code>, <code>review_history</code> или <code>comment_history</code> он автоматически снижается до 8, поскольку такие предупреждения существенно объёмнее. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>project_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>branch_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>snapshot_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>severity</code> | |||
|<code>string[]</code> | |||
|нет | |||
|<code>Critical</code>, <code>Major</code>, <code>Minor</code>, <code>Unspecified</code>. Фильтр по <code>review.severity</code>, применяется на стороне коннектора | |||
|- | |||
|<code>review</code> | |||
|<code>string[]</code> | |||
|нет | |||
|<code>Confirmed</code>, <code>Won't fix</code>, <code>False Positive</code>, <code>Unclear</code> | |||
|- | |||
|<code>warnClass</code> | |||
|<code>string[]</code> | |||
|нет | |||
|Идентификатор детектора | |||
|- | |||
|<code>file</code> | |||
|<code>string[]</code> | |||
|нет | |||
|Подстрока пути к файлу | |||
|- | |||
|<code>traces</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить трассы. Активирует режим расширенных полей (лимит по умолчанию — 8) | |||
|- | |||
|<code>checker_info</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить метаданные детектора (CWE, описание) | |||
|- | |||
|<code>review_history</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить историю ревью. Режим расширенных полей | |||
|- | |||
|<code>comment_history</code> | |||
|<code>bool</code> | |||
|нет | |||
|Включить комментарии. Режим расширенных полей | |||
|- | |||
|<code>custom_filter</code> | |||
|string | |||
|нет | |||
|Имя или идентификатор сохранённого фильтра | |||
|- | |||
|<code>limit</code> | |||
|int | |||
|нет | |||
|Максимальное количество предупреждений в ответе. По умолчанию — <code>30</code>, в режиме расширенных полей — <code>8</code>. Значение <code>0</code> снимает ограничение. Явно заданное <code>limit</code> отменяет автоматическое снижение | |||
|- | |||
|<code>fields</code> | |||
|<code>string[]</code> | |||
|нет | |||
|См. описание у <code>get_markers</code> | |||
|} | |||
'''Вызов:''' | |||
<code>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 | |||
)</code> | |||
'''Ответ:''' | |||
<code>{ | |||
"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."}] | |||
} | |||
] | |||
}</code> | |||
---- | |||
=== get_diff === | |||
Сравнение двух снимков. Категории располагаются под ключом <code>markers</code>: <code>new_markers</code> (появилось в новом снимке), <code>missing_markers</code> (исчезло из нового), <code>modified_markers</code> (тот же идентификатор, изменился контекст), <code>matched_markers</code> (совпало в обоих). Параметры <code>project_id</code> и <code>branch_id</code> не требуются — достаточно UUID снимков. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>base_snapshot_id</code> | |||
|string (UUID) | |||
|да | |||
|Старый снимок | |||
|- | |||
|<code>head_snapshot_id</code> | |||
|string (UUID) | |||
|нет | |||
|Новый снимок; если не указан, сравнение выполняется с предыдущим по времени | |||
|- | |||
|<code>level</code> | |||
|int | |||
|нет | |||
|<code>0</code> — только статистика; <code>1</code> — статистика и идентификаторы маркеров; <code>2</code> — полные маркеры по категориям | |||
|- | |||
|<code>checker_info</code> | |||
|bool | |||
|нет | |||
|Метаданные детекторов для маркеров (только при <code>level >= 2</code>) | |||
|- | |||
|<code>limit</code> | |||
|int | |||
|нет | |||
|Максимальное количество маркеров '''на каждую категорию''' при <code>level >= 2</code>. По умолчанию — <code>20</code>, значение <code>0</code> снимает ограничение. Параметр игнорируется при <code>level < 2</code> | |||
|- | |||
|<code>fields</code> | |||
|<code>string[]</code> | |||
|нет | |||
|См. описание у <code>get_markers</code>/<code>get_warnings</code>. Применяется к маркерам внутри категорий при <code>level >= 2</code> | |||
|} | |||
'''Вызов (<code>level=0</code>):''' | |||
<code>get_diff( | |||
base_snapshot_id="72b3df7b-c15a-4e3d-8f92-a041dc6e5b87", | |||
head_snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9", | |||
level=0 | |||
)</code> | |||
'''Ответ (<code>level=0</code>):''' | |||
<code>{ | |||
"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 | |||
} | |||
}</code> | |||
'''Ответ (<code>level=2</code>)''' — каждая категория внутри <code>markers</code> оформляется и ограничивается независимо: | |||
<code>{ | |||
"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": [...]} | |||
} | |||
}</code> | |||
Если требуется полное содержимое категории, следует увеличить <code>limit</code> либо запросить нужные идентификаторы отдельным вызовом <code>get_markers</code>. Маркеры внутри категорий проходят ту же компактную обработку, что и в <code>get_warnings</code>: значение <code>fields=["*"]</code> возвращает фиксированный набор полей коннектора, а не произвольные «сырые» поля API. | |||
---- | |||
=== get_advanced_file_preview === | |||
Фрагмент исходного кода из снимка вокруг указанной строки. Параметры <code>project_id</code> и <code>branch_id</code> не требуются — достаточно идентификатора снимка и пути к файлу. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>snapshot_id</code> | |||
|string (UUID) | |||
|да | |||
| | |||
|- | |||
|<code>file_path</code> | |||
|string | |||
|да | |||
|Путь к файлу в том виде, в котором его возвращают <code>get_markers</code> и <code>get_warnings</code> | |||
|- | |||
|<code>line</code> | |||
|int | |||
|нет | |||
|Центральная строка, нумерация с 1 (по умолчанию <code>1</code>) | |||
|- | |||
|<code>before</code> | |||
|int | |||
|нет | |||
|Количество строк до центральной (по умолчанию <code>0</code>) | |||
|- | |||
|<code>after</code> | |||
|int | |||
|нет | |||
|Количество строк после центральной (по умолчанию <code>99999</code> — до конца файла) | |||
|} | |||
'''Вызов:''' | |||
<code>get_advanced_file_preview( | |||
snapshot_id="b42cb563-86f4-4f96-900a-7782163327c9", | |||
file_path="/.build/execute_cmd.c", | |||
line=3327, | |||
before=10, | |||
after=10 | |||
)</code> | |||
'''Ответ:''' | |||
<code>{ | |||
"line": 3327, | |||
"content": " for (l = list; l && --reply; l = l->next)\n\t;\n return (l->word->word);\n", | |||
"total_lines": 6082 | |||
}</code> | |||
---- | |||
=== get_project_groups === | |||
Получить группу проектов по имени или UUID. Группы объединяют проекты в логические блоки — например, по команде или продукту. | |||
'''Параметры.''' | |||
{| class="wikitable" | |||
!Имя | |||
!Тип | |||
!Обязательный | |||
!Описание | |||
|- | |||
|<code>name_or_id</code> | |||
|string | |||
|да | |||
|Имя группы или её UUID | |||
|} | |||
'''Вызов:''' | |||
<code>get_project_groups(name_or_id="Linux Tools")</code> | |||
'''Ответ:''' | |||
<code>{ | |||
"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"} | |||
] | |||
}</code> | |||
<code>projects[].id</code> — это <code>project_id</code>, который далее передаётся в <code>get_snapshots</code>. Группы и проекты — разные сущности; идентификатор группы и идентификатор проекта не взаимозаменяемы. | |||
== Примеры сценариев == | == Примеры сценариев == | ||
Revision as of 10:54, 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. Группы и проекты — разные сущности; идентификатор группы и идентификатор проекта не взаимозаменяемы.