# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project goal Build an **MCP (Model Context Protocol) server** that lets an LLM drive the CAD system **КОМПАС-3D** (ASCON). The server exposes КОМПАС operations (create/open documents, build 2D geometry, 3D parts and assemblies, read/write parameters, run macros) as MCP tools. Authoritative references: - **SDK knowledge base in this repo: `docs/Kompas3D_SDK/`** — clean Markdown, one article per COM interface, with YAML tags; search it with Grep/Read (see below). Generated from the offline HTML mirror `docs/KOMPAS_SDK_ru-RU/` by `tools/build_kompas3d_sdk.py`. Prefer this over the web. For non-trivial lookups, delegate to the **`kompas-sdk-research`** skill (Sonnet subagent) to save context. - Online SDK docs: https://help.ascon.ru/KOMPAS_SDK/22/ru-RU/index.html - Local SDK install: `C:\Program Files\ASCON\KOMPAS-3D v24 Home\SDK` ## Navigating the SDK docs (`docs/Kompas3D_SDK/`) `docs/Kompas3D_SDK/` is a structured MD knowledge base distilled from the 26 000-page Help&Manual WebHelp export. One article per COM interface/topic, split into `interfaces/`, `enums/`, `structures/`, `guides/` (+ `resources/` images), each with YAML frontmatter (`type`, `api`, `domain`, `tags`, `sources`); methods/properties are `## ` headings inside the interface article. **Search it directly — do not browse the raw HTML:** - **Grep** over `docs/Kompas3D_SDK/` for an interface/method/property name or Russian keyword (method names are `## SetSideParam - …` headings, so the name lands you in the right article). - **Read** the matching `*.md` — the interface article holds all its members, `Синтаксис Automation:`/`Синтаксис COM:` blocks (in code fences), parameters, notes. - `docs/Kompas3D_SDK/index.md` — table of contents by category. Filter by frontmatter tags, e.g. `Grep "type: enum"` or `Grep "domain: \[.*3d"`. The base is gitignored (reproducible). Regenerate from the local HTML mirror with `python tools/build_kompas3d_sdk.py` — it reads the WebHelp page registry `docs/KOMPAS_SDK_ru-RU/zoom_pageinfo.js` directly (no separate index step). KsAPI pages (`ksapi_*`) are intentionally excluded from the base. **The source HTML mirror contains two parallel mirrors of the same interfaces:** - *«API интерфейсов. Версия 7»* — filenames **without** prefix (`iapplication_*`, `idocuments_*`). This is the **COM API7/API5** reference — the one this project uses; it is what lands in the MD base. - *«API интерфейсов. KsAPI»* — `ksapi_*`-prefixed filenames: the cross-platform Qt/C++ **KsAPI** flavour. Same concepts, different (non-COM) binding — excluded from the base; ignore unless explicitly working with KsAPI. ## Current state **v1 + v2 + STEP/assembly + direct B-rep edit + structural model inspection implemented and working** (full sketch→feature→inspect→STEP round-trip + move_face + describe_model validated end-to-end). Stack: **.NET 8 (`net8.0-windows`, x64), C#**, MCP via the official `ModelContextProtocol` SDK over **stdio**. **43 MCP tools, 60 tests green.** v2 added: sketch-on-face (by point and by index), revolve (boss/cut + sketch axis), fillet/chamfer (edge-by-point and by index), and Query tools `get_part_info` (МЦХ), `get_bounding_box`, `list_faces`, `list_edges`. After v2: `import_step`, `export_step` (`ConversionService`, `ConversionTools`), `list_components` (assembly traversal via `TopPart → IParts7`). `move_face` (`FaceEditService`, `EditTools`) — direct B-rep face editing. Latest: **structural model inspection** — `describe_model`, `list_features`, `list_bodies`, `list_variables`, `describe_face`, `describe_edge`, `measure` (`ModelInspectionService`, `InspectionTools`). `describe_model` is the preferred first call over `model_snapshot` (no token cost for image context; gives feature tree, bodies, variables, topology summary, МЦХ). See [`README.md`](README.md) and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md); design decisions/caveats in [`docs/OPEN_QUESTIONS.md`](docs/OPEN_QUESTIONS.md). Principle: **MCP = translating SDK capabilities into general tools** (not task-specific). On top of MCP — skill **`.claude/skills/kompas-3d/`** with a methodology (playbooks, heuristics, validated in `usecases/`). Layout: `usecases/` (in .gitignore) is the proving ground; proven techniques are promoted to the skill. Layout: `src/Kompas.Mcp.Core` (COM layer), `src/Kompas.Mcp.Host` (MCP stdio server + tools), `tests/Kompas.Mcp.Tests` (unit + integration), `libs/kompas-interop/*.dll` (vendored КОМПАС interop assemblies from SDK `Samples/Common`, referenced via `Directory.Build.props` → `KompasInteropDir`). ```powershell dotnet build -c Release # build dotnet test --filter "Category=Unit" # unit tests (no COM) dotnet test --filter "Category=Integration" # integration (requires running КОМПАС) dotnet run --project src/Kompas.Mcp.Host # start the MCP server (stdio) ``` Key implementation facts (don't relearn): - **All COM calls run on one dedicated STA thread** (`KompasDispatcher.InvokeAsync`); КОМПАС is single-instance STA. Services never touch COM off that thread. - Connection goes through **API5** (`KOMPAS.Application.5` → `KompasObject`) then `ksGetApplication7()` → `IApplication`; the API5 root is needed for `ksPart` 3D-building and `ksDocument3D` snapshots. - 3D is built via **API5 `ksPart`** (`NewEntity(o3d_sketch/o3d_bossExtrusion/o3d_bossRotated/o3d_fillet/o3d_chamfer/...)`, `ksBossExtrusionDefinition`/`ksCutExtrusionDefinition`/`ksBossRotatedDefinition`/`ksFilletDefinition`/`ksChamferDefinition`); cut-through holes use `dtBoth` + `etThroughAll`. API7 is used for app/documents. - **Face/edge selection**: `ksPart.EntityCollection(o3d_face|o3d_edge)` → `SelectByPoint(x,y,z)` (world mm) filters to objects through the point, then `GetByIndex(0)`; or by stable index from `list_faces`/`list_edges`. `ksFaceDefinition.IsPlanar/IsCylinder/...` + `GetArea(ST_MIX_MM)` classify faces. `ksEdgeDefinition.IsLineSeg/IsCircle/IsArc/...` + `GetLength()` classify/measure edges. Sketch axis = line with system style **3** (осевая). Fillet/chamfer by edge index via `fillet_edge_index`/`chamfer_edge_index` (more reliable than by-point). - **МЦХ / mass props**: use **API5 `ksPart.CalcMassInertiaProperties(ST_MIX_MM|ST_MIX_KG)`** → `ksMassInertiaParam` (`v`/`m`/`F`/`xc`/`yc`/`zc`), computed on demand. **Do NOT** use API7 `IMassInertiaParam7.Calculate()` — its `Actual` flag sticks after the first calc and won't refresh on API5 geometry changes (stale volume). Bounding box: `ksPart.GetGabarit(full:false, ...)`. - **Snapshot**: `ksDocument3D.SaveAsToRasterFormat(file, ksRasterFormatParam)` renders to a temp file (the in-memory `resultArrayBytes` stays empty when a filename is given); read bytes back. Return to MCP via `ImageContentBlock.FromBytes(bytes, mime)` — **not** `Data = bytes` (Data holds base64 bytes). Use `model_snapshot` only for visually-spatial questions; **prefer `describe_model` first**. - Logs go to **stderr** (stdout is the MCP channel). Integration tests reuse one КОМПАС via `KompasFixture`; artifacts land in gitignored `.scratch/`. - **Structural model inspection** (`ModelInspectionService`, `InspectionTools`): `describe_model` — one-call structural "passport" (bounding box + МЦХ + bodies + topology summary + feature tree + variables); preferred over snapshot. `list_features` — feature tree with params (depth/radius/legs). `list_bodies` — list solid/surface bodies with face count. `list_variables` — model variables (name/expression/value, external/info flags). `describe_face` — drill-down by index (type, area, normal, radius, edge count). `describe_edge` — drill-down by index (type, length, adjacent faces, vertices). `measure` — distance/angle between two objects (face|edge|vertex by index, unit `ST_MIX_MM`). - **Feature tree API** (don't relearn): read via API5 `ksPart.GetFeature()` → `(ksFeature).SubFeatureCollection(true,false)` → `ksFeatureCollection`. Cast `(ksFeature)part` does NOT work (RCW QI returns null) — must use `GetFeature()`. `ksFeature.type` returns only coarse `o3d_entity` and does NOT distinguish operations; precise type and params come from `ksFeature.GetObject()` → `ksEntity.GetDefinition()` and matching definition type (`ksBossExtrusionDefinition.GetSideParam`, `ksFilletDefinition.radius`, `ksChamferDefinition.GetChamferParam`, …). Node name ("Элемент выдавливания:1", "Скругление:1") is localized by КОМПАС itself. - **STEP import/export, `list_components`, `move_face`, and full inspection layer are done.** Not yet done: body split/reposition as MCP tools (SplitSolids/BodyRepositions — driveable but not yet implemented); patterns/arrays, 2D drawing, assembly building. Known caveat: boss/cut direction on a selected face depends on face-normal orientation (`forward` may need flipping — agent picks via snapshot or `describe_face` normal). See `docs/OPEN_QUESTIONS.md` → «Ревью v2». - **"STEP import without history"** detected structurally: `bodyCount > 0 && no formative features && features.Count <= bodyCount+1` (only origin + body). STEP with edits (move_face: "Смещённая плоскость", "Разрезать", "Переместить грани", "Булева операция") — that already has history. - **Topology/measure API**: `ksFaceDefinition.EdgeCollection` / `GetCylinderParam` / `GetSurface().GetNormal` + `normalOrientation`; `ksEdgeDefinition.GetAdjacentFace(bool)` / `GetVertex(bool)` → `ksVertexDefinition.GetPoint`; bodies via `ksPart.BodyCollection()` → `ksBody` (`IsSolid` / `FaceCollection`); variables via `ksPart.VariableCollection()` → `ksVariable`; measurements via `ksPart.GetMeasurer()` → `ksMeasurer` (`SetObject1/2`, `unit=ST_MIX_MM`, `Calc`, `distance`/`MinDistance`/`angle` in degrees / `IsAngleValid`). - **STEP import COM pattern** (verified): `IApplication.get_Converter((object)(int)ksConverterFromSTEP=-3)` (pass format code, not DLL path) → `IConverter.ConverterParameters(cmd)` → set `IAdditionConvertParameters.Format=ksConverterFromSTEP` → `IKompasDocument3D1.ConvertFromAdditionFormat(path, prm)`. Export: `ConvertToAdditionFormat` with format codes for AP203/AP214/AP242. Param co-classes (AdditionConvertParameters etc.) are NOT CoCreatable — only via converter factories. Assembly traversal: `IKompasDocument3D.TopPart → IPart7.Parts (IParts7)`. Extract component: `prm.NeedCreateComponentsFiles=true` (writes .m3d files next to STEP) + `IPart7.OpenSourceDocument`. - **Direct B-rep face editing (`move_face`)** (verified on top_spacer, 39.45→41.45 mm height): API7 face object retrieved via `IPart7.FindObjectsByPoint(x,y,z,true)` → cast to `KompasAPI7.IFace`; containers acquired at runtime via COM-QI: `(ISurfaceContainer)part`, `(IModelContainer)part`; `FaceMover` (SetFaces + Offset + Direction + Update) moves the face. distance>0 = outward (add material), <0 = inward. Works on both parametric and imported B-rep geometry. Full split-reposition workflow (SplitSolids/BodyRepositions) is driveable but not yet exposed as tools. ## КОМПАС-3D API architecture (the critical context) КОМПАС-3D is automated via a **COM Automation API**, Windows-only. КОМПАС-3D **must be installed and running/launchable** on the same machine — the MCP server is a COM client, not a standalone CAD engine. There are **two coexisting API generations**: | | Entry point | Namespace (C#) | Style | Use when | |---|---|---|---|---| | **API5** (legacy) | `KompasObject` | `Kompas6API5` | procedural, flat | older features, 2D primitives, bootstrapping | | **API7** (modern, preferred) | `IApplication` / `_Application` | `KompasAPI7` | OOP, interface-based | everything new — documents, 3D, parameters | Constants live in separate libraries: `Kompas6Constants`, `Kompas6Constants3D` (C#), or `ksConstants.h` / `ksConstants3D.h` (C++). ### Connection pattern (verified from `Samples/CSharp.zip`) 1. Get the КОМПАС root object by COM ProgID. **Verified on this machine (v24 Home):** `KOMPAS.Application.7` and `KOMPAS.Application.5` are registered; `KOMPASLT.*` is **absent** — the Home edition uses the regular (non-LT) ProgIDs. Resolution order: - `KOMPAS.Application.7` — direct API7 `IApplication` (preferred) - `KOMPAS.Application.5` — API5 `KompasObject`, then `ksGetApplication7()` - `KOMPASLT.Application.5` — fallback for other installations - New instance: `Activator.CreateInstance(Type.GetTypeFromProgID(progId))` - Attach to a running instance: `Marshal.GetActiveObject(progId)` 2. If you entered via API5, obtain the modern application: `IApplication appl = (IApplication)kompas.ksGetApplication7();` (via `KOMPAS.Application.7` you already hold `IApplication`). 3. Set `appl.Visible = true` to show the КОМПАС window; drive documents via API7 interfaces (`IKompasDocument2D`, `IKompasDocument3D`, …). > The SDK C# samples are mostly **КОМПАС plugin libraries** (DLLs loaded *into* КОМПАС as ActiveX, entry methods like `ExternalRunCommand`/`ExternalMenuItem`, registered via `[ComRegisterFunction]`). For an MCP server we want the **opposite direction**: a standalone *external automation client* that connects out-of-process via the ProgID pattern above. Read the samples for API usage, not for the plugin packaging/registration boilerplate. ## SDK layout (read-only reference, not part of this repo) Under `C:\Program Files\ASCON\KOMPAS-3D v24 Home\SDK`: - `lib\*.tlb` — COM type libraries to reference / generate interop from: `kAPI5.tlb`, `kAPI7.tlb`, `ksConstants.tlb`, `ksConstants3D.tlb`, `kAPI2D5COM.tlb`, `kAPI3D5COM.tlb`. - `lib64\` — 64-bit import libs (`kAPI7.lib`, `kAPI5.lib`, …) and `.a` for C++/Builder. - `Include\` — C++/Pascal headers (`Ks_TLB.h`, `kAPI2D5COM.h`, `LDefin2D.pas`, …). - `KsAPI\` — the **KsAPI** (Qt/C++ cross-platform flavour): `Include\KsAPI.h`, `ksConstants*.h`, `Lib64\ksAPI.lib`, plus `Help\С чего начать.pdf` and a Linux/Debian 12 build guide. - `Samples\` — zipped examples per language: `CSharp.zip`, `C++.zip`, `Pascal.zip`, `Basic.zip`. Inside `CSharp.zip`, the `Step1`…`Step12` and `Step2_API7_2D` / `Step2_API7_3D` projects are the progressive tutorial; `Gayka`, `SlideWrk`, `EventsAuto` are larger feature demos. - `Help\KOMPAS_SDK_ru-RU.zip` and `KsAPI\Help\KsAPI_Help.zip` — offline copy of the docs. To inspect a sample without unpacking the whole archive: `unzip -p "\Samples\CSharp.zip" "Automation/Step2_API7_3D/Step2_API7_3D.cs"`. Note the `.cs` sample sources are **Windows-1251 encoded** (Cyrillic comments appear garbled in UTF-8 tools). ## Conventions / gotchas - **Windows-only & 64-bit**: target x64 to match the installed КОМПАС; mixing bitness breaks COM activation. КОМПАС v24 Home is the installed edition — some full-edition API features may be unavailable. - **Encoding**: SDK source samples are CP1251. New project files should be UTF-8. - **COM lifetime**: release COM objects (`Marshal.ReleaseComObject`) / scope them; a leaked reference keeps the КОМПАС process alive. - **API choice**: prefer API7 for new tool implementations; drop to API5 only for things API7 doesn't expose.