Skip to main content
Glama
Eduardo-Mariola

AutoCAD Plant 3D MCP Server

README.md
# AutoCAD Plant 3D MCP Server — native P&ID

MCP (Model Context Protocol) server that lets Claude — in Claude Code, Claude Desktop or any MCP
client — **build, check and renumber real AutoCAD Plant 3D P&IDs**: equipment, process and signal
lines, line groups, off-page connectors, tags and labels created through the Plant 3D .NET API (so
they pass validation and carry connectivity), plus read-only checks straight on the project
database. It also keeps the general AutoCAD tools (drawing, entities, layers, blocks, annotation,
screenshots) and the read-only Plant 3D 3D-piping queries.

By **Eduardo Mariola** — Chemical Engineering, UNESP (Brazil).

## Why this exists

My plant design course took two semesters: a benzyl alcohol plant, from patent search to process
simulation, economic evaluation and drawings. The P&IDs had to be delivered in AutoCAD Plant 3D:
11 sheets and about 2,400 engineering items.

Drawing them through generic AutoCAD automation does not work — Plant 3D's validation rejects raw
geometry and nothing gets connected. So the work went through the Plant 3D API instead, with a
.NET plugin, and through a lot of trial and error that ended up in about 150 automation scripts
and a set of hard-won rules: in what order a sheet must be built, where exactly a line must end to
connect, why property writes silently fail, how to label, how not to crash AutoCAD. The visual
standard — one sheet per control volume, numbering by area, orthogonal lines, aligned equipment —
came from studying finished projects of previous years and my own finished P&ID.

This repository consolidates that work, done in Claude Code sessions on my own machine, into two
MCP tools (`pid_native`, `pid_qa`), a plugin with 27 new commands and a field guide
([docs/pid-native.md](docs/pid-native.md)).

> **Em português.** Os P&IDs da planta de álcool benzílico (11 folhas, ~2.400 itens) tinham de sair
> no Plant 3D, e desenhar por automação genérica do AutoCAD não serve: a validação recusa e nada
> fica conectado. O caminho foi a API do Plant 3D, um plugin .NET e uns 150 scripts, além das regras
> aprendidas no erro (ordem de montagem, onde a linha tem de terminar, por que a gravação de
> propriedade falha em silêncio, rótulos, quedas do AutoCAD). O padrão visual veio de projetos
> prontos de anos anteriores e do meu P&ID finalizado. Este repositório junta tudo isso.

## Features

- **Native P&ID authoring** (`pid_native`): insert equipment, instruments and valves by style;
  process and signal lines with real connections (and automatic nozzles); line groups; off-page
  connectors; tag properties; tag labels; register drawings in the project — always in the
  drawing you name, never in "whatever is active"
- **Session control**: start Plant 3D, open a drawing, NETLOAD the plugin and dismiss the dialogs
  that silently block COM (unsigned DLL, Drawing Recovery, Error Report)
- **P&ID checks** (`pid_qa`), read-only on `ProcessPower.dcf`: duplicate and unregistered tags,
  orphan objects, line list from line groups, control loops from the signal-line graph,
  connectivity (free line ends, unpaired off-page connectors), picklists
- **Sheet audit** from the live drawing: diagonal segments, labels over lines or symbols,
  overlapping symbols, crossings, glued parallel runs, alignment, raw AutoCAD entities, open line
  ends and the equipment each one leads to
- **Orthogonal router** for new lines (straight, L, Z, then a grid search with elbow cost)
- **Renumbering plans** for valves, line groups and instrument loops, in two passes and grouped by
  sheet, ready for `set_props`
- **AutoCAD tools**: drawing, entity, layer, block, annotation, view/screenshot (File IPC with
  AutoCAD, or headless DXF with ezdxf)
- **Plant 3D 3D-piping queries** (`plant3d`): line list, BOM, valves, instruments, welds, bolts and
  gaskets, pipe length, spec validation, equipment, exports

## Requirements

- Windows 10/11
- AutoCAD Plant 3D 2027 (2026 works by building the plugin for .NET 8, see below)
- Python 3.10 or higher, with [uv](https://docs.astral.sh/uv/) (or pip)
- .NET 10 SDK to build the plugin (`dotnet --version`)

## Installation

1. Clone this repository:
```bash
git clone https://github.com/Eduardo-Mariola/autocad-plant3d-mcp.git
cd autocad-plant3d-mcp
```

2. Install the Python server:
```bash
uv sync
```

3. Build the Plant 3D plugin:
```bash
cd plant3d-plugin
dotnet build -c Release
```
For AutoCAD Plant 3D 2026:
`dotnet build -c Release -p:AcadDir="C:\Program Files\Autodesk\AutoCAD 2026" -p:TargetFramework=net8.0-windows`

The DLL lands in `plant3d-plugin\bin\Release\PlantMcpDispatch.dll`; `pid_native start` loads it.

## Configuration

### Claude Code

```bash
claude mcp add --scope user autocad -- "C:\path\to\autocad-plant3d-mcp\.venv\Scripts\python.exe" -m autocad_mcp
```

### Claude Desktop

Add to `%APPDATA%\Claude\claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "autocad": {
      "command": "C:\\path\\to\\autocad-plant3d-mcp\\.venv\\Scripts\\python.exe",
      "args": ["-m", "autocad_mcp"],
      "env": { "AUTOCAD_MCP_BACKEND": "auto" }
    }
  }
}
```

**Environment variables:**

| Variable | Default | Purpose |
|---|---|---|
| `AUTOCAD_MCP_IPC_DIR` | `C:/temp` | folder for the JSON request/response files |
| `AUTOCAD_MCP_ACAD_EXE` | `C:\Program Files\Autodesk\AutoCAD 2027\acad.exe` | executable started by `pid_native start` |
| `AUTOCAD_MCP_PLANT_DLL` | the plugin built in this repo | DLL loaded by `netload` |
| `AUTOCAD_MCP_PID_TIMEOUT` | `240` | seconds to wait for a plugin answer |
| `AUTOCAD_MCP_BACKEND` | `auto` | `file_ipc` (AutoCAD) or `ezdxf` (headless) for the general tools |
| `AUTOCAD_MCP_PLANT3D_ROOT` | — | folder with Plant 3D projects, to name projects instead of paths |

**Important notes:**
- Use the full absolute path to the virtual environment's Python
- Restart Claude Desktop completely after editing the file
- Keep the Plant 3D window maximized while tools run: a minimized window rejects COM calls

## Usage

### Running the server

```bash
uv run python -m autocad_mcp
```

### Available tools

#### `pid_native` — native P&ID authoring (operations)
- Session: `start`, `netload`, `open_drawing`, `dismiss_dialogs`, `quit`
- Project: `ping`, `project_info`, `open_project`, `add_drawing`, `remove_drawing`, `save`
- Reading: `dwg_assets`, `asset_info`, `opc_status`, `check_annotation`, `locate`, `unisolate`, `pnid_probe`
- Building: `add_asset`, `add_control_valve`, `new_line_group`, `add_line`, `add_line_in_group`,
  `assign_groups`, `add_offpage`, `opc_connect`, `set_props`, `set_vertices`, `move_entity`,
  `erase`, `own_asset`, `clone_blocks`, `add_annotation`, `call` (any plugin command)

#### `pid_qa` — checks, routing and plans (read-only)
- Database: `summary`, `duplicate_tags`, `orphans`, `line_groups`, `control_loops`,
  `connectivity`, `picklists`, `sheet_rowids`
- Sheet: `audit_sheet`, `label_collisions`, `open_ends`, `route`
- Plans: `plan_valve_numbers`, `plan_line_numbers`, `plan_instrument_loops`

#### General AutoCAD and Plant 3D tools
- `drawing`, `entity`, `layer`, `block`, `annotation`, `view`, `system` — AutoCAD through File IPC
  (or headless DXF)
- `plant3d` — read-only 3D-piping queries (`list_lines`, `bom`, `list_valves`, `weld_list`,
  `pipe_length`, `validate_specs`, `list_equipment`, `export`, …)
- `specgen` — Plant 3D specs/catalogs from a piping-class spreadsheet
- `pnid` — line list extracted from P&IDs in PDF
- `pid` — schematic P&ID symbols for AutoCAD LT (CTO library)

### Example data

`dwg_assets` answer (shortened):
```json
{
  "drawing": "P&ID - VC4.dwg",
  "assets": [
    {"rowid": 25422, "class_name": "HorizontalCentrifugalPump", "tag": "P-401B",
     "style": "Horizontal Centrifugal Pump Style", "handle": "11B9",
     "position": [3.296, 4.607], "rotation": 0, "min": [3.081, 4.350], "max": [3.938, 4.950]}
  ],
  "lines": [
    {"rowid": 25530, "class_name": "Primary", "style": "Primary Style",
     "handle": "11F2", "vertices": [[3.938, 4.607], [6.500, 4.607]]}
  ]
}
```

`ProcessPower.dcf` tables used by `pid_qa`:
```
PnPDrawings            PnPID, "Dwg Name"
PnPDataLinks           RowId, DwgId, RowClassName, DwgHandleLow
PnPRowRelations        ROWID, RELID, RelationshipTypeName   (PipeLineGroupRelationship, LineStartAsset, ...)
Instrumentation        PnPID, Tag, Area, Type, LoopNumber
HandValves             PnPID, Tag, Code, Number
PipeLineGroup          PnPID, LineNumber, Service, NominalSize, NominalSpec
PipeLines / SignalLines  process and signal segments
LineStartAsset / LineEndAsset / LineInlineAsset / LineNozzle / LineOffPageConnector
ConnectorsRelationship off-page connector pairs
```

Plugin request and answer (`C:/temp`):
```
autocad_mcp_plant_cmd_<id>.json     {"request_id", "command", "params", "ts"}
autocad_mcp_plant_result_<id>.json  {"request_id", "ok", "payload", "error"}
```

## Usage examples

### Start Plant 3D with the plugin
```python
pid_native(operation="start", data={"drawing": "C:/Projects/Plant/PID DWG/P&ID - VC10.dwg"})
pid_native(operation="project_info", data={"doc": "VC10.dwg"})
```

### Build part of a sheet, in the right order
```python
# 1. equipment
pid_native(operation="add_asset", data={"doc": "VC10.dwg", "style": "Dome Roof Tank Style",
           "items": [{"at": [6.0, 8.0]}, {"at": [12.0, 8.0]}]})
# 3. process line ending exactly on the outline; nozzles created where missing
pid_native(operation="add_line", data={"doc": "VC10.dwg", "style": "Primary Style",
           "nozzle": True, "items": [{"vertices": [[3.0, 6.2], [6.0, 6.2]]}]})
# 4. inline valve on the existing line
pid_native(operation="add_asset", data={"doc": "VC10.dwg", "style": "Gate Valve Style",
           "items": [{"at": [4.5, 6.2], "scale": 0.25}]})
pid_native(operation="save", data={"doc": "VC10.dwg"})
```

### Check the project and one sheet
```python
pid_qa(operation="duplicate_tags", data={"project": "C:/Projects/Plant"})
pid_qa(operation="connectivity", data={"project": "C:/Projects/Plant", "sheet": "VC10"})
pid_qa(operation="audit_sheet", data={"doc": "VC10.dwg"})
pid_qa(operation="open_ends", data={"doc": "VC10.dwg", "project": "C:/Projects/Plant"})
pid_qa(operation="route", data={"doc": "VC10.dwg", "from": [3.2, 14.0], "to": [9.8, 6.5]})
```

### Renumber hand valves by area, safely
```python
plan = pid_qa(operation="plan_valve_numbers", data={"project": "C:/Projects/Plant",
              "areas": {"VC1": 1, "VC2": 2, "VC3": 3}})
# for each sheet: pass1 items, save, pass2 items, save
pid_native(operation="set_props", data={"doc": "VC3.dwg", "items": [...]})
pid_native(operation="save", data={"doc": "VC3.dwg"})
```

## Lessons learned

The short version of [docs/pid-native.md](docs/pid-native.md):

- Build in order: equipment → off-page connectors → process lines → inline components → bubbles →
  signal lines → tags → labels.
- A line connects only if its end is exactly on the component outline (or a nozzle). The API never
  connects line to line: branches need a tee.
- Writing a property needs the owning sheet open and targeted, an unconditional save, and a real
  change of value (two passes) — otherwise it reports success and persists nothing.
- Never move or scale symbols outside the API: their connection points stay behind.
- Save every few items and back up `.dwg` and `.dcf` together: the database is written live, the
  drawing only on save.

## Development

```bash
uv sync --extra dev
uv run pytest tests/pid_native      # native P&ID tests (synthetic project database, no AutoCAD)
uv run pytest                       # whole suite
```

Project layout:

```
src/autocad_mcp/
  pid_native/          native P&ID: ipc, session, dcf, geometry, routing, numbering, tools
  server.py            MCP tools
  plant3d_query.py     read-only 3D-piping queries
  backends/            File IPC (AutoCAD) and ezdxf (headless)
plant3d-plugin/src/    .NET plugin (MCPPLANTDISPATCH): PidOps, OpcOps, UtilOps, AnnotOps, ...
docs/pid-native.md     field guide
```

Roadmap, in Portuguese: [FERRAMENTAS_PROPOSTAS.md](FERRAMENTAS_PROPOSTAS.md) — what is implemented
and what is still proposed.

## Credits

Built on the MIT-licensed [autocadplant3d-mcp](https://github.com/Romeraaa/autocadplant3d-mcp)
(itself based on [autocad-mcp](https://github.com/puran-water/autocad-mcp)); their notice is kept in
[LICENSE](LICENSE).

## License

MIT