Power CAD MCP
One line: Draw, inspect, and edit AutoCAD drawings — live via COM or headless DXF — directly from an MCP client.
Session & files:
cad_status,new_drawing,open_drawing,save_drawing,get_drawing_info(name, path, units, current layer, entity count, extents).Layers:
list_layers,create_layer,update_layer(color, linetype, on/frozen/locked, rename),set_current_layer,delete_layer(unused only).Draw entities: lines, polylines, rectangles, polygons, circles, arcs, ellipses, points, single/multiline text, dimensions (aligned/linear/horizontal/vertical), hatches (ANSI31, SOLID, …).
Batch drawing:
draw_batchruns up to 500 operations in one call.Blocks:
list_blocks,create_blockfrom existing entities,insert_block(by name or .dwg path, with scale/rotation).Query & edit:
list_entities,get_entityby handle, thendelete_entities,move_entities,copy_entities,rotate_entities,scale_entities,mirror_entities,offset_entity,set_entity_properties.Views & output:
zoom_extents,zoom_window,render_preview(PNG to eyeball results),export_drawingto pdf/dwg/dxf/png/svg/bmp/wmf.Raw AutoCAD commands:
run_command(AutoCAD backend only; shell/loader commands blocked, LISP off by default).Conventions: every created object returns a hex
handle; coordinates in drawing units[x, y(, z)]; angles in degrees CCW from +X.
Provides tools for reading, modifying, and validating AutoCAD 2027 drawings, including querying entities, replacing text, moving objects, modifying openings, creating geometry, and running atomic batch edits with dry-run previews, verification, and rollback.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Power CAD MCP change the door width to 900mm in the floor plan"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Power CAD MCP
AI 어시스턴트(Claude Desktop, Claude Code 등 MCP 클라이언트)가 AutoCAD 2027 도면을 읽고, 수정하고, 검증하도록 해 주는 Model Context Protocol 서버 모음입니다.
구성 | 위치 | 용도 |
power-cad-server + AutoCAD 2027 플러그인 (C#/.NET 10, 주력) | 실도면 수정. AutoCAD 내부에서 트랜잭션으로 실행하고, 수정 직전 대상 확인·수정 직후 자동 검증·실패 시 롤백 | |
power-cad-mcp (Python) | COM 폴백 작도 및 파일 인벤토리(42개 도구)와 AutoCAD 없는 DXF/PNG/PDF 작도·미리보기, Ontology 건물 데이터 조회·도면 대조·블록 대조·인벤토리 대조·Graph RAG 질의응답(11개 도구) | |
best-cad-mcp (외부, 선택) |
| 도면 의미·객체 관계 분석 — 별도 MCP 서버로 함께 연결 |
설계 문서: 프레임워크 · 운영 지침(ASTRA) · 시각 안내 · 오픈소스 고정 목록
주력: power-cad-server (C#)
Claude ─stdio─▶ power-cad-server ─Named Pipe(토큰)─▶ PowerCad.Plugin.A27 (AutoCAD 2027 내부) ─▶ 도면 DB도구 65개 (C# 0.5.0 preview):
분류 | 도구 |
프레임워크 |
|
의미 컨텍스트 |
|
Ontology (읽기 전용) |
|
연결 |
|
조회 |
|
인벤토리 |
|
작성 |
|
수정 |
|
레이어 |
|
블록·패턴 자산 |
|
측정 |
|
화면 |
|
묶음 |
|
HS-STEEL 자산 |
|
저장 |
|
시각 검증 (보조, 읽기 전용) |
|
HS 강재 핸드오프 (읽기 전용) |
|
서버 옵션: power-cad-server [--simulate] [--target <autocad-2027-PID|PID>] [--read-only] [--home <dir>].
같은 값을 환경 변수 POWER_CAD_SIMULATE, POWER_CAD_TARGET, POWER_CAD_READ_ONLY, POWER_CAD_HOME(검색 폴더, 기본 %LOCALAPPDATA%\PowerCad)으로도 줄 수 있고 CLI 플래그가 우선합니다.
블록 라이브러리 폴더는 기본 Documents\PowerCad\blocks이며 POWER_CAD_BLOCK_LIBRARY로 바꿉니다.
AutoCAD가 명령·대화상자로 바쁘면 20초 안에 CAD_BUSY로 답합니다(POWER_CAD_BUSY_TIMEOUT, 초 단위로 변경).
모든 수정은 같은 절차를 거칩니다: 지문으로 대상 확인 → 한 트랜잭션에서 변경 → 변경된 대상만 재검증 → 실패 시 전체 롤백 → before/after 보고.
dry_run: true로 실제와 같은 조건의 미리보기를 받을 수 있습니다.
설치 (Windows, AutoCAD 2027)
git clone https://github.com/khs0927/power-cad-mcp
cd power-cad-mcp
powershell -ExecutionPolicy Bypass -File scripts\install_autocad_plugin.ps1.NET 10 SDK가 없으면 winget으로 설치한 뒤 플러그인과 서버를 빌드하고, AutoCAD 번들을
%APPDATA%\Autodesk\ApplicationPlugins\PowerCad.bundle에 설치하고, Claude Desktop에 power-cad를 등록합니다.
AutoCAD를 재시작한 뒤 명령줄에서 POWERCAD_STATUS로 확인하세요.
빌드 없이 쓰려면 Releases에서 PowerCad-<버전>-win-x64.zip을 받아 압축을 풀고, 그 폴더에서 powershell -ExecutionPolicy Bypass -File scripts\install_autocad_plugin.ps1 -SkipBuild를 실행합니다.
AutoCAD 없이 먼저 써 보기: power-cad-server --simulate (샘플 평면도: 벽, 실명, 동적 문, 창, 잠긴 레이어).
개발
./scripts/build_dotnet.sh # restore → build(플러그인 포함) → 전체 테스트 → dist/PowerCad.bundle, dist/server/win-x64
dotnet test dotnet/PowerCad.TestsRelated MCP server: autocad-mcp
Codex 연결
OpenAI Docs의 MCP 등록 안내에 따라 빌드된 서버를 등록합니다.
powershell -ExecutionPolicy Bypass -File scripts\register_codex.ps1개발용 시뮬레이터는 -Name power-cad-dev -Simulate로 별도 등록할 수 있습니다.
등록 전에 새 플러그인도 설치해야 실제 도면에서 새 계약을 사용할 수 있습니다.
새 서버에서는 cad_get_document_identity로 현재 도면 ID를 읽고 cad_bind_document로 고정한 뒤 수정합니다.
document_id는 도면 DB의 FingerprintGuid에 묶여 있어 같은 세션에서 다시 조회해도 바뀌지 않습니다(database_fingerprint로도 확인 가능).
자세한 개발 상태·사용 순서·인수 조건은 프레임워크 운영 문서를 참조하세요.
보조: power-cad-mcp (Python)
AutoCAD 백엔드 (Windows) — 실행 중인 AutoCAD에 COM으로 붙어 실시간으로 그립니다.
Headless DXF 백엔드 (모든 OS) — AutoCAD 없이 ezdxf로 도면을 만들고 DXF/PNG/PDF/SVG로 저장합니다.
두 백엔드는 같은 42개 도구를 제공합니다.

도구 목록 (Python)
분류 | 도구 |
세션/파일 |
|
레이어 |
|
작도 |
|
블록 |
|
조회/편집 |
|
화면/기타 |
|
Ontology (읽기 전용) |
|
save_drawing(path=...)·export_drawing은 열려 있는 도면 자신이 아닌 기존 파일을 덮어쓰지 않습니다. 교체하려면overwrite=true를 명시하세요 (자동 승인되는 WRITE 도구가 도면 텍스트의 프롬프트 주입으로 사용자 파일을 덮어쓰는 것을 방지).
규칙:
좌표는
[x, y]또는[x, y, z](도면 단위), 각도는 도(degree), +X 기준 반시계 방향입니다.생성된 모든 객체는 handle(16진 문자열)과 함께 반환되며, 이후 편집은 handle로 합니다.
색상은 ACI 번호(0–256) 또는 이름(
red,yellow,green,cyan,blue,magenta,white,bylayer…).많은 객체를 그릴 때는
draw_batch한 번으로 처리하면 훨씬 빠릅니다 (AutoCAD 왕복 횟수 감소).상대 경로는
POWER_CAD_WORKSPACE(기본: 현재 폴더) 기준으로 해석되며, 확장자가 없으면 자동으로 붙습니다.
설치 (Python, Windows + AutoCAD 2027)
사전 조건: Windows 10/11, AutoCAD 2027 실행 중, Python 3.10+ (없으면 스크립트가 uv로 설치).
git clone https://github.com/khs0927/power-cad-mcp
cd power-cad-mcp
powershell -ExecutionPolicy Bypass -File scripts\setup_windows.ps1스크립트가 하는 일: .venv 생성 → 패키지 설치 → AutoCAD 연결 확인(--check) →
%APPDATA%\Claude\claude_desktop_config.json에 power-cad-py 서버 등록(기존 파일은 .bak으로 백업).
주력 C# 서버(power-cad, install_autocad_plugin.ps1이 등록)와 이름이 겹치지 않아 둘을 함께 쓸 수 있습니다. 다른 이름은 -Name으로 지정합니다.
끝나면 Claude Desktop을 재시작하세요.
수동 등록
Claude Desktop (%APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"power-cad-py": {
"command": "uvx",
"args": ["--from", "git+https://github.com/khs0927/power-cad-mcp", "power-cad-mcp"],
"env": { "POWER_CAD_BACKEND": "autocad" }
}
}
}Claude Code:
claude mcp add power-cad-py -e POWER_CAD_BACKEND=autocad -- uvx --from git+https://github.com/khs0927/power-cad-mcp power-cad-mcp연결 확인
.venv\Scripts\power-cad-mcp.exe --backend autocad --check # 상태 JSON 출력, 연결 실패 시 exit 1
python scripts\smoke_test_autocad.py # 새 도면에 테스트 도형을 그림설정 (환경 변수)
변수 | 기본값 | 설명 |
|
|
|
| – | COM ProgID 지정(쉼표 구분). 기본 순서: |
|
|
|
| 현재 폴더 | 상대 경로 기준 폴더 |
| – | DXF 백엔드에서 시작 시 열/저장할 파일 |
|
|
|
|
|
|
| – |
|
|
| Ontology MCP 실행 명령. ROOT가 설정된 경우 기본값 사용 |
|
| .NET 서버 전용: |
|
| .NET AutoCAD 플러그인: AutoCAD가 명령·대화상자로 바쁠 때 |
| – | Sion Ontology Platform의 HTTP base URL. 설정 시 Sion AEC federation을 우선 사용 |
|
| Sion AEC HTTP 호출 제한시간(초, 1–120) |
| – | 원격 Sion 호출용 Bearer token. loopback이 아닌 Sion URL에는 필수 |
| Python: |
|
|
| Python·C# 서버: Ontology REST 호출 제한시간(초, 1–120). .NET |
|
| Python·C# 서버: |
| – | Python·C# 서버가 Ontology REST에 보내는 Bearer token. Ontology 서버의 |
|
| Python 서버: |
| – | 테스트 전용: 설정하면 |
CLI 옵션: power-cad-mcp [--backend auto|autocad|dxf] [--workspace DIR] [--dxf-path FILE] [--launch] [--transport stdio|streamable-http|sse --host 127.0.0.1 --port 8765] [--check] [--version]
Sion / Ontology / CAIR 컨텍스트 연결
C#/.NET 10 주력 서버는 두 개의 읽기 전용 의미 컨텍스트 경로를 지원합니다.
POWER_CAD_SION_URL이 설정되어 있으면 Sion Ontology Platform의/api/v1/aec/query를 우선 사용합니다.Sion URL이 없으면 기존
POWER_CAD_ONTOLOGY_ROOT+aec-mcp직접 연결을 사용합니다.
Sion 경로에서는 응답이 반드시 canonical=false, read_only=true여야 합니다. 이 계약을 만족하지 않으면 Power CAD가 컨텍스트를 거부합니다.
cad_context_query가 Sion 또는 Ontology에서 CAIR global memory를 검색합니다.CAD 형식의
geometry_ref에서 handle 후보만 추출합니다.후보마다 현재 AutoCAD에
cad_get을 호출해 실제 존재와 fingerprint를 검증합니다.결과는 1, 2, 3… 번호가 붙은
context_idcandidate space로 반환됩니다.cad_context_select(context_id, choice)가 선택 시점에 fingerprint를 다시 검증합니다.cad_context_actions(context_id, candidate_choice)가 현재 live entity에 허용되는 작업만 번호형 action-space로 반환합니다.cad_context_action_select(..., action_choice)가 번호를 실제cad_get/cad_move/cad_replace_text/cad_modify_opening중 하나로 해석하면서 fingerprint를 다시 검증합니다.후보 선택과 action 선택 모두
may_execute_mutation=false입니다. 실제 수정은 기존 edit tool의expect_fingerprint와 transaction/rollback 경계를 그대로 거쳐야 합니다.
골든 경로는 Ontology → Sion AEC federation → Power CAD live verification → AutoCAD transaction/rollback입니다. Ontology/GraphRAG/Sion 결과가 직접 AutoCAD를 수정할 수 없고, 오래된 지식이나 잘못된 매핑은 live CAD 재검증 단계에서 차단됩니다.
Ontology 건물 데이터 자동 조회 (Python·C# 서버)
Google Drive의 모든 DWG/DXF를 파싱해 둔 Ontology(aec_intelligence, Postgres + AGE + pgvector)를 읽기 전용 REST API로 조회합니다.
자동화를 시작할 때 문·창·벽·실, 상세도, CAD 블록을 사용자가 일일이 나열하지 않아도 관련 항목을 스스로 모아 옵니다.
설정:
Ontology 쪽에서 REST API를 띄웁니다(Ontology
docker compose up api기본http://127.0.0.1:58000).다른 주소라면
POWERCAD_ONTOLOGY_URL을 지정합니다. 예:claude mcp add power-cad -e POWERCAD_ONTOLOGY_URL=http://127.0.0.1:58000 -- power-cad-mcpC# 주력 서버(power-cad-server)는 기본 주소가 없으므로 항상 지정합니다. 예:claude mcp add power-cad -e POWERCAD_ONTOLOGY_URL=http://127.0.0.1:58000 -- power-cad-server(C# 서버의ontology_*도구는 아래 표와 같은 이름·인자·결과를 돌려주며, 오류 문구 앞에[ONTOLOGY_UNAVAILABLE]/[ONTOLOGY_FAILED]같은 코드가 붙습니다.draw_batch연결과open_drawing표시는 Python 서버에만 있습니다.)서비스가 꺼져 있으면 각 도구는
Ontology service is not reachable at …오류를 돌려주고, 작도 도구는 영향을 받지 않습니다.
도구 | REST | 용도 |
|
| 종류별 객체 수(한글 별칭 포함), 도면 분류, 레이어, 블록, 층, 프로젝트 |
|
|
|
|
| 블록 정의, 사용 횟수, 속성 태그, 레이어, 예시 파일. |
|
|
|
|
| 객체와 1–2 hop 그래프 이웃(층·실·호스트 벽·시트·블록 정의) |
|
| 어휘 + 벡터 + 그래프 하이브리드 검색 ( |
|
| Graph RAG 질의응답: 서버가 질문을 키워드/벡터/지식그래프 탐색/프로젝트 요약으로 라우팅하고, 로컬 LLM(Ollama)이 그 근거만으로 한국어 답을 만듭니다. 모든 답은 |
| 위 조합 | 작업 문장 하나로 필요한 자료 묶음을 한 번에 반환 ( |
|
| Ontology 객체 id → 현재 열린 도면의 실제 handle 확인(읽기 전용) |
|
| Ontology 블록 중 열린 도면에 정의가 있어 |
|
| 도면 파일의 census와 Ontology가 가진 같은 파일의 행 대조: 수집 여부, 핸들 차이, 레이어별 객체 수, 클래스별 수(ZIUM 레이어 포함). 맞대어 볼 수 없는 것은 |
ontology_auto_context(task, drawing?, project_id?, k?)는 작업 문장(한국어/영어)에서 키워드로 대상을 추론합니다.
project_id를 주면 객체·도면·블록·검색 호출 모두 그 프로젝트로 한정합니다.
문/도어/door →
Door, 창/창문/window →Window, 창호 →Window+Door, 벽/벽체/wall →Wall, 실/방/room →Space기둥 →
Column, 보 →Beam, 철골/H-형강 →SteelSection+구조도, 계단·슬래브평면/상세/단면/입면/구조/리스트·일람표 → 도면 분류, 블록/심볼 → 블록 목록
2층/2F/지하1층/B1F/옥상→ 층,AW-02같은 부호 → 검색어
예: "2층 평면도 문 리스트 갱신" → 2F의 Door 객체, 평면도·일람표 시트, Door 블록, 검색 결과를 한 번에 받습니다.
층/시트/부호 필터로 결과가 없으면 해당 클래스 전체로 넓히고 warnings에 이유를 남깁니다.
검색은 추론한 클래스(하나일 때)와 층을 kind/storey 필터로 함께 보냅니다. API는 층을 정확히 일치로 비교하고 층 정보가 없는 도면도 많으므로,
층 필터로 결과가 없으면 층 없이 다시 찾습니다. API가 질의 전체를 한 구절로 비교하기 때문에 작업 문장으로 결과가 없으면
부호·도면·클래스 단어로 다시 검색하는데, 클래스 단어는 그 클래스를 kind로 묶어 보내므로 창이 창고, 실이 화장실에 걸리지 않습니다.
이때 warnings에는 실제로 보낸 키워드만 남깁니다.
도면이 열려 있으면 묶음의 검색 결과·객체마다 in_open_drawing(원본 파일이 지금 열린 도면인지)이 붙고, open_drawing과
counts.in_open_drawing이 함께 옵니다. 열린 도면을 알 수 없으면(예: AutoCAD 미실행) 이 표시는 조용히 생략됩니다.
Ontology 객체 → 도면 handle (ontology_locate)
Ontology 객체에는 handle, document_id, source_file이 있지만 handle은 도면 하나 안에서만 고유합니다.
다른 도면의 handle을 그대로 move_entities에 넘기면 엉뚱한 객체가 바뀔 수 있으므로, 편집 전에 ontology_locate(element_ids)로 확인합니다.
객체마다
/v1/elements/{id}/context로 행을 받아source_file과 열린 도면(get_drawing_info의 name/path)을 비교합니다. 양쪽 모두 폴더가 있으면 전체 경로(구분자\=/, 겹친/정리, 대소문자 무시,.dwg/.dxf/.dwt/.dws확장자 무시)를 비교하고, 한쪽이 파일 이름뿐이면 파일 이름만 비교합니다(A-201.dwg=a-201.DXF). 이름이 같아도 열린 도면이 저장되지 않았거나(경로 없음) 기본 이름(Drawing1등)이면 같은 파일이라고 증명할 수 없으므로other_drawing("open drawing is unsaved/default-named; cannot prove it is the source file")입니다.같은 도면이면 모델 공간에서만 handle을 찾고(레이어 레코드·블록 정의 안·종이 공간 객체는 "없음"), 엔티티 종류·레이어·블록 이름이 객체 클래스에 맞는지 봅니다 (예: 블록
DOOR_SINGLE인 문인데 LINE이면 불일치, 문인데 DIMENSION/TEXT면 불일치, 실(Space)은 TEXT 허용).matched에는 긍정 근거가 하나 이상 필요합니다: 알려진 클래스(문·창·벽·기둥·실·주석 등), 같은 레이어, 또는 같은 블록 이름(익명*U…참조 포함).결과
status:matched(편집 가능) ·unverified(반대 근거도 긍정 근거도 없음 — 편집에 쓰지 않음) ·mismatch(handle은 있으나 대상이 달라 보임,reasons) ·handle_missing(같은 도면 모델 공간에 없음, 다른 배치 탭 등) ·other_drawing(다른 파일, 열린 도면 없음, 미저장/기본 이름 — handle을 조회조차 하지 않음) ·not_found(Ontology에 없는 id, 또는 API가 다른 객체를 돌려줌 —error: "API returned element …")../..같은 id는 오류로 거부합니다.각 결과에
element_id,handle,source_file,open_drawing,entity(종류·레이어·블록 이름·위치 요약)가 있고,matched_handles에 편집 가능한 handle만 모읍니다.도면을 절대 수정하지 않습니다.
권장 흐름:
ontology_auto_context(task)— 대상 후보를 모으고in_open_drawing으로 지금 도면의 것인지 확인필요하면 해당 도면을
open_drawing으로 연 뒤ontology_locate(element_ids)—status="matched"인 handle만 고름get_entity/move_entities/delete_entities/set_entity_properties등 편집 도구에 그 handle을 넘김
자동화 진입점 연결: draw_batch(operations, task="…", auto_context=true)로 호출하거나 POWERCAD_ONTOLOGY_AUTO_CONTEXT=1을 켜면
작도 전에 ontology_auto_context(task)가 실행되어 결과의 ontology_context에 붙습니다. 서비스가 꺼져 있어도 작도는 그대로 진행되고
ontology_context.available=false와 오류 문구만 남습니다. 조회가 성공하면 ontology_targets도 붙습니다: 묶음 안의 객체를 추가 Ontology 호출 없이
ontology_locate와 같은 규칙으로 열린 도면에 대조해, matched인 객체의 element_id·class·name·handle·엔티티 종류와 상태별 개수(counts)를 요약합니다.
작도 작업 자체는 바뀌지 않습니다. Ontology 결과는 참고 정보이므로, 실제 수정에는 matched handle만 쓰세요.
Ontology 블록 → insert_block (ontology_block_candidates)
insert_block은 열린 도면에 정의된 블록 이름만 받습니다. ontology_block_candidates(name_or_task, project_id?, limit?)는
Ontology 블록 카탈로그(/v1/blocks)와 열린 도면의 블록 정의(list_blocks)를 대조합니다. 도면을 수정하지 않고, 다른 파일에서 정의를 가져오지도 않습니다.
name_or_task: 블록 이름/와일드카드(DOOR*→name_like) 또는 작업 문장("문 블록 배치"→ 인스턴스가Door로 분류된 블록). 공백 없는 단어(문,door)는 이름과 분류 두 가지로 찾습니다.이름 비교는 대소문자를 무시하고 블록의
effective_names도 봅니다(동적 블록은*U12같은 익명 이름으로 저장되기 때문).insertable: 열린 도면에 정의가 있음 →insert_name을 그대로insert_block(name=…)에 넘깁니다(base_point,entity_count포함). 이름 질의에 맞지만 Ontology에 없는 도면 내 블록도note와 함께 여기에 나옵니다.other_files: 다른 도면에만 있음 →example_files에 있는 파일을 열어 작업하거나, 사용자가 블록을 직접 가져와야 합니다. Ontology가 이 도면에서 읽었다고 하는데 지금 정의가 없으면(purge/이름 변경)note로 알려 줍니다.not_insertable: XREF(Ontology 쪽이든 열린 도면의 같은 이름 정의든), effective name 없는 익명 블록. 블록 테이블을 읽지 못하면unverified에 두고warnings에 이유를 남깁니다.
도면 인벤토리 ↔ Ontology (ontology_census_check, Python 서버)
drawing_census(로컬, 파일의 모든 객체)와 Ontology(수집된 건물 데이터)는 따로 만든 인벤토리입니다.
ontology_census_check(path, census_json?, project_id?, standard?)는 같은 파일을 두고 둘을 대조합니다. 파일도 도면도 바꾸지 않습니다.
문서 찾기:
/v1/drawings의name/source_key를 파일명으로 비교(대소문자 무시,.dwg=.dxf). 여러 개면project_id→ 높은 리비전 → 최근 수집 순으로 고르고 나머지는other_documents.handles: handle이 있는 Ontology 요소를 census의entity_index에서 찾습니다.only_in_ontology는 수집 후 파일이 바뀐 것(또는 다른 리비전),only_in_census_*는 Ontology가 요소로 만들지 않은 레이아웃 객체(치수·일반 선 등 — 결함 아님). 블록 정의 내부와 ATTRIB은 제외합니다.layers: OntologyLayer행의entity_count/block_entity_count와 census의 레이아웃/블록 정의 객체 수 →equal/differs/not_in_ontology.classes: 클래스별 Ontology 요소 수 옆에 같은 레이어의 census 객체 수와 ZIUM 표준 레이어(문DOOR, 창WIN·WINBAR, 벽WAL1~3, 계단STAIR, 실실명)의 객체 수. 객체 수 ≠ 요소 수이므로 일치 판정은 하지 않습니다. 정확한 대조는handles입니다.not_comparable: handle 없는 Ontology 행(문서·레이어·뷰), 블록 내부, 기둥·구조벽이 섞인 ZIUMCOL, 표준 없이 만든 census 등 — 이유와 함께.파일이 수집 시각 이후 수정됐거나
census_json이 다른 파일의 것이면warnings에 남깁니다.entity_index가 없는 예전 census.json은drawing_census를 다시 돌리세요.
COM 편집 플랜에서 Ontology id 쓰기 (scripts/com_plan_runner.py)
com_plan_runner.py의 플랜(docs/playbooks/*.plan.json)은 대상을 handle + 예상 형상으로 고정합니다. op마다 elements를 두면
handle 대신(또는 함께) Ontology 객체 id로 대상을 지정할 수 있습니다.
{"id": "D1", "op": "delete", "elements": {"@door": "obs_18a…", "AA4": "obs_33b…"},
"expect": {"@door": "AcDbBlockReference", "AA4": "AcDbPolyline"}}@로 시작하는 키는 자리표시자로, 그 op의expect키·handles·handle에서 확인된 handle로 바뀝니다.그 밖의 키는 플랜에 이미 적힌 handle이며, 객체가 정확히 그 handle로 확인되어야 합니다.
검증 전에 Ontology REST API(
--ontology-url, 없으면POWERCAD_ONTOLOGY_URL, 기본http://127.0.0.1:58000)에서 객체를 받아ontology_locate와 같은 규칙(원본 파일 = 열린 도면, handle 존재, 엔티티 타당성)으로 대조합니다. 하나라도matched가 아니거나 쓰이지 않는 키·같은 handle로 겹치는 대상이 있으면{"ok": false, "stage": "resolve"}로 플랜 전체를 거부합니다(unverified도 거부, 해석 중 예외도 traceback 없이stage:"resolve").elements가 없어도 한 op 안에서 같은 handle을 두 번 적으면(aa4와AA4처럼 대소문자만 달라도) 검증 단계에서 거부합니다.그 뒤 기존 예상 형상 검사가 확인된 handle에 그대로 실행되고, 결과에
resolved(키 → id → handle)가 붙습니다.elements가 없는 플랜은 Ontology에 접속하지 않습니다.
보안
run_command는 AutoCAD 명령줄에 그대로 입력을 보냅니다. 도면 속 텍스트가 프롬프트에 섞여 들어올 수 있으므로
AutoCAD 밖으로 나갈 수 있는 명령(SHELL, START, SCRIPT, APPLOAD, NETLOAD, VBARUN, QUIT 등)은 항상 차단되고,
보안 관련 시스템 변수(SECURELOAD, TRUSTEDPATHS, MTEXTED 등 PROTECTED_SYSVARS)는 어떤 형태로도 바꿀 수 없고,
AutoLISP는 기본적으로 꺼져 있습니다. 필요 없다면 POWER_CAD_ALLOW_COMMANDS=0으로 완전히 끌 수 있습니다.
POWER_CAD_ALLOW_COMMANDS 기본값을 1로 유지하는 이유: run_command는 MCP destructive 주석이 붙어 있어 클라이언트가
실행 전 사용자 승인을 받고, OS·코드 로딩으로 나가는 경로(차단 명령, 보호 시스템 변수, LISP)는 기본값에서도 막혀 있습니다.
남는 위험은 열린 도면 안의 편집(되돌리기 가능)뿐인데, 끄면 FILLET/OFFSET 옵션처럼 전용 도구가 없는 작업을 전혀 할 수 없습니다.
도면을 무인으로 일괄 처리하거나 신뢰할 수 없는 도면 텍스트를 다룰 때는 0으로 두세요.
구조
src/power_cad_mcp/
server.py MCP 도구 정의 (MCPServer, mcp SDK 2.x)
backends/base.py 백엔드 인터페이스 (handle 기반, 각도=도)
backends/com_backend.py AutoCAD COM: 전용 STA 스레드, busy 재시도(IMessageFilter), 오류 변환
backends/dxf_backend.py ezdxf headless 백엔드 + 렌더링
safety.py run_command 필터
ontology.py Ontology REST 클라이언트(urllib), 작업 문장 키워드 추론, auto_context 묶음, 객체→도면 handle 대조(locate)
census.py drawing_census: 파일의 모든 객체 인벤토리(census.json)
census_check.py census ↔ Ontology 대조(ontology_census_check)
source_binding_acceptance.py Ontology 핸드오프 → 실행 전 준비 상태 검증(실행 권한은 부여하지 않음)
config.py · errors.py · geometry.py · colors.py 설정, 오류 변환, 기하 계산, 색 이름
tests/
fake_acad.py AutoCAD COM 객체 모델 모사 → COM 백엔드를 Linux CI에서도 검증
test_live_autocad.py 실제 AutoCAD 대상 테스트 (옵트인)COM 객체는 스레드(아파트먼트)에 묶여 있고 MCP 런타임은 동기 도구를 임의의 워커 스레드에서 실행하므로,
모든 AutoCAD 호출은 하나의 전용 STA 스레드로 모아서 실행합니다. AutoCAD가 바쁠 때(RPC_E_CALL_REJECTED)는
COM 메시지 필터가 자동으로 재시도하며, 도형을 만드는 호출은 중복 생성을 막기 위해 통째로 재실행하지 않습니다.
개발
uv venv && uv pip install -e ".[dev]"
pytest # DXF end-to-end, 가짜 AutoCAD COM, stdio 프로세스, Ontology 계약, 유닛 (실기 AutoCAD·실제 Ontology API 테스트는 옵트인)
ruff check . && ruff format --check .
python -m build # dist/*.whl, dist/*.tar.gz
python examples/demo_floor_plan.py # headless 데모 → examples/out/
python examples/demo_floor_plan.py --backend autocad # 실행 중인 AutoCAD에 그리기실제 AutoCAD 테스트 (Windows):
$env:POWER_CAD_LIVE_TESTS = "1"; pytest -m autocad -v실제 Ontology API와의 계약 테스트 (도면이 하나 이상 적재된 API가 필요, 읽기 전용):
POWERCAD_ONTOLOGY_LIVE_URL=http://127.0.0.1:58000 pytest tests/test_ontology_live.py -v문제 해결
Could not attach to a running AutoCAD— AutoCAD가 실행 중이고 도면 하나가 열려 있는지 확인하세요. AutoCAD와 MCP 서버는 같은 사용자, 같은 권한 수준이어야 합니다(한쪽만 "관리자 권한으로 실행"이면 COM 연결 실패).AutoCAD stayed busy— 명령 실행 중이거나 대화상자가 열려 있습니다. AutoCAD에서Esc를 누르고 다시 시도하세요.PDF 내보내기 —
DWG To PDF.pc3플로터를 사용해 도면 범위를 용지에 맞춰 출력합니다.DXF로 내보내기(AutoCAD) — AutoCAD의 SaveAs를 사용하므로, 원래 DWG가 있다면 다시 원래 파일로 저장해 활성 문서를 되돌립니다.
License
MIT
Available Tools
41 toolsadd_dimensionC
Dimension the distance between p1 and p2 (aligned, or linear/horizontal/vertical).
Inputs: p1 (required), p2 (required), location (required), kind, +4 more. Returns: object
add_hatchC
Fill a closed boundary with a hatch pattern or solid fill.
Inputs: boundary (required), angle, color, layer, +2 more. Returns: object
add_mtextB
Add multiline text (MTEXT) with its top-left corner at the insertion point.
Inputs: text (required), insert (required), color, layer, +2 more. Returns: object
add_textB
Add single-line text at the insertion point (left baseline).
Inputs: text (required), insert (required), color, layer, +2 more. Returns: object
cad_statusARead-onlyIdempotent
Report the active backend (AutoCAD over COM, or headless DXF), connection and open drawing.
Inputs: no named parameters. Returns: object
copy_entitiesB
Copy entities, offsetting the copies by a displacement vector. Returns the new entities.
Inputs: handles (required), displacement (required). Returns: result
create_blockC
Define a new block from existing model-space entities.
Inputs: name (required), handles (required), base_point (required), delete_source. Returns: object
create_layerB
Create a layer (or update it if it exists) and optionally make it current.
Inputs: name (required), color, linetype, lineweight, +1 more. Returns: object
delete_entitiesCDestructive
Erase entities.
Inputs: handles (required). Returns: object
delete_layerCDestructive
Delete an unused layer.
Inputs: name (required). Returns: object
draw_arcB
Draw a circular arc counter-clockwise from start_angle to end_angle.
Inputs: center (required), radius (required), end_angle (required), start_angle (required), +3 more. Returns: object
draw_batchB
Create many entities in one call. Returns the created entity (or error) for every operation.
Inputs: operations (required), stop_on_error. Returns: object
draw_circleC
Draw a circle.
Inputs: center (required), radius (required), color, layer, +1 more. Returns: object
draw_ellipseC
Draw a full ellipse.
Inputs: ratio (required), center (required), major_axis (required), color, +2 more. Returns: object
draw_lineC
Draw a straight line segment.
Inputs: end (required), start (required), color, layer, +1 more. Returns: object
draw_pointC
Place a POINT entity.
Inputs: location (required), color, layer. Returns: object
draw_polygonA
Draw a regular polygon as a closed polyline.
Inputs: sides (required), center (required), radius (required), color, +3 more. Returns: object
draw_polylineB
Draw a polyline through the points (2D lightweight polyline; 3D if Z varies).
Inputs: points (required), color, layer, closed, +1 more. Returns: object
draw_rectangleA
Draw an axis-aligned rectangle (closed polyline) from two opposite corners.
Inputs: corner1 (required), corner2 (required), color, layer, +1 more. Returns: object
export_drawingB
Export the drawing: AutoCAD → pdf/dwg/dxf/png/bmp/wmf; headless → dxf/png/pdf/svg.
Inputs: path (required), format. Returns: object
get_drawing_infoBRead-onlyIdempotent
Name, path, units, current layer, entity count and extents of the active drawing.
Inputs: no named parameters. Returns: object
get_entityBRead-onlyIdempotent
Get one entity's type, layer, color and geometry by handle.
Inputs: handle (required). Returns: object
insert_blockC
Insert a block reference.
Inputs: name (required), insert (required), color, layer, +2 more. Returns: object
list_blocksARead-onlyIdempotent
List block definitions available for insert_block.
Inputs: no named parameters. Returns: result
list_entitiesBRead-onlyIdempotent
List model-space entities with their geometry (filtered, up to limit).
Inputs: layer, limit, entity_type. Returns: object
list_layersARead-onlyIdempotent
List layers with color, linetype and on/frozen/locked/current state.
Inputs: no named parameters. Returns: result
mirror_entitiesA
Mirror entities across the line p1-p2 (keeps the originals unless delete_source).
Inputs: p1 (required), p2 (required), handles (required), delete_source. Returns: result
move_entitiesB
Move entities by a displacement vector [dx, dy(, dz)].
Inputs: handles (required), displacement (required). Returns: result
new_drawingA
Create a new, empty drawing and make it active.
Inputs: template. Returns: object
offset_entityB
Create a parallel copy (OFFSET) of a line, arc, circle or polyline.
Inputs: handle (required), distance (required). Returns: result
open_drawingB
Open an existing drawing and make it active.
Inputs: path (required). Returns: object
render_previewARead-onlyIdempotent
Render the current drawing to a PNG image so you can check the result visually.
Inputs: no named parameters.
rotate_entitiesB
Rotate entities about a base point.
Inputs: angle (required), handles (required), base_point (required). Returns: result
run_commandADestructive
Send raw input to the AutoCAD command line (AutoCAD backend only). Shell/script/loader commands are blocked; AutoLISP needs POWER_CAD_ALLOW_LISP=1.
Inputs: command (required). Returns: object
save_drawingA
Save the active drawing (optionally under a new name).
Inputs: path. Returns: object
scale_entitiesB
Scale entities uniformly about a base point.
Inputs: factor (required), handles (required), base_point (required). Returns: result
set_current_layerA
Make a layer current; new entities without an explicit layer go there.
Inputs: name (required). Returns: object
set_entity_propertiesB
Change an entity's layer, color, linetype or lineweight.
Inputs: handle (required), color, layer, linetype, +1 more. Returns: object
update_layerA
Change a layer's color/linetype, turn it on/off, freeze/thaw, lock/unlock or rename it.
Inputs: name (required), on, color, frozen, +3 more. Returns: object
zoom_extentsB
Zoom the view to show the whole drawing.
Inputs: no named parameters. Returns: object
zoom_windowA
Zoom the view to the window spanned by two corners.
Inputs: p1 (required), p2 (required). Returns: object
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 41 tools
Each tool targets a distinct action+resource: drawing primitives, entity edits (move/copy/rotate/scale/mirror), and layer operations are cleanly separated. Minor overlap between create_layer (which also updates) and update_layer, and draw_batch vs individual draw_* tools, but boundaries remain readable.
Overwhelmingly consistent verb_noun pattern (draw_line, list_entities, create_layer, zoom_extents). Only minor deviations like cad_status (noun-first) and get_drawing_info break the otherwise predictable scheme.
41 tools is heavy for a single server, though CAD genuinely spans drawing, layers, blocks, entity editing, views and export so most tools earn their place. Still, the surface could be trimmed or further consolidated (e.g. more batch variants).
Strong lifecycle coverage: drawing setup, primitives, layer management, blocks, entity CRUD and transforms, viewing and export. Gaps like trim/extend/fillet and undo are notable but not blocking for core workflows.
Related MCP Connectors
DXF and PDF/X-4 for AI agents: structured facts, PNG renders, an interactive in-chat viewer.
CAD in ChatGPT and Claude: editable parts, STEP/STL/drawings, in-chat 3D, automatic checks.
150+ hosted tools: describe-to-build CAD, scan-to-CAD, architecture studio, web research, media.
Headless CAD engine & MCP server for 2D/3D drafting, solids, DXF/SVG export, and automation.
Related MCP Servers
- AlicenseAqualityDmaintenanceEnables automated CAD operations via natural language, supporting both AutoCAD LT on Windows and headless DXF generation on any platform.8MIT
- AlicenseBqualityDmaintenanceEnables AI agents to automate AutoCAD LT and create DXF files headless, with tools for drawing, entity, layer, block, annotation, PID, and system operations.16MIT
- AlicenseAqualityDmaintenanceEnables reading, analyzing, and editing CAD files (DXF and DWG) via natural language, including entity queries, layer management, and safe copy-based edits.171MIT
- AlicenseAqualityBmaintenanceEnables an AI assistant to conversationally control Autodesk AutoCAD, drawing, inspecting, and editing plans, and includes a cross-platform DXF engine that runs without AutoCAD on macOS and Linux. It exposes tools for rendering views as images, batching geometry, blocks, and structures, measuring and checking plans, and undoing whole batches.12MIT