Model Context Protocol server for local HWPX document automation.
Project description
๐ hwpx-mcp-server
ํ๊ธ(HWPX) ๋ฌธ์๋ฅผ AI๋ก ์๋ํํ๋ MCP ์๋ฒ
ํ๊ธ ์๋ํ๋ก์ธ์ ์์ด ยท ์์ ํ์ด์ฌ ยท ํฌ๋ก์ค ํ๋ซํผ
hwpx-mcp-server๋ Model Context Protocol(MCP) ํ์ค์ ๋ฐ๋ฅด๋ ์๋ฒ๋ก, python-hwpx ๊ธฐ๋ฐ์์ HWPX ๋ฌธ์์ ์ด๋ ยท ๊ฒ์ ยท ํธ์ง ยท ์ ์ฅ์ AI ํด๋ผ์ด์ธํธ์์ ์ง์ ์ํํ ์ ์๊ฒ ํฉ๋๋ค.
Note โ ์ด ์๋ฒ๋ Open XML ๊ธฐ๋ฐ
.hwpxํฌ๋งท์ ์ง์ํฉ๋๋ค. ๋ ๊ฑฐ์ ๋ฐ์ด๋๋ฆฌ.hwpํฌ๋งท์ ์ง์ ํธ์ง ๋์์ด ์๋๋๋ค.
Why?
๊ตญ๋ด ๊ณต๊ณต๊ธฐ๊ดยทํ๊ตยท๊ธฐ์ ์์๋ ํ๊ธ ๋ฌธ์ ๊ธฐ๋ฐ ์ ๋ฌด๊ฐ ๋งค์ฐ ๋ง์ง๋ง, ์๋ํ๋ ์ค๋ซ๋์ OS/ํ๋ก๊ทธ๋จ ์์กด์ฑ์ด ์ปธ์ต๋๋ค.
hwpx-mcp-server๋ ์ด ์ ์ฝ์ ์ค์ด๋ ๋ฐ ์ด์ ์ ๋ง์ถฅ๋๋ค.
- โ OS ๋ฌด๊ด โ Windows, macOS, Linux์์ ๋์
- โ ํ๊ธ ์๋ํ๋ก์ธ์ ๋ถํ์ โ ์์ ํ์ด์ฌ ๊ธฐ๋ฐ ์ฒ๋ฆฌ
- โ AI ๋ค์ดํฐ๋ธ โ Claude Desktop, VS Code, Gemini CLI ๋ฑ MCP ํด๋ผ์ด์ธํธ์ ์ง์ ์ฐ๊ฒฐ
- โ
Stateless ๊ธฐ๋ณธ ์ค๊ณ โ ๋๊ตฌ ํธ์ถ๋ง๋ค
filename์ ๋ช ์ํด ์ผ๊ด์ ์ผ๋ก ์คํ
Use Cases
- ์ค์ ์ฌ์ฉ ์ฌ๋ก 9๊ฐ ๋ณด๊ธฐ:
docs/use-cases.md - ์ข
ํฉ ํ
์คํธ ๋ฆฌํฌํธ:
tests/hwpx_mcp_report_updated.md
Quick Start
1. ์ค์น & ์คํ
uv ๊ธฐ์ค:
uvx hwpx-mcp-server
๋๋ pip ์ค์น:
pip install hwpx-mcp-server
hwpx-mcp-server
์๊ตฌ์ฌํญ:
Python >= 3.10python-hwpx >= 2.6
ํ์ฌ ๊ฒ์ฆ ๊ธฐ์ค upstream ๋ฒ์ : python-hwpx 2.7.1
2. MCP ํด๋ผ์ด์ธํธ ์ค์
Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"hwpx": {
"command": "uvx",
"args": ["hwpx-mcp-server"]
}
}
}
Gemini CLI
~/.gemini/settings.json:
{
"mcpServers": {
"hwpx": {
"command": "uvx",
"args": ["hwpx-mcp-server"]
}
}
}
VS Code (Copilot Chat)
.vscode/mcp.json:
{
"servers": {
"hwpx": {
"command": "uvx",
"args": ["hwpx-mcp-server"]
}
}
}
Cursor / Windsurf
๊ฐ ์๋ํฐ MCP ์ค์ ํ์ผ์ ๋์ผํ ๋ธ๋ก์ ์ถ๊ฐ:
{
"mcpServers": {
"hwpx": {
"command": "uvx",
"args": ["hwpx-mcp-server"]
}
}
}
Features
๊ธฐ๋ณธ ๋ชจ๋์์ 30๊ฐ ๋๊ตฌ๋ฅผ ์ ๊ณตํ๋ฉฐ, ๊ณ ๊ธ ๋ชจ๋(HWPX_MCP_ADVANCED=1)์์๋ ์ด 40๊ฐ ๋๊ตฌ๊น์ง ํ์ฅ๋ฉ๋๋ค.
๐ ์ฝ๊ธฐ & ํ์
| ๋๊ตฌ | ์ค๋ช |
|---|---|
get_document_info |
๋ฌธ์ ๋ฉํ๋ฐ์ดํฐ/์น์ /๋ฌธ๋จ/ํ ๊ฐ์ ์กฐํ |
get_document_text |
๋ฌธ์ ์ ์ฒด ํ
์คํธ ์ถ์ถ (max_chars ์ง์) |
get_document_outline |
์ ๋ชฉ/๊ฐ์ ๊ตฌ์กฐ ์ถ์ถ |
get_paragraph_text |
ํน์ ๋ฌธ๋จ ํ ์คํธ ์กฐํ |
get_paragraphs_text |
๋ฌธ๋จ ๋ฒ์ ์กฐํ |
list_available_documents |
ํด๋ ๋ด .hwpx ํ์ผ ๋ชฉ๋ก ์กฐํ |
๐ ๊ฒ์ & ์นํ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
find_text |
ํค์๋ ๊ฒ์ + ์ปจํ ์คํธ ๋ฐํ |
search_and_replace |
๋จ์ผ ์นํ (split-run ๋ณด๊ฐ) |
batch_replace |
๋ค์ค ์นํ ์ผ๊ด ์คํ |
โ๏ธ ํธ์ง
| ๋๊ตฌ | ์ค๋ช |
|---|---|
add_heading |
์ ๋ชฉ(ํค๋ฉ) ๋ฌธ๋จ ์ถ๊ฐ |
add_paragraph / insert_paragraph / delete_paragraph |
๋ฌธ๋จ ์ถ๊ฐ/์ฝ์ /์ญ์ |
add_page_break |
ํ์ด์ง ๋๋๊ธฐ ์ถ๊ฐ |
add_memo / remove_memo |
๋ฉ๋ชจ ์ถ๊ฐ/์ ๊ฑฐ |
copy_document |
๋ฌธ์ ์์ ๋ณต์ฌ |
๐ ํ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
add_table / get_table_text |
ํ ์์ฑ/์กฐํ |
set_table_cell_text |
์ ํ ์คํธ ์์ |
merge_table_cells / split_table_cell |
์ ๋ณํฉ/๋ถํ |
format_table |
ํ ํค๋ ๋ฑ ๊ธฐ๋ณธ ์์ ์ ์ฉ |
๐จ ์คํ์ผ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
format_text |
ํ ์คํธ ๋ฒ์ ์์ ์ ์ฉ(๊ตต๊ธฐ, ๊ธฐ์ธ์, ๋ฐ์ค, ์์ ๋ฑ) |
create_custom_style |
์ปค์คํ ์คํ์ผ ์์ฑ |
list_styles |
๋ฌธ์ ์คํ์ผ ๋ชฉ๋ก ์กฐํ |
๐ค ์ฝ๊ธฐ/์ถ์ถ
| ๋๊ตฌ | ์ค๋ช |
|---|---|
hwpx_to_markdown |
HWPX payload๋ฅผ Markdown์ผ๋ก ๋ณํ |
hwpx_to_html |
HWPX payload๋ฅผ HTML๋ก ๋ณํ |
hwpx_extract_json |
HWPX payload๋ฅผ ๊ตฌ์กฐํ JSON์ผ๋ก ์ถ์ถ |
์คํ์ผ ์ฐธ์กฐ ํ:
add_paragraph(..., style=...)์ insert_paragraph(..., style=...)๋ list_styles์ id, create_custom_style์ด ๋ฐํํ๋ style_id, ์คํ์ผ ์ด๋ฆ์ ๋ชจ๋ ๋ฐ์ ์ ์์ต๋๋ค.
๐ฌ ๊ณ ๊ธ (์ต์ )
HWPX_MCP_ADVANCED=1์ผ ๋ ํ์ฑํ:
| ๋๊ตฌ | ์ค๋ช |
|---|---|
package_parts |
OPC ํํธ ๋ชฉ๋ก ์กฐํ |
package_get_xml / package_get_text |
ํํธ XML/ํ ์คํธ ์กฐํ |
object_find_by_tag / object_find_by_attr |
XML ์์ ๊ฒ์ |
plan_edit / preview_edit / apply_edit |
ํธ์ง ๊ณํ/๋ฏธ๋ฆฌ๋ณด๊ธฐ/์ ์ฉ |
validate_structure / lint_text_conventions |
๊ตฌ์กฐ ๊ฒ์ฆ/ํ ์คํธ ๋ฆฐํธ |
Configuration
| ๋ณ์ | ์ค๋ช | ๊ธฐ๋ณธ๊ฐ |
|---|---|---|
HWPX_MCP_MAX_CHARS |
ํ ์คํธ ๋ฐํ ๋๊ตฌ ๊ธฐ๋ณธ ์ต๋ ๊ธธ์ด | 10000 |
HWPX_MCP_AUTOBACKUP |
1์ด๋ฉด ์ ์ฅ ์ .bak ๋ฐฑ์
์์ฑ |
1 |
HWPX_MCP_ADVANCED |
1์ด๋ฉด ๊ณ ๊ธ ๋๊ตฌ ํ์ฑํ |
0 |
LOG_LEVEL |
๋ก๊ทธ ๋ ๋ฒจ | INFO |
ํ๊ฒฝ ๋ณ์ ํฌํจ MCP ์ค์ ์์:
{
"mcpServers": {
"hwpx": {
"command": "uvx",
"args": ["hwpx-mcp-server"],
"env": {
"HWPX_MCP_MAX_CHARS": "12000",
"HWPX_MCP_AUTOBACKUP": "1",
"HWPX_MCP_ADVANCED": "0",
"LOG_LEVEL": "INFO"
}
}
}
}
Advanced
๐ฆ OPC ํํธ ์กฐํ
๊ณ ๊ธ ๋ชจ๋์์ ๋ฌธ์ ๋ด๋ถ ํํธ๋ฅผ ์ง์ ์กฐํํ ์ ์์ต๋๋ค.
package_partspackage_get_xmlpackage_get_text
๐งญ ํธ์ง ํ์ดํ๋ผ์ธ
๊ณ ๊ธ ๋ชจ๋์์ plan_edit โ preview_edit โ apply_edit ํ๋ฆ์ผ๋ก ๋ณ๊ฒฝ ๊ณํ์ ๊ฒํ ํ๊ณ ์ ์ฉํ ์ ์์ต๋๋ค.
๐งช ๊ตฌ์กฐ/๊ท์น ๊ฒ์ฌ
๊ณ ๊ธ ๋ชจ๋์์ ๋ค์ ๊ฒ์ฌ ๋๊ตฌ๋ฅผ ์ฌ์ฉํ ์ ์์ต๋๋ค.
validate_structurelint_text_conventions
Testing
# ํ
์คํธ ์์กด์ฑ ์ค์น
python -m pip install -e ".[test]"
# ์ ์ฒด ํ
์คํธ
python -m pytest -q
ํ๊ท ํ
์คํธ๋ ์ค์ HWPX ์ถ๋ ฅ ๋ณ๊ฒฝ์ ๊ฒ์ฆํ๋๋ก ์ ์งํฉ๋๋ค. ์ต์ ๊ฒฐ๊ณผ๋ python -m pytest -q๋ก ํ์ธํ์ธ์.
- ์ค์ ์ฌ์ฉ ์ฌ๋ก:
docs/use-cases.md - ์ข
ํฉ ๋ฆฌํฌํธ:
tests/hwpx_mcp_report_updated.md - ํ๊ท ํ
์คํธ:
tests/test_hwpx_report_regressions.py
Architecture
hwpx-mcp-server
โโโ src/hwpx_mcp_server/
โ โโโ server.py # Stateless MCP ์ง์
์
โ โโโ hwpx_ops.py # ๊ณ ๊ธ/๋ด๋ถ ์ฐ์ฐ ๋ํผ
โ โโโ storage.py # ์ ์ฅ ๋ฐฑ์๋ (atomic save)
โ โโโ core/ # ๋ฌธ๋จ/ํ/๊ฒ์/์์ ํต์ฌ ๋ก์ง
โ โโโ tools.py # ํ์ฅ ๋๊ตฌ ์คํค๋ง/์ ์
โ โโโ schema/ # JSON ์คํค๋ง ๋น๋/์ ๋ฆฌ๊ธฐ
โโโ tests/ # ๋จ์ + E2E + ํ๊ท ํ
์คํธ
โโโ pyproject.toml
Comparison
| hwpx-mcp-server | hwp(๋ฐ์ด๋๋ฆฌ) COM ์๋ํ ๊ณ์ด | |
|---|---|---|
| ๋์ ํฌ๋งท | .hwpx (Open XML) |
.hwp (๋ฐ์ด๋๋ฆฌ) ์ค์ฌ |
| OS | Windows ยท macOS ยท Linux | ๋์ฒด๋ก Windows ์ค์ฌ |
| ํ๊ธ ํ๋ก๊ทธ๋จ ์์กด | ๋ถํ์ | ํ์ํ ๊ฒฝ์ฐ๊ฐ ๋ง์ |
| ์ฐ๋ ๋ฐฉ์ | MCP + ํ์ด์ฌ ๋ผ์ด๋ธ๋ฌ๋ฆฌ | ๋ฐ์คํฌํฑ ์ฑ ์๋ํ |
Upstream Compatibility Notes
- ๋ฌธ์ํ๋ MCP ๊ธฐ๋ฅ ๊ธฐ์ค ์ต์ upstream ๋ฒ์ ์
python-hwpx >= 2.6์ ๋๋ค. - ํ์ฌ ์ ์ฅ์๋ ๋ก์ปฌ editable checkout ๊ธฐ์ค
python-hwpx 2.7.1๊ณผ ํธํ์ฑ์ ๊ฒ์ฆํ์ต๋๋ค. format_text๋ ์ค์ run-levelcharPrIDRef๋ฅผ ๋ถ๋ฆฌ/๊ฐฑ์ ํ๋ฉฐ ์ ์ฅ ํ ๋ค์ ์ด์ด๋ ์์ ๋ณ๊ฒฝ์ด ์ ์ง๋ฉ๋๋ค.create_custom_style๋ ์ฌ์ฌ์ฉ ๊ฐ๋ฅํstyle_id๋ฅผ ๋ฐํํ๋ฉฐ, ์์ ์ค๋ฒ๋ผ์ด๋๊ฐ ์์ผ๋ฉด ๋ณ๋์ upstreamcharPr๋ฅผ ์์ฑํฉ๋๋ค.- ๋ก์ปฌ ํ์ผ ์ฐ๊ธฐ๋
storage.py์ atomic save ๊ฒฝ๋ก๋ฅผ ๊ณตํต ์ฌ์ฉํฉ๋๋ค.
Contributing
๊ธฐ์ฌ๋ฅผ ํ์ํฉ๋๋ค.
- Fork ํ ๋ธ๋์น ์์ฑ
- ๋ณ๊ฒฝ + ํ ์คํธ ์ถ๊ฐ/์์
pytest -qํต๊ณผ ํ์ธ ํ PR
License
MIT ยฉ ๊ณ ๊ทํ (Kyuhyun Koh)
Author
๊ณ ๊ทํ โ ๊ด๊ต๊ณ ๋ฑํ๊ต ์ ๋ณดยท์ปดํจํฐ ๊ต์ฌ
- โ๏ธ kokyuhyun@hotmail.com
- ๐ @airmang
Transport Modes (Stdio + HTTP)
Existing stdio usage is unchanged:
hwpx-mcp-server
Run the same MCP tool set over Streamable HTTP:
hwpx-mcp-server --transport streamable-http --host 127.0.0.1 --port 8000
Environment variables are also supported:
HWPX_MCP_TRANSPORT(stdioorstreamable-http)HWPX_MCP_HOST(default:127.0.0.1)HWPX_MCP_PORT(default:8000)
Note: HTTP auth is intentionally kept simple for now (dev mode). A production auth hook is left as a TODO in the server entrypoint.
New Read/Extract Tools
All three tools accept exactly one input source:
hwpx_base64: base64 encoded.hwpxbytesurl: downloadablehttps://...URL
Common options:
output:fullorchunkschunk_strategy:sectionorparagraphmax_chars_per_chunk: integer, default via server setting
1) hwpx_to_markdown
Response:
{
"markdown": "# Title\n\nParagraph...",
"chunks": ["..."],
"meta": {
"source_type": "base64",
"section_count": 2,
"paragraph_count": 10,
"table_count": 1,
"figure_caption_count": 1
}
}
2) hwpx_to_html
Response:
{
"html": "<!doctype html><html>...</html>",
"chunks": ["<section>...</section>"],
"meta": {
"source_type": "url",
"image_policy": "omitted"
}
}
3) hwpx_extract_json
Response:
{
"doc": {
"title": "Title",
"toc": [{ "level": 1, "text": "Title", "paragraph_index": 0 }],
"sections": [{ "index": 0, "title": "Title", "paragraphs": [] }],
"tables": [],
"figures": []
},
"chunks": [{ "chunk_index": 0, "strategy": "section", "section": {} }],
"meta": {
"source_type": "base64"
}
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hwpx_mcp_server-2.2.1.tar.gz.
File metadata
- Download URL: hwpx_mcp_server-2.2.1.tar.gz
- Upload date:
- Size: 105.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
81b026ad1c755f90ff94bba641d4b694bef9c5b0d8bc91a71e9d6753e10b6660
|
|
| MD5 |
1ccf94d9f3308e6729ed817ff93ef8f8
|
|
| BLAKE2b-256 |
74c57ae2392437f5b028507c2ea8b58eb341d48adc79a39e9a3718a0b8a4c8fd
|
Provenance
The following attestation bundles were made for hwpx_mcp_server-2.2.1.tar.gz:
Publisher:
release.yml on airmang/hwpx-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hwpx_mcp_server-2.2.1.tar.gz -
Subject digest:
81b026ad1c755f90ff94bba641d4b694bef9c5b0d8bc91a71e9d6753e10b6660 - Sigstore transparency entry: 1059474370
- Sigstore integration time:
-
Permalink:
airmang/hwpx-mcp-server@905dd4aff420c0fb6275f31dc02c909486815574 -
Branch / Tag:
refs/tags/v2.2.1 - Owner: https://github.com/airmang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@905dd4aff420c0fb6275f31dc02c909486815574 -
Trigger Event:
push
-
Statement type:
File details
Details for the file hwpx_mcp_server-2.2.1-py3-none-any.whl.
File metadata
- Download URL: hwpx_mcp_server-2.2.1-py3-none-any.whl
- Upload date:
- Size: 90.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ab2d2377074174eacb51e541938ab188e6e13b6b803d482c4164ad645cf42f0d
|
|
| MD5 |
ec2d6e619812e0ff4dfa0e2e635d980c
|
|
| BLAKE2b-256 |
25e56007b7097ff4f13821beb52ac2bee1e267d1181c7483cf4d90f76a3cf2d4
|
Provenance
The following attestation bundles were made for hwpx_mcp_server-2.2.1-py3-none-any.whl:
Publisher:
release.yml on airmang/hwpx-mcp-server
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
hwpx_mcp_server-2.2.1-py3-none-any.whl -
Subject digest:
ab2d2377074174eacb51e541938ab188e6e13b6b803d482c4164ad645cf42f0d - Sigstore transparency entry: 1059474372
- Sigstore integration time:
-
Permalink:
airmang/hwpx-mcp-server@905dd4aff420c0fb6275f31dc02c909486815574 -
Branch / Tag:
refs/tags/v2.2.1 - Owner: https://github.com/airmang
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@905dd4aff420c0fb6275f31dc02c909486815574 -
Trigger Event:
push
-
Statement type: