HWPX MCP Server
by Dayoooun
README.md
# HWPX MCP Server - Enhanced Edition
[](https://github.com/Dayoooun/hwpx-mcp)
[](https://github.com/mjyoo2/hwp-extension)
> π **Original νλ‘μ νΈλ₯Ό Forkνμ¬ μμ μ±κ³Ό κΈ°λ₯μ λν κ°μ ν λ²μ μ
λλ€.**
AI λꡬ(Claude λ±)μ μ°λνμ¬ νκΈ(HWPX) λ¬Έμλ₯Ό μλμΌλ‘ νΈμ§ν μ μλ MCP(Model Context Protocol) μλ²μ
λλ€.
---
## π Cross-Platform Support
**λͺ¨λ μ΄μ체μ μμ μλν©λλ€!**
| OS | MCP μλ² | HWPX νΈμ§ | κ²°κ³Όλ¬Ό νμΈ |
|:---:|:---:|:---:|:---|
| β
Windows | β
| β
| νμ»΄μ€νΌμ€ |
| β
macOS | β
| β
| νμ»΄μ€νΌμ€ Mac |
| β
Linux | β
| β
| νμ»΄μ€νΌμ€ Linux / LibreOffice* |
> **μ κ°λ₯νκ°μ?**
> HWPX νμΌμ **ZIP + XML ꡬ쑰**μ
λλ€. νκΈ νλ‘κ·Έλ¨ μμ΄λ Node.jsλ§μΌλ‘ μλ²½νκ² μ½κ³ μΈ μ μμ΅λλ€.
>
> *LibreOfficeλ HWPXλ₯Ό μ νμ μΌλ‘ μ§μν©λλ€. μλ²½ν νΈνμ μν΄ νμ»΄μ€νΌμ€ μ¬μ©μ κΆμ₯ν©λλ€.
---
## β¨ Enhanced Features (κ°μ λ κΈ°λ₯)
μλ³Έ νλ‘μ νΈ λλΉ λ€μκ³Ό κ°μ **ν΅μ¬ λ¬Έμ λ€μ ν΄κ²°**νμ΅λλ€:
### π§ Critical Bug Fixes
| λ¬Έμ | μλ³Έ μν | κ°μ ν |
|------|----------|---------|
| **ν
μ΄λΈ μ μ₯ μ€ν¨** | μ
μμ ν μ μ₯ν΄λ λ³κ²½μ¬ν μ¬λΌμ§ | β
μλ²½νκ² μ μ₯λ¨ |
| **ν
μ€νΈ κ²ΉμΉ¨ νμ** | μ μ₯ ν νκΈμμ μ΄λ©΄ κΈμκ° κ²Ήμ³ νμ | β
μ μ νμ |
| **νμΌ μμ** | μ μ₯ μ κ°λ νμΌμ΄ μμλ¨ | β
μμμ μ°κΈ°λ‘ 100% μμ |
| **λ€μ€ μ
μμ** | κ°μ νμ μ¬λ¬ μ
μμ μ XML μμ | β
μΈλ±μ€ κ΄λ¦¬λ‘ μμ |
| **μκ°/μ€κ°κ²© μμ€** | μ μ₯ ν μ€νμΌ μ 보 μ μ€ | β
λͺ¨λ μ€νμΌ λ³΄μ‘΄ |
### π Technical Improvements
1. **Atomic File Writing (μμμ νμΌ μ°κΈ°)**
- μμ νμΌ β ZIP κ²μ¦ β μμμ μ΄λ
- μ μ₯ μ€ μ€λ₯ λ°μν΄λ μλ³Έ νμΌ λ³΄νΈ
2. **Smart Lineseg Reset (μ€λ§νΈ μ€ λ μ΄μμ μ΄κΈ°ν)**
- ν
μ€νΈ μμ μ `lineseg` μλ μ΄κΈ°ν
- νκΈ νλ‘κ·Έλ¨μ΄ μ΄ λ μλμΌλ‘ μ€λ°κΏ μ¬κ³μ°
- ν
μ€νΈ κ²ΉμΉ¨ νμ μμ ν΄κ²°
3. **Depth-based XML Parsing (κΉμ΄ κΈ°λ° XML νμ±)**
- κΈ°μ‘΄ lazy regexμ μ€μ²© ꡬ쑰 μ€μΈμ λ¬Έμ ν΄κ²°
- 볡μ‘ν ν
μ΄λΈ(μ€μ²© ν
μ΄λΈ, subList λ±) μλ²½ μ§μ
4. **Complete Style Preservation (μ€νμΌ μμ 보쑴)**
- `charPr`, `spacing` λ± μλ³Έ μ€νμΌ 100% μ μ§
- λΆμμ ν μ§λ ¬ν λ‘μ§ μ κ±°λ‘ λ°μ΄ν° λ¬΄κ²°μ± λ³΄μ₯
5. **Safe Multi-Cell Updates (μμ ν λ€μ€ μ
μ
λ°μ΄νΈ)**
- κ°μ ν(row)μ μ¬λ¬ μ
μ λμμ μμ ν΄λ μμ
- νλ³ κ·Έλ£Ήν + μμ μ²λ¦¬λ‘ μΈλ±μ€ μμ λ°©μ§
---
## π¦ Installation
### 1. MCP μλ² μ€μΉ
```bash
git clone https://github.com/Dayoooun/hwpx-mcp.git
cd hwpx-mcp/mcp-server
npm install
npm run build
```
### 2. MCP ν΄λΌμ΄μΈνΈ μ€μ
μλμμ μ¬μ©νλ ν΄λΌμ΄μΈνΈλ₯Ό μ ννμΈμ.
---
#### π₯οΈ Claude Desktop
**μ€μ νμΌ μμΉ:**
| OS | κ²½λ‘ |
|----|------|
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |
**μ€μ λ΄μ©:**
```json
{
"mcpServers": {
"hwpx-mcp": {
"command": "node",
"args": ["C:/path/to/hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
> β οΈ Windowsμμλ κ²½λ‘μ `\\` λλ `/` μ¬μ© (μ: `C:/Users/username/hwpx-mcp/...`)
---
#### π» Claude Code (CLI)
**λ°©λ² 1: νλ‘μ νΈλ³ μ€μ ** (`.mcp.json` νμΌμ νλ‘μ νΈ λ£¨νΈμ μμ±)
```json
{
"mcpServers": {
"hwpx-mcp": {
"command": "node",
"args": ["/path/to/hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
**λ°©λ² 2: μ μ μ€μ ** (`~/.claude/settings.json`)
```json
{
"mcpServers": {
"hwpx-mcp": {
"command": "node",
"args": ["/path/to/hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
**λ°©λ² 3: CLI λͺ
λ Ήμ΄λ‘ μΆκ°**
```bash
claude mcp add hwpx-mcp node /path/to/hwpx-mcp/mcp-server/dist/index.js
```
---
#### π· Cursor
**μ€μ νμΌ:** `~/.cursor/mcp.json` (μμΌλ©΄ μμ±)
```json
{
"mcpServers": {
"hwpx-mcp": {
"command": "node",
"args": ["/path/to/hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
λλ **Cursor Settings > MCP** μμ μ§μ μΆκ° κ°λ₯
---
#### π VS Code (MCP νμ₯ μ¬μ© μ)
**μ€μ νμΌ:** `.vscode/mcp.json` (νλ‘μ νΈ ν΄λ λ΄)
```json
{
"servers": {
"hwpx-mcp": {
"command": "node",
"args": ["${workspaceFolder}/../hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
> `${workspaceFolder}` λ³μλ₯Ό νμ©νλ©΄ μλ κ²½λ‘ μ§μ κ°λ₯
---
#### π οΈ κΈ°ν MCP ν΄λΌμ΄μΈνΈ
μΌλ°μ μΈ MCP μ€μ νμ:
```json
{
"mcpServers": {
"hwpx-mcp": {
"command": "node",
"args": ["/absolute/path/to/hwpx-mcp/mcp-server/dist/index.js"]
}
}
}
```
**κ²½λ‘ μμ:**
| OS | κ²½λ‘ μμ |
|----|----------|
| Windows | `C:/Users/username/hwpx-mcp/mcp-server/dist/index.js` |
| macOS | `/Users/username/hwpx-mcp/mcp-server/dist/index.js` |
| Linux | `/home/username/hwpx-mcp/mcp-server/dist/index.js` |
---
### 3. μ€μΉ νμΈ
ν΄λΌμ΄μΈνΈ μ¬μμ ν MCP λꡬ λͺ©λ‘μμ `hwpx-mcp` μλ²μ 77κ° λκ΅¬κ° νμλλ©΄ μ±κ³΅!
---
## π MCP Tools (77κ°)
### π λ¬Έμ κ΄λ¦¬ (Document Management) - 5κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `create_document` | μ λΉ HWPX λ¬Έμ μμ± | `title?`, `creator?` |
| `open_document` | HWPX λ¬Έμ μ΄κΈ° | `file_path` |
| `close_document` | μ΄λ¦° λ¬Έμ λ«κΈ° | `doc_id` |
| `save_document` | λ¬Έμ μ μ₯ (λ°±μ
/λ¬΄κ²°μ± κ²μ¦ μ§μ) | `doc_id`, `output_path?`, `create_backup?`, `verify_integrity?` |
| `list_open_documents` | νμ¬ μ΄λ¦° λ¬Έμ λͺ©λ‘ μ‘°ν | - |
**보μ λ²μ:** νμ¬ npm μλ²μ VS Code λ²λ€ μλ² λͺ¨λ νμΌ κ²½λ‘λ₯Ό μμ
ν΄λ μμΌλ‘ μ ννμ§ μμ΅λλ€.
μ λκ²½λ‘Β·μμκ²½λ‘Β·λλ ν°λ¦¬ μ¬λ³Όλ¦ λ§ν¬λ₯Ό ν΅ν μΈλΆ νμΌ μ κ·Όμ΄ κ°λ₯νλ―λ‘, μ λ’°νλ λ‘컬 MCP
ν΄λΌμ΄μΈνΈμμλ§ μ¬μ©νκ³ OS κΆν λλ 컨ν
μ΄λλ‘ μ κ·Ό λ²μλ₯Ό μ ννμΈμ.
npm μλ²μ μ μ₯ μμ νμΌΒ·λ°±μ
보νΈλ νμΌ μ κ·Ό λ²μ μ νμ λμ νμ§ μμ΅λλ€.
### π λ¬Έμ μ 보 (Document Info) - 5κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_document_text` | λ¬Έμ μ 체 ν
μ€νΈ μΆμΆ | `doc_id` |
| `get_document_structure` | λ¬Έμ ꡬ쑰 μ‘°ν (μΉμ
/λ¨λ½/ν
μ΄λΈ/μ΄λ―Έμ§ μ) | `doc_id` |
| `get_document_metadata` | λ©νλ°μ΄ν° μ‘°ν (μ λͺ©, μ μ, λ μ§ λ±) | `doc_id` |
| `set_document_metadata` | λ©νλ°μ΄ν° μμ | `doc_id`, `title?`, `creator?`, `subject?`, `description?` |
| `get_word_count` | κΈμμ/λ¨μ΄μ ν΅κ³ | `doc_id` |
### π λ¨λ½ (Paragraphs) - 8κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_paragraphs` | λ¨λ½ λͺ©λ‘ μ‘°ν (ν
μ€νΈ/μ€νμΌ ν¬ν¨) | `doc_id`, `section_index?` |
| `get_paragraph` | νΉμ λ¨λ½ μμΈ μ 보 | `doc_id`, `section_index`, `paragraph_index` |
| `insert_paragraph` | μ λ¨λ½ μ½μ
| `doc_id`, `section_index`, `after_index`, `text` |
| `delete_paragraph` | λ¨λ½ μμ | `doc_id`, `section_index`, `paragraph_index` |
| `update_paragraph_text` | λ¨λ½ ν
μ€νΈ λ΄μ© μμ | `doc_id`, `section_index`, `paragraph_index`, `text`, `run_index?` |
| `append_text_to_paragraph` | κΈ°μ‘΄ λ¨λ½μ ν
μ€νΈ μΆκ° | `doc_id`, `section_index`, `paragraph_index`, `text` |
| `copy_paragraph` | λ¨λ½μ λ€λ₯Έ μμΉλ‘ λ³΅μ¬ | `doc_id`, `source_section`, `source_paragraph`, `target_section`, `target_after` |
| `move_paragraph` | λ¨λ½μ λ€λ₯Έ μμΉλ‘ μ΄λ | `doc_id`, `source_section`, `source_paragraph`, `target_section`, `target_after` |
### π¨ ν
μ€νΈ μ€νμΌ (Text Styling) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_text_style` | κΈμ μμ μ‘°ν (ν°νΈ/ν¬κΈ°/μμ λ±) | `doc_id`, `section_index`, `paragraph_index`, `run_index?` |
| `set_text_style` | κΈμ μμ μ€μ | `doc_id`, `section_index`, `paragraph_index`, `bold?`, `italic?`, `underline?`, `strikethrough?`, `font_name?`, `font_size?`, `font_color?`, `background_color?` |
| `get_paragraph_style` | λ¬Έλ¨ μμ μ‘°ν (μ λ ¬/μ€κ°κ²©/μ¬λ°± λ±) | `doc_id`, `section_index`, `paragraph_index` |
| `set_paragraph_style` | λ¬Έλ¨ μμ μ€μ | `doc_id`, `section_index`, `paragraph_index`, `align?`, `line_spacing?`, `margin_*?`, `first_line_indent?` |
### π κ²μ/μΉν (Search & Replace) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `search_text` | λ¬Έμ λ΄ ν
μ€νΈ κ²μ (μ κ·μ μ§μ, **ν
μ΄λΈ μ
ν¬ν¨**) | `doc_id`, `query`, `case_sensitive?`, `regex?`, `include_tables?` |
| `replace_text` | ν
μ€νΈ μ°Ύμ λ°κΎΈκΈ° | `doc_id`, `old_text`, `new_text`, `case_sensitive?`, `regex?`, `replace_all?` |
| `replace_text_in_cell` | **νΉμ ν
μ΄λΈ μ
λ΄ ν
μ€νΈ μΉν** | `doc_id`, `section_index`, `table_index`, `row`, `col`, `old_text`, `new_text` |
| `batch_replace` | μ¬λ¬ ν
μ€νΈ μΌκ΄ μΉν | `doc_id`, `replacements[]` (old_text, new_text μ λ°°μ΄) |
### π ν
μ΄λΈ (Tables) - 12κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_tables` | λ¬Έμ λ΄ λͺ¨λ ν
μ΄λΈ λͺ©λ‘ | `doc_id` |
| `get_table` | νΉμ ν
μ΄λΈ μ 체 λ°μ΄ν° μ‘°ν | `doc_id`, `section_index`, `table_index` |
| `get_table_cell` | νΉμ μ
λ΄μ© μ‘°ν | `doc_id`, `section_index`, `table_index`, `row`, `col` |
| `update_table_cell` | μ
λ΄μ© μμ (μ€νμΌ λ³΄μ‘΄) | `doc_id`, `section_index`, `table_index`, `row`, `col`, `text`, `char_shape_id?` |
| `set_cell_properties` | μ
μμ± μ€μ (ν¬κΈ°/λ°°κ²½μ/μ λ ¬) | `doc_id`, `section_index`, `table_index`, `row`, `col`, `width?`, `height?`, `background_color?`, `vertical_align?` |
| `insert_table` | μ ν
μ΄λΈ μ½μ
| `doc_id`, `section_index`, `after_index`, `rows`, `cols`, `width?` |
| `insert_table_row` | ν
μ΄λΈμ ν μ½μ
| `doc_id`, `section_index`, `table_index`, `after_row`, `cell_texts?` |
| `delete_table_row` | ν
μ΄λΈμμ ν μμ | `doc_id`, `section_index`, `table_index`, `row_index` |
| `insert_table_column` | ν
μ΄λΈμ μ΄ μ½μ
| `doc_id`, `section_index`, `table_index`, `after_col` |
| `delete_table_column` | ν
μ΄λΈμμ μ΄ μμ | `doc_id`, `section_index`, `table_index`, `col_index` |
| `insert_nested_table` | **μ
μμ μ€μ²© ν
μ΄λΈ μ½μ
(ν μμ ν)** | `doc_id`, `section_index`, `parent_table_index`, `row`, `col`, `nested_rows`, `nested_cols`, `data?` |
| `get_table_as_csv` | ν
μ΄λΈμ CSV νμμΌλ‘ μΆμΆ | `doc_id`, `section_index`, `table_index`, `delimiter?` |
### π νμ΄μ§ μ€μ (Page Settings) - 2κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_page_settings` | νμ΄μ§ μ€μ μ‘°ν (μ©μ§ ν¬κΈ°/μ¬λ°±) | `doc_id`, `section_index?` |
| `set_page_settings` | νμ΄μ§ μ€μ λ³κ²½ | `doc_id`, `section_index?`, `width?`, `height?`, `margin_*?`, `orientation?` |
### πΌοΈ μ΄λ―Έμ§ (Images) - 5κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_images` | λ¬Έμ λ΄ λͺ¨λ μ΄λ―Έμ§ λͺ©λ‘ | `doc_id` |
| `insert_image` | μ΄λ―Έμ§ νμΌ μ½μ
(BinData μλ λ±λ‘) | `doc_id`, `section_index`, `after_index`, `image_path`, `width?`, `height?` |
| `update_image_size` | κΈ°μ‘΄ μ΄λ―Έμ§ ν¬κΈ° λ³κ²½ | `doc_id`, `section_index`, `image_index`, `width`, `height` |
| `delete_image` | μ΄λ―Έμ§ μμ | `doc_id`, `section_index`, `image_index` |
| `render_mermaid` | **Mermaid λ€μ΄μ΄κ·Έλ¨μ μ΄λ―Έμ§λ‘ μ½μ
** | `doc_id`, `mermaid_code`, `after_index`, `section_index?`, `width?`, `height?`, `theme?`, `background_color?` |
### βοΈ λν (Shapes) - 3κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `insert_line` | μ λν μ½μ
| `doc_id`, `section_index`, `after_index`, `x1`, `y1`, `x2`, `y2`, `stroke_color?`, `stroke_width?` |
| `insert_rect` | μ¬κ°ν λν μ½μ
| `doc_id`, `section_index`, `after_index`, `x`, `y`, `width`, `height`, `fill_color?`, `stroke_color?` |
| `insert_ellipse` | νμ λν μ½μ
| `doc_id`, `section_index`, `after_index`, `cx`, `cy`, `rx`, `ry`, `fill_color?`, `stroke_color?` |
### π 머리κΈ/λ°λ₯κΈ (Header/Footer) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_header` | λ¨Έλ¦¬κΈ λ΄μ© μ‘°ν | `doc_id`, `section_index?` |
| `set_header` | λ¨Έλ¦¬κΈ μ€μ | `doc_id`, `text`, `section_index?`, `apply_page_type?` (both/even/odd) |
| `get_footer` | λ°λ₯κΈ λ΄μ© μ‘°ν | `doc_id`, `section_index?` |
| `set_footer` | λ°λ₯κΈ μ€μ | `doc_id`, `text`, `section_index?`, `apply_page_type?` (both/even/odd) |
### π κ°μ£Ό/λ―Έμ£Ό (Footnotes/Endnotes) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_footnotes` | λ¬Έμ λ΄ λͺ¨λ κ°μ£Ό λͺ©λ‘ | `doc_id` |
| `insert_footnote` | νΉμ μμΉμ κ°μ£Ό μ½μ
| `doc_id`, `section_index`, `paragraph_index`, `text` |
| `get_endnotes` | λ¬Έμ λ΄ λͺ¨λ λ―Έμ£Ό λͺ©λ‘ | `doc_id` |
| `insert_endnote` | νΉμ μμΉμ λ―Έμ£Ό μ½μ
| `doc_id`, `section_index`, `paragraph_index`, `text` |
### π λΆλ§ν¬/νμ΄νΌλ§ν¬ (Bookmarks/Hyperlinks) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_bookmarks` | λ¬Έμ λ΄ λͺ¨λ λΆλ§ν¬ λͺ©λ‘ | `doc_id` |
| `insert_bookmark` | νΉμ μμΉμ λΆλ§ν¬ μ½μ
| `doc_id`, `section_index`, `paragraph_index`, `name` |
| `get_hyperlinks` | λ¬Έμ λ΄ λͺ¨λ νμ΄νΌλ§ν¬ λͺ©λ‘ | `doc_id` |
| `insert_hyperlink` | νμ΄νΌλ§ν¬ μ½μ
| `doc_id`, `section_index`, `paragraph_index`, `url`, `text` |
### β μμ (Equations) - 2κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_equations` | λ¬Έμ λ΄ λͺ¨λ μμ λͺ©λ‘ | `doc_id` |
| `insert_equation` | μμ μ½μ
(HWP μμ μ€ν¬λ¦½νΈ νμ) | `doc_id`, `section_index`, `after_index`, `script` |
### π¬ λ©λͺ¨ (Memos/Comments) - 3κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_memos` | λ¬Έμ λ΄ λͺ¨λ λ©λͺ¨/μ£Όμ λͺ©λ‘ | `doc_id` |
| `insert_memo` | λ©λͺ¨/μ£Όμ μ½μ
| `doc_id`, `section_index`, `paragraph_index`, `content`, `author?` |
| `delete_memo` | λ©λͺ¨/μ£Όμ μμ | `doc_id`, `memo_id` |
### π μΉμ
(Sections) - 5κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_sections` | λ¬Έμ λ΄ λͺ¨λ μΉμ
λͺ©λ‘ | `doc_id` |
| `insert_section` | μ μΉμ
μ½μ
| `doc_id`, `after_index` |
| `delete_section` | μΉμ
μμ | `doc_id`, `section_index` |
| `get_section_xml` | **μΉμ
Raw XML μ‘°ν (AI λ¬Έμ μ‘°μμ©)** | `doc_id`, `section_index?` |
| `set_section_xml` | **μΉμ
Raw XML κ΅μ²΄ (HWPML νμ νμ)** | `doc_id`, `xml`, `section_index?`, `validate?` |
### π μ€νμΌ μ μ (Style Definitions) - 4κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_styles` | λ¬Έμμ μ μλ μ€νμΌ λͺ©λ‘ | `doc_id` |
| `get_char_shapes` | κΈμ λͺ¨μ(CharShape) μ μ λͺ©λ‘ | `doc_id` |
| `get_para_shapes` | λ¬Έλ¨ λͺ¨μ(ParaShape) μ μ λͺ©λ‘ | `doc_id` |
| `apply_style` | λ¨λ½μ μ€νμΌ μ μ© | `doc_id`, `section_index`, `paragraph_index`, `style_id` |
### π° λ¨ μ€μ (Column Layout) - 2κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `get_column_def` | λ¨(Column) μ€μ μ‘°ν | `doc_id`, `section_index?` |
| `set_column_def` | λ¨ μ€μ λ³κ²½ (λ€λ¨ νΈμ§) | `doc_id`, `count`, `section_index?`, `type?`, `same_size?`, `gap?` |
### π€ λ΄λ³΄λ΄κΈ° (Export) - 2κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `export_to_text` | λ¬Έμλ₯Ό ν
μ€νΈ νμΌλ‘ λ΄λ³΄λ΄κΈ° | `doc_id`, `output_path` |
| `export_to_html` | λ¬Έμλ₯Ό HTML νμΌλ‘ λ΄λ³΄λ΄κΈ° | `doc_id`, `output_path` |
### β©οΈ μ€ν μ·¨μ (Undo/Redo) - 2κ°
| Tool | μ€λͺ
| μ£Όμ νλΌλ―Έν° |
|------|------|--------------|
| `undo` | λ§μ§λ§ λ³κ²½ μ€ν μ·¨μ | `doc_id` |
| `redo` | μ€ν μ·¨μν λ³κ²½ λ€μ μ€ν | `doc_id` |
---
### μ¬μ© μμ
```typescript
// λ¬Έμ μ΄κΈ°
await mcp.open_document({ file_path: "report.hwpx" })
// ν
μ΄λΈ μ
μμ
await mcp.update_table_cell({
doc_id: "...",
section_index: 0,
table_index: 0,
row: 0,
col: 1,
text: "μμ λ λ΄μ©"
})
// μ€μ²© ν
μ΄λΈ μ½μ
(ν μμ ν)
await mcp.insert_nested_table({
doc_id: "...",
section_index: 0,
parent_table_index: 0,
row: 1,
col: 2,
nested_rows: 2,
nested_cols: 2,
data: [["A1", "A2"], ["B1", "B2"]]
})
// Mermaid λ€μ΄μ΄κ·Έλ¨ μ½μ
await mcp.render_mermaid({
doc_id: "...",
mermaid_code: "graph TD; A-->B; B-->C;",
after_index: 0,
theme: "default"
})
// μ μ₯
await mcp.save_document({ doc_id: "..." })
```
#### ν
μ΄λΈ μ
κ²μ/μΉν μν¬νλ‘μ°
λμΌν ν
μ€νΈκ° μ¬λ¬ κ³³μ μμ λ **νΉμ μμΉ**λ§ μμ νλ λ°©λ²:
```typescript
// 1. ν
μ΄λΈ ν¬ν¨ κ²μμΌλ‘ μμΉ νμ
const results = await mcp.search_text({
doc_id: "...",
query: "μμ λμ",
include_tables: true // ν
μ΄λΈ μ
ν¬ν¨
})
// κ²°κ³Ό: [{ text: "μμ λμ", location: { type: "table", tableIndex: 2, row: 3, col: 1 } }, ...]
// 2. μνλ μμΉμ μ
λ§ μ λ° μΉν
await mcp.replace_text_in_cell({
doc_id: "...",
section_index: 0,
table_index: 2, // κ²μ κ²°κ³Όμμ νμΈν μμΉ
row: 3,
col: 1,
old_text: "μμ λμ",
new_text: "μλ‘μ΄λ΄μ©"
})
```
---
## π Supported Format
| ν¬λ§· | νμ₯μ | μ½κΈ° | μ°κΈ° |
|------|--------|:----:|:----:|
| HWPX | .hwpx | β
| β
|
| HWP | .hwp | β | β |
> **Note**: HWP(λ°μ΄λ리) νμΌμ μ§μνμ§ μμ΅λλ€. νμ»΄μ€νΌμ€μμ HWPXλ‘ λ³ν ν μ¬μ©νμΈμ.
---
## π Release Notes
### v0.4.0 (Enhanced Search & Diagram Support)
- π **New Feature**: `search_text`μ `include_tables` μ΅μ
μΆκ° - ν
μ΄λΈ μ
λ΄ ν
μ€νΈλ κ²μ
- π **New Feature**: `replace_text_in_cell` - νΉμ ν
μ΄λΈ μ
λ΄ ν
μ€νΈλ§ μ λ° μΉν
- π **New Feature**: `render_mermaid` - Mermaid λ€μ΄μ΄κ·Έλ¨μ μ΄λ―Έμ§λ‘ λ¬Έμμ μ½μ
- Flowchart, Sequence, Class Diagram λ± λͺ¨λ Mermaid λ¬Έλ² μ§μ
- ν
λ§ μ ν κ°λ₯ (default, dark, forest, neutral)
- π **New Feature**: `get_section_xml` / `set_section_xml` - μΉμ
Raw XML μ§μ μ‘°μ
- AI κΈ°λ° κ³ κΈ λ¬Έμ νΈμ§ μλλ¦¬μ€ μ§μ
- π§ **Improvement**: `insert_image` μμ κ°μ
- BinData ν΄λμ μ΄λ―Έμ§ μλ μ μ₯
- content.hpf λ§€λνμ€νΈ μλ λ±λ‘
- νμΌ μμ μμ΄ μ΄λ―Έμ§ μ½μ
보μ₯
### v0.3.1 (npm server maintenance)
- npm μλ²μ μμ νμΌΒ·λ°±μ
λ§ν¬ 곡격 λ°©μ΄ λ° μ μ₯ μ€ν¨ μ μλ³Έ 보쑴
- λΆλ¦¬λ ν
μ€νΈ νκ·Έ μ μ₯ λλ½ μμ , μμ‘΄μ± κ°±μ λ° μ΄μ κ°λ₯ν νκ· ν
μ€νΈ 보μ
- κΈ°μ‘΄ νμΌ κ²½λ‘ μ¬μ©λ² μ μ§. μμ
ν΄λ μ κ·Ό μ ν λ° μμ μ μ₯ μμ μ ν¬ν¨νμ§ μμ
### v0.3.0 (Nested Table Support)
- π **New Feature**: `insert_nested_table` - ν
μ΄λΈ μ
μμ μ€μ²© ν
μ΄λΈ μ½μ
κΈ°λ₯
- λΆλͺ¨ ν
μ΄λΈμ νΉμ μ
μ μ ν
μ΄λΈμ μ½μ
- μ΄κΈ° λ°μ΄ν° μ§μ κ°λ₯ (2D λ°°μ΄)
- HWPX νμ€ κ΅¬μ‘°(`treatAsChar`, `hp:subList`) μλ²½ μ€μ
- π§ **Improvement**: charSpacing νμ± κ°μ (μμ± μμ 무κ΄νκ² μ²λ¦¬)
### v0.2.1 (Critical Fix)
- π₯ **Critical Fix**: κ°μ νμ μ¬λ¬ μ
λμ μμ μ νμΌ μμ λ¬Έμ μμ ν΄κ²°
- ν(row)λ³ μ
λ°μ΄νΈ κ·Έλ£Ήνλ‘ μΈλ±μ€ λΆμΌμΉ λ°©μ§
- μμ(descending) μ²λ¦¬λ‘ μμ ν XML μμ 보μ₯
### v0.2.0 (Enhanced Edition)
- π₯ **Major Fix**: ν
μ€νΈ μμ μ lineseg μλ μ΄κΈ°νλ‘ κ²ΉμΉ¨ νμ μμ ν΄κ²°
- π§ **Bug Fix**: μ€μ²© ν
μ΄λΈ ꡬ쑰μμ XML μμ κ²½κ³ μ€μΈμ λ¬Έμ μμ
- π‘οΈ **Stability**: μμμ νμΌ μ°κΈ°λ‘ νμΌ μμ λ°©μ§
- π¦ **Preservation**: μλ³Έ charPr/spacing μ€νμΌ μμ 보쑴
### v0.1.0 (Original)
- μ΅μ΄ λ¦΄λ¦¬μ€ (mjyoo2/hwp-extension)
---
## π Credits
- Original Project: [mjyoo2/hwp-extension](https://github.com/mjyoo2/hwp-extension)
- Enhanced by: [Dayoooun](https://github.com/Dayoooun)
---
## π License
MIT
---
## π€ Contributing
λ²κ·Έ 리ν¬νΈ λ° κΈ°λ₯ μμ²: [GitHub Issues](https://github.com/Dayoooun/hwpx-mcp/issues)
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessUnresponsive