feat(bench): performance lane + task-matrix chart; docs: README rebuilt around four evidence lanes
- benchmarks/perf_suite.py: fixed headless workloads (2k creates, 10k build/export/reopen, 10k region query, premium quality pass) timed through the same backend methods the tools call; machine fingerprint recorded; self-measurement only - benchmarks/render_perf_chart.py -> docs/assets/autocad-mcp-perf.svg (log-scale wall time) - benchmarks/render_matrix_chart.py -> docs/assets/autocad-mcp-taskmatrix.svg (tasks x servers status heatmap from published reports) - render_live_chart now tolerates other lanes sharing results/published/ - README: PyPI-first install, four-lane benchmark section with Python-generated visuals, v1.4 feature table, updated client/config/roadmap - published perf report: benchmarks/results/published/perf-ezdxf.json Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
co-authored by
Cursor
parent
67f2c3b575
commit
21cbc62df5
@@ -1,7 +1,7 @@
|
||||
# AutoCAD MCP Pro
|
||||
|
||||
Production-grade AutoCAD automation for AI agents—live through COM on Windows,
|
||||
or headless through ezdxf on any platform.
|
||||
Production-grade AutoCAD automation for AI agents — live through COM on
|
||||
Windows, or headless through ezdxf on any platform.
|
||||
|
||||
[](https://github.com/U-C4N/Autocad-MCP/actions/workflows/ci.yml)
|
||||
[](https://pypi.org/project/autocad-mcp-pro/)
|
||||
@@ -11,84 +11,38 @@ or headless through ezdxf on any platform.
|
||||
[](https://github.com/U-C4N/Autocad-MCP/stargazers)
|
||||
|
||||
One typed MCP contract controls two execution engines. Build and edit drawings,
|
||||
query exact geometry, apply engineering standards, refine quality issues inside
|
||||
transactions, and deliver hashed artifacts with validation evidence.
|
||||
query exact geometry, apply engineering standards (ISO 128/129/286/1101),
|
||||
refine quality issues inside transactions, and deliver hashed artifacts with
|
||||
validation evidence.
|
||||
|
||||
> **v1.4 release snapshot:** 131 tools · 6 resources · 5 prompt templates ·
|
||||
> 474 collected tests. Runtime discovery through `system_about` is authoritative.
|
||||
|
||||
## Start in 60 seconds
|
||||
## Install in 10 seconds
|
||||
|
||||
```bash
|
||||
git clone https://github.com/U-C4N/Autocad-MCP.git
|
||||
cd Autocad-MCP
|
||||
python -m venv .venv
|
||||
pip install autocad-mcp-pro # or: uvx autocad-mcp-pro
|
||||
autocad-mcp # stdio MCP server, backend auto-selected
|
||||
```
|
||||
|
||||
Activate the environment and start the stdio server:
|
||||
|
||||
```powershell
|
||||
# Windows
|
||||
.venv\Scripts\Activate.ps1
|
||||
pip install -e .
|
||||
python server.py
|
||||
```
|
||||
Headless (no AutoCAD required, any OS) or live AutoCAD on Windows:
|
||||
|
||||
```bash
|
||||
# macOS / Linux
|
||||
source .venv/bin/activate
|
||||
pip install -e .
|
||||
python server.py
|
||||
AUTOCAD_MCP_BACKEND=ezdxf autocad-mcp # portable DXF engine
|
||||
AUTOCAD_MCP_BACKEND=com autocad-mcp # live AutoCAD (pip install "autocad-mcp-pro[com]")
|
||||
```
|
||||
|
||||
That starts the headless-capable server with automatic backend selection. For
|
||||
live AutoCAD control on Windows:
|
||||
Extras: `[com]` live AutoCAD (pywin32 + Pillow), `[pdf]` PDF/screenshot
|
||||
rendering (matplotlib), `[full]` everything. Working from a checkout is the
|
||||
same commands with `pip install -e ".[full]"` and `python server.py`.
|
||||
|
||||
```powershell
|
||||
pip install -e ".[com]"
|
||||
$env:AUTOCAD_MCP_BACKEND = "com"
|
||||
python server.py
|
||||
```
|
||||
## Benchmarks — three lanes, all reproducible
|
||||
|
||||
No AutoCAD installation is needed for the ezdxf backend:
|
||||
Every number below is generated by a script in [`benchmarks/`](benchmarks/)
|
||||
and rendered to SVG with Python (matplotlib). No hand-edited charts, no
|
||||
adjectives.
|
||||
|
||||
```powershell
|
||||
$env:AUTOCAD_MCP_BACKEND = "ezdxf"
|
||||
python server.py
|
||||
```
|
||||
|
||||
## Evidence, not adjectives
|
||||
|
||||

|
||||
|
||||
The graphic is generated with Matplotlib from
|
||||
[`benchmarks/source_review.json`](benchmarks/source_review.json). A fixed,
|
||||
public 100-point rubric covers functional CAD breadth, correctness and delivery,
|
||||
backend reach, engineering production, tests, and security.
|
||||
|
||||
| Project | Score | Evidence |
|
||||
|---|---:|:---:|
|
||||
| **[U-C4N/Autocad-MCP](https://github.com/U-C4N/Autocad-MCP)** | **93** | A |
|
||||
| [varavista/autocad-mcp](https://github.com/varavista/autocad-mcp) | 84 | A |
|
||||
| [beiming183-cloud/AutoCAD-MCP](https://github.com/beiming183-cloud/AutoCAD-MCP) | 83 | A |
|
||||
| [AnCode666/multiCAD-mcp](https://github.com/AnCode666/multiCAD-mcp) | 73 | A |
|
||||
| [puran-water/autocad-mcp](https://github.com/puran-water/autocad-mcp) | 70 | A |
|
||||
| [NCO-1986/AutoCAD_mcp](https://github.com/NCO-1986/AutoCAD_mcp) | 68 | B |
|
||||
|
||||
This is a dated source review—not a claim that every project completed a shared
|
||||
live AutoCAD run. Evidence grade **A** means source plus executable local
|
||||
evidence was reviewed; **B** means source and tool surface were reviewed but the
|
||||
live AutoCAD path was not fully executed.
|
||||
|
||||
Reproduce the chart and run the ten-task reference adapter:
|
||||
|
||||
```bash
|
||||
pip install -e ".[pdf]"
|
||||
python -m benchmarks.render_chart
|
||||
python -m benchmarks.run_competitors --server autocad-mcp-pro --backend ezdxf --json
|
||||
```
|
||||
|
||||
### Live-run lane — same harness, pinned competitors
|
||||
### 1 · Live-run scores — same harness, pinned competitors
|
||||
|
||||

|
||||
|
||||
@@ -98,13 +52,13 @@ python -m benchmarks.run_competitors --server autocad-mcp-pro --backend ezdxf --
|
||||
| [beiming183-cloud/AutoCAD-MCP](https://github.com/beiming183-cloud/AutoCAD-MCP) | `11f7c47` | 50.0 | 5/10 | 50% |
|
||||
| [puran-water/autocad-mcp](https://github.com/puran-water/autocad-mcp) | `95476a3` | 45.0 | 4/10 | 50% |
|
||||
|
||||
Same ten fixed tasks, same runner, headless ezdxf lane. Competitors are driven
|
||||
Ten fixed tasks, one runner, headless ezdxf lane. Competitors are driven
|
||||
**black-box over MCP stdio** using their own documented tool contracts at the
|
||||
pinned commit, and every geometry claim is verified by re-opening the exported
|
||||
DXF with ezdxf in the harness — no competitor self-reporting. `unsupported`
|
||||
scores zero in the fixed matrix; per-task statuses with exact reasons are
|
||||
committed under [`benchmarks/results/published/`](benchmarks/results/published/).
|
||||
File-IPC (live AutoCAD) lanes run locally, not in CI.
|
||||
DXF with ezdxf inside the harness — no self-reporting. `unsupported` scores
|
||||
zero in the fixed matrix; per-task reasons are committed under
|
||||
[`benchmarks/results/published/`](benchmarks/results/published/). File-IPC
|
||||
(live AutoCAD) lanes run locally, not in CI.
|
||||
|
||||
```bash
|
||||
python -m benchmarks.run_competitors --server puran-water-autocad-mcp --backend ezdxf
|
||||
@@ -112,39 +66,97 @@ python -m benchmarks.run_competitors --server beiming183-autocad-mcp --backend e
|
||||
python -m benchmarks.render_live_chart
|
||||
```
|
||||
|
||||
The complete rubric, caveats, version A/B suite, and reproduction commands live
|
||||
in [`benchmarks/`](benchmarks/README.md).
|
||||
### 2 · Task matrix — where the score comes from
|
||||
|
||||
## Why this architecture holds up
|
||||

|
||||
|
||||
### One contract, two engines
|
||||
The single score hides *which* capabilities exist, so the matrix shows every
|
||||
task against every server: green = verified pass, amber = partial, gray = the
|
||||
server documents no equivalent (planning, refinement, TABLE/MLEADER, hashed
|
||||
delivery), red = attempted but failed verification.
|
||||
|
||||
The COM backend controls a live AutoCAD session on Windows through a
|
||||
single-threaded STA executor. The ezdxf backend creates, edits, renders, and
|
||||
validates DXF drawings without AutoCAD. Both return the same typed entities,
|
||||
layers, blocks, drawing metadata, and capability format.
|
||||
```bash
|
||||
python -m benchmarks.render_matrix_chart
|
||||
```
|
||||
|
||||
### Geometry agents do not have to guess
|
||||
### 3 · Headless performance — scale evidence
|
||||
|
||||
Tools such as `point_from_snap`, `point_intersection`, and `point_tangent`
|
||||
resolve exact construction coordinates from drawing entities. Handle-preserving
|
||||
edit tools and smart selection keep agents attached to real geometry instead of
|
||||
reconstructing state from prose.
|
||||

|
||||
|
||||
### Quality is a loop
|
||||
| Workload | Wall time | Throughput / result |
|
||||
|---|---:|---|
|
||||
| Create 2,000 lines (individual calls) | 0.64 s | ~3,100 entities/s |
|
||||
| 10,000 lines: build + DXF export + reopen | 13.9 s | ~700 entities/s end-to-end |
|
||||
| Region query over 10,000 entities | 3.4 s | 2,500 matched |
|
||||
| Premium pass (layers + part + dims + full critique) | 0.32 s | 0 issues |
|
||||
|
||||
`drawing_preflight` checks whether an engineering request is ready to draw.
|
||||
`drawing_critique` reports standards and geometry issues. `drawing_refine`
|
||||
repairs the supported subset inside isolated transactions and rolls back rounds
|
||||
that reduce quality. `drawing_finalize` combines structural validation,
|
||||
standards critique, a scalar score, and invalidity ratio.
|
||||
Workloads call the same backend methods the MCP tools call, so server-side
|
||||
overhead is included. Self-measurement only — competitor servers would pay an
|
||||
extra stdio serialization cost that in-process runs do not, so no cross-server
|
||||
timing claims are made. Numbers move with hardware; the machine fingerprint is
|
||||
recorded in the report.
|
||||
|
||||
### Delivery carries evidence
|
||||
```bash
|
||||
python -m benchmarks.perf_suite --out benchmarks/results/published/perf-ezdxf.json
|
||||
python -m benchmarks.render_perf_chart
|
||||
```
|
||||
|
||||
`drawing_deliver` creates the requested artifacts, computes SHA-256 hashes,
|
||||
reopens the canonical DXF, compares entity/layer/type counts and bounds, and
|
||||
writes `manifest.json` plus `validation.json`. A successful tool call is not
|
||||
treated as proof that the drawing survived export.
|
||||
### 4 · Source-reviewed capability rubric (context)
|
||||
|
||||

|
||||
|
||||
Six named AutoCAD MCP projects scored against a fixed public 100-point rubric
|
||||
(CAD breadth, correctness and delivery, backend reach, engineering production,
|
||||
tests, security), generated from
|
||||
[`benchmarks/source_review.json`](benchmarks/source_review.json). This is a
|
||||
dated source review — evidence grade **A** means source plus executable local
|
||||
evidence was reviewed; **B** means the live AutoCAD path was not fully
|
||||
executed. It is not a shared live run; lanes 1-3 above are the runtime
|
||||
evidence. Full rubric, caveats and the version A/B suite:
|
||||
[`benchmarks/README.md`](benchmarks/README.md).
|
||||
|
||||
## What ships in v1.4
|
||||
|
||||
| Area | Tools |
|
||||
|---|---|
|
||||
| Drawing lifecycle | create, open, save, export DXF/PDF, audit, purge, undo/redo |
|
||||
| Geometry | lines, arcs, polylines, splines, hatches, trim/extend/fillet/chamfer, handle-preserving edits |
|
||||
| Annotation | ISO 129 toleranced dimensions, **ISO 286 fits** (`fit="H7"`), TABLE, MLEADER, GD&T frames + datums (ISO 1101) |
|
||||
| Engineering generators | involute gears (front + section A-A), DIN 6885 keyed bores, ISO A3 titleblock |
|
||||
| **Paper space** *(new)* | `layout_list/create/set_current`, scaled `viewport_create`, `drawing_export_pdf(layout=...)` |
|
||||
| **3D solids** *(new, opt-in)* | `solid_box/cylinder/extrude/revolve/boolean` on live AutoCAD (`ENABLE_3D=true`) |
|
||||
| Quality loop | `drawing_preflight` → `drawing_plan` → `drawing_critique` → `drawing_refine` → `drawing_finalize` (0-100 score) |
|
||||
| Delivery | `drawing_deliver`: DXF/PDF/PNG + SHA-256 manifest + reopen-parity checks |
|
||||
| Discovery | **tool profiles** *(new)*: `TOOL_PROFILE=lean` (~46 tools) / `core` / `full` for clients with tight tool caps |
|
||||
|
||||
The tool surface evolves — ask `system_about` for the live grouped inventory
|
||||
and `system_capabilities` for per-backend support modes instead of copying
|
||||
lists from this README.
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[MCP host / AI agent] --> B[FastMCP server]
|
||||
B --> C[Error - audit - timing - logging middleware]
|
||||
C --> D[Typed tool contract + tool profiles]
|
||||
D --> E[COM backend]
|
||||
D --> F[ezdxf backend]
|
||||
E --> G[Live AutoCAD]
|
||||
F --> H[Headless DXF]
|
||||
E --> I[Engineering quality + delivery]
|
||||
F --> I
|
||||
```
|
||||
|
||||
- `server.py` — FastMCP surface, lifespan, middleware, resources, prompts.
|
||||
- `backends/base.py` — shared typed contract + capability model.
|
||||
- `backends/com_backend.py` — single-STA-thread COM executor with per-call
|
||||
timeouts.
|
||||
- `backends/ezdxf_backend.py` — `asyncio.to_thread`-wrapped DXF engine with
|
||||
snapshot transactions.
|
||||
- `engineering/` — standards-aware planning, generators, critique, scoring,
|
||||
fits, refinement, validation, delivery.
|
||||
- `security.py` — path validation and command/AutoLISP sanitization.
|
||||
|
||||
## Backend capabilities
|
||||
|
||||
@@ -153,210 +165,135 @@ treated as proof that the drawing survived export.
|
||||
| Live AutoCAD document control | ✓ | — |
|
||||
| Headless DXF creation and editing | — | ✓ |
|
||||
| Cross-platform execution | — | ✓ |
|
||||
| Deterministic entity/query contract | ✓ | ✓ |
|
||||
| Transactions and rollback | ✓ | ✓ |
|
||||
| Paper-space layouts + viewports | ✓ | ✓ |
|
||||
| Viewport model-content rendering | ✓ | — |
|
||||
| TABLE and MLEADER semantics | Native | Portable composite |
|
||||
| 3D solids (opt-in) | ✓ | — (no headless ACIS) |
|
||||
| Screenshots | AutoCAD window | Matplotlib render |
|
||||
| Raw AutoCAD commands / AutoLISP | Opt-in | — |
|
||||
|
||||
Use `system_capabilities` at runtime instead of assuming backend support. The
|
||||
machine-readable response distinguishes `native`, `composite`, `emulated`, and
|
||||
`unsupported` behavior where the engines differ.
|
||||
`system_capabilities` returns this machine-readably (`native`, `composite`,
|
||||
`rendered`, `snapshot`, `shared`, `unsupported`) — use it at runtime instead of
|
||||
assuming.
|
||||
|
||||
## A production drawing workflow
|
||||
|
||||
The server exposes low-level CAD primitives, but the intended engineering path
|
||||
uses deterministic orchestration and validation:
|
||||
|
||||
```text
|
||||
drawing_preflight → drawing_plan → drawing_apply_iso_layers
|
||||
→ deterministic create/edit tools → dimension_auto
|
||||
→ deterministic create/edit tools → dimension_auto (+ fit="H7" callouts)
|
||||
→ drawing_critique → drawing_refine
|
||||
→ drawing_finalize → drawing_deliver
|
||||
→ layout_create + viewport_create → drawing_finalize → drawing_deliver
|
||||
```
|
||||
|
||||
Representative capability groups include:
|
||||
|
||||
| Area | Examples |
|
||||
|---|---|
|
||||
| Drawing lifecycle | create, open, save, export, audit, purge, undo/redo |
|
||||
| Geometry | lines, arcs, polylines, hatches, splines, trim/extend/fillet/chamfer |
|
||||
| Annotation | dimensions, ISO 129 tolerances, TABLE, MLEADER, text editing |
|
||||
| Engineering | gears, keyed bores, title blocks, ISO 1101 GD&T and datums |
|
||||
| Query | entity/layer/block inspection, selection, bounds, distance and area |
|
||||
| Quality | preflight, critique, score, transactional refinement and finalization |
|
||||
| Delivery | PDF/PNG/DXF output, hashes, manifests and reopen-parity checks |
|
||||
|
||||
The tool surface evolves. Ask `system_about` for the live grouped inventory
|
||||
instead of building integrations around a copied list from this README.
|
||||
|
||||
## Installation profiles
|
||||
|
||||
| Profile | Command | Use case |
|
||||
|---|---|---|
|
||||
| Core | `pip install -e .` | Headless ezdxf workflows |
|
||||
| COM | `pip install -e ".[com]"` | Live AutoCAD on Windows |
|
||||
| PDF | `pip install -e ".[pdf]"` | PDF export and headless screenshots |
|
||||
| Full | `pip install -e ".[full]"` | Both backends and all render features |
|
||||
|
||||
Requirements:
|
||||
|
||||
- Python 3.11+
|
||||
- [FastMCP](https://github.com/jlowin/fastmcp) 3.0+
|
||||
- [ezdxf](https://github.com/mozman/ezdxf) 1.3+
|
||||
- AutoCAD, `pywin32`, and Pillow only for live COM control
|
||||
- Matplotlib only for PDF/headless rendering and benchmark visualization
|
||||
|
||||
## Connect an MCP client
|
||||
|
||||
### Claude Desktop
|
||||
|
||||
Add a server entry to `claude_desktop_config.json` and use the absolute path to
|
||||
your checkout:
|
||||
### Claude Desktop / Cursor / any stdio host
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"autocad": {
|
||||
"command": "python",
|
||||
"args": ["C:\\path\\to\\Autocad-MCP\\server.py"],
|
||||
"command": "autocad-mcp",
|
||||
"env": {
|
||||
"AUTOCAD_MCP_BACKEND": "auto",
|
||||
"ALLOWED_PATHS": "C:\\Users\\you\\Documents\\AutoCAD"
|
||||
"ALLOWED_PATHS": "C:\\Users\\you\\Documents\\AutoCAD",
|
||||
"TOOL_PROFILE": "full"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Cursor, Cline, Continue, Goose, and other stdio-capable MCP hosts use the same
|
||||
`command` plus `args` shape. The model vendor is not part of the server
|
||||
contract.
|
||||
After `pip install autocad-mcp-pro` the `autocad-mcp` command is on PATH; from
|
||||
a checkout use `"command": "python"`, `"args": ["path/to/server.py"]`. The
|
||||
model vendor is not part of the server contract.
|
||||
|
||||
### Local HTTP
|
||||
|
||||
```bash
|
||||
fastmcp run server.py:mcp --transport http --port 8000
|
||||
autocad-mcp --transport http --port 8000
|
||||
```
|
||||
|
||||
Loopback is the default. A non-loopback bind is refused unless remote HTTP is
|
||||
explicitly enabled and bearer-token authentication is configured.
|
||||
Loopback only by default; a non-loopback bind is refused unless remote HTTP is
|
||||
explicitly enabled **and** a bearer token is configured.
|
||||
|
||||
## Configuration
|
||||
|
||||
Set variables in your shell, process manager, or MCP client configuration.
|
||||
[`.env.example`](.env.example) is a reference; the server reads process
|
||||
environment variables directly.
|
||||
|
||||
| Variable | Default | Purpose |
|
||||
|---|---|---|
|
||||
| `AUTOCAD_MCP_BACKEND` | `auto` | Select `auto`, `com`, or `ezdxf` |
|
||||
| `AUTOCAD_MCP_BACKEND` | `auto` | `auto`, `com`, or `ezdxf` |
|
||||
| `TOOL_PROFILE` | `full` | `lean` (~46 curated tools), `core` (hides escape hatches), `full` |
|
||||
| `ENABLE_3D` | `false` | Expose the opt-in `solid_*` tools (COM backend) |
|
||||
| `LOG_LEVEL` | `INFO` | Python logging level |
|
||||
| `ALLOWED_PATHS` | empty | Comma-separated absolute paths the server may access |
|
||||
| `MAX_UNDO_STACK` | `5` | Maximum retained undo snapshots |
|
||||
| `MAX_DXF_BYTES` | `52428800` | Reject larger DXF input; `0` disables the check |
|
||||
| `MAX_LIST_LIMIT` | `5000` | Bound list and selection response sizes |
|
||||
| `COM_CALL_TIMEOUT` | `60` | Per-call live AutoCAD timeout in seconds |
|
||||
| `DANGEROUS_COMMANDS_ENABLED` | `false` | Allow blocked commands/LISP and report unsafe mode |
|
||||
| `MAX_DXF_BYTES` | `52428800` | Reject larger DXF input; `0` disables |
|
||||
| `MAX_LIST_LIMIT` | `5000` | Bound list/selection response sizes |
|
||||
| `COM_CALL_TIMEOUT` | `60` | Per-call live AutoCAD timeout (seconds) |
|
||||
| `DANGEROUS_COMMANDS_ENABLED` | `false` | Allow blocked commands/LISP; reported as unsafe mode |
|
||||
| `ALLOW_REMOTE_HTTP` | `false` | Permit a non-loopback HTTP bind |
|
||||
| `MCP_AUTH_TOKEN` | empty | Bearer token required for remote HTTP |
|
||||
|
||||
Backend selection:
|
||||
|
||||
| Value | Behavior |
|
||||
|---|---|
|
||||
| `auto` | Try COM on Windows, then fall back to ezdxf |
|
||||
| `com` | Require a reachable live AutoCAD instance |
|
||||
| `ezdxf` | Force portable, headless DXF operation |
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[MCP host / AI agent] --> B[FastMCP server]
|
||||
B --> C[Error · audit · timing · logging middleware]
|
||||
C --> D[Typed tool contract]
|
||||
D --> E[COM backend]
|
||||
D --> F[ezdxf backend]
|
||||
E --> G[Live AutoCAD]
|
||||
F --> H[Headless DXF]
|
||||
E --> I[Engineering quality + delivery]
|
||||
F --> I
|
||||
```
|
||||
|
||||
- `server.py` owns the FastMCP surface, lifespan, middleware, resources, and
|
||||
prompt templates.
|
||||
- `backends/base.py` defines the shared contract and capability model.
|
||||
- `backends/com_backend.py` serializes COM calls through one STA thread with
|
||||
per-call timeouts.
|
||||
- `backends/ezdxf_backend.py` wraps synchronous DXF work with
|
||||
`asyncio.to_thread` and snapshot-based transactions.
|
||||
- `engineering/` contains standards-aware planning, drawing, critique, scoring,
|
||||
refinement, validation, and delivery.
|
||||
- `security.py` centralizes path validation and command/LISP sanitization.
|
||||
|
||||
## Security model
|
||||
|
||||
The server treats tool input as untrusted:
|
||||
Tool input is treated as untrusted:
|
||||
|
||||
- Every file path passes through traversal and allowed-root validation.
|
||||
- Dangerous AutoCAD commands and AutoLISP channels are blocked by default.
|
||||
- Remote HTTP requires explicit opt-in and a bearer token.
|
||||
- DXF size, query-result size, undo history, and COM call duration are bounded.
|
||||
- Audit middleware records tool timing and failures.
|
||||
- `system_status` and `system_about` expose `unsafe_mode` when dangerous
|
||||
- every path passes traversal + allowed-root validation;
|
||||
- dangerous AutoCAD commands and AutoLISP channels are blocked by default,
|
||||
with regression tests for known bypass patterns;
|
||||
- remote HTTP requires explicit opt-in plus a bearer token;
|
||||
- DXF size, response sizes, undo history and COM call duration are bounded;
|
||||
- audit middleware records tool timing and failures;
|
||||
- `system_status` / `system_about` expose `unsafe_mode` when dangerous
|
||||
operations are enabled.
|
||||
|
||||
`DANGEROUS_COMMANDS_ENABLED=true` is a trust decision, not an installation
|
||||
shortcut. Keep it disabled for agents or clients you do not fully control.
|
||||
|
||||
Please avoid filing public issues for vulnerabilities. Contact the maintainer
|
||||
through [GitHub](https://github.com/U-C4N) first.
|
||||
Please report vulnerabilities privately via [GitHub](https://github.com/U-C4N)
|
||||
rather than public issues.
|
||||
|
||||
## Development
|
||||
|
||||
```bash
|
||||
pip install -e ".[full]"
|
||||
pip install pytest pytest-asyncio pytest-cov ruff build
|
||||
python -m pytest
|
||||
python -m ruff check .
|
||||
python -m ruff format --check .
|
||||
python -m pytest # 474 tests
|
||||
python -m ruff check . && python -m ruff format --check .
|
||||
python -m build
|
||||
```
|
||||
|
||||
Focused benchmark checks:
|
||||
|
||||
```bash
|
||||
python -m pytest tests/test_benchmark_chart.py tests/test_benchmark_v2.py -q
|
||||
python -m benchmarks.render_chart
|
||||
```
|
||||
CI runs the same gates on Linux (3.11/3.12), Windows (mocked-COM suite),
|
||||
plus package, Docker and MCP-registry-schema jobs. Releases are tag-driven:
|
||||
`git tag vX.Y.Z && git push origin vX.Y.Z` builds, publishes to PyPI and cuts
|
||||
the GitHub Release. See
|
||||
[`docs/RELEASE-DISTRIBUTION.md`](docs/RELEASE-DISTRIBUTION.md).
|
||||
|
||||
Repository map:
|
||||
|
||||
```text
|
||||
server.py FastMCP surface and orchestration
|
||||
config.py Environment-driven settings
|
||||
security.py Path, command, and AutoLISP guards
|
||||
version.py Canonical package version
|
||||
backends/ COM and ezdxf implementations
|
||||
engineering/ Standards, critique, refinement, delivery
|
||||
benchmarks/ Reproducible data, runners, and reports
|
||||
tests/ Headless, mocked-COM, contract, and security tests
|
||||
server.py FastMCP surface and orchestration
|
||||
config.py Environment-driven settings
|
||||
security.py Path, command, and AutoLISP guards
|
||||
version.py Canonical package version
|
||||
backends/ COM and ezdxf implementations
|
||||
engineering/ Standards, generators, critique, fits, delivery
|
||||
benchmarks/ Runners, adapters, published reports, chart renderers
|
||||
tests/ Headless, mocked-COM, contract, and security tests
|
||||
```
|
||||
|
||||
## Roadmap
|
||||
## Roadmap (1.5)
|
||||
|
||||
The next priorities are capability-aware tool discovery, paper-space/layout
|
||||
depth, ISO 286 fits, Windows CI coverage, opt-in COM 3D solids, and real
|
||||
cross-project runtime adapters. Features are published when their contracts and
|
||||
limitations are testable—not when they make a longer checklist.
|
||||
Screenshot overlay + handle grounding, ezdxf redo (forward snapshots), COM
|
||||
`block_create_from_entities`, ISO 286 transition/interference hole letters
|
||||
(delta rule), titleblock on paper-space layouts. Features are published when
|
||||
their contracts and limitations are testable — not when they make a longer
|
||||
checklist.
|
||||
|
||||
## Contributing
|
||||
|
||||
Pull requests are welcome, especially for reproducible competitor adapters,
|
||||
Pull requests are welcome — especially reproducible competitor adapters,
|
||||
mocked/live COM coverage, engineering standards, and backend parity. For a
|
||||
large change, open an issue first so the tool contract and evidence plan can be
|
||||
agreed before implementation.
|
||||
large change, open an issue first so the tool contract and evidence plan can
|
||||
be agreed before implementation.
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
Reference in New Issue
Block a user