solidworks-mcp
README.md
# solidworks-mcp
An MCP server that drives a local SOLIDWORKS installation to build and modify
parametric solid models.
Verified against **SOLIDWORKS 2026 SP0** (revision 34.0.0) on Windows 11.
## How it works
```
MCP client ──stdio──► solidworks-mcp ──COM──► SLDWORKS.exe
```
SOLIDWORKS exposes a classic COM automation API. The server attaches to a
running instance (or launches one), and every tool maps onto that API.
**All lengths are in millimetres and all angles in degrees.** The SOLIDWORKS API
is metric-SI internally; conversion happens at the tool boundary.
## Requirements
- SOLIDWORKS installed and licensed, on the same machine.
- Python 3.12+, 64-bit — it must match SOLIDWORKS' architecture or COM will not bind.
- [uv](https://docs.astral.sh/uv/) for dependency management.
## Install
```bash
uv sync
```
## Register with an MCP client
For Claude Code:
```bash
claude mcp add solidworks -- uv --directory E:\solid run solidworks-mcp
```
For a client that reads a JSON config:
```json
{
"mcpServers": {
"solidworks": {
"command": "uv",
"args": ["--directory", "E:\\solid", "run", "solidworks-mcp"]
}
}
}
```
## Tools
**Session and documents** — `solidworks_status`, `new_part`, `open_part`,
`save_part`, `close_part`
**Sketching** — `list_planes`, `start_sketch`, `start_sketch_on_face`,
`sketch_line`, `sketch_centerline`, `sketch_circle`, `sketch_rectangle`,
`sketch_arc`, `sketch_polygon`, `sketch_ellipse`, `add_sketch_dimension`,
`add_sketch_relation`, `finish_sketch`
**Features** — `extrude`, `cut_extrude`, `revolve`, `fillet`, `select_entity`,
`clear_selection`
**Parametric control** — `list_features`, `list_dimensions`, `set_dimension`,
`add_equation`, `list_equations`, `rebuild`
**Inspection** — `get_measurements`, `capture_view`
## A worked example
Building a 80 × 50 × 10 mm plate with a hole, then driving it parametrically:
```
new_part
start_sketch(plane="front")
sketch_rectangle(0, 0, 80, 50)
add_sketch_dimension(entities=[[40, 0]], value=80) -> "D1@Croquis1"
add_sketch_dimension(entities=[[0, 25]], value=50) -> "D2@Croquis1"
finish_sketch
extrude(depth=10)
start_sketch(plane="front")
sketch_circle(40, 25, 8)
finish_sketch
cut_extrude(depth=10, end_condition="through_all", reverse=True)
fillet(radius=5, edges=[[0,0,5], [80,0,5], [80,50,5], [0,50,5]])
set_dimension("D1@Croquis1", 120) -> the solid rebuilds to 120 mm wide
get_measurements -> bounding box 120 x 50 x 10 mm
capture_view("isometric")
```
## Things worth knowing
**Sketches created through the API have no dimensions.** SOLIDWORKS only adds
driving dimensions when you ask for them, so a sketch drawn with `sketch_*`
alone has nothing to drive. Call `add_sketch_dimension` while the sketch is
still open if you intend to change the geometry later.
**Cut direction follows the sketch normal.** A sketch on the Front Plane cutting
a solid that was extruded away from it needs `reverse=True`, otherwise the cut
travels into empty space and fails.
**Reference plane names are localised.** A Spanish install names features
`Croquis1` and `Saliente-Extruir1`. Tools accept the logical aliases
`front`/`top`/`right` and resolve them by position in the feature tree, so they
work regardless of UI language. `list_planes` reports the real names.
**SOLIDWORKS must be running.** There is no supported headless mode. The server
launches the application if it is not already open.
**Modal dialogs deadlock COM.** `add_sketch_dimension` temporarily disables the
"input dimension value" preference, which would otherwise pop a modal box and
hang the call, and restores it afterwards.
## Implementation notes
Two pywin32 behaviours shape the code and are easy to trip over:
- **Zero-argument COM members are auto-invoked on attribute access.** Under late
binding `doc.GetTitle` returns the title string; `doc.GetTitle()` raises
`TypeError: 'str' object is not callable`. Members taking one or more
arguments are called normally.
- **Typed nulls and in/out parameters need explicit VARIANTs.** Optional
interface arguments reject a bare `None` with "Type mismatch" and need
`VARIANT(VT_DISPATCH, None)`; error and warning out-parameters need
`VARIANT(VT_BYREF | VT_I4, 0)`, with the result read back from `.value`.
COM objects live in a single-threaded apartment, so `com_bridge.py` funnels every
call through one dedicated thread. Enum values in `constants.py` were read from
`swconst.tlb` rather than transcribed from documentation, because some differ
from commonly quoted values — `swEndCondThroughAllBoth` is 9, not 8.
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues