# MCP Pencil Tools Reference / Tham Chiếu MCP Pencil

> [!NOTE]
> MCP Pencil cho phép tương tác realtime với Pencil editor thông qua các tools.
> Yêu cầu: Có file `.pen` đang mở trong Pencil editor.

## Khi Nào Dùng MCP vs Build Scripts

| Tác vụ | MCP Pencil | Build Scripts |
|--------|------------|---------------|
| Thiết kế UI realtime | ✅ Dùng MCP | ❌ |
| Xem screenshot | ✅ `get_screenshot` | ❌ |
| Lấy style guide | ✅ `get_style_guide` | ❌ |
| Build library từ Atomic | ❌ | ✅ `scripts/build.py` |
| Merge nhiều files | ❌ | ✅ `scripts/build.py -m` |
| Extract components | ❌ | ✅ `scripts/extract-atomic.py` |

---

## Tools Overview

### 1. Document Management

| Tool | Mục đích |
|------|----------|
| `open_document` | Mở file `.pen` hoặc tạo mới (`"new"`) |
| `get_editor_state` | Lấy state hiện tại: file đang mở, selection, components |
| `get_variables` | Đọc design tokens (colors, spacing, typography) |
| `set_variables` | Cập nhật design tokens |

### 2. Design Operations

| Tool | Mục đích |
|------|----------|
| `batch_design` | Insert/Update/Replace/Copy/Move/Delete nodes |
| `batch_get` | Đọc nodes theo ID hoặc search patterns |
| `snapshot_layout` | Kiểm tra layout structure, tìm overlapping |
| `find_empty_space_on_canvas` | Tìm vị trí trống để đặt frame mới |

### 3. Guidelines & Inspiration

| Tool | Mục đích |
|------|----------|
| `get_guidelines` | Lấy hướng dẫn theo topic: `design-system`, `landing-page`, `table`, `code`, `tailwind` |
| `get_style_guide_tags` | Liệt kê tags có sẵn cho style guide |
| `get_style_guide` | Lấy style guide theo tags hoặc tên |

### 4. Verification

| Tool | Mục đích |
|------|----------|
| `get_screenshot` | Chụp screenshot node để verify |

### 5. Batch Operations

| Tool | Mục đích |
|------|----------|
| `search_all_unique_properties` | Tìm all unique values của properties |
| `replace_all_matching_properties` | Thay thế properties matching |

---

## batch_design Operations

Operations trong `batch_design` dùng syntax đặc biệt:

```javascript
// Insert (I) - Thêm node mới
binding=I(parent, {type: "frame", layout: "vertical", ...})

// Update (U) - Cập nhật properties (KHÔNG dùng cho children)
U(nodeId, {content: "New text", fill: "$--foreground"})
U(instanceId+"/childId", {content: "Override text"})

// Replace (R) - Thay thế node hoàn toàn (dùng cho slot content)
newNode=R(instanceId+"/slotId", {type: "text", content: "Custom"})

// Copy (C) - Copy node (tạo ref nếu reusable)
copiedNode=C(sourceId, parent, {positionDirection: "right", positionPadding: 100})

// Move (M) - Di chuyển node
M(nodeId, newParent, index)

// Delete (D) - Xóa node
D(nodeId)

// Generate Image (G) - Tạo image fill cho frame/rectangle
G(nodeId, "ai", "modern office workspace")  // AI generated
G(nodeId, "stock", "coffee shop interior")  // Stock photo
```

### Quy Tắc Quan Trọng

> [!IMPORTANT]
> - Mỗi I, C, R **PHẢI** có binding name
> - Dùng `instanceId+"/childId"` để override descendants
> - **KHÔNG** dùng U() cho descendants của node vừa Copy - dùng `descendants` trong Copy operation
> - Max 25 operations mỗi `batch_design` call

---

## Workflow Chuẩn

### 1. Khởi Đầu
```
get_editor_state(include_schema: true)
→ Xác định file, selection, reusable components
```

### 2. Lấy Context
```
get_guidelines("design-system")  // Hoặc "landing-page"
get_variables()                   // Design tokens
batch_get(patterns: [{reusable: true}], readDepth: 2)  // Components
```

### 3. Thiết Kế
```
// Tạo placeholder frame trước
batch_design(`
screen=I(document, {type: "frame", placeholder: true, ...})
`)

// Thêm content
batch_design(`
sidebar=I("screenId", {type: "ref", ref: "SidebarComp"})
content=I("screenId", {type: "frame", ...})
...
`)

// Xóa placeholder khi xong
batch_design(`U("screenId", {placeholder: false})`)
```

### 4. Verify
```
get_screenshot(nodeId: "screenId")
→ Kiểm tra visual output
```

---

## Ví Dụ: Dashboard Screen

```javascript
// Batch 1: Structure
screen=I(document, {type: "frame", name: "Dashboard", layout: "horizontal", width: 1440, height: 900, fill: "$--background", placeholder: true})
sidebar=I(screen, {type: "ref", ref: "SidebarComp", height: "fill_container"})
main=I(screen, {type: "frame", layout: "vertical", width: "fill_container", height: "fill_container", padding: 32, gap: 24})

// Batch 2: Sidebar items
item1=I(sidebar+"/contentSlot", {type: "ref", ref: "SidebarItem", descendants: {"labelId": {content: "Dashboard"}}})
item2=I(sidebar+"/contentSlot", {type: "ref", ref: "SidebarItem", descendants: {"labelId": {content: "Users"}}})

// Batch 3: Main content
header=I("mainId", {type: "frame", layout: "horizontal", width: "fill_container", justifyContent: "space_between"})
title=I(header, {type: "text", content: "Dashboard", fontSize: 24, fontWeight: "600", fill: "$--foreground"})
cards=I("mainId", {type: "frame", layout: "horizontal", gap: 16})
card1=I(cards, {type: "ref", ref: "CardComp", width: "fill_container"})
card2=I(cards, {type: "ref", ref: "CardComp", width: "fill_container"})

// Batch 4: Finalize
U("screenId", {placeholder: false})
```

---

## Common Patterns

### Override Component Text
```javascript
button=I(container, {type: "ref", ref: "ButtonComp"})
U(button+"/labelText", {content: "Submit"})
```

### Replace Slot Content
```javascript
card=I(container, {type: "ref", ref: "CardComp"})
customContent=R(card+"/contentSlot", {type: "frame", layout: "vertical", gap: 8, children: [
  {type: "text", content: "Custom Title", fontSize: 18},
  {type: "text", content: "Description", fontSize: 14}
]})
```

### Add Image to Frame
```javascript
heroFrame=I(container, {type: "frame", width: 600, height: 400})
G(heroFrame, "ai", "modern tech office, bright, professional")
```

### Find Empty Space
```javascript
find_empty_space_on_canvas(width: 1440, height: 900, padding: 100, direction: "right")
→ Trả về {x, y} cho vị trí trống
```

---

## Troubleshooting

| Vấn đề | Giải pháp |
|--------|-----------|
| "A file needs to be open" | Dùng `open_document` trước |
| Update descendants fail | Dùng path: `instanceId+"/childId"` |
| Copy descendants fail | Dùng `descendants` trong Copy, KHÔNG Update riêng |
| Nodes overlap | Dùng `find_empty_space_on_canvas` |
| Layout broken | Kiểm tra `snapshot_layout(problemsOnly: true)` |

---

## Related

- [Design System Guidelines](./DESIGN_SYSTEM.md) - Nếu có
- [File Format Reference](./FILE_FORMAT.md) - Chi tiết .pen schema
- [Build System Reference](./BUILD_SYSTEM.md) - Scripts cho build/extract
