Инкремент 9. 83 инструмента, 331 тест. + заметка о ревью реализации в спеке (Codex + pi/glm-5.1 + pi/kimi-k2.6). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
27 KiB
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 thekompas-sdk-researchsubagent (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"orGrep "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 done →
docs/ARCHITECTURE.md§10. - Backlog / what's left →
docs/TODO.md(canonical; top of «2D-ЧЕРТЁЖ» = next priority. Associative diametral/radial→circle binding (associateflag), 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 / caveats →
docs/OPEN_QUESTIONS.md. Known caveat («Ревью v2»): boss/cut direction on a selected face depends on face-normal orientation —forwardmay need flipping; the agent picks via snapshot ordescribe_facenormal. - 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 thedocs/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 againstlibs/kompas-interop/*.dllby reflection.docs-maintainer(model: Sonnet,Read/Edit/Write/Glob/Grep): syncsREADME.md/CLAUDE.md/docs/ARCHITECTURE.md/docs/OPEN_QUESTIONS.md/docs/presentation.htmlwith 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.props → KompasInteropDir).
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.5→KompasObject) thenksGetApplication7()→IApplication; the API5 root is needed forksPart3D-building andksDocument3Dsnapshots. API7 is used for app/documents, holes, assemblies, drawings, direct B-rep edit. - 3D via API5
ksPart:NewEntity(o3d_*)+ matching definition; always checkentity.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), axeso3d_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 usedtBoth+etThroughAll. - Face/edge selection:
ksPart.EntityCollection(o3d_face|o3d_edge)→SelectByPoint(x,y,z)(world mm) →GetByIndex(0); or by stable index fromlist_faces/list_edges(helpersSelectFaceByIndex/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 API7IMassInertiaParam7.Calculate()— itsActualflag 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-memoryresultArrayBytesstays empty when a filename is given); read bytes back. Return to MCP viaImageContentBlock.FromBytes(bytes, mime)— notData = bytes(Data holds base64 bytes). Usemodel_snapshotonly for visually-spatial questions; preferdescribe_modelfirst (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 inheritIntegrationTestBase(IAsyncLifetime) →DocumentService.CloseAllAsyncafter each test (prevents tab accumulation). - Feature tree API: read via API5
ksPart.GetFeature()→(ksFeature).SubFeatureCollection(true,false)→ksFeatureCollection. Cast(ksFeature)partdoes NOT work (RCW QI returns null) — must useGetFeature().ksFeature.typereturns only coarseo3d_entityand does NOT distinguish operations; precise type and params come fromksFeature.GetObject()→ksEntity.GetDefinition()+ the matching definition (ksBossExtrusionDefinition.GetSideParam,ksFilletDefinition.radius,ksChamferDefinition.GetChamferParam, …). Node names ("Элемент выдавливания:1") are localized by КОМПАС. Features registered by id in_featuressupport patterns/mirror; helpersRequireSketch/RequireFeature. - Variables (API5): create/read via
ksPart.GetFeature().VariableCollection(property on root ksFeature) — NOTksPart.VariableCollection()(returns external-only). Expression is the leading field; value is derived. Apply viaksPart.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 (RemoveVariablereturns FALSE). Geometry limitation: variables drive geometry only in a parametric model (sketch dims linked to variable names); our sketches use literal coords →set_variablestores/computes the value but does NOT move geometry. Parametric sketches unavailable via COM (ksCDimWithVariablenot constructible from external automation — seedocs/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 viaksPart.BodyCollection()→ksBody(IsSolid/FaceCollection); measurements viaksPart.GetMeasurer()→ksMeasurer(SetObject1/2,unit=ST_MIX_MM,Calc,distance/MinDistance/anglein 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=ksConverterFromSTEP→IKompasDocument3D1.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 viaIPart7.FindObjectsByPoint(x,y,z,true)→ cast toKompasAPI7.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 viaSketchGeometry.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=0→SetThinParam(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 — usesketch_create_on_offset_planefor non-base sections.- offset plane (
sketch_create_on_offset_plane,ksPlaneOffsetDefinition, o3d_planeOffset=14):SetPlane(base)+offsetmm +direction→Create()→ 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 mapsdef.direction = !outward. Validate0<angle<90. (o3d_DraftFromEdges=644/IDraftFromEdgesis 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 viaOperationArray().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:countincludes the original instance (count=3 → 3 instances). Axes:CoordinateAxis{X,Y,Z}→o3d_axisOX/OY/OZ(Core/Modeling/CoordinateAxis.cs, analogous toBasePlane.cs). - Hole ops (API7 only —
ksHoleDefinitionabsent in API5 interop;HoleService):HoleCore(ksHoleTypeEnum holeType, Action<IHole3D> configure)—configuresetsHoleParametersafterHoleTypeis 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, namespaceKompas.Mcp.Core.Assemblies):assembly_add_component—IParts7.AddFromFile(path, ExternalFile=true, Redraw=true)→IPart7.Placement(IPlacement3D) →SetOrigin(x,y,z)(mm, assembly world CS) →UpdatePlacement(true)→top.RebuildModel(true). Empirical:UpdatePlacementreturns FALSE for a manually-positioned component (no mates) — NOT an error. ValidateDocumentType==ksDocumentAssemblybefore touchingTopPart; rollback viaIFeature7.Delete+RebuildModel.assembly_add_mate—top.MateConstraints(IMateConstraints3D) →Add(MateConstraintType)→BaseObject1/2(faces viatop.FindObjectsByPoint(x,y,z,FirstLevel=false)) →ParamValue(distance) →Update()→RebuildModel(true); checkmate.Valid(false → rollbackmate.Owner.Delete). Typescoincidence(mc_Coincidence=0) /distance(mc_Distance=5, value>0) verified live;parallel/perpendicular/concentric/angle/tangency— future. - Drawing (API7,
DrawingService, namespaceKompas.Mcp.Core.Drawings) — entry viaIKompasDocument2D; 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)whereprojTypes=object[]{1,3,5}(Front/Up/Left as SAFEARRAY VT_I4). Success:created==3; content check: sum of new views'IView.ObjectCount> 0 else rollbackIView.Delete. ReturnsViewNumbers(theIView.Numbervalues — 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.Stroverwrites, no Clear needed) →stamp.Update(). Fields→columns (ksStampEnum): Name=1, Designation=2, Material=3. Non-transactional (all cells → singleUpdate).- Dimensions go into
(ISymbols2DContainer)view, NOT the sheet, and are NOT counted inIView.ObjectCount(that counts geometry inIDrawingContainer) — verify placement via the container's*.Count. Common flow:Add()→ set coords →AutoNominalValue=true→Update()→ checkValid→ read((IDimensionText)dim).NominalValue; rollbackdim.Delete()on FALSE/invalid/zero. Leader/angle in radians (DimensionAngles.ToRadians). Free placement = set coords directly; associative (diametral/radial only) = setBaseObjectto 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=trueflag): instead of coords, find a projected circle in(IDrawingContainer)view.Circlesby center+radius key (CircularObjectMatch.SelectMatchIndex, tol 1 mm; throws on none/ambiguous; concentric disambiguated by radius), setdim.BaseObject = circle(_CircleimplementsIDrawingObject) →NominalValueread from geometry.RequireViewContainersgives both QIs; free path stays onRequireSymbols2DContainer. Arc/angular/rough binding — not yet (own spike needed;ILineDimensionhas noBaseObject). - angular (
IAngleDimension,AngleDimensions.Add(ksDrADimension=10)): vertexXc,Yc+ side ptsX1,Y1/X2,Y2+ arc-positionX3,Y3(positions the arc only, does NOT pick the angle); measured angle chosen byDimensionType=AngleDimensionType{Min,Max,More}(on rays 0°/45° → min=45°/max=135° supplement/more=315° reflex).NominalValuein degrees.
- linear (
drawing_add_rough(Roughs.Add()/IRough:BranchX0/Y0,Angle) +(IRoughParams)roughQI:SignType=RoughSignType{NoProcessing,DeleteMaterial,WithoutDeleteMaterial}, value (Ra/Rz) =RoughParamText.Str.drawing_add_text— text lives inIDrawingContainer, NOTISymbols2DContainer, and NOT inIView.ObjectCount:(IDrawingContainer)view.DrawingTexts.Add()/IDrawingText(X/Y/Angle) +(IText)dt.Str= text; count viaDrawingTexts.Count. Do NOT setHeight(that's block height, not font).drawing_set_technical_requirements— document-level:(IDrawingDocument)doc.TechnicalDemand/ITechnicalDemand:td.Text.Str = text→td.Update()(IsCreatedFalse→True on first set; overwrites;\nmultiline).DrawingAnnotationResult{Value(read-back), ViewNumber}is the shared result for rough/text.drawing_add_leader—ISymbols2DContainer.Leaders.Add(ksDrLeader)→IBaseLeader. КРИТИЧЕСКИЙ ПОРЯДОК (спайк): новая выноска имеет 0 ответвлений →(IBranchs)bl.AddBranchByPoint(0,x,y)(остриё) ДОSetBranchTextPosition(textX,textY)/Update, иначе КОМПАС падаетRPC_E_SERVERFAULT. Текст —(ILeader)bl.TextOnShelf.Str;ShelfDirection(enumShelfDirection{Auto,Right,Left,Up,Down}, Auto = не задавать).AddBranchByPoint/SetBranchTextPositionвозвращают bool — проверять. Результат — общийDrawingAnnotationResult.drawing_set_sheet_format—RequireLayoutSheet(n).Format(ISheetFormat):Format=ksDocumentFormatEnum(PaperFormat{A0..A5,User}+PaperFormats.Parse/ToKompas/FromKompas), standard → setVerticalOrientation=!landscape(W/H auto-computed from enum+orientation, e.g. A3 landscape→420×297); User → setFormatWidth/Heightonly, КОМПАС auto-derivesVerticalOrientationfrom 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
ksDocument2Dwrappers):ksArcBy3Points;ksArcByAngle(centre/radius/start-end angles in degrees + counterClockwise flag);ksEllipseviaksEllipseParam(KompasObject.GetParamStruct(ko_EllipseParam=22); property names areA/BUPPERCASE in the interop);ksRegularPolygonviaksRegularPolygonParam(ko_RegularPolygonParam=92;describe = !inscribed); NURBS spline viaksNurbs(order=4)+ksNurbsPointloop +ksEndObj;ksPoint. Param structs released after use.PartModeleris partial:.cs(registry/helpers/NewParam<T>/reset),.Sketch.cs(2D primitives),.Features.cs(extrude/revolve/fillet/chamfer). StaticSketchGeometry(Core/Modeling) holds enum maps + validators (RequirePositive,RequireVertexCount,RequirePoints,RequireMin). Point lists userecord SketchPoint(X, Y)(JSON namesx/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)
- Get the КОМПАС root object by COM ProgID. Verified on this machine (v24 Home):
KOMPAS.Application.7andKOMPAS.Application.5are registered;KOMPASLT.*is absent — the Home edition uses the regular (non-LT) ProgIDs. Resolution order:KOMPAS.Application.7— direct API7IApplication(preferred)KOMPAS.Application.5— API5KompasObject, thenksGetApplication7()KOMPASLT.Application.5— fallback for other installations- New instance:
Activator.CreateInstance(Type.GetTypeFromProgID(progId)) - Attach to a running instance:
Marshal.GetActiveObject(progId)
- If you entered via API5, obtain the modern application:
IApplication appl = (IApplication)kompas.ksGetApplication7();(viaKOMPAS.Application.7you already holdIApplication). - Set
appl.Visible = trueto 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.afor 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, plusHelp\С чего начать.pdfand a Linux/Debian 12 build guide.Samples\— zipped examples per language:CSharp.zip,C++.zip,Pascal.zip,Basic.zip. InsideCSharp.zip, theStep1…Step12andStep2_API7_2D/Step2_API7_3Dprojects are the progressive tutorial;Gayka,SlideWrk,EventsAutoare larger feature demos.Help\KOMPAS_SDK_ru-RU.zipandKsAPI\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.