MCP server that gives LLMs the ability to author, inspect, and iterate on 3D CAD models with OpenCASCADE via the OCCTSwift family.
Part of the OCCTSwift ecosystem — see the ecosystem map for how this package sits on top of the kernel, viewport, bridge, and AIS layers. SemVer-stable from v1.0.0.
The Swift implementation calls OCCT directly in-process — no subprocess, no JSONL marshalling — and exposes 50 typed MCP tools that cover authoring, scene reads, mutation, introspection, construction, analysis, I/O, mesh, drawing, selection / remap, and dimension overlays.
LLM picks a typed tool (boolean_op, transform_body, render_preview, …)
→ OCCTMCP runs the OCCT operation directly via OCCTSwift / Tools / AIS / Mesh
→ Writes BREP/STEP/PNG + manifest.json + annotations.json
→ OCCTSwiftViewport (optional) auto-reloads the 3D model
For novel geometry the typed tools don't cover, the LLM falls back to execute_script: arbitrary Swift code with the full OCCTSwift API, compiled and run in-process.
50 tools, organized below. Call get_api_reference({ category: "mcp_tools" }) to dump every tool's JSON Schema in one shot — useful for LLM auto-discovery. Most flows can answer "what's the volume?", "make it red", "boolean-subtract these", "render a preview", "add a dimension between these two faces", "export to STEP", and "draw this" without ever touching execute_script.
| Tool | Purpose |
|---|---|
execute_script |
Write & execute arbitrary Swift CAD code (full OCCTSwift API) |
get_script |
Read the most recent script's source |
get_api_reference |
Browse OCCTSwift API by category |
| Tool | Purpose |
|---|---|
get_scene |
Read current scene manifest (bodies, colors, materials) |
export_model |
List exported BREP / STEP / STL / OBJ file paths |
compare_versions |
Diff current scene vs N runs ago (added / removed / appearance / file changed) |
| Tool | Purpose |
|---|---|
remove_body |
Delete a body from the scene (manifest + BREP file) |
clear_scene |
Wipe all bodies, optionally keep diff history |
rename_body |
Change a body's id |
set_appearance |
Update color / opacity / roughness / metallic / display name |
| Tool | Purpose |
|---|---|
validate_geometry |
Per-body topology validation (isValid, error counts) |
compute_metrics |
Volume, area, centroid, bounding box, principal axes |
query_topology |
Find faces / edges / vertices matching criteria, return stable IDs |
measure_distance |
Min distance + contacts between two bodies |
recognize_features |
Pockets and holes via AAG heuristics |
inspect_assembly |
Walk an XCAF assembly tree (STEP / IGES / XBF) |
| Tool | Purpose |
|---|---|
apply_feature |
Drill / fillet / chamfer / extrude / revolve / thread / boolean (FeatureSpec) |
transform_body |
Translate / rotate / uniform-scale (records identity history for remap) |
boolean_op |
Union / subtract / intersect / split (records per-input history for remap) |
mirror_or_pattern |
Mirror / linear / circular pattern → N new bodies |
| Tool | Purpose |
|---|---|
check_thickness |
Wall-thickness analysis with thin-region flags |
analyze_clearance |
Pairwise interference / minimum clearance |
heal_shape |
Heal imported / non-watertight geometry; before/after stats |
| Tool | Purpose |
|---|---|
select_topology |
Pick faces / edges / vertices, get a stable selectionId |
remap_selection |
Carry selectionIds across mutations of the same body (history-based for transform / heal / boolean / apply_feature; centroid heuristic fallback otherwise) |
find_correspondences |
Map selectionIds from a source body onto a target body that's a known transform of the source — mirror_or_pattern outputs are the typical case |
select_by_feature |
Bulk pick by feature kind (e.g. all hole edges) |
list_selections |
Inspect the in-memory selection registry |
clear_selections |
Wipe the registry |
| Tool | Purpose |
|---|---|
add_dimension |
Add a linear / angular / radial dimension; renders in render_preview |
add_scene_primitive |
Add trihedron / workPlane / axis / pointCloud / boundingBox / diffMarker |
auto_dimension |
Heuristic dimension drop for the principal extents |
show_bounding_box |
Add a body's AABB as an overlay |
diff_overlay |
Visualize the diff between two snapshots |
remove_scene_annotation |
Remove a dimension or primitive by id |
list_annotations |
Inspect the annotations sidecar |
| Tool | Purpose |
|---|---|
read_brep |
Load a .brep from disk into the scene |
import_file |
Multi-format import (STEP / IGES / STL / OBJ); optional XCAF assembly |
export_scene |
Export to STEP / IGES / BREP / STL / OBJ / glTF / GLB |
set_assembly_metadata |
Modify XCAF document or per-component metadata |
| Tool | Purpose |
|---|---|
generate_mesh |
Tessellate to triangles + quality metrics |
simplify_mesh |
QEM mesh decimation to .stl/.obj — wraps OCCTSwiftMesh's Mesh.simplified (vendored meshoptimizer) |
render_preview |
One-shot PNG render with measurement labels and primitive overlays |
generate_drawing |
Multi-view ISO 128-30 DXF technical drawing |
| Tool | Purpose |
|---|---|
graph_validate |
Validate a BREP's topology graph (raw path) |
graph_compact |
Drop unreferenced graph nodes; write rebuilt BREP |
graph_dedup |
Deduplicate shared surface / curve geometry |
graph_ml |
Export topology + UV/edge samples as ML-friendly JSON |
feature_recognize |
Pockets + holes (raw BREP path; recognize_features is the scene-aware wrapper) |
This repo ships two implementations side-by-side:
- Swift (
Sources/,Package.swift) — the primary server. In-process against OCCTSwift / OCCTSwiftMesh / OCCTSwiftTools / OCCTSwiftAIS / DrawingComposer using the official Swift MCP SDK. 50 tools. macOS 15+ (the OCCT.xcframework arm64 platform). - Node / TypeScript (
src/,dist/) — the original implementation. Shells out to theocctkitCLI for everything Swift-side. 36 tools (the pre-v0.4 surface; selection / remap / annotations are Swift-only). Useful if you can't run a macOS binary.
Both speak stdio MCP and read/write the same manifest format.
- macOS 15+ (for the Swift implementation)
- Swift 6.1+ / Xcode 16+
- For the Node implementation only: Node.js 18+, plus a sibling clone of OCCTSwiftScripts so
occtkitis on$PATH(ormake installit)
git clone https://github.com/gsdali/OCCTMCP.git
cd OCCTMCP
swift build -c releaseIn Claude Code's .mcp.json:
{
"mcpServers": {
"occtmcp": {
"command": "/path/to/OCCTMCP/.build/release/occtmcp-server"
}
}
}The Swift package is published on the Swift Package Index.
git clone https://github.com/gsdali/OCCTMCP.git
cd OCCTMCP
npm install
npm run buildIn .mcp.json:
{
"mcpServers": {
"occtmcp": {
"command": "node",
"args": ["/path/to/OCCTMCP/dist/index.js"]
}
}
}The LLM can author CAD models by composing typed tools — most everyday flows never touch execute_script:
boolean_op(op: "subtract", aBodyId: "block", bBodyId: "hole", outputBodyId: "drilled")
→ "drilled" body added to the scene
select_topology(bodyId: "drilled", kind: "face", limit: 1)
→ returns selectionId "sel:drilled#face[12]"
add_dimension(kind: "linear", anchors: [...]) ; render_preview()
For novel geometry, drop into execute_script with the full OCCTSwift API:
import OCCTSwift
import ScriptHarness
let ctx = ScriptContext()
let C = ScriptContext.Colors.self
let box = Shape.box(width: 40, height: 30, depth: 20)!
let hole = Shape.cylinder(radius: 5, height: 30)!
.translated(by: SIMD3(20, -1, 10))!
let result = box.subtracting(hole)!
let filleted = result.filleted(radius: 2.0)!
try ctx.add(filleted, id: "part", color: C.steel, name: "Bracket")
try ctx.emit(description: "Filleted bracket with mounting hole")The get_api_reference tool provides documentation for:
- primitives — box, cylinder, sphere, cone, torus, wedge
- sweeps — extrude, revolve, pipe sweep, loft, ruled
- booleans — union, subtract, intersect, section
- modifications — fillet, chamfer, shell, offset, draft, defeature
- transforms — translate, rotate, scale, mirror
- wires — rectangle, circle, polygon, spline, helix, offset
- curves2d/3d — line, arc, ellipse, bspline, bezier, interpolate
- surfaces — plane, cylinder, cone, sphere, extrusion, revolution, plate
- analysis — volume, area, distance, bounds, validation
- import_export — STL, STEP, IGES, BREP, OBJ, PLY
- mcp_tools — every MCP tool's JSON Schema (handy for LLM auto-discovery)
OCCTMCP follows Semantic Versioning. The Swift port reached v1.0.0 on 2026-05-09 — feature-complete against the original Node implementation, plus a layer of selection / remap / annotation tools that are Swift-only.
Releases are tagged on GitHub. The main branch is what SPI tracks.
LGPL-2.1-or-later — same as OCCTSwift.