Skip to main content
Glama
h9661
by h9661
README.md
<div align="center">

# HWPX MCP Server

**한글 문서(HWPX)를 AI로 안전하게 읽고 · 편집하고 · 배치까지 재현한다.**

한컴오피스 없이 Node.js만으로 동작하는 [Model Context Protocol](https://modelcontextprotocol.io) 서버.
Claude·Cursor 등 MCP 클라이언트에 연결하면 146개 도구로 한글 문서를 다룰 수 있습니다.

[![Version](https://img.shields.io/badge/version-2.0.0-brightgreen)](CHANGELOG.md)
[![Tests](https://img.shields.io/badge/tests-790%20passing-brightgreen)](#-검증-quality-gates)
[![Tools](https://img.shields.io/badge/tools-146-blue)](#-도구-tools)
[![License](https://img.shields.io/badge/license-MIT-blue)](#-credits--license)
[![Node](https://img.shields.io/badge/node-%E2%89%A518-339933?logo=node.js&logoColor=white)](#-설치-installation)

</div>

---

HWPX는 ZIP + XML 구조라 한글 프로그램 없이도 다룰 수 있습니다. 하지만 "그냥 XML을 고치면" 문서가 깨지기 쉽습니다 — 이 서버는 **무손실 CST**와 **쓰기 게이트** 위에서 편집하고, 나아가 문서의 **레이아웃을 재현**하고 문서 전체를 **구조적으로 재구성**할 수 있음을 검증합니다.

```jsonc
// 30초 요약
open_document → search / edit (스타일 승계, 원자적 계획) → save_document   // 안전 편집
render_preview / render_pdf                                              // 저장 전 미리보기
reconstruct + verify:manipulation                                       // 원본과 구조·픽셀 동일 재구성 증명
```

## ✨ 무엇이 다른가 (Highlights)

- 🔒 **무손실 CST 아키텍처** — 무손실 XML 구문 트리가 단일 진실 소스. 수정하지 않은 문서는 저장 시 **바이트 단위로 동일**하고, 편집은 대상 요소 스팬 안에서만 바이트를 바꿉니다.
- ✅ **검증되는 쓰기** — 저장 응답이 `structural_integrity_verified`(아카이브/XML 불변식)와 `intent_verified`(편집 의도 대비 사후조건)로 분리됩니다. **검증에 실패한 쓰기는 디스크에 도달하지 않습니다.**
- 🧩 **의미 기반 안전 편집** — `insert_paragraphs`는 스타일·탭·번호 서식은 승계하되 위험한 페이로드는 제거하고, `preview_edit_plan` / `apply_edit_plan`으로 다중 편집을 하나의 스냅샷/undo 경계에서 원자적으로 적용(실패 시 롤백)합니다.
- 🖼️ **레이아웃 재현 엔진** — 섹션 CST를 Page→Column→Block→Line **박스 트리**로 배치(문단 여백·자간·줄간격, 표 auto-grow, 다단, 부동/인라인 객체). `render_preview`(페이지별 SVG HTML)와 `render_pdf`(헤드리스 Chrome)로 **저장 전에 결과를 미리 봅니다.**
- 🎯 **조작 완전성 (v2.0)** — 원본 문서를 빈 문서에 도구로 재구성하면 원본과 **구조적으로 동일**(해석-의미 diff=0)하고, 우리 렌더러로 출력한 PDF가 원본과 **픽셀 동일**함을 코퍼스 전체에서 게이트로 증명합니다.
- 🛠️ **146개 도구** — 문단·표·이미지·도형·수식·머리글/바닥글·각주/미주·북마크·하이퍼링크·메모·섹션·스타일·페이지·다단·목차·렌더·내보내기·undo/redo.

> 전체 변경 이력은 [CHANGELOG.md](CHANGELOG.md)를 참고하세요.

## 📦 설치 (Installation)

**요구사항:** Node.js ≥ 18. PDF 출력을 쓰려면 Chrome 또는 Edge(선택).

```bash
git clone https://github.com/h9661/hwpx-mcp.git
cd hwpx-mcp
npm install
npm run build
```

MCP 클라이언트에 서버를 등록합니다 (경로는 빌드된 `dist/index.js` **절대 경로**):

```json
{
  "mcpServers": {
    "hwpx-mcp": {
      "command": "node",
      "args": ["/absolute/path/to/hwpx-mcp/dist/index.js"]
    }
  }
}
```

| 클라이언트 | 설정 위치 |
|--|--|
| **Claude Desktop** | `%APPDATA%\Claude\claude_desktop_config.json` (Win) · `~/Library/Application Support/Claude/claude_desktop_config.json` (mac) · `~/.config/Claude/claude_desktop_config.json` (Linux) |
| **Claude Code** | `.mcp.json`(프로젝트) 또는 `claude mcp add hwpx-mcp node /path/to/dist/index.js` |
| **Cursor** | `~/.cursor/mcp.json` |
| **VS Code (MCP)** | `.vscode/mcp.json` (`"servers"` 키) |

> Windows 경로는 `/` 또는 `\\`를 사용하세요. 등록 후 클라이언트를 재시작하면 도구 목록에 `hwpx-mcp`가 나타납니다.

## 🚀 빠른 시작 (Quick Start)

```typescript
await mcp.open_document({ file_path: "report.hwpx" })

// 1) 스타일을 승계해 문단 삽입 (secPr/표/필드 등 위험 페이로드는 제거)
await mcp.insert_paragraphs({
  doc_id, section_index: 0, after_ref: "<현재 element_ref>",
  texts: ["새 문단 1", "새 문단 2"],
})

// 2) 같은 텍스트가 여러 곳일 때, 특정 셀만 정밀 치환
await mcp.replace_text_in_cell({
  doc_id, section_index: 0, table_index: 2, row: 3, col: 1,
  old_text: "대상", new_text: "새 내용",
})

// 3) 저장 전에 결과를 PDF로 미리보기
await mcp.render_pdf({ doc_id, output_path: "preview.pdf" })

await mcp.save_document({ doc_id })
```

## 🔌 도구 (Tools)

카테고리별 개요입니다. 전체 목록·파라미터는 MCP 클라이언트의 도구 패널에서 확인하세요.

| 카테고리 | 대표 도구 |
|--|--|
| **문서 관리** | `create_document`, `open_document`, `save_document`, `close_document` |
| **문서 정보** | `get_document_text`, `get_document_structure`, `get_word_count`, `get_document_outline` |
| **단락** | `get_paragraphs`, **`insert_paragraphs`**, `update_paragraph_text`, `copy_paragraph`, `move_paragraph`, `set_paragraph_numbering` |
| **편집 계획** | **`preview_edit_plan`**, **`apply_edit_plan`** |
| **스타일** | `set_text_style`, `set_paragraph_style`, `apply_style` |
| **검색/치환** | `search_text`(표 포함), `replace_text`, `replace_text_in_cell`, `batch_replace` |
| **표** | `insert_table`, `update_table_cell`, `set_cell_paragraphs`, `insert_nested_table`, `merge_cells`/`split_cell`, `set_cell_borders`, `get_table_as_csv` |
| **이미지/도형** | `insert_image`, `render_mermaid`, `insert_line`/`insert_rect`/`insert_ellipse` |
| **레이아웃/렌더** | `get_page_map`, **`render_preview`**, **`render_pdf`**, `set_page_settings`, `set_column_def`, `update_static_toc` |
| **참조/주석** | `insert_footnote`/`insert_endnote`, `insert_bookmark`, `insert_hyperlink`, `insert_memo` |
| **원시 XML** | `get_section_xml`, `set_section_xml`, **`replace_element_xml`** |
| **런타임/기타** | **`get_server_info`**, `insert_equation`, `export_to_text`/`export_to_html`, `undo`/`redo` |

## ✅ 검증 (Quality Gates)

이 저장소는 "잘 될 것"이 아니라 **측정된 게이트**로 품질을 담보합니다.

| 게이트 | 명령 | 기준 |
|--|--|--|
| **테스트 스위트** | `npm test` | 790 통과 (106 파일) |
| **레이아웃 정확도** | `npm run verify:corpus` | 실문서 16종에서 정확 페이지 **98.58%**, ±1 페이지 **100%** |
| **조작 완전성** | `MANIP_GATE=1 npm test` | 재구성 diff=0 **16/16**, 스타일 카탈로그 **16/16**, 렌더 픽셀 동일 **16/16**, 변형 왕복 무손실 |

> `LAYOUT_GATE=1` / `MANIP_GATE=1`은 실문서 코퍼스가 있을 때만 동작하며(기밀 문서는 커밋 제외), 기본 테스트는 코퍼스 없이 빠르게 돕니다.

## 📋 지원 포맷 & 알려진 제한

| 포맷 | 읽기 | 쓰기 |
|--|:--:|:--:|
| HWPX (.hwpx) | ✅ | ✅ |
| HWP (.hwp, 바이너리) | ❌ | ❌ |

**Known limitations**
- **자가검증 실패 문서는 읽기 전용**: 열기 시 CST 라운드트립 자가검증에 실패한 문서는 조회만 가능하며, `repair_xml`로 복구 후 저장할 수 있습니다.
- **렌더 충실도는 우리 엔진 기준**: `render_preview`/`render_pdf`는 한글의 **인쇄 시점 재줄바꿈**과 래스터라이저 차이가 있어 한글 출력과 100% 픽셀 일치는 아닙니다. 최종본은 한글에서 확인을 권장합니다(재구성-원본 픽셀 동일성은 우리 렌더러 기준으로 게이트 검증됨).
- **PDF 출력엔 Chrome/Edge 필요**: `render_pdf`는 헤드리스 브라우저(`--print-to-pdf`)를 사용합니다. `CHROME_PATH`로 경로 지정 가능.
- **병렬 테스트 flake**(`CellMerge`, `SemanticModel.corpus` 등, ~1/8): 단독/부분 병렬에선 안정 → 로직 결함이 아닌 하네스 타임아웃 아티팩트.

## 🗺️ 로드맵 (Roadmap)

<details>
<summary><b>✅ v2.0에서 완료</b> — 레이아웃 충실도 · 조작 완전성</summary>

- **레이아웃 엔진 v2**: 박스 모델 배치(표 auto-grow·다단·부동객체), 문자-클래스 폰트 메트릭, 캘리브레이션 CLI, 실문서 코퍼스 회귀 게이트(정확 페이지 98.58%).
- **프리뷰 렌더러**: `render_preview`(페이지별 SVG HTML) + `render_pdf`(헤드리스 Chrome), 탭스톱·양끝맞춤·머리/바닥글·이미지·표까지 반영.
- **조작 완전성**: 원본→빈 문서 재구성이 구조 diff=0 + 렌더 픽셀 동일 + 변형 왕복 무손실임을 코퍼스 전체 게이트로 증명(SemanticModel·StructuralDiff·Reconstructor·CoverageMap·MutationRoundTrip·`verify:manipulation`).
</details>

**다음 (v2.x+)**
- 범용 edit plan(삽입·수정·삭제·이동·표를 한 트랜잭션으로) · 문서 diff/patch
- 스타일 라이브러리 · 번호/불릿 확장 · 표 프리셋
- Markdown ⇄ HWPX 구조 보존 변환, HWP(바이너리) 읽기 브리지
- 대용량 스트리밍 · 증분 저장 · 벤치마크

PR·이슈 환영합니다 → [GitHub Issues](https://github.com/h9661/hwpx-mcp/issues)

## 🙏 Credits & License

- 계보: [mjyoo2/hwp-extension](https://github.com/mjyoo2/hwp-extension) → [Dayoooun](https://github.com/Dayoooun) → **[h9661/hwpx-mcp](https://github.com/h9661/hwpx-mcp)**
- License: **MIT** — [LICENSE](LICENSE)