SkillAgentSearch skills...

HwpForge

Rust library for programmatic control of Korean HWPX documents โ€” Markdownโ†’HWPX conversion, JSON round-trip editing, MCP server for AI agents ๐Ÿ”ฅ

Install / Use

/learn @ai-screams/HwpForge
About this skill

Quality Score

0/100

Supported Platforms

Claude Code
Cursor

README

HwpForge ๐Ÿ”ฅ

Rust๋กœ ํ•œ๊ธ€(HWP/HWPX) ๋ฌธ์„œ๋ฅผ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ๋ฐฉ์‹์œผ๋กœ ์ œ์–ด

Hancom ํ•œ๊ธ€ ํŒŒ์ผ ์ฝ๊ธฐ, ์“ฐ๊ธฐ, ๋ณ€ํ™˜

<div align="center">

CI codecov Tests unsafe forbidden Lines of Code

crates.io docs.rs crates.io downloads MSRV License: MIT OR Apache-2.0

MCP Ready GitHub release GitHub last commit GitHub stars

Security Policy Contributing PRs Welcome Made in Korea Buy Me a Coffee

</div> <div align="center"> <img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/banner-main.png" alt="HwpForge Banner" width="600"> </div>

HwpForge๋ž€?

HwpForge๋Š” HWPX ๋ฌธ์„œ(ZIP + XML, KS X 6101)๋ฅผ ๋‹ค๋ฃจ๊ธฐ ์œ„ํ•œ ์˜คํ”ˆ์†Œ์Šค ์ˆœ์ˆ˜ Rust ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ํ•œ๊ตญ์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์›Œ๋“œํ”„๋กœ์„ธ์„œ์ธ Hancom ํ•œ๊ธ€์˜ ์ตœ์‹  ํฌ๋งท์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ง€์› ๋ฒ„์ „

| ํ•œ๊ธ€ ๋ฒ„์ „ | ํฌ๋งท | ์ฝ๊ธฐ | ์“ฐ๊ธฐ | ์Šคํƒ€์ผ ์„ธํŠธ | | ----------------- | ------------ | ---- | ---- | ------------------------------ | | ํ•œ๊ธ€ 2014 ~ 2020 | HWPX (.hwpx) | โœ… | โœ… | Classic (18 styles) | | ํ•œ๊ธ€ 2022 ~ 2024 | HWPX (.hwpx) | โœ… | โœ… | Modern (22 styles, ๊ธฐ๋ณธ๊ฐ’) | | ํ•œ๊ธ€ 2025+ | HWPX (.hwpx) | โœ… | โœ… | Latest (23 styles) | | ํ•œ๊ธ€ 97 ~ 2010 | HWP5 (.hwp) | โœ… | โ€” | โ€” |

  • HWPX: OWPML ๊ตญ๊ฐ€ํ‘œ์ค€ (KS X 6101) ๊ธฐ๋ฐ˜, ZIP + XML ์ปจํ…Œ์ด๋„ˆ
  • HWP5: ๊ตฌํ˜• ๋ฐ”์ด๋„ˆ๋ฆฌ ํฌ๋งท. ํ˜„์žฌ๋Š” CLI ์ค‘์‹ฌ์˜ ์ฝ๊ธฐ/์ ๊ฒ€/์žฌ์ถœ๋ ฅ ๊ฒฝ๋กœ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค (convert-hwp5, audit-hwp5, census-hwp5)
  • ์Šคํƒ€์ผ ์„ธํŠธ๋Š” HancomStyleSet enum์œผ๋กœ ์„ ํƒ ๊ฐ€๋Šฅ (๊ธฐ๋ณธ: Modern)

LLM-first ์„ค๊ณ„ ๐Ÿ”ฅ โ€” AI ์นœํ™”์ ์ธ Markdown๊ณผ ๊ณต์‹ ํ•œ๊ธ€ ๋ฌธ์„œ ํฌ๋งท(HWPX), ๋‘ ์„ธ๊ณ„๋ฅผ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ž‡์Šต๋‹ˆ๋‹ค. LLM์ด Markdown์œผ๋กœ ์ž‘์„ฑํ•œ ๋‚ด์šฉ์€ ๊ณต๋ฌธ์„œ ๊ทœ๊ฒฉ์˜ HWPX๋กœ ์ปดํŒŒ์ผ๋˜๊ณ  ๐Ÿ“œ, ๋ฐ˜๋Œ€๋กœ ๊ธฐ์กด HWPX ๋ฌธ์„œ๋Š” AI๊ฐ€ ์‰ฝ๊ฒŒ ์ฝ์„ ์ˆ˜ ์žˆ๋Š” ๊ตฌ์กฐ๋กœ ๊บผ๋‚ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค โš’๏ธ.

  • ๐Ÿ“„ HWPX ์™„์ „ ๊ฐ€์ด๋“œ ๋‹ค์šด๋กœ๋“œ โ€” HwpForge API๋กœ ์ƒ์„ฑํ•œ 4์„น์…˜ ๋ฐ๋ชจ ๋ฌธ์„œ (ํ•œ๊ธ€์—์„œ ์—ด์–ด๋ณด์„ธ์š”)
  • HWPX Reader for AI โ€” ๊ธฐ์กด ํ•œ๊ธ€ ๋ฌธ์„œ(.hwpx)๋ฅผ Markdown์œผ๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ LLM์ด ์ฆ‰์‹œ ์ดํ•ด ๊ฐ€๋Šฅ
  • Full HWPX codec โ€” HWPX ํŒŒ์ผ์„ ์†์‹ค ์—†์ด ๋””์ฝ”๋”ฉ/์ธ์ฝ”๋”ฉ (lossless roundtrip)
  • Markdown bridge โ€” GFM Markdown๊ณผ HWPX ๊ฐ„ ์–‘๋ฐฉํ–ฅ ๋ณ€ํ™˜ (์ฝ๊ธฐ + ์“ฐ๊ธฐ)
  • YAML style template โ€” Figma Design Token์ฒ˜๋Ÿผ ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ์Šคํƒ€์ผ ์ •์˜ (ํฐํŠธ, ํฌ๊ธฐ, ์ƒ‰์ƒ)
  • Type-safe API โ€” branded index, typestate validation, zero unsafe code

๋น ๋ฅธ ์‹œ์ž‘

์„ค์น˜

# Cargo.toml์— ์ถ”๊ฐ€
cargo add hwpforge

# Markdown ์ง€์› ํฌํ•จ
cargo add hwpforge --features full

๋˜๋Š” Cargo.toml์— ์ง์ ‘ ์ถ”๊ฐ€:

[dependencies]
hwpforge = "0.5"

๐Ÿ”จ Hammer โ€” CLI๋กœ ์‹œ์ž‘ํ•˜๊ธฐ

CLI ๋„๊ตฌ hwpforge(Hammer)๋ฅผ ์„ค์น˜ํ•˜๋ฉด ํ„ฐ๋ฏธ๋„์—์„œ ๋ฐ”๋กœ ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

cargo install hwpforge-bindings-cli
# Markdown โ†’ HWPX ๋ณ€ํ™˜
hwpforge convert report.md -o report.hwpx

# HWPX ๊ตฌ์กฐ ํ™•์ธ
hwpforge inspect report.hwpx

# HWPX โ†’ Markdown ๋ณ€ํ™˜ (AI๊ฐ€ ํ•œ๊ธ€ ๋ฌธ์„œ ์ฝ๊ธฐ)
hwpforge to-md report.hwpx -o report.md

# HWPX โ†’ JSON ์ถ”์ถœ (AI ํŽธ์ง‘์šฉ)
hwpforge to-json report.hwpx --section 0 > section0.json

# JSON โ†’ HWPX ์ง์ ‘ ์ƒ์„ฑ
hwpforge from-json section0.json -o new.hwpx

# JSON์œผ๋กœ ์„น์…˜ ๊ต์ฒด
hwpforge patch report.hwpx --section 0 < modified.json -o updated.hwpx

# JSON Schema ์ถœ๋ ฅ (AI agent์šฉ)
hwpforge schema document

AI-first ์„ค๊ณ„: CLI๋Š” AI agent(Claude Code ๋“ฑ)๊ฐ€ ์ฃผ ์‚ฌ์šฉ์ž์ž…๋‹ˆ๋‹ค. Markdown์œผ๋กœ ๋ฌธ์„œ๋ฅผ ์ƒ์„ฑํ•œ ๋’ค, JSON round-trip์œผ๋กœ ๊ธฐ์กด ์Šคํƒ€์ผ์„ ๋ณด์กดํ•˜๋ฉด์„œ section ๋‹จ์œ„๋กœ ์ •๋ฐ€ํ•˜๊ฒŒ ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. --json ํ”Œ๋ž˜๊ทธ๋กœ ๋ชจ๋“  ๋ช…๋ น์–ด๊ฐ€ machine-readable ์ถœ๋ ฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

โš™๏ธ Anvil โ€” MCP Server (Beta)๋กœ AI๊ฐ€ ์ง์ ‘ ํ•œ๊ธ€ ๋ฌธ์„œ๋ฅผ ๋‹ค๋ฃจ๋‹ค

Claude Code, Codex CLI, Claude, ChatGPT, Cursor, Antigravity ๋“ฑ MCP ์ง€์› AI ๋„๊ตฌ์—์„œ ํ•œ๊ธ€ ๋ฌธ์„œ๋ฅผ ์ง์ ‘ ์ƒ์„ฑํ•˜๊ณ  ํŽธ์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ MCP surface๋Š” ๋ฒ ํƒ€์ด๋ฉฐ, HWP5 ๊ฒฝ๋กœ๋Š” MCP๊ฐ€ ์•„๋‹ˆ๋ผ CLI workflow๋ฅผ ์šฐ์„ ํ•ฉ๋‹ˆ๋‹ค. "๋ณด๊ณ ์„œ ๋งŒ๋“ค์–ด์ค˜"๋ผ๊ณ  ๋งํ•˜๋ฉด, AI๊ฐ€ ์•Œ์•„์„œ .hwpx ํŒŒ์ผ์„ ๋š๋”ฑ ๋งŒ๋“ค์–ด๋ƒ…๋‹ˆ๋‹ค.

AI ๋„๊ตฌ์— ๋“ฑ๋ก

ํ•œ ์ค„์ด๋ฉด ์„ค์น˜ + ๋“ฑ๋ก์ด ๋๋‚ฉ๋‹ˆ๋‹ค. npm์€ npx -y๊ฐ€ ์ž๋™์œผ๋กœ ๋ฐ”์ด๋„ˆ๋ฆฌ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•ฉ๋‹ˆ๋‹ค.

<details> <summary><strong>Claude Code</strong> (ํ„ฐ๋ฏธ๋„)</summary>
# npm (๊ถŒ์žฅ โ€” Rust ํˆด์ฒด์ธ ๋ถˆํ•„์š”)
claude mcp add hwpforge -- npx -y @hwpforge/mcp

# Cargo (Rust ๊ฐœ๋ฐœ์ž์šฉ)
cargo install hwpforge-bindings-mcp && claude mcp add hwpforge hwpforge-mcp

# ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ (๊ธ€๋กœ๋ฒŒ)
claude mcp add --global hwpforge -- npx -y @hwpforge/mcp
</details> <details> <summary><strong>Codex CLI</strong> (ํ„ฐ๋ฏธ๋„)</summary>

~/.codex/config.toml์— ์ถ”๊ฐ€:

[mcp_servers.hwpforge]
command = "npx"
args = ["-y", "@hwpforge/mcp"]

๋˜๋Š” CLI๋กœ:

codex mcp add hwpforge -- npx -y @hwpforge/mcp
</details> <details> <summary><strong>Claude Desktop</strong> (์•ฑ)</summary>

์„ค์ • ํŒŒ์ผ์„ ํŽธ์ง‘ํ•ฉ๋‹ˆ๋‹ค:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
</details> <details> <summary><strong>ChatGPT Desktop</strong> (์•ฑ)</summary>

Settings โ†’ Tools โ†’ Add MCP Server์—์„œ:

  • Name: hwpforge
  • Command: npx -y @hwpforge/mcp

๋˜๋Š” ์„ค์ • ํŒŒ์ผ์„ ์ง์ ‘ ํŽธ์ง‘:

{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
</details> <details> <summary><strong>Cursor</strong> (์—๋””ํ„ฐ)</summary>

ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ์— .cursor/mcp.json ์ƒ์„ฑ:

{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
</details> <details> <summary><strong>Antigravity</strong> (์—๋””ํ„ฐ)</summary>

... ๋“œ๋กญ๋‹ค์šด โ†’ MCP Store โ†’ Manage MCP Servers โ†’ View raw config (mcp_config.json)์— ์ถ”๊ฐ€:

{
  "mcpServers": {
    "hwpforge": {
      "command": "npx",
      "args": ["-y", "@hwpforge/mcp"]
    }
  }
}
</details>

๋“ฑ๋กํ•˜๋ฉด 9๊ฐœ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค

| ๋„๊ตฌ | ํ•˜๋Š” ์ผ | ํ•œ๋งˆ๋”” | | -------------------- | ----------------------- | ------------------------------------ | | hwpforge_convert | Markdown โ†’ HWPX ๋ณ€ํ™˜ | "์ด ๋งˆํฌ๋‹ค์šด์„ ํ•œ๊ธ€ ํŒŒ์ผ๋กœ!" | | hwpforge_inspect | HWPX ๊ตฌ์กฐ ํ™•์ธ | "์ด ๋ฌธ์„œ ๋ญ๊ฐ€ ๋“ค์–ด์žˆ์–ด?" | | hwpforge_to_json | HWPX โ†’ JSON ์ถ”์ถœ | "์ด ์„น์…˜ ๋‚ด์šฉ ์ข€ ๊บผ๋‚ด๋ด" | | hwpforge_patch | JSON์œผ๋กœ ์„น์…˜ ๊ต์ฒด | "์ด ๋ถ€๋ถ„๋งŒ ๋ฐ”๊ฟ”์„œ ๋‹ค์‹œ ์ €์žฅํ•ด" | | hwpforge_templates | ์Šคํƒ€์ผ ํ”„๋ฆฌ์…‹ ์กฐํšŒ | "์–ด๋–ค ํ…œํ”Œ๋ฆฟ ์“ธ ์ˆ˜ ์žˆ์–ด?" | | hwpforge_validate | HWPX ๊ตฌ์กฐ/๋ฌด๊ฒฐ์„ฑ ๊ฒ€์ฆ | "์ด ํŒŒ์ผ ๋ฌธ์ œ ์—†๋Š”์ง€ ํ™•์ธํ•ด" | | hwpforge_restyle | ์Šคํƒ€์ผ ํ”„๋ฆฌ์…‹ ์ผ๊ด„ ์ ์šฉ | "์ด ๋ฌธ์„œ ํฐํŠธ ๋ฐ”๊ฟ”์ค˜" | | hwpforge_from_json | JSON โ†’ HWPX ์ง์ ‘ ์ƒ์„ฑ | "์ด JSON์œผ๋กœ ํ•œ๊ธ€ ํŒŒ์ผ ๋งŒ๋“ค์–ด" | | hwpforge_to_md | HWPX โ†’ Markdown ๋ณ€ํ™˜ | "์ด ํ•œ๊ธ€ ๋ฌธ์„œ๋ฅผ Markdown์œผ๋กœ ๊บผ๋‚ด์ค˜" |

์—…๋ฐ์ดํŠธ / ์‚ญ์ œ

npm์€ npx -y๊ฐ€ ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์„ ๊ฐ€์ ธ์˜ค๋ฏ€๋กœ ๋ณ„๋„ ์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค.

# Cargo ์‚ฌ์šฉ์ž๋งŒ ํ•ด๋‹น
cargo install hwpforge-bindings-mcp --force   # ์—…๋ฐ์ดํŠธ
cargo uninstall hwpforge-bindings-mcp          # ์‚ญ์ œ

์™œ MCP? CLI(Hammer)๋Š” AI๊ฐ€ bash ๋ช…๋ น์„ ์‹คํ–‰ํ•ด์•ผ ํ•˜์ง€๋งŒ, MCP(Anvil)๋Š” AI๊ฐ€ ๋„ค์ดํ‹ฐ๋ธŒ ๋„๊ตฌ๋กœ ์ง์ ‘ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ฒฝ๋กœ ํŒŒ์‹ฑ๋„, stdout ํ•ด์„๋„ ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. JSON-RPC๋กœ ์š”์ฒญํ•˜๋ฉด ๊ตฌ์กฐํ™”๋œ JSON์œผ๋กœ ์‘๋‹ต โ€” ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”จ ๋ฌธ์„œ ์ƒ์„ฑ

use hwpforge::core::{Document, Draft, Paragraph, Run, Section, PageSettings};
use hwpforge::foundation::{CharShapeIndex, ParaShapeIndex};

let mut doc = Document::<Draft>::new();
doc.add_section(Section::with_paragraphs(
    vec![Paragraph::with_runs(
        vec![Run::text("Hello, ํ•œ๊ธ€!", CharShapeIndex::new(0))],
        ParaShapeIndex::new(0),
    )],
    PageSettings::a4(),
));

โš’๏ธ HWPX๋กœ ์ธ์ฝ”๋”ฉ

use hwpforge::hwpx::{HwpxEncoder, HwpxStyleStore};
use hwpforge::core::ImageStore;

let validated = doc.validate().unwrap();
let style_store = HwpxStyleStore::with_default_fonts("ํ•จ์ดˆ๋กฌ๋ฐ”ํƒ•");
let image_store = ImageStore::new();
let bytes = HwpxEncoder::encode(&validated, &style_store, &image_store).unwrap();
std::fs::write("output.hwpx", &bytes).unwrap();

โš’๏ธ HWPX ๋””์ฝ”๋”ฉ

use hwpforge::hwpx::HwpxDecoder;

let result = HwpxDecoder::decode_file("input.hwpx").unwrap();
println!("์„น์…˜ ์ˆ˜: {}", result.document.sections().len());

โš’๏ธ HWPX โ†’ Markdown ๋ณ€ํ™˜ (AI๊ฐ€ ํ•œ๊ธ€ ๋ฌธ์„œ ์ฝ๊ธฐ)

<div align="center"> <table> <tr> <td align="center"><strong>๐Ÿ“„ ํ•œ๊ธ€ ์›๋ณธ (.hwpx)</strong></td> <td align="center"><strong>๐Ÿ“ Markdown ๋ณ€ํ™˜ ๊ฒฐ๊ณผ</strong></td> </tr> <tr> <td><img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/hwpx-original.png" width="400" alt="ํ•œ๊ธ€ ์›๋ณธ ๋ฌธ์„œ"></td> <td><img src="https://raw.githubusercontent.com/ai-screams/HwpForge/main/assets/hwpx-to-md-result.png" width="400" alt="Markdown ๋ณ€ํ™˜ ๊ฒฐ๊ณผ"></td> </tr> </table> </div>
use hwpforge::hwpx::HwpxDecoder;
use hwpforge::md::MdEncoder;

let decoded = HwpxDecoder::decode_file("government_report.hwpx").unwrap();
let validated = decoded.document.validate().unwrap();
let markdown = 
View on GitHub
GitHub Stars5
CategoryDevelopment
Updated3d ago
Forks0

Languages

Rust

Security Score

90/100

Audited on Mar 29, 2026

No findings