Skip to main content

MCP server for reading, editing, inspecting, and validating local HWPX documents with AI agents.

Project description

๐Ÿ“„ hwpx-mcp-server

AI ์—์ด์ „ํŠธ๊ฐ€ HWPX ๋ฌธ์„œ๋ฅผ ๋ฐ”๋กœ ์ฝ๊ณ , ์ฐพ๊ณ , ์ฑ„์šฐ๊ณ , ๋งŒ๋“ค๊ฒŒ ํ•˜๋Š” MCP ์„œ๋ฒ„

ํ•ต์‹ฌ ํŒŒ์ผ ์ฒ˜๋ฆฌ๋Š” ํ•œ๊ธ€ ์›Œ๋“œํ”„๋กœ์„ธ์„œ ์—†์ด ยท ์ˆœ์ˆ˜ ํŒŒ์ด์ฌ ยท ํฌ๋กœ์Šค ํ”Œ๋žซํผ

PyPI Python License Tests


๐Ÿงฉ HWPX Stack (3์ข…)

๊ณ„์ธต ๋ ˆํฌ ์—ญํ• 
๐Ÿ“ฆ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ python-hwpx ์ˆœ์ˆ˜ ํŒŒ์ด์ฌ HWPX ํŒŒ์‹ฑยทํŽธ์ง‘ยท์ƒ์„ฑ ์ฝ”์–ด
๐Ÿ”Œ MCP ์„œ๋ฒ„ hwpx-mcp-server MCP ํด๋ผ์ด์–ธํŠธ(Claude Desktop, VS Code ๋“ฑ)์—์„œ HWPX ์กฐ์ž‘
๐ŸŽฏ ์—์ด์ „ํŠธ ์Šคํ‚ฌ hwpx-plugin ์—์ด์ „ํŠธ๊ฐ€ HWPX๋ฅผ ๋ฐ”๋กœ ์“ฐ๊ฒŒ ํ•ด์ฃผ๋Š” first-party ํ”Œ๋Ÿฌ๊ทธ์ธยท์Šคํ‚ฌ ๋ฒˆ๋“ค

hwpx-mcp-server๋Š” python-hwpx ํ”„๋กœ์ ํŠธ๊ฐ€ ์ง์ ‘ ์œ ์ง€๋ณด์ˆ˜ํ•˜๋Š” first-party MCP ์„œ๋ฒ„์ž…๋‹ˆ๋‹ค. ์ด๋Š” ํ•œ์ปด์˜ ๊ณต์‹ ์ œํ’ˆ ๋˜๋Š” ์ธ์ฆ ์„œ๋ฒ„๋ผ๋Š” ๋œป์ด ์•„๋‹™๋‹ˆ๋‹ค.

ํ˜„์žฌ ๊ณต๊ฐœ ๋ฆด๋ฆฌ์Šค๋Š” hwpx-mcp-server 4.3.0์ด๋ฉฐ ์ตœ์†Œ ํ˜ธํ™˜ ์ฝ”์–ด๋Š” python-hwpx 3.3.1, ๋Œ€์‘ ์Šคํ‚ฌ ์ตœ์†Œ ๋ฒ„์ „์€ 0.5.0์ž…๋‹ˆ๋‹ค. ๊ธฐ๋ณธ 121๊ฐœยท๊ณ ๊ธ‰ ๋ชจ๋“œ ํฌํ•จ 132๊ฐœ ๋„๊ตฌ์™€ 28๊ฐœ skill-required ๋„๊ตฌ๋Š” ์œ ์ง€๋˜๋ฉฐ ๊ณ„์•ฝ ํ•ด์‹œ๋Š” f82caecbcfc742e9์ž…๋‹ˆ๋‹ค. MCP ์„œ๋ฒ„๋Š” ํ˜„์žฌ ๋ณ„๋„์˜ Development Status classifier๋ฅผ ์„ ์–ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฆด๋ฆฌ์Šค ๋ฒ„์ „๊ณผ ์ง€์› ๋ฒ„์ „์€ ๋ฌธ์„œํ™”ํ•˜๋˜, classifier๊ฐ€ ์ถ”๊ฐ€๋˜๊ธฐ ์ „๊นŒ์ง€ ์„ฑ์ˆ™๋„๋ฅผ ์ž„์˜๋กœ ์Šน๊ฒฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.


์™œ / ๋ฌด์—‡์„ ํ•˜๋‚˜

hwpx-mcp-server๋Š” ๋ชจ๋ธ ์ปจํ…์ŠคํŠธ ํ”„๋กœํ† ์ฝœ(MCP) ํ‘œ์ค€ ์„œ๋ฒ„๋กœ, python-hwpx ์œ„์—์„œ HWPX ๋ฌธ์„œ์˜ ์—ด๋žŒยท๊ฒ€์ƒ‰ยทํŽธ์ง‘ยท์–‘์‹์ฑ„์›€ยท์ƒ์„ฑยท์ถ”์ถœ์„ AI ํด๋ผ์ด์–ธํŠธ์—์„œ ์ง์ ‘ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

  • ์šด์˜์ฒด์ œ ๋ฌด๊ด€ โ€” Windows, macOS, Linux์—์„œ ๋™์ž‘
  • ํ•ต์‹ฌ ํŒŒ์ผ ์ฒ˜๋ฆฌ์— ํ•œ๊ธ€ ์›Œ๋“œํ”„๋กœ์„ธ์„œ ๋ถˆํ•„์š” โ€” ์ˆœ์ˆ˜ ํŒŒ์ด์ฌ ์ฒ˜๋ฆฌ, ์„œ๋ฒ„ยทCIยท๋กœ์ปฌ ์–ด๋””์„œ๋‚˜ ๊ฐ™์€ ํ๋ฆ„
  • AI ์—ฐ๋™ ์ค‘์‹ฌ โ€” Claude Desktop, VS Code, Gemini CLI ๋“ฑ MCP ํด๋ผ์ด์–ธํŠธ์™€ ์ง์ ‘ ์—ฐ๊ฒฐ
  • ๋ฌธ์„œ ์กฐ์ž‘์„ ๋„๊ตฌ ํ˜ธ์ถœ๋กœ ํ‘œ์ค€ํ™” โ€” ์ฝ๊ธฐยทํŽธ์ง‘ยท๋ณต์ œยท์–‘์‹์ฑ„์›€ยท๊ฒ€์ฆ์„ ํ•˜๋‚˜์˜ ๋„๊ตฌ ์ง‘ํ•ฉ์œผ๋กœ ๋…ธ์ถœ
  • ๋ช…์‹œ์ ์ธ ํŒŒ์ผ ์œ„์น˜ ๊ณ„์•ฝ โ€” ํŒŒ์ผ ์›์‹œ ๋„๊ตฌ๋งˆ๋‹ค locator์™€ ์ž…๋ ฅยท์ถœ๋ ฅ ๊ฒฝ๋กœ๋ฅผ ์ง€์ •ํ•˜๋Š” ์ผ๊ด€๋œ ๋ฐฉ์‹

ํŒŒ์ผ ์›์‹œ ๋„๊ตฌ๋Š” ๋ช…์‹œ์ ์ธ locator์™€ ์ž…๋ ฅยท์ถœ๋ ฅ ๊ฒฝ๋กœ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด ์žฅ๊ธฐ workflow, ๋ Œ๋” ํ, revision/idempotency ๊ธฐ๋ก์€ ์˜๋„์ ์œผ๋กœ ์ƒํƒœ๋ฅผ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์„œ๋ฒ„ ์ „์ฒด๋ฅผ stateless๋ผ๊ณ  ํ‘œํ˜„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ฐธ๊ณ  ์ด ์„œ๋ฒ„๋Š” Open XML ๊ธฐ๋ฐ˜ .hwpx ํฌ๋งท์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ๋ฐ”์ด๋„ˆ๋ฆฌ .hwp๋Š” ์ง์ ‘ ํŽธ์ง‘ ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค.

๋น ๋ฅธ ์‹œ์ž‘

์„ค์น˜ ๋ฐ ์‹คํ–‰

uv ๊ธฐ์ค€:

uvx hwpx-mcp-server

๋˜๋Š” pip ์„ค์น˜ ํ›„ ์‹คํ–‰:

pip install hwpx-mcp-server
hwpx-mcp-server

๋น„-HWPX ๋ฌธ์„œ(PDF/DOCX/XLSX/HTML/TXT)๋ฅผ document_to_markdown ๊ฒฝ๋กœ๋กœ ์ฝ์œผ๋ ค๋ฉด MarkItDown adapter extra๋ฅผ ํ•จ๊ป˜ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

pip install "hwpx-mcp-server[ingest]"

์š”๊ตฌ ์‚ฌํ•ญ: Python >= 3.10 ยท python-hwpx >= 3.3.1

MCP ํด๋ผ์ด์–ธํŠธ ์„ค์ •

์„ค์ • ํŒŒ์ผ์— ์•„๋ž˜ ๋ธ”๋ก ํ•˜๋‚˜๋งŒ ๋„ฃ์œผ๋ฉด hwpx ์„œ๋ฒ„๋ฅผ ๋ฐ”๋กœ ์žก์Šต๋‹ˆ๋‹ค.

  • Claude Desktop โ€” claude_desktop_config.json
  • Gemini CLI โ€” ~/.gemini/settings.json
  • VS Code โ€” .vscode/mcp.json (ํ‚ค๊ฐ€ mcpServers ๋Œ€์‹  servers)
  • Cursor / Windsurf โ€” ๊ฐ ์—๋””ํ„ฐ์˜ MCP ์„ค์ • ํŒŒ์ผ
{
  "mcpServers": {
    "hwpx": {
      "command": "uvx",
      "args": ["hwpx-mcp-server"],
      "env": {
        "HWPX_MCP_WORKSPACE_ROOTS": "[\"~/Documents\"]"
      }
    }
  }
}

HWPX_MCP_WORKSPACE_ROOTS์—๋Š” ๋ฌธ์„œ๊ฐ€ ์žˆ๋Š” ํด๋”(์ ˆ๋Œ€๊ฒฝ๋กœ ๋˜๋Š” ~)๋ฅผ ์ง€์ •ํ•˜์„ธ์š”. Windows๋Š” "[\"C:\\\\hwpx\"]"์ฒ˜๋Ÿผ ์”๋‹ˆ๋‹ค. ๊ฐ’์„ ๋น„์›Œ ๋‘๋ฉด ์„œ๋ฒ„๋Š” ์‹คํ–‰ ์œ„์น˜(cwd)๋ฅผ root๋กœ ์“ฐ๋ ค ํ•˜์ง€๋งŒ, Claude Desktop ๊ฐ™์€ GUI ํด๋ผ์ด์–ธํŠธ๋Š” ์„œ๋ฒ„๋ฅผ ์‹œ์Šคํ…œ ๋””๋ ‰ํ„ฐ๋ฆฌ(Windows C:\Windows\System32, macOS /)์—์„œ ๋„์šฐ๋ฏ€๋กœ ์ด๋Ÿฐ degenerate cwd๋Š” ๊ฑฐ๋ถ€๋˜๊ณ  ๋ชจ๋“  ๋ฌธ์„œ ๊ฒฝ๋กœ๊ฐ€ ๋ง‰ํž™๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ฒ˜์Œ๋ถ€ํ„ฐ ์ด ๊ฐ’์„ ์„ค์ •ํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.

ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ๋” ๋„˜๊ธธ ๋•Œ๋Š” env ๋ธ”๋ก์— ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

{
  "mcpServers": {
    "hwpx": {
      "command": "uvx",
      "args": ["hwpx-mcp-server"],
      "env": {
        "HWPX_MCP_WORKSPACE_ROOTS": "[\"~/Documents\"]",
        "HWPX_MCP_MAX_CHARS": "12000",
        "HWPX_MCP_ADVANCED": "0",
        "LOG_LEVEL": "INFO"
      }
    }
  }
}

hwpx-plugins ๋ฒˆ๋“ค์˜ ๋Ÿฐ์ฒ˜(plugins/<host>/hwpx-plugin/scripts/hwpx-mcp-server)๋กœ๋„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋กœ์ปฌ ๊ฐœ๋ฐœ ์‹œ ๋ ˆํฌ๊ฐ€ ๊ณตํ†ต ๋ถ€๋ชจ ์•„๋ž˜์— ์—†์œผ๋ฉด HWPX_MCP_SERVER_REPO, PYTHON_HWPX_REPO๋ฅผ ์ ˆ๋Œ€๊ฒฝ๋กœ๋กœ ์ง€์ •ํ•˜์„ธ์š”.

ํ•˜๋‚˜์˜ ํ๋ฆ„๋ถ€ํ„ฐ

์ฒ˜์Œ๋ถ€ํ„ฐ ๋ชจ๋“  ๋„๊ตฌ๋ฅผ ์™ธ์šธ ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค. ๋ณดํ†ต ์•„๋ž˜ ํ•˜๋‚˜๋กœ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค.

  1. ์ฝ๊ธฐ โ€” get_document_info โ†’ get_document_outline / get_document_text โ†’ find_text, get_table_map ๋“ฑ์œผ๋กœ ํ•„์š”ํ•œ ๋ถ€๋ถ„๋งŒ. (์ €์žฅํ•˜์ง€ ์•Š์Œ)
  2. ์•ˆ์ „ ์ˆ˜์ • โ€” copy_document๋กœ ์‚ฌ๋ณธ ์ƒ์„ฑ โ†’ ์ฝ๊ธฐ ๋„๊ตฌ๋กœ ๋Œ€์ƒ ํ™•์ธ โ†’ search_and_replace, set_table_cell_text ๊ฐ™์€ ์ „๋ฌธ ๋„๊ตฌ ๋˜๋Š” ์ด์ข… ํŽธ์ง‘์šฉ apply_document_commands๋กœ ๊ฐ€์žฅ ์ž‘์€ ๋ณ€๊ฒฝ โ†’ ๋‹ค์‹œ ์ฝ์–ด ํ™•์ธ โ†’ ๊ฒ€ํ† ๊ฐ€ ๋๋‚œ ๋ณต์‚ฌ๋ณธ์„ handoff.

ํ•ต์‹ฌ์€ copy first ยท smallest edit ยท re-read after edits์ž…๋‹ˆ๋‹ค.

๋ฌด์—‡์„ ํ•˜๋‚˜

๊ธฐ๋ณธ ๋ชจ๋“œ์—์„œ ๋‹ค์ˆ˜์˜ HWPX ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜๋ฉฐ, ๊ณ ๊ธ‰ ๋ชจ๋“œ(HWPX_MCP_ADVANCED=1)์—์„œ ์ ๊ฒ€ยท๊ฒ€์ฆ์šฉ ๋„๊ตฌ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ํ…Œ๋งˆ๋ณ„ ๋Œ€ํ‘œ ํ•˜์ด๋ผ์ดํŠธ์ž…๋‹ˆ๋‹ค. ์ „์ฒด ๋„๊ตฌ ๋ชฉ๋กยท์‹œ๊ทธ๋‹ˆ์ฒ˜๋Š” docs/use-cases.md์™€ docs/skill-first-workflows.md๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.

  • ๐Ÿ“– ์ฝ๊ธฐยทํƒ์ƒ‰ โ€” get_document_info, get_document_text, get_document_outline, find_text, get_table_text, get_table_map, find_cell_by_label, list_styles. get_document_map์€ ์•„์›ƒ๋ผ์ธยทํ‘œ ์ง€๋„ยท๋ˆ„๋ฆ„ํ‹€ยท์•ต์ปค๋ฅผ ํ•œ ํ˜ธ์ถœ๋กœ ๋ฐ˜ํ™˜(์™•๋ณต ์ตœ์†Œํ™”). (์ €์žฅํ•˜์ง€ ์•Š์Œ)
  • ๐Ÿ“ฅ ๋กœ์ปฌ ๋ฌธ์„œ ingest โ€” document_to_markdown, document_extract_json, markdown_to_document_plan์ด ๋กœ์ปฌ ๋ฌธ์„œ๋ฅผ Markdown/JSON/document plan์œผ๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. HWPX๋Š” python-hwpx ์—”์ง„์„ ์šฐ์„  ์‚ฌ์šฉํ•˜๊ณ , ๋น„-HWPX๋Š” [ingest] extra ์„ค์น˜ ์‹œ MarkItDown adapter๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ”Ž ๊ฒ€์ƒ‰ยท์น˜ํ™˜ โ€” search_and_replace, batch_replace, replace_in_paragraph, replace_by_anchor. (find_text ์™ธ ์ฆ‰์‹œ ์ €์žฅ)
  • โœ๏ธ ํŽธ์ง‘ยทํŠธ๋žœ์žญ์…˜ โ€” add_heading, add_paragraph/insert_paragraph/delete_paragraph, add_page_break, add_memo ๊ณ„์—ด. apply_document_commands๋Š” ์ด์ข… command ๋ชฉ๋ก์„ ํ•œ ๋ฒˆ์— ์›์ž ์ ์šฉํ•˜๋ฉฐ ์ „์ฒด ๋กค๋ฐฑยทdry_runยทexpected_revisionยทidempotency_key๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. apply_edits๋Š” ์ „ํ™˜๊ธฐ ํ˜ธํ™˜ facade์ž…๋‹ˆ๋‹ค. undo_last_edit๋Š” .bak ๋ณต์›, byte_preserving_patch๋Š” ๋ฏธ์ˆ˜์ • ์˜์—ญ ๋ฐ”์ดํŠธ ๋ณด์กด, add_tracked_edit๋Š” ๋ณ€๊ฒฝ ์ถ”์ (redline)์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿงฉ ๋‹ค์ค‘ story ์›์ž ํŽธ์ง‘ โ€” apply_document_commands ํ•œ ํ˜ธ์ถœ์—์„œ ๋ณธ๋ฌธ, ํ‘œ ์…€, ๊ธฐ์กด ๊ตฌ์—ญ์˜ ๋‹จ์ˆœ BOTH ๋จธ๋ฆฌ๊ธ€ ํ…์ŠคํŠธ๋ฅผ ํ•จ๊ป˜ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ•˜๋‚˜๋ผ๋„ ์‹คํŒจํ•˜๋ฉด ์ถœ๋ ฅ ์ „์ฒด๋ฅผ ๋กค๋ฐฑํ•˜๋ฉฐ, ๊ตฌ์กฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณด์กดํ•  ์ˆ˜ ์—†๋Š” rich/control ๋จธ๋ฆฌ๊ธ€์€ ๋ณ€๊ฒฝ ์—†์ด ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿ“Š ํ‘œยท์–‘์‹์ฑ„์›€ โ€” add_table, set_table_cell_text, merge_table_cells/split_table_cell, format_table, table_compute(ํ•ฉ๊ณ„ยทํ‰๊ท ยท์†Œ๊ณ„). ํ˜ผํ•ฉ ์–‘์‹์˜ ๊ธฐ๋ณธ ๊ฒฝ๋กœ๋Š” analyze_form_fill โ†’ apply_form_fill โ†’ verify_form_fill์ด๋ฉฐ ์…€ยทํ•„๋“œยท๋ณธ๋ฌธ ๋ฏธ์ˆ˜์ • ์˜์—ญ์˜ ๋ฐ”์ดํŠธ ๋ณด์กด ์ฆ๊ฑฐ๋ฅผ ํ•จ๊ป˜ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. fill_by_path์™€ template-formfit ์Œ์€ ์ „ํ™˜๊ธฐ ํ˜ธํ™˜ ๊ฒฝ๋กœ์ž…๋‹ˆ๋‹ค.
  • ๐Ÿ–Š๏ธ ํ˜ผํ•ฉ ์–‘์‹ ๋‹จ์ผ ํŠธ๋žœ์žญ์…˜ โ€” list_form_fields์™€ ์ฝ๊ธฐ ๋„๊ตฌ๋กœ ๋Œ€์ƒ์„ ํ™•์ธํ•œ ๋’ค analyze_form_fill(plan=...) โ†’ apply_form_fill(plan=compiledPlan) โ†’ verify_form_fill(plan=...)๋กœ native fieldยทlabel cellยทcanonical pathยทbody anchor๋ฅผ ํ•œ ๋ฒˆ์— ์›์ž ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. fill_form_field๋Š” ๋‹จ์ผ ๋„ค์ดํ‹ฐ๋ธŒ ํ•„๋“œ ํ˜ธํ™˜ ๊ฒฝ๋กœ์ด๊ณ , ํ‰๊ฐ€๊ณ„ํš์€ apply_evalplan_fill, ์‹œํ—˜์ง€๋Š” compose_exam์˜ ๋…๋ฆฝ ์ „๋ฌธ ๊ฒฝ๋กœ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ๐Ÿงพ ์„ ์–ธํ˜• ๋ฌธ์„œ ์ƒ์„ฑ โ€” hwpx.document_plan.v1๋กœ OWPML์„ ์ง์ ‘ ๋งŒ์ง€์ง€ ์•Š๊ณ  ์„ ์–ธ: validate_document_plan/analyze_document_plan(ํŒŒ์ผ ๋ฏธ์ƒ์„ฑ) โ†’ create_document_from_plan(์ƒ์„ฑ+๊ฒ€์ฆ), inspect_document_authoring_quality, inspect_operating_plan_quality. ์ œ์•ˆ์„œ๋„ document plan ๊ฒฝ๋กœ๊ฐ€ ๊ธฐ๋ณธ์ด๋ฉฐ create_proposal_document๋Š” ํ˜ธํ™˜ facade์ž…๋‹ˆ๋‹ค. compose_exam์€ ์–‘์‹ HWPX+๋งˆํฌ๋‹ค์šด โ†’ ์‹œํ—˜์ง€ ์žฌ์กฐํŒ(verify_question_splits).
  • ๐Ÿ›๏ธ ๊ณต๋ฌธ์„œยท๋น„๊ตยท๋Œ€๋Ÿ‰ ์ƒ์‚ฐ โ€” inspect_official_document_style(ํ–‰์ •์—…๋ฌด ๊ทœ์ • lint: ํ•ญ๋ชฉ๊ธฐํ˜ธ ์œ„๊ณ„ยท"๋."ยท๋ถ™์ž„ยท๋‚ ์งœ), inspect_reference_consistency, doc_diff ํ›„ comparison document plan์„ create_document_from_plan์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ์‹ ๊ตฌ๋Œ€์กฐํ‘œ, mail_merge(ํ…œํ”Œ๋ฆฟ+CSV/JSON โ†’ N๋ถ€ยทํŒŒ์ผ๋ช… ํŒจํ„ดยทzip), inspect_mail_merge_placeholders. create_comparison_table_document๋Š” ํ˜ธํ™˜ facade์ž…๋‹ˆ๋‹ค.
  • ๐ŸŽจ ์„œ์‹ยท๊ทธ๋ฆผยท์ƒ์„ฑ๊ธฐ โ€” set_paragraph_format, set_page_setup, set_header_footer, set_page_number, set_list_format, format_text, create_custom_style(์ž…๋ ฅ์€ pt/mm/% ์ธ๊ฐ„ ๋‹จ์œ„); insert_picture(manifest ์ž๋™ ๋“ฑ๋ก)/replace_picture; build_image_grid(์‚ฌ์ง„๋Œ€์ง€)ยทbuild_meeting_nameplatesยทbuild_organization_chart.
  • ๐Ÿ–ฅ๏ธ ํ”„๋ฆฌ๋ทฐยท์ถ”์ถœยท๋ณต๊ตฌยท์ง„๋‹จ โ€” render_preview(HTML/PNG ์‹œ๊ฐ ์ž๊ธฐ๊ฒ€์ฆ), hwpx_to_markdown/hwpx_to_html/hwpx_extract_json(payloadยทURL ์ž…๋ ฅ, ํŒŒ์ผ ๋ฏธ์ˆ˜์ •), repair_hwpx(์›๋ณธ ๋ณด์กดยทmimetype-first ์žฌํŒจํ‚น, recover=true๋กœ ์†์ƒ ZIP LFH scan ๋ณต๊ตฌ; ์‘๋‹ต crcOk/validatePackage.ok/recovered ํ™•์ธ), mcp_server_health(๋ฐฐํฌ ์Šคํ ์ž๊ธฐ์ง„๋‹จยทcapability handshake).
  • ๐Ÿ”ฌ ๊ณ ๊ธ‰(HWPX_MCP_ADVANCED=1) โ€” package_parts, package_get_xml/package_get_text, object_find_by_tag/object_find_by_attr, validate_structure, lint_text_conventions ๋“ฑ ์ €์ˆ˜์ค€ ์ ๊ฒ€ ๋„๊ตฌ. plan_edit/preview_edit/apply_edit๋Š” ํ•œ ์ „ํ™˜ ๊ธฐ๊ฐ„๋งŒ ์œ ์ง€ํ•˜๋Š” deprecated stub์ด๋ฉฐ ์‹ ๊ทœ ํ๋ฆ„์€ apply_document_commands๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

์œ„์น˜ ๊ณ„์•ฝ โ€” paragraph_index๋Š” ๋ณธ๋ฌธ ์ง์† ๋ฌธ๋‹จ์˜ 0-based ์ธ๋ฑ์Šค์ž…๋‹ˆ๋‹ค. ํ‘œ ์•ˆ ๋ฌธ๋‹จ์€ ์ด ์ธ๋ฑ์Šค์— ์„ž์ง€ ์•Š๊ณ  {"kind":"table_cell_paragraph","table_index":0,"row":0,"col":1,"cell_paragraph_index":0} ๊ฐ™์€ location ๊ฐ์ฒด๋กœ ์ง€์ •ํ•˜๋ฉฐ, get_table_map/find_text๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์„ ๊ทธ๋Œ€๋กœ ๋„˜๊ธธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์•ˆ์ „ ์‚ฌ์šฉ ์›์น™

์ด ์„œ๋ฒ„์˜ ๊ณต๊ฐœ ํ‘œ๋ฉด์€ ์œ„ MCP ๋„๊ตฌ ์ง‘ํ•ฉ์ž…๋‹ˆ๋‹ค. ์›Œํฌํ”Œ๋กœ ๋ฌธ์„œ๋‚˜ ์Šคํ‚ฌ ์˜ˆ์‹œ๋Š” ์ด ๋„๊ตฌ๋“ค์˜ ์กฐํ•ฉ ํŒจํ„ด์ด์ง€ ๋ณ„๋„ ๊ณ„์•ฝ์ด ์•„๋‹™๋‹ˆ๋‹ค.

  • read first โ€” ๋จผ์ € ์ฝ๊ธฐ ๋„๊ตฌ๋กœ ๋ฌธ์„œ๋ฅผ ํŒŒ์•…ํ•œ๋‹ค.
  • copy before risky edits โ€” ๊ฒฐ๊ณผ๋ฌผ์„ ๋ณด์กดํ•ด์•ผ ํ•˜๋ฉด copy_document๋ฅผ ๋จผ์ € ํ˜ธ์ถœํ•œ๋‹ค.
  • mutating tools persist immediately โ€” ์ˆ˜์ • ๋„๊ตฌ๋Š” ํ˜ธ์ถœ ์ฆ‰์‹œ ์ €์žฅ๋˜๋ฏ€๋กœ ๊ฒ€ํ† ์šฉ์€ ๋ณต์‚ฌ๋ณธ์—์„œ ์ž‘์—…ํ•œ๋‹ค.
  • explicit handoff uses the reviewed copy โ€” ๋‚ฉํ’ˆยทhandoff๋Š” ๊ฒ€ํ† ๊ฐ€ ๋๋‚œ ๋ณต์‚ฌ๋ณธ ํŒŒ์ผ ๊ธฐ์ค€.
  • advanced mode๋Š” ์ ๊ฒ€/๊ฒ€์ฆ์šฉ์œผ๋กœ ๋ถ„๋ฆฌ โ€” package inspectionยทedit planningยทvalidation์€ HWPX_MCP_ADVANCED=1์ผ ๋•Œ๋งŒ ์“ฐ๊ณ  ๊ธฐ๋ณธ ํ๋ฆ„๊ณผ ์„ž์ง€ ์•Š๋Š”๋‹ค.

ํ’ˆ์งˆ ๊ฒŒ์ดํŠธ ๊ณ„์•ฝ (no raw XML)

๋ชจ๋ธ์€ operation/plan๋งŒ ๋ณด๋‚ด๊ณ  raw XML์„ ์ง์ ‘ ํŽธ์ง‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. raw_xml_replace, arbitrary_xpath_mutation ๊ฐ™์€ ์›์‹œ XML ํ‘œ๋ฉด์€ public ๋„๊ตฌ๋กœ ๋…ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ๋ฌธ์„œ ์ €์žฅ ๊ฒฝ๋กœ๋Š” python-hwpx์˜ SavePipeline ๊ฒŒ์ดํŠธ๋ฅผ ์‚ฌ์šฉํ•ด ๋ฌด๊ฒฐ์„ฑยทXMLยทOPC/IDยท์—ด๋ฆผ์•ˆ์ „์„ ๊ฒ€์‚ฌํ•˜๊ณ , ์š”์ฒญํ•œ ํ’ˆ์งˆ ์ˆ˜์ค€์— ๋”ฐ๋ผ FormFitยท๋ ˆ์ด์•„์›ƒยท์‹œ๊ฐ ์˜ค๋ผํด๊นŒ์ง€ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

  • quality๋ฅผ ๋ฐ›๋Š” ์ผ๋ฐ˜ ์ €์žฅ ๋„๊ตฌ๋Š” ์‘๋‹ต์— visualComplete๋ฅผ ์‹ฃ์Šต๋‹ˆ๋‹ค: ok, status(verified/unverified/failed), errorCodes, warnings, suggestedRetry. quality๋ฅผ ์ƒ๋žตํ•˜๋ฉด transparent(์—ด๋ฆผ์•ˆ์ „), "strict" ๋˜๋Š” {"mode":"strict","overflowPolicy":"fail","layoutLint":"strict"}๋กœ ์˜ฌ๋ฆฌ๋ฉด ์ถ”๊ฐ€ ๊ฒŒ์ดํŠธ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • byte_preserving_patch, apply_table_ops, apply_body_ops, apply_evalplan_fill์€ untouched package byte๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๋ช…์‹œ์  carveout์ž…๋‹ˆ๋‹ค. ์ด ๊ฒฝ๋กœ๋Š” guarded publication, open-safety, byte/member diff์™€ ๊ณตํ†ต verification receipt๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ visualComplete๋ฅผ ์ฃผ์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ‘œยทํ‰๊ฐ€๊ณ„ํš์€ ์š”์ฒญ ์‹œ ์‹ค์ œ ๋ Œ๋” ๊ฒ€์‚ฌ๋ฅผ ๋ณ„๋„ ์ˆ˜ํ–‰ํ•˜๊ณ , ๋ณธ๋ฌธ fast path๋Š” ์ „์ฒด ์žฌ๋ Œ๋”๋ฅผ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ํ•ด๋‹น ๊ฒฝ๋กœ์˜ ๊ฒŒ์ดํŠธ๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์ €์žฅ์ด ๋ณด๋ฅ˜๋˜๊ฑฐ๋‚˜ ์†Œ์œ ํ•œ ํ›„๋ณด๋งŒ ์›๋ณต๋˜๊ณ (ok=false), ๊ตฌ์กฐํ™”๋œ ์˜ค๋ฅ˜ ์ฝ”๋“œ๋กœ ์žฌ์‹œ๋„ ์—ฌ๋ถ€๋ฅผ ์•Œ๋ฆฝ๋‹ˆ๋‹ค.
  • capability handshake๊ฐ€ core/mcp/plugin ๋ฒ„์ „+ํ•ด์‹œ๋ฅผ ์ ๊ฒ€ํ•˜๊ณ , skew ์‹œ ์“ฐ๊ธฐ๋ฅผ fail-closed๋กœ ์ฐจ๋‹จํ•ฉ๋‹ˆ๋‹ค(mcp_server_health.capability). ์ง„๋‹จ/์šฐํšŒ๋Š” HWPX_MCP_REQUIRE_CAPABILITY=0.

visual_review_required=true๋Š” ๊ตฌ์กฐ/ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๊ฒ€์ฆ์€ ํ†ต๊ณผํ–ˆ์ง€๋งŒ ๋ Œ๋”๋ง๋œ ์‹œ๊ฐ ๋ ˆ์ด์•„์›ƒ์€ ์•„์ง ์ฆ๋ช…๋˜์ง€ ์•Š์•˜๋‹ค๋Š” ๋œป์ž…๋‹ˆ๋‹ค. ์šด์˜ ๊ณ„ํš์„œยทtemplate-formfit ๊ฒฐ๊ณผ๋ฅผ ์ตœ์ข… ์ œ์ถœ ๊ฐ€๋Šฅ(submission-ready)์œผ๋กœ ์ฃผ์žฅํ•˜๋ ค๋ฉด ์—ด๋ฆฐ ๋ฌธ์„œ๋ฅผ ๊ฒ€ํ† ํ•ด hwpx.visual-review.v1 ์ฆ๊ฑฐ๋ฅผ ๋‚จ๊ธฐ๊ณ  current.status="observed_pass"์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ™˜๊ฒฝ ๋ณ€์ˆ˜

๋ณ€์ˆ˜ ์„ค๋ช… ๊ธฐ๋ณธ๊ฐ’
HWPX_MCP_MAX_CHARS ํ…์ŠคํŠธ ๋ฐ˜ํ™˜ ๋„๊ตฌ ๊ธฐ๋ณธ ์ตœ๋Œ€ ๊ธธ์ด 10000
HWPX_MCP_AUTOBACKUP 1์ด๋ฉด ์ €์žฅ ์ „ .bak ๋ฐฑ์—… ์ƒ์„ฑ 1
HWPX_MCP_ADVANCED 1์ด๋ฉด ๊ณ ๊ธ‰ ๋„๊ตฌ ํ™œ์„ฑํ™” 0
HWPX_MCP_WORKSPACE_ROOTS ํ—ˆ์šฉํ•  workspace ์ ˆ๋Œ€๊ฒฝ๋กœ์˜ JSON ๋ฐฐ์—ด(๋ณต์ˆ˜ root ์ง€์›). ์ƒ๋Œ€๊ฒฝ๋กœ๋Š” ์ฒซ root ๊ธฐ์ค€ unset โ†’ ํ”„๋กœ์„ธ์Šค cwd. ๋‹จ cwd๊ฐ€ degenerate(ํŒŒ์ผ์‹œ์Šคํ…œ ๋ฃจํŠธ, Windows ์‹œ์Šคํ…œ ๋””๋ ‰ํ„ฐ๋ฆฌ)๋ฉด WORKSPACE_ROOT_INVALID๋กœ ๊ฑฐ๋ถ€ํ•˜๋‹ˆ ์ด ๊ฐ’ ์„ค์ •์„ ๊ถŒ์žฅ
HWPX_MCP_SANDBOX_ROOT ๋‹จ์ผ root ๊ตฌ๋ฒ„์ „ ํ˜ธํ™˜ ๋ณ€์ˆ˜. ์ƒˆ ์„ค์ •์—์„œ๋Š” HWPX_MCP_WORKSPACE_ROOTS ์‚ฌ์šฉ unset
HWPX_MCP_FETCH_TIMEOUT_SECONDS URL ๊ธฐ๋ฐ˜ HWPX fetch timeout 20.0
HWPX_MCP_ALLOW_PRIVATE_NETWORK 1์ด๋ฉด ์‹ ๋ขฐ๋œ ์‚ฌ์„ค/๋ฃจํ”„๋ฐฑ HTTPS ๋Œ€์ƒ ํ—ˆ์šฉ. ๋งํฌ๋กœ์ปฌยทmetadataยท์˜ˆ์•ฝ ์ฃผ์†Œ๋Š” ๊ณ„์† ์ฐจ๋‹จ 0
HWPX_MCP_QUALITY ์ „์—ญ ๊ธฐ๋ณธ ์ €์žฅ ๊ฒŒ์ดํŠธ ์ •์ฑ…(transparent/strict). ๋„๊ตฌ๋ณ„ quality๊ฐ€ ์šฐ์„  transparent
HWPX_MCP_REQUIRE_CAPABILITY 0์ด๋ฉด capability skew fail-closed๋ฅผ ๋”(์ง„๋‹จ/์ „๋ฌธ๊ฐ€์šฉ) 1
LOG_LEVEL ๋กœ๊ทธ ๋ ˆ๋ฒจ INFO

๊ฒฝ๋กœ๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ workspace ๋ฐ– traversal๊ณผ symlink escape๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. URL ์ž…๋ ฅ๊ณผ HTTP storage/render transport๋Š” HTTPS ๋ฐ ๊ณต๊ฐœ IP๋งŒ ํ—ˆ์šฉํ•˜๊ณ , ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ์™€ ์‹ค์ œ ์—ฐ๊ฒฐ ํ”ผ์–ด๋ฅผ ๋‹ค์‹œ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์„ค๋ง opt-in์€ ์šด์˜์ž๊ฐ€ ๋Œ€์ƒ์„ ์‹ ๋ขฐํ•˜๊ณ  ๋„คํŠธ์›Œํฌ ๊ฒฝ๊ณ„๋ฅผ ๋ณ„๋„๋กœ ํ†ต์ œํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•˜์„ธ์š”.

macOS์™€ renameat2๋ฅผ ์ œ๊ณตํ•˜๋Š” Linux์˜ canonical mixed-form ๋ฐ byte-preserving form ๊ฒŒ์‹œ ๊ฒฝ๋กœ๋Š” root/parent descriptor์™€ ๋Œ€์ƒ byteยทidentity snapshot์— ๋ฌถ์—ฌ ๋™์‹œ renameยทsymlink ๊ต์ฒด๋„ ์‹คํŒจ ํ›„ ์›๋ณตํ•ฉ๋‹ˆ๋‹ค. Windows์™€ ๊ทธ ์›์ž ๊ตํ™˜ primitive๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š” ๊ธฐํƒ€ POSIX ํ˜ธ์ŠคํŠธ์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ fallback์€ ๋™์ผํ•œ handle-relative ๋ณด์žฅ์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ํ˜ธ์ŠคํŠธ์—์„œ๋Š” ๋กœ์ปฌ workspace๋ฅผ ์‹ ๋ขฐ๋œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ทจ๊ธ‰ํ•˜๊ณ  ACL ๋˜๋Š” host sandbox๋กœ ๊ฐ™์€ ์‚ฌ์šฉ์ž ๊ถŒํ•œ์˜ ๋™์‹œ reparse/rename์„ ๋ง‰์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๋” ๋ณด๊ธฐ

ํ…Œ์ŠคํŠธ

python -m pip install -e ".[test]"   # ํ…Œ์ŠคํŠธ ์˜์กด์„ฑ ์„ค์น˜
python -m pytest -q                   # ์ „์ฒด ํ…Œ์ŠคํŠธ

๊ฐ์‚ฌ์˜ ๋ง

์ฝ”์–ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ python-hwpx ์œ„์—์„œ ๋™์ž‘ํ•˜๋ฉฐ, ์•„๋ž˜ ๊ณต๊ฐœ ํ‘œ์ค€ยทํ”„๋กœ์ ํŠธ์— ๋นš์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

License

Apache License 2.0. See LICENSE and NOTICE.

์ž‘์„ฑ์ž

๊ณ ๊ทœํ˜„ โ€” ๊ด‘๊ต๊ณ ๋“ฑํ•™๊ต ์ •๋ณดยท์ปดํ“จํ„ฐ ๊ต์‚ฌ

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

hwpx_mcp_server-4.3.2.tar.gz (476.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

hwpx_mcp_server-4.3.2-py3-none-any.whl (349.4 kB view details)

Uploaded Python 3

File details

Details for the file hwpx_mcp_server-4.3.2.tar.gz.

File metadata

  • Download URL: hwpx_mcp_server-4.3.2.tar.gz
  • Upload date:
  • Size: 476.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hwpx_mcp_server-4.3.2.tar.gz
Algorithm Hash digest
SHA256 3071e23ecd4b82eb57c88d28acc9b568d835d1ec1ace79b218d99a2b02140da2
MD5 3ac17caba58d1f37bbc67d5b5eb5e596
BLAKE2b-256 9ca470fffc97ca28ceaccbd0fc6c69a781fdee1ed097a8a77d2dcd8d06788ee0

See more details on using hashes here.

Provenance

The following attestation bundles were made for hwpx_mcp_server-4.3.2.tar.gz:

Publisher: release.yml on airmang/hwpx-mcp-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file hwpx_mcp_server-4.3.2-py3-none-any.whl.

File metadata

  • Download URL: hwpx_mcp_server-4.3.2-py3-none-any.whl
  • Upload date:
  • Size: 349.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for hwpx_mcp_server-4.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 c1631c4e7a7b7c630e04af2c3d96184fca4b96298cd5954973fc1724caf669b9
MD5 2e4a44af99304eaa2def9d97a81127a1
BLAKE2b-256 ebdb1dd8f1daeacdabea650dafa25676814b7a619d2155385024a972d8abc2bd

See more details on using hashes here.

Provenance

The following attestation bundles were made for hwpx_mcp_server-4.3.2-py3-none-any.whl:

Publisher: release.yml on airmang/hwpx-mcp-server

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page