---
name: kompas-mcp-dev
description: Внутренняя методика доработки самого MCP-сервера КОМПАС-3D в этом репозитории — два слоя (инструмент/методика), полигон usecases/, продуктизация приёма в общий инструмент, делегирование поиска по справке SDK субагенту kompas-sdk-research. Используй, когда задача — доработать сервер (новый инструмент, тесты, плагин, CI), а не построить деталь. Для построения деталей — навык kompas-3d.
---

# kompas-mcp-dev — доработка MCP-сервера КОМПАС-3D

Область: код сервера, тесты, упаковка в плагин. Построение деталей — навык `kompas-3d`.
Архитектура, принципы и бэклог — в `CLAUDE.md` (каталога `docs/` в репозитории нет и заводить его
не нужно). Тяжёлые справочники вынесены сюда, чтобы не висеть в контексте каждой сессии:

- **`reference/com-implementation-facts.md`** — проверенные COM-цепочки: загрузка interop, STA-диспетчер,
  построение через API5 `ksPart`, выбор граней/рёбер, МЦХ, снимки, дерево построения, переменные,
  STEP, прямое редактирование B-rep, формообразующие, массивы и зеркало, отверстия, сборки, чертежи,
  примитивы эскиза. **Читай перед правкой COM-слоя** и дописывай туда каждую новую проверенную цепочку.
- **`reference/plugin-and-release.md`** — устройство `plugin/`, доставка сервера, ветка `dist`, релизный
  workflow, подводные камни CI, обновление RAG-базы справки SDK.

## Два слоя (важно не смешивать)

- **MCP-сервер** (`src/Kompas.Mcp.Host`) — *инструмент*. Он **транслирует возможности COM API/SDK
  КОМПАС** в MCP-инструменты. Инструменты делаются **общими** (по возможностям SDK), а не под
  конкретную задачу. Расширяя MCP, добавляй универсальную операцию (`import_step`, `list_components`,
  «переместить грань», «рассечь тело»), а не «сделать вот эту деталь».
- **Навык `kompas-3d`** — *методика*. Как из общих инструментов собрать решение: порядок шагов,
  выбор геометрии, проверка результата, обход подводных камней.

Итог: **MCP = чем делать, навык = как делать.** Новый приём сначала обкатывается кейсом, потом
обобщается: инструмент → в MCP, метод → в навык `kompas-3d`.

## Правила формы инструмента (каталог оптимизирован под агента)

Каталог сознательно сжат с 84 инструментов до 56 — экономится не только контекст, но и число
вызовов, а каждый лишний вызов это лишний шанс сбиться. Держи форму:

- **Инструмент = смысл операции, вариант = параметр.** `extrude(mode=boss|cut)`,
  `hole(type=simple|counterbore|…)`, `pattern(kind=linear|circular)`. Отдельный инструмент заводи,
  только если у варианта своя схема параметров (`sweep`, `loft`, `rib` — законно отдельные).
- **Объект выбирается индексом ИЛИ точкой одним инструментом.** Не плоди `*_index`-двойники:
  `faceIndex`/`edgeIndices` из `list_faces`/`list_edges` — основной путь, `x,y,z` — запасной.
  У операций API7, которые умеют только точку, индекс переводится в точку через
  `ModelInspectionService.FaceCenterPointAsync` (середина параметрической области грани).
- **Пакет вместо серии вызовов.** Списочный параметр (`entities[]`, `edgeIndices[]`, `featureIds[]`)
  выполняется за ОДИН заход на STA-поток: см. `PartModeler.AddEntitiesAsync` и синхронные ядра
  примитивов рядом с ним. Ошибка обязана называть позицию в пакете.
- **Схема не запрещает неверную комбинацию полей — это делает валидация.** Сообщение называет
  `type=…` и недостающий параметр (`SketchEntityInputs`, `FeatureTools.Required`), иначе агент
  тратит лишний ход на догадки.
- **Текст исключения доходит до клиента только через фильтр.** MCP-SDK показывает сообщение лишь у
  `McpException`, остальное подменяет на «An error occurred invoking '&lt;tool&gt;'» — то есть без
  фильтра ВСЕ наши подсказки в исключениях пропадают. В `Program.cs` стоит
  `WithRequestFilters(... AddCallToolFilter ...)`, который отдаёт `CallToolResult{IsError=true}` с
  текстом от `ToolErrorText.Describe` (Core/Startup: разворачивает `AggregateException`, склеивает
  до трёх вложенных причин через «←»). Пишешь новое сообщение об ошибке — помни, что до агента
  дойдёт именно оно.
- **У мутирующей операции есть `name` — имя узла в дереве построения.** Прокидывается до создания
  объекта (`PartModeler.NewEntity` для API5, `IModelObject.Name` до `Update()` для API7-путей),
  нормализуется в `FeatureName`. Заводишь новую операцию — добавь параметр сразу: дерево из
  «Эскиз:1…Эскиз:9» нечитаемо ни человеку, ни агенту, вернувшемуся к модели.
- **Ответ операции несёт то, что нужно для СЛЕДУЮЩЕГО шага.** Надпись отдаёт габарит глифов
  (`TextMetrics`), а не только ширину ячейки; примитив проверяется по объёму. Иначе агент строит
  вслепую и пересобирает документ ради замера — цикл, который стоил регресс-прогону четырёх кругов.
- **Мутирующая операция сама дописывает итог проверки** через `AutoValidation.AnnotateAsync`
  (`Core/Validation`). Переключатель — `set_auto_validate` и `KOMPAS_MCP_AUTOVALIDATE`; проверка
  никогда не превращает удачную операцию в ошибку (сбой самой проверки уходит в примечание).

## Продуктизация приёма

> Если нужного инструмента ещё нет — не хардкодь обход под кейс. Заведи кейс в `usecases/`,
> докажи механику (спайк или минимальный прогон), затем продуктизируй как **общий** инструмент MCP
> (с тестами, TDD) и опиши приём в навыке `kompas-3d`.

**Спайк — только чтобы проверить теорию; результат выдаётся инструментами MCP.** Отдельный
dotnet-проект в `usecases/<кейс>/` (ссылка на `Kompas.Mcp.Core`, `KompasInteropLoader.Install()`
первой строкой) — законный способ измерить метрику, проверить COM-цепочку или опровергнуть
утверждение навыка. Но **итоговая деталь/чертёж всегда строится вызовами MCP-инструментов**:
раннер обходит ровно тот слой, который мы и проверяем (схемы инструментов, разбор входа, форму
ответа, авто-валидацию), поэтому «построено раннером» не считается за проверку сервера. Если
инструментов не хватает — это и есть находка кейса: доработать сервер, а не достроить в обход.
Проверочный проект после кейса удаляй, полученные числа переноси в `plan.md` кейса и в навык.

Порядок для нового инструмента:

1. **Сигнатуры и константы** — через субагента `kompas-sdk-research` (см. ниже), затем перепроверка
   рефлексией по `libs/kompas-interop/*.dll`: справка врёт (напр. `IRadialDimension.NominalValue`
   отдаёт радиус, а не диаметр; `direction` у `ksInclineDefinition` инвертирован).
2. **Спайк вживую** — минимальный прогон на запущенном КОМПАС; COM-цепочка считается верной только
   после этого.
3. **Сервис в `src/Kompas.Mcp.Core/<домен>/`** + валидация параметров отдельным статическим классом
   (`*Validation`, `SketchGeometry`) — она покрывается unit-тестами без COM.
4. **Инструмент в `src/Kompas.Mcp.Host/Tools/<Группа>Tools.cs`** — по файлу на группу.
5. **Тесты**: unit на валидацию/маппинг перечислений, integration на реальную геометрию
   (класс наследует `IntegrationTestBase`, артефакты — в `.scratch/`).
6. **Документация**: каталог инструментов в `README.md` (+ счётчик в заголовке), проверенная
   COM-цепочка и подводные камни — в `reference/com-implementation-facts.md` (здесь же, в навыке)
   и в память (`kompas-*-api*.md`). Правь эти файлы сам — субагента для документации больше нет.

## Проверка

```powershell
dotnet build -c Release
dotnet test --filter "Category=Unit"            # без COM
dotnet test --filter "Category=Integration"     # нужен запущенный КОМПАС
pwsh -NoProfile -File tools/tests/run-ps-tests.ps1   # PowerShell плагина (Pester)
```

CI гоняет только `Category=Unit&Requires!=Windows` на Linux-раннере — integration там не запустится
никогда. Формат решения `.slnx` понимает лишь SDK 9+, поэтому в CI проекты указаны путями.

## Делегирование

**Прогон задачи целиком** — субагент **`cad-engineer`** (`.claude/agents/`, наследует модель; из
инструментов — только навыки, чтение и MCP `kompas`, ничего пишущего). Отладочный цикл навыка и
каталога: правишь `plugin/skills/*` или сервер → натравливаешь субагента на ту же задачу с нуля →
читаешь его протокол (вызовы, затыки, цитаты из навыка, чего не хватило в инструментах). Смысл именно
в чистом контексте: если задача решается только с твоими подсказками по ходу — значит, недоработан
навык, а не субагент. Правок он не делает принципиально, поэтому нехватка инструмента возвращается
находкой, а не самодельным обходом. В плагин не входит.

**Поиск по справке SDK** (сигнатуры, константы, перечисления, цепочки COM-вызовов) — субагент
**`kompas-sdk-research`** (Haiku, read-only). Справка живёт **не в репозитории**, а в RAG-базе
`kompas-sdk` (MCP-сервер, репозиторий `kompas-sdk-docs`) — грепать по проекту бесполезно, доступ к
базе есть только у субагента. Ошибка стоит дёшево: ответ всё равно перепроверяется рефлексией по
interop-сборкам.

## Ориентиры в репозитории

- Инструменты и реализация: `src/Kompas.Mcp.Host/Tools/*`, `src/Kompas.Mcp.Core/*`.
- Кейсы (полигон подходов): `usecases/` — локальный, в `.gitignore`, в плагин не входит.
- Публикуемые навыки плагина: `plugin/skills/` (`kompas-3d`, `kompas-fdm-design`) — источник истины;
  `.claude/skills/<навык>` это junction'ы, раскладку делает `tools/sync-agent-assets.ps1`.
  Перед `git checkout` на ревизию без `plugin/skills` — сначала `-Remove`, иначе checkout ломается
  на полпути (подробности в `CLAUDE.md`).
- Плагин и доставка сервера: `plugin/` (манифест, `server.lock.json`, лаунчер) — версия в
  `plugin.json` и `server.lock.json` должна совпадать, это проверяет CI.
- Память: `kompas-step-and-assembly-api`, `kompas-drawing-api7`, `kompas-hole-api7`,
  `kompas-formative-features-api5`, `kompas-pattern-mirror-api5`, `kompas-variables-api5`.
