Files
mikhail 5d51b9e1af docs: выноска — TODO, README, ARCHITECTURE, OPEN_QUESTIONS, presentation, CLAUDE.md
Инкремент 9. 83 инструмента, 331 тест. + заметка о ревью реализации в спеке
(Codex + pi/glm-5.1 + pi/kimi-k2.6).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 00:33:33 +03:00

27 KiB
Raw Permalink Blame History

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). Committed to the repo (canonical), distilled from the КОМПАС SDK help. Prefer this over the web. For non-trivial lookups, dispatch the kompas-sdk-research subagent (Haiku) 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 committed to the repo (canonical) — no regeneration step. It covers the COM API7/API5 reference this project uses (interfaces named iapplication_*, idocuments_*, …). The cross-platform Qt/C++ KsAPI flavour (ksapi_*, non-COM binding) is intentionally excluded from the base — ignore unless explicitly working with KsAPI.

Current state

Status: v1 + v2 + STEP/assembly + direct B-rep edit + structural inspection + 2D drawings — 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. 83 MCP tools, 331 tests green (201 unit + 130 integration).

Where to look (single source of truth — do not duplicate these lists here):

  • Full tool catalog (by group, all 83) → README.md §«Инструменты».
  • Roadmap / what's already donedocs/ARCHITECTURE.md §10.
  • Backlog / what's leftdocs/TODO.md (canonical; top of «2D-ЧЕРТЁЖ» = next priority. Associative diametral/radial→circle binding (associate flag), sheet format (drawing_set_sheet_format), leaders (drawing_add_leader) done — next: bases, tolerances, arc/angular/rough binding; plus extra mate types, package E continuation).
  • Design decisions / caveatsdocs/OPEN_QUESTIONS.md. Known caveat («Ревью v2»): boss/cut direction on a selected face depends on face-normal orientation — forward may need flipping; the agent picks via snapshot or describe_face normal.
  • Verified COM call-chains & gotchas → «Key implementation facts» below + memory files (kompas-*-api*.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. A separate skill .claude/skills/kompas-fdm-design/ is a DFM methodology layer for FDM/FFF 3D-printing (overhang rules, wall thickness, teardrop holes, fits/clearances, orientation for strength, elephant foot, bosses/inserts/snap-fits) with a lightweight geometry audit using existing inspection tools; it works on top of kompas-3d (the build layer) and exports via export_step — no slicer integration.

Delegation subagents (.claude/agents/, dispatched via the Agent tool to keep heavy work off Opus's context — system prompt lives in the agent definition, so pass only the variable part as the prompt):

  • kompas-sdk-research (model: Haiku, read-only — Glob/Grep/Read): finds an interface/method/enum/constant signature in the docs/Kompas3D_SDK/ MD knowledge base and returns a compressed summary. Dispatch it for any non-trivial SDK lookup instead of grepping the help yourself; a wrong answer is cheap — Opus re-verifies against libs/kompas-interop/*.dll by reflection.
  • docs-maintainer (model: Sonnet, Read/Edit/Write/Glob/Grep): syncs README.md/CLAUDE.md/docs/ARCHITECTURE.md/docs/OPEN_QUESTIONS.md/docs/presentation.html with code changes from a change summary you provide. Dispatch it for doc updates instead of editing docs by hand. (Both were skills before — converted to native subagents; the model split reflects task type: bounded retrieval → Haiku, judgement-heavy editing → Sonnet.)

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.propsKompasInteropDir).

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: API5 (KOMPAS.Application.5KompasObject) then ksGetApplication7()IApplication; the API5 root is needed for ksPart 3D-building and ksDocument3D snapshots. API7 is used for app/documents, holes, assemblies, drawings, direct B-rep edit.
  • 3D via API5 ksPart: NewEntity(o3d_*) + matching definition; always check entity.Create() return. Entity codes: o3d_sketch/o3d_bossExtrusion/o3d_cutExtrusion/o3d_bossRotated/o3d_fillet/o3d_chamfer, o3d_shellOperation=43, o3d_ribOperation=44, o3d_baseEvolution=45 (sweep), o3d_baseLoft=30, o3d_planeOffset=14, o3d_meshCopy=35 (linear pattern), o3d_circularCopy=36, o3d_mirrorOperation=48, o3d_mirrorAllOperation=49, o3d_incline=42 (draft), axes o3d_axisOX/OY/OZ=71/72/73. Definitions: ksBossExtrusionDefinition/ksCutExtrusionDefinition/ksBossRotatedDefinition/ksFilletDefinition/ksChamferDefinition/ksShellDefinition/ksRibDefinition/ksBaseEvolutionDefinition/ksBaseLoftDefinition/ksPlaneOffsetDefinition/ksMeshCopyDefinition/ksCircularCopyDefinition/ksMirrorCopyDefinition/ksMirrorCopyAllDefinition/ksInclineDefinition. Cut-through holes use dtBoth + etThroughAll.
  • Face/edge selection: ksPart.EntityCollection(o3d_face|o3d_edge)SelectByPoint(x,y,z) (world mm) → GetByIndex(0); or by stable index from list_faces/list_edges (helpers SelectFaceByIndex/SelectEdgeByIndex, range-checked before mutation; by-index more reliable than by-point). Classify: ksFaceDefinition.IsPlanar/IsCylinder/… + GetArea(ST_MIX_MM); ksEdgeDefinition.IsLineSeg/IsCircle/IsArc/… + GetLength(). Sketch axis = line with system style 3 (осевая).
  • МЦХ / 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 (structural «passport» — bbox + МЦХ + bodies + topology + feature tree + variables, no image token cost).
  • Logs go to stderr (stdout is the MCP channel). Integration tests reuse one КОМПАС via KompasFixture; artifacts land in gitignored .scratch/. All integration test classes inherit IntegrationTestBase (IAsyncLifetime) → DocumentService.CloseAllAsync after each test (prevents tab accumulation).
  • Feature tree API: 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() + the matching definition (ksBossExtrusionDefinition.GetSideParam, ksFilletDefinition.radius, ksChamferDefinition.GetChamferParam, …). Node names ("Элемент выдавливания:1") are localized by КОМПАС. Features registered by id in _features support patterns/mirror; helpers RequireSketch/RequireFeature.
  • Variables (API5): create/read via ksPart.GetFeature().VariableCollection (property on root ksFeature) — NOT ksPart.VariableCollection() (returns external-only). Expression is the leading field; value is derived. Apply via ksPart.RebuildModel() (check return); after rebuild the RCW variable is stale → re-read via a fresh collection (ReadValueFresh). Dependents recalculate automatically; deletion fails if dependents exist (RemoveVariable returns FALSE). Geometry limitation: variables drive geometry only in a parametric model (sketch dims linked to variable names); our sketches use literal coords → set_variable stores/computes the value but does NOT move geometry. Parametric sketches unavailable via COM (ksCDimWithVariable not constructible from external automation — see docs/superpowers/specs/2026-05-27-parametric-sketch-findings.md; do not retry without new info).
  • Topology / measure API: ksFaceDefinition.EdgeCollection / GetCylinderParam / GetSurface().GetNormal + normalOrientation; ksEdgeDefinition.GetAdjacentFace(bool) / GetVertex(bool)ksVertexDefinition.GetPoint; bodies via ksPart.BodyCollection()ksBody (IsSolid / FaceCollection); measurements via ksPart.GetMeasurer()ksMeasurer (SetObject1/2, unit=ST_MIX_MM, Calc, distance/MinDistance/angle in degrees / IsAngleValid).
  • "STEP import without history" detected structurally: bodyCount > 0 && no formative features && features.Count <= bodyCount+1 (only origin + body). STEP with edits ("Смещённая плоскость" / "Разрезать" / "Переместить грани" / "Булева операция") already has history.
  • STEP import/export COM pattern (verified): IApplication.get_Converter((object)(int)ksConverterFromSTEP=-3) (pass format code, not DLL path) → IConverter.ConverterParameters(cmd)IAdditionConvertParameters.Format=ksConverterFromSTEPIKompasDocument3D1.ConvertFromAdditionFormat(path, prm). Export: ConvertToAdditionFormat (format codes AP203/AP214/AP242). Param co-classes (AdditionConvertParameters etc.) are NOT CoCreatable — only via converter factories. Assembly traversal (list_components): 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): API7 face via IPart7.FindObjectsByPoint(x,y,z,true) → cast to KompasAPI7.IFace; containers via runtime COM-QI (ISurfaceContainer)part, (IModelContainer)part; FaceMover (SetFaces + Offset + Direction + Update) moves the face. distance>0 = outward (add material), <0 = inward. Works on parametric and imported B-rep. Full split-reposition workflow (SplitSolids/BodyRepositions) is driveable; only partly exposed as tools (split_solid_by_plane, move_body, boolean_union).
  • Forming ops (API5 definitions):
    • shell (ksShellDefinition, o3d_shellOperation=43): thickness + thinType (bool, = !outward) + FaceArray() (open faces ≥1 by index). Transient RCWs intentionally not released (consistent with Fillet/Chamfer).
    • rib (ksRibDefinition, =44): SetSketch(sketch)index=0, angle, side (left|right|up|down → 0/1/2/3 via SketchGeometry.RibSide()); SetThinParam(dtBoth, t/2, t/2) if symmetric, else (dtNormal, t, 0). Empirical: the rib contour must float in the gap (not touch the body) — КОМПАС extends the web automatically.
    • sweep (ksBaseEvolutionDefinition, =45): SetSketch(profile)PathPartArray().Add(path)sketchShiftType=0SetThinParam(false)Create(). Profile & path on different (usually ⟂) planes; profileSketchId != pathSketchId.
    • loft (ksBaseLoftDefinition, =30): Sketchs().Add(each)SetLoftParam(false,false,true)SetThinParam(false). ≥2 closed sections on parallel planes — use sketch_create_on_offset_plane for non-base sections.
    • offset plane (sketch_create_on_offset_plane, ksPlaneOffsetDefinition, o3d_planeOffset=14): SetPlane(base) + offset mm + directionCreate() → sketch on it (OpenSketchOnOffsetPlaneAsync).
    • draft (ksInclineDefinition, o3d_incline=42 — API5 calls the op Incline, NOT Draft): FaceArray() (by index) + SetPlane(neutral base plane) + angle (degrees) + direction. Empirical, opposite to SDK docs: direction=false=expanding/outward (adds material), true=tapering/inward → code maps def.direction = !outward. Validate 0<angle<90. (o3d_DraftFromEdges=644 / IDraftFromEdges is a different op — not used.)
  • Patterns & mirror (API5): linear_pattern (ksMeshCopyDefinition, =35): SetAxis1(axis) + SetCopyParamAlongAxis(true,0,count,step,false) + count2=1 (disables 2nd direction → 1D); features via OperationArray(). circular_pattern (ksCircularCopyDefinition, =36): SetAxis(axis); count1=1 (radial off), count2=count (ring), step2=angle° between neighbours, factor2=false, inverce=reverse; GetOperationArray().Add(feature). mirror_operation (ksMirrorCopyDefinition, =48): SetPlane(base) + GetOperationArray().Add(feature). mirror_body (ksMirrorCopyAllDefinition, =49): SetPlane(base); ChooseBodies() casts to null in interop and is NOT needed — mirrors all bodies keeping the original (volume doubles). Empirical: count includes the original instance (count=3 → 3 instances). Axes: CoordinateAxis{X,Y,Z}o3d_axisOX/OY/OZ (Core/Modeling/CoordinateAxis.cs, analogous to BasePlane.cs).
  • Hole ops (API7 only — ksHoleDefinition absent in API5 interop; HoleService): HoleCore(ksHoleTypeEnum holeType, Action<IHole3D> configure)configure sets HoleParameters after HoleType is assigned (the type-specific sub-interface is inaccessible until the type is fixed). Placement shared: IModelContainer/IHole3D/IHoleDisposal + Points3D, direction chosen by volume delta, orphan rollback. None registered in _features → no id returned. hole=ksHTBase, configure=null. hole_counterbore=ksHTCounterbore + (ISpotfacingHoleParameters) (SpotfacingDiameter/SpotfacingDepth). hole_countersink=ksHTCountersinking + (ICountersinkHoleParameters) (CountersinkType=ksCTDiameterAngle, CountersinkDiameter/Angle). hole_conic=ksHTConic + (IConicHoleParameters) (ConicType=ksCNAngle, ConicAngle).
  • Assembly (API7, AssemblyService, namespace Kompas.Mcp.Core.Assemblies): assembly_add_componentIParts7.AddFromFile(path, ExternalFile=true, Redraw=true)IPart7.Placement (IPlacement3D) → SetOrigin(x,y,z) (mm, assembly world CS) → UpdatePlacement(true)top.RebuildModel(true). Empirical: UpdatePlacement returns FALSE for a manually-positioned component (no mates) — NOT an error. Validate DocumentType==ksDocumentAssembly before touching TopPart; rollback via IFeature7.Delete + RebuildModel. assembly_add_matetop.MateConstraints (IMateConstraints3D) → Add(MateConstraintType)BaseObject1/2 (faces via top.FindObjectsByPoint(x,y,z,FirstLevel=false)) → ParamValue (distance) → Update()RebuildModel(true); check mate.Valid (false → rollback mate.Owner.Delete). Types coincidence(mc_Coincidence=0) / distance(mc_Distance=5, value>0) verified live; parallel/perpendicular/concentric/angle/tangency — future.
  • Drawing (API7, DrawingService, namespace Kompas.Mcp.Core.Drawings) — entry via IKompasDocument2D; requires an active drawing doc (DocumentType==ksDocumentDrawing). All coords are view-local (mm) unless noted. Model file must be saved before placing views.
    • drawing_create_standard_views: doc2d.ViewsAndLayersManager.Views.AddStandartViews(path, "#Спереди", projTypes, x, y, scale, dx=20, dy=20) where projTypes=object[]{1,3,5} (Front/Up/Left as SAFEARRAY VT_I4). Success: created==3; content check: sum of new views' IView.ObjectCount > 0 else rollback IView.Delete. Returns ViewNumbers (the IView.Number values — address views by these when placing annotations).
    • drawing_fill_title_block: doc2d.LayoutSheets.ItemByNumber[1].Stamp (IStamp) → stamp.Text[columnId].Str = text (indexed property; IText.Str overwrites, no Clear needed) → stamp.Update(). Fields→columns (ksStampEnum): Name=1, Designation=2, Material=3. Non-transactional (all cells → single Update).
    • Dimensions go into (ISymbols2DContainer)view, NOT the sheet, and are NOT counted in IView.ObjectCount (that counts geometry in IDrawingContainer) — verify placement via the container's *.Count. Common flow: Add() → set coords → AutoNominalValue=trueUpdate() → check Valid → read ((IDimensionText)dim).NominalValue; rollback dim.Delete() on FALSE/invalid/zero. Leader/angle in radians (DimensionAngles.ToRadians). Free placement = set coords directly; associative (diametral/radial only) = set BaseObject to a projected circle → value read from geometry (see below).
      • linear (ILineDimension): X1,Y1,X2,Y2 (extension pts) + X3,Y3 (dim line) + Orientation (DimensionOrientation{Horizontal,Vertical,Parallel}ksLinDParallel=0/Horizontal=1/Vertical=2; parallel needs no explicit Angle).
      • diametral (IDiametralDimension): Xc,Yc,Radius + Angle; NominalValue = 2·Radius.
      • radial (IRadialDimension): Xc,Yc,Radius + Angle, DimensionType=true; NominalValue = Radius, NOT diameter — contrary to SDK docs, confirmed by spike.
      • associative diametral/radial (associate=true flag): instead of coords, find a projected circle in (IDrawingContainer)view.Circles by center+radius key (CircularObjectMatch.SelectMatchIndex, tol 1 mm; throws on none/ambiguous; concentric disambiguated by radius), set dim.BaseObject = circle (_Circle implements IDrawingObject) → NominalValue read from geometry. RequireViewContainers gives both QIs; free path stays on RequireSymbols2DContainer. Arc/angular/rough binding — not yet (own spike needed; ILineDimension has no BaseObject).
      • angular (IAngleDimension, AngleDimensions.Add(ksDrADimension=10)): vertex Xc,Yc + side pts X1,Y1/X2,Y2 + arc-position X3,Y3 (positions the arc only, does NOT pick the angle); measured angle chosen by DimensionType = AngleDimensionType{Min,Max,More} (on rays 0°/45° → min=45°/max=135° supplement/more=315° reflex). NominalValue in degrees.
    • drawing_add_rough (Roughs.Add()/IRough: BranchX0/Y0, Angle) + (IRoughParams)rough QI: SignType = RoughSignType{NoProcessing,DeleteMaterial,WithoutDeleteMaterial}, value (Ra/Rz) = RoughParamText.Str.
    • drawing_add_texttext lives in IDrawingContainer, NOT ISymbols2DContainer, and NOT in IView.ObjectCount: (IDrawingContainer)view.DrawingTexts.Add()/IDrawingText (X/Y/Angle) + (IText)dt.Str = text; count via DrawingTexts.Count. Do NOT set Height (that's block height, not font).
    • drawing_set_technical_requirementsdocument-level: (IDrawingDocument)doc.TechnicalDemand/ITechnicalDemand: td.Text.Str = texttd.Update() (IsCreated False→True on first set; overwrites; \n multiline).
    • DrawingAnnotationResult{Value(read-back), ViewNumber} is the shared result for rough/text.
    • drawing_add_leaderISymbols2DContainer.Leaders.Add(ksDrLeader)IBaseLeader. КРИТИЧЕСКИЙ ПОРЯДОК (спайк): новая выноска имеет 0 ответвлений → (IBranchs)bl.AddBranchByPoint(0,x,y) (остриё) ДО SetBranchTextPosition(textX,textY)/Update, иначе КОМПАС падает RPC_E_SERVERFAULT. Текст — (ILeader)bl.TextOnShelf.Str; ShelfDirection (enum ShelfDirection{Auto,Right,Left,Up,Down}, Auto = не задавать). AddBranchByPoint/SetBranchTextPosition возвращают bool — проверять. Результат — общий DrawingAnnotationResult.
    • drawing_set_sheet_formatRequireLayoutSheet(n).Format (ISheetFormat): Format=ksDocumentFormatEnum (PaperFormat{A0..A5,User}+PaperFormats.Parse/ToKompas/FromKompas), standard → set VerticalOrientation=!landscape (W/H auto-computed from enum+orientation, e.g. A3 landscape→420×297); User → set FormatWidth/Height only, КОМПАС auto-derives VerticalOrientation from W/H and ignores the flag, never swaps W/H (spike)sheet.Update(). New drawing defaults A4 portrait. ValidateFormatDimensions: User needs W/H>0, standard forbids W/H (must be 0).
  • Richer sketch primitives (API5 ksDocument2D wrappers): ksArcBy3Points; ksArcByAngle (centre/radius/start-end angles in degrees + counterClockwise flag); ksEllipse via ksEllipseParam (KompasObject.GetParamStruct(ko_EllipseParam=22); property names are A/B UPPERCASE in the interop); ksRegularPolygon via ksRegularPolygonParam (ko_RegularPolygonParam=92; describe = !inscribed); NURBS spline via ksNurbs(order=4) + ksNurbsPoint loop + ksEndObj; ksPoint. Param structs released after use. PartModeler is partial: .cs (registry/helpers/NewParam<T>/reset), .Sketch.cs (2D primitives), .Features.cs (extrude/revolve/fillet/chamfer). Static SketchGeometry (Core/Modeling) holds enum maps + validators (RequirePositive, RequireVertexCount, RequirePoints, RequireMin). Point lists use record SketchPoint(X, Y) (JSON names x/y).

КОМПАС-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 Step1Step12 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 "<path>\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.