이 저장소가 대체 무엇인가.
Pascal Editor는 설치 없이 브라우저에서 집의 평면도를 그리고 3D로 확인하는 오픈소스 3D 건축 편집기다. 벽을 그으면 자동으로 모서리가 맞춰지고(mitering), 문을 배치하면 벽에 구멍이 뚫리며(CSG), 계단을 놓으면 위층 슬라브에 자동으로 개구부가 생긴다.
하지만 2026년 7월 현재 가장 중요한 변화는 packages/mcp다. README은 이를 "Model Context Protocol server for the Pascal 3D editor. Drives the @pascal-app/core scene graph from any MCP-compatible AI host."라고 설명한다 — 즉 Claude 같은 AI가 브라우저 없이 헤드리스로 씬을 조작할 수 있다. create_wall, place_item, cut_opening부터 사진 한 장으로 방을 3D로 재구성하는 photo-to-scene까지, 40개 넘는 MCP 툴이 등록돼 있다.
README의 자기소개는 짧고 명확하다: "A 3D building editor built with React Three Fiber and WebGPU." 실제로 열어 보면 Site → Building → Level → (Wall/Slab/Ceiling/Roof/Zone) → Item의 계층 구조 위에서, 각 요소가 Zod 스키마로 타입 검증되고 Zustand 스토어에 플랫 딕셔너리로 저장된다.
루트 AGENTS.md(=CLAUDE.md=GEMINI.md 심링크)는 이 레포가 "Consumed both as npm packages and (in pascalorg/private-editor) as a git submodule"라고 밝힌다 — 즉 이 공개 레포가 상용 서비스(private-editor)의 엔진 역할도 겸한다. 오픈소스 코어 위에 비공개 프로덕트를 얹는 전형적인 "오픈 코어" 전략이다.
stdio 또는 HTTP로 "MCP 서버"와 통신하며, 서버가 노출한 tools(함수)·resources(데이터)·prompts(템플릿)를 AI가 호출한다. Pascal Editor의 @pascal-app/mcp는 "3D 씬 편집"을 MCP 툴로 노출해, AI가 "침실 3평짜리 방 하나 만들어줘"라고 하면 실제로 벽 노드가 생성되게 한다.수백 개의 벽·문·창문·배관을 다루면서도 60fps를 유지하는 비결은 모든 노드를 Record<id, Node> 평면 딕셔너리에 저장하고, 변경된 노드만 dirtyNodes Set에 표시해 다음 프레임에서 그 노드의 지오메트리만 재계산하는 것이다. Figma·Notion류 에디터가 쓰는 패턴을 3D 씬 그래프에 적용한 사례다.
WebGPU 실전 적용 · MCP로 "AI가 집 짓기" · IFC 건축 표준 지원 · 서드파티 플러그인 생태계.
Spline·SketchUp Web 같은 도구는 WebGL 기반이거나 폐쇄형 SaaS다. 오픈소스 + WebGPU + React 생태계 통합 + AI 에이전트 연동을 동시에 만족하는 3D 건축 에디터는 사실상 없었다.
| 영역 | 2026-03 시점 | 2026-07 현재 |
|---|---|---|
| 패키지 수 | 앱 1개 + 패키지 9개 | 앱 2개 + 패키지 10개(+mcp) |
| 노드 타입 | Wall/Slab/Zone/Item 등 소수 | 44종 — 계단·엘리베이터·배관 포함 |
| AI 연동 | 없음 | packages/mcp — 자연어 씬 조작 |
| 건축 표준 | 없음 | packages/ifc-converter |
| 확장성 | 내장 기능뿐 | 공식 Plugin 계약(plugin-trees) |
완전 오픈소스이면서 WebGPU 렌더러를 쓰고, 건축 특화 CSG 불리언 연산(벽에 문 구멍 뚫기)과 Claude가 직접 부를 수 있는 40여 개의 MCP 툴을 동시에 갖춘 것이 독보적이다. "AI가 도면을 그리는" 데모가 실제로 동작하는 몇 안 되는 오픈소스 사례다.
| 비교 항목 | Pascal Editor | Spline / SketchUp Web |
|---|---|---|
| 오픈소스 | ✅ MIT | ❌ |
| WebGPU 지원 | ✅ | ❌ (WebGL) |
| 건축 특화 노드 | ✅ 44종(MEP 포함) | △(범용 3D 또는 부분 지원) |
| AI 에이전트(MCP) 연동 | ✅ 공식 패키지 | ❌ |
| IFC 건축 표준 호환 | ✅ | ❌ / △(플러그인) |
주목도를 끌어올린 구체적 요인은 다음과 같다. ① "AI가 집을 짓는다"는 화제성. MCP 서버 하나로 Claude가 create_room·add_door·furnish_room을 호출해 실제 3D 건물을 만드는 데모는 AI 에이전트 시대의 대표적 활용 사례가 됐다.
② Vision AI 파이프라인. analyze_floorplan_image·analyze_room_photo·photo_to_scene 툴로 스마트폰 사진 한 장을 3D 씬으로 역변환하는 기능은 실측(measurement) 도구로도 활용 가치가 크다.
③ 프로덕션급 아키텍처 문서. wiki/architecture/의 17개 문서와 .agents/skills/review-architecture/는 대규모 오픈소스 프로젝트가 AI 코딩 에이전트와 협업하는 법을 실전으로 보여준다.
프론트엔드(R3F/WebGPU) · MCP 백엔드(Bun+SQLite) · Turborepo 10패키지 인프라.
| 기술 | 버전 | 역할 |
|---|---|---|
| React | 19.2.4 | UI 컴포넌트 프레임워크 |
| Next.js | 16.2.9 | SSR, 라우팅, 빌드(App Router) |
| Three.js | 0.184.0 | 3D 렌더링 엔진 (WebGPU 렌더러) |
| React Three Fiber | 9.5.0 | Three.js의 React 선언적 래퍼 |
| Drei | 10.7.7 | R3F 유틸리티 컴포넌트 모음 |
| Tailwind CSS | 4.2.1 | 유틸리티 기반 CSS |
| Radix UI | 1.2.8 | 접근성 갖춘 헤드리스 UI(Tooltip 등) |
| 기술 | 역할 |
|---|---|
| Zustand | 경량 상태관리 — 스토어 계층(useScene/useViewer/useEditor) 분리 |
| Zundo | Zustand 기반 Undo/Redo(50단계 히스토리, "시간 여행" 미들웨어) |
| Zod | 4.3.5 — 44종 노드 스키마의 런타임 검증. MCP 툴 입력 검증에도 재사용 |
| IndexedDB | 클라이언트 영구 저장소(브라우저) |
| 기술 | 역할 |
|---|---|
| three-bvh-csg | BVH 기반 CSG 불리언 연산 — 벽에 문/창문 구멍 뚫기, 지붕 절단 |
| Spatial Grid Manager | 충돌 감지 및 배치 유효성 검사 |
| mitt | 타입 안전 이벤트 이미터 — 노드/그리드 이벤트 버스 |
| @dgreenheck/ez-tree | 플러그인(plugin-trees)의 프로시저럴 나무 지오메트리 라이브러리 |
| 기술 | 역할 |
|---|---|
| Bun 런타임 | 브라우저·React·WebGPU 없이 헤드리스로 씬 그래프 조작 |
| MCP SDK | tools/resources/prompts 노출. stdio 및 HTTP(bearer token) 트랜스포트 지원 |
| SQLite(WAL 모드) | ~/.pascal/data/pascal.db — 로컬 씬 저장, 트랜잭션 버전 체크로 동시 저장 충돌 방지 |
| Server-Sent Events | MCP가 편집한 변경을 스트리밍 → 열린 브라우저 탭에 실시간 반영 |
| Vision 분석 툴 | 이미지를 씬 데이터로 해석(analyze-floorplan-image 등) |
| 기술 | 버전 | 역할 |
|---|---|---|
| Turborepo | 2.9.17+ | 10패키지 모노레포 빌드 오케스트레이션, 증분 캐시 |
| Bun | 1.3.0 | 패키지 매니저 & 런타임(packageManager 고정) |
| Biome | 2.4.16 | Rust 기반 Linter+Formatter(ESLint/Prettier 대체) |
| TypeScript | 6.0.3 | 전 패키지 100% 타입 커버리지 |
| react-scan | 0.5.3 | React 렌더링 성능 시각화(dev) |
packages/core/src/schema/nodes/)는 에디터 UI의 폼 검증뿐 아니라 MCP 툴의 입력 파라미터 검증에도 그대로 재사용된다. 사람이 클릭해서 만든 벽이든, Claude가 create_wall을 호출해 만든 벽이든 동일한 타입 안전성을 보장받는다는 뜻이다.3계층 레이어 경계 + 3체크박스 노드 정의 모델 + MCP↔브라우저 실시간 동기화.
Pascal Editor의 아키텍처는 AGENTS.md가 못박은 세 개의 엄격한 레이어 경계 위에 서 있다. packages/core는 Three.js를 몰라야 하고(순수 도메인 로직), packages/viewer는 에디터 개념(툴·패널·모드)을 몰라야 하며(뷰어 격리), apps/editor만 이 둘을 조합해 실제 편집 경험을 만든다. 이 경계 위에 MCP 서버가 core를 헤드리스로 직접 구동하는 네 번째 진입점이 얹혀 있다.
먼저 전체 그림 한 장으로 숲을 본다.
이제 대표 흐름 한 줄기 — "AI가 벽 하나를 새로 만들면 브라우저 화면에 어떻게 나타나는가" — 를 입력부터 출력까지 손으로 따라가 본다.
packages/viewer가 useEditor·에디터 툴·페인트 모드 같은 "에디터 전용 어휘"를 절대 몰라야 한다는 규칙. 덕분에 @pascal-app/viewer는 단독 npm 패키지로 배포돼, 서드파티가 에디터 기능 없이 "3D 뷰어만" 임베드할 수 있다. 위반 여부는 .agents/skills/review-architecture 스킬이 PR마다 자동 점검한다.
Pascal에서 흔한 모양새는 노드 종류(kind)마다 NodeDefinition의 독립적인 3개 필드 중 필요한 조합만 켜는 것이다. 조건 분기 대신 "필드 존재 여부 = 참여 여부"로 다형성을 표현한다.
| 필드 | 용도 | 고르는 기준 |
|---|---|---|
geometry? | 순수 함수. (node, ctx, ...) => Object3D | 노드 데이터만으로 메시가 결정될 때(선반·기둥·벽) |
renderer? | 커스텀 React 컴포넌트가 메시 생성을 전담 | useGLTF·인스턴싱·TSL 셰이더가 필요할 때(존, 나무) |
system? | 프레임마다 도는 컴포넌트(useFrame, null 반환) | 애니메이션·투명도 전환이 필요할 때(문 열림) |
// shelf — 순수 geometry만, React·프레임 로직 없음
export const shelfDefinition: NodeDefinition<typeof ShelfNode> = {
geometry: buildShelfGeometry, // geometry.ts의 순수 함수
}
// door — 순수 geometry + 애니메이션 system 병행
export const doorDefinition: NodeDefinition<typeof DoorNode> = {
geometry: buildDoorGeometry,
system: { module: () => import('./animation') }, // operationState 진행
}
3체크박스 모델은 "레고 부품 카탈로그"다. 어떤 부품(노드 킨드)은 순수 성형(geometry)만 필요하고, 어떤 건 조립 설명서(renderer)가 따로 있어야 하며, 어떤 건 태엽(system)이 돌아야 움직인다. 세 속성이 독립적이라 필요한 것만 골라 끼운다 — 모든 부품에 태엽을 강제하지 않는다.
MCP와 브라우저가 같은 씬을 동시에 편집할 수 있다는 점도 이 레포의 특징이다. 저장 전 버전을 체크해, 두 클라이언트가 동시에 저장하면 live_sync_version_conflict를 반환하고 재로드하게 한다 — 낙관적 동시성 제어(optimistic concurrency)의 실전 사례다. 이 흐름의 세부 예외 처리(충돌 재시도 로직 등)는 이 문서에서는 생략한다.
2개 앱 + 10개 패키지 Turborepo 모노레포 — 1,302개 TS/TSX 파일.
| 폴더 | 역할 |
|---|---|
packages/core/ | Three.js를 몰라야 하는 순수 로직. UI와 MCP가 동시 소비하는 단일 도메인 레이어. |
packages/viewer/ | 에디터 개념을 모르는 "순수 3D 캔버스", 그 자체로 npm 배포. |
packages/mcp/ | 신규 핵심. vision·photo-to-scene·scene-lifecycle·templates·variants 5그룹. |
wiki/architecture/ | AI 코딩 에이전트가 읽도록 설계된 규범 문서. PR 리뷰에 자동 활용. |
@pascal-app/{core,viewer,editor,mcp})을 오픈소스로 공개하고, 이를 서브모듈로 끌어와 쓰는 별도 비공개 저장소(pascalorg/private-editor)에서 상용 기능을 얹는 사업 모델. 커뮤니티 기여가 코어 엔진 품질을 직접 개선하면서도 회사는 별도 수익화 레이어를 가질 수 있다.이 저장소에서 "무엇을 배울 수 있는가" — 개념 → 코드 위치 → 실습 아이디어.
packages/mcp 전체가 "도메인 로직을 AI가 호출 가능한 툴로 노출하는 법"의 실전 교과서다. tools/index.ts에서 툴이 등록되는 방식, operations/scene-operations.ts가 core 스토어를 감싸는 어댑터 계층, storage/sqlite-scene-store.ts의 버전 체크 기반 낙관적 동시성 제어를 함께 읽으면 "브라우저 없는 헤드리스 AI 백엔드"를 통째로 배운다.
실습: packages/mcp/src/tools/measure.ts(가장 단순한 툴 중 하나)를 읽고, 같은 패턴으로 "노드 개수를 킨드별로 세는" 새 MCP 툴을 하나 추가해 호출해 보기.
packages/core가 Three.js를 import하면 안 된다는 규칙은 컴파일러가 아니라 AGENTS.md + review-architecture 스킬이 지킨다. 사람/AI 리뷰어가 읽는 "헌법 문서"로 아키텍처를 통제하는 대규모 오픈소스의 실전 운영 방식을 배운다.
실습: wiki/architecture/viewer-isolation.md를 읽고, packages/viewer 소스에서 실제로 에디터 전용 개념을 import하는 곳이 있는지 검증(없어야 정상).
plugin-trees는 "structurally identical to a third-party plugin" — 내부 전용 API를 전혀 쓰지 않고 @pascal-app/*를 peer-dependency로만 소비한다. 플러그인 작성자에게 신뢰를 주는 가장 확실한 방법은, 자사 팀도 같은 제약 안에서 만든 예제를 공개하는 것이라는 통찰을 얻는다.
실습: wiki/architecture/plugin-authoring.md의 Plugin 계약을 읽고, plugin-trees/src/index.ts가 그 계약의 어떤 필드를 채우는지 대조.
packages/ifc-converter는 Uint8Array의 IFC 바이트를 받아 Pascal의 노드/루트ID/통계로 변환하는 순수 함수 라이브러리다(DOM·React 의존 없음). 실무 CAD/BIM 파일 포맷을 다루는 첫 진입점으로 삼기 좋다.
실습: 공개 IFC 예제 파일을 apps/ifc-converter UI에 업로드해, 변환된 노드 수와 원본 IFC 엔티티 수를 비교.
코드 예시 하나로 낙관적 동시성 제어의 감을 잡아보자. "업데이트는 사람이든 MCP든 같은 경로를 탄다"는 점이 핵심이다.
// 업데이트 시 dirtyNodes에 자동 추가 (사람이든 MCP든 동일 경로)
useScene.getState().updateNode(wallId, { thickness: 0.2 })
// GeometrySystem 렌더 루프: dirty 노드 중 def.geometry 보유자만 처리
useFrame(() => {
for (const id of dirtyNodes) {
const group = sceneRegistry.nodes.get(id) // O(1)
const built = def.geometry(node, ctx, ...)
disposeOldChildren(group); group.add(...built.children)
clearDirty(id)
}
})
WebGPU 지원 브라우저 필수 · MCP 서버는 Bun만 있으면 헤드리스로 별도 구동.
| 구성요소 | 최소 요구사항 | 권장 사항 |
|---|---|---|
| 브라우저(에디터 UI) | Chrome 113+ / Edge 113+ (WebGPU 지원) | Chrome 최신 안정판 |
| GPU | WebGPU 지원 GPU | 전용 GPU, 복잡한 건물일수록 유리 |
| Node.js | 18+ | 20+ |
| Bun | 1.3.0(packageManager 고정) | 동일 버전 유지 권장 |
| RAM | 8GB | 16GB(다층 건물 + 다수 MEP 노드 편집 시) |
| MCP 서버(헤드리스) | Bun만 있으면 브라우저·GPU 불필요 | 에디터와 별도 프로세스로 상시 구동 |
| OS | macOS, Windows, Linux | — |
브라우저 3D 에디터를 직접 만져보려면 WebGPU GPU가 필요하지만, AI가 도면을 짜는 워크플로만 체험하고 싶다면 MCP 서버를 --stdio 모드로 실행하는 것만으로 충분하다. Claude Desktop 설정 파일에 서버를 등록하면 그래픽 환경 없이도 "AI에게 집을 설계시키는" 경험을 할 수 있다.
WebGPU는 Chrome/Edge에서 기본 활성화됐지만 Firefox·Safari는 여전히 플래그 뒤에 있거나 부분 지원이다. 또한 개발 서버는 반드시 루트 디렉토리에서 실행해야 packages/core·packages/viewer의 워처가 함께 돌아 핫 리로드가 동작한다 — 개별 앱 폴더에서 실행하면 패키지 변경이 반영되지 않는다.
난이도별로 손을 움직여 보는 5가지 — 3D 에디터부터 MCP AI 연동까지.
git clone https://github.com/pascalorg/editor.git
cd editor
bun install
bun dev
# http://localhost:3002 에서 에디터 열기
벽·바닥·계단·지붕을 그려 보고, packages/core/src/schema/nodes/ 폴더의 44개 파일 목록만 훑어보며 이 에디터가 얼마나 광범위한 건축 요소(굴뚝·태양광판·덕트·엘리베이터)를 다루는지 체감한다.
# 리포 루트에서
bun run --filter=@pascal-app/mcp build
claude mcp add pascal bun /absolute/path/to/editor/packages/mcp/dist/bin/pascal-mcp.js
Claude Code 세션에서 "정원 딸린 작은 집 하나 만들어줘"처럼 자연어로 요청해, create_room·add_door·furnish_room 같은 MCP 툴이 실제로 호출되는 과정을 관찰한다.
packages/nodes/src/에 새 킨드(예: "beam" 기둥보)를 추가하되, geometry만 채우는 가장 단순한 조합으로 시작한다. Zod 스키마 → nodeRegistry 등록 → 에디터 툴바에서 배치까지 전체 흐름을 경험한다.
packages/mcp/src/tools/vision/analyze-room-photo.ts와 photo-to-scene/을 읽고, 실제 방 사진을 MCP 클라이언트로 전달해 벽 위치·문/창문 추정 결과가 씬 노드로 변환되는지 확인한다.
packages/plugin-trees를 통째로 복사해 다른 조경 요소 플러그인으로 리네이밍하고, Plugin 계약(panels·parametrics·tool/preview)을 따라 좌측 프리셋 패널까지 갖춘 완전한 플러그인을 만든다.
5주 코스 — R3F/WebGPU 기초부터 MCP 서버 직접 만들기까지.
| 주차 | 주제 | 학습 자료 |
|---|---|---|
| 1주차 | R3F + WebGPU 기초, useFrame/useThree 훅, 벽 렌더링 경로 추적 | Three.js 공식 문서 · r3f.docs.pmnd.rs |
| 2주차 | Zustand 다중 스토어 분리 이유, Zundo Undo/Redo, node-definitions.md 정독 | wiki/architecture/ |
| 3주차 | CSG 불리언 연산 이론, BVH 가속 원리, 벽에 창문 배치 시 cutout 경로 추적 | three-bvh-csg 문서 |
| 4주차 | MCP 스펙(tools/resources/prompts), tools→operations→core 어댑터 정독 | modelcontextprotocol.io |
| 5주차 | Plugin 계약 정독 + 나만의 플러그인 완성, IFC 변환기로 CAD 상호운용성 실습 | wiki/architecture/plugin-authoring.md |
Pascal Editor는 세 분야가 교차한다. MCP(Anthropic의 AI 도구 연동 표준), BIM/IFC(건축 정보 모델링 업계 표준 — Revit·ArchiCAD와의 상호운용성), 그리고 게임 엔진 패턴(더티 플래그·씬 레지스트리 같은 시스템 분리). 이 셋을 동시에 다루는 오픈소스는 드물어, 각 분야를 따로 공부하되 이 레포를 "교차점 사례"로 삼으면 이해가 빠르다.
이 프로젝트를 읽을 때 반복 등장하는 용어 정리.
| 키워드 | 뜻 |
|---|---|
| MCP | AI 호스트(Claude 등)와 외부 도구/데이터를 연결하는 Anthropic 표준 프로토콜 |
| NodeDefinition(3체크박스) | geometry/renderer/system 3개 독립 필드로 렌더링 방식을 조합하는 등록 모델 |
| Dirty Node / Dirty Flag | 변경된 노드만 표시해 다음 프레임에 그 노드만 재계산하는 최적화 패턴 |
| Scene Registry | 노드 ID → Three.js Object3D 매핑. 선언적 React와 명령적 Three.js 사이의 브릿지 |
| Layer Isolation | core는 Three.js를, viewer는 에디터 개념을 몰라야 한다는 아키텍처 경계 규칙 |
| Live Sync | MCP의 씬 변경을 SSE로 스트리밍해 열린 브라우저 탭에 실시간 반영하는 메커니즘 |
| Optimistic Concurrency | 락 대신 저장 시 버전 체크로 동시 편집 충돌을 감지하는 방식 |
| CSG | 불리언 연산(합/차/교)으로 복잡한 형태를 만드는 기법. 벽에 문 구멍 뚫기에 사용 |
| BVH | Bounding Volume Hierarchy. 공간을 계층적으로 분할해 CSG·충돌·레이캐스팅을 가속 |
| IFC | 건축/BIM 업계 표준 파일 포맷. Revit·ArchiCAD 등과의 상호운용성 핵심 |
| Open Core | 엔진은 오픈소스로 공개하고 비공개 서브모듈 레포에서 상용 기능을 얹는 사업 모델 |
| Plugin (Manifest) | 서드파티가 노드 킨드·좌측 패널을 추가하는 공식 계약. 1st-party 예제는 plugin-trees |
| WebGPU | WebGL 차세대 표준. GPU 컴퓨트 셰이더, 멀티스레드 렌더링, 낮은 API 오버헤드 |
| Turborepo | 변경된 패키지만 증분 재빌드하는 모노레포 빌드 오케스트레이터 |
원본을 직접 확인하고 싶을 때.