Files
autocad-mcp-pro/.cursor/skills/autocad-mcp/references/architecture.md
T
2026-04-27 12:20:57 +03:00

2.5 KiB

Architecture

File Structure

server.py                    FastMCP 3.0 server — all tool/resource/prompt registrations
├── config.py                Settings class (pydantic-settings, env vars)
├── security.py              validate_path() + sanitize_command() + sanitize_lisp()
└── backends/
    ├── base.py              AutoCADBackend ABC + data models
    ├── ezdxf_backend.py     Headless DXF ops via ezdxf library
    └── com_backend.py       Live AutoCAD control via pywin32 COM

Dual-Backend Strategy Pattern

AutoCADBackend (in base.py) is an abstract base class. Both backends implement the full interface. The server creates exactly one backend at startup via _make_backend():

  1. Check AUTOCAD_MCP_BACKEND env var
  2. If auto or com on Windows: try COM → fall back to ezdxf
  3. If non-Windows or ezdxf: use ezdxf

Data Models

Defined in base.py:

  • EntityInfo: {handle, type, layer, color, linetype, visible, properties}
  • LayerInfo: {name, color, linetype, lineweight, is_on, is_frozen, is_locked, is_current}
  • BlockInfo: {name, origin, attribute_count, entity_count, is_xref, description}
  • DrawingInfo: {name, full_path, saved, entity_count, layer_count, block_count, extents_min, extents_max, units, version, backend}
  • CommandResult: {ok, payload, error}

Backend Differences

Feature ezdxf COM
Platform Any Windows only
AutoCAD needed No Yes (running)
View/zoom No-op Full control
Screenshots matplotlib render Win32 window capture
Commands/LISP Not supported Full support
Undo DXF snapshot stack Native AutoCAD undo
Threading asyncio.to_thread via _async() ThreadPoolExecutor (single thread, STA)
File formats DXF only DWG + DXF

FastMCP Server

The mcp object is configured with:

  • Lifespan: autocad_lifespan — initializes backend, stores in ctx.lifespan_context["backend"]
  • Middleware: ErrorHandling → AuditLog (custom timing) → Timing → Logging
  • _backend(ctx): Helper that retrieves backend from context, raises ToolError if unavailable

Adding a New Tool

  1. Add abstract method to AutoCADBackend in backends/base.py
  2. Implement in EzdxfBackend — wrap sync calls with _async(func)
  3. Implement in ComBackend — wrap COM calls with self._com(func)
  4. Register in server.py: @mcp.tool(...) calling _backend(ctx).method(...)
  5. Use _dc(result) to convert dataclass returns to dicts
  6. Write tests in tests/