{
  "markdown": "# che-word-mcp\n\nA Swift-native MCP (Model Context Protocol) server for Microsoft Word document (.docx) manipulation. This is the **first Swift OOXML library** that directly manipulates Office Open XML without any third-party Word dependencies.\n\n[中文說明](README_zh-TW.md)\n\n## Features\n\n- **Pure Swift Implementation**: No Node.js, Python, or external runtime required\n- **Direct OOXML Manipulation**: Works directly with XML, no Microsoft Word installation needed\n- **Single Binary**: Just one executable file\n- **234 MCP Tools**: Comprehensive document manipulation across documents, tables, hyperlinks, headers, sections, styles, numbering, content controls, comments, footnotes, equations, fields, and Track Changes\n- **Office.js OOXML Roadmap P0 = 100%**: All eight P0 sub-issues closed (umbrella [#43](https://github.com/PsychQuant/che-word-mcp/issues/43)). Surface coverage is now competitive with Office.js for the read/write side of every P0 capability.\n- **Round-trip silent corruption closed (v3.13.5, [#56](https://github.com/PsychQuant/che-word-mcp/issues/56))**: 5 sub-stack-completion rounds (R5 / R5-CONT / R5-CONT-2 / R5-CONT-3 / R5-CONT-4) closed 30 findings (16 P0 + 21 P1) across rounds 4-8 of 6-AI cross-verification. Bumps `ooxml-swift` to v0.19.5 (v0.19.4 held back per verify-gate). **No MCP source changes** — fix architecture lives entirely in `ooxml-swift`. Round 4 walker symmetry across headers/footers/footnotes/endnotes (`accept_revision` / `reject_revision` / `get_hyperlinks` / `replace_text` reach all parts). Round 5 per-container relationships round-trip (`update_hyperlink` URL sync targets owning part rels). Round 6 `delete_hyperlink` mirror + container `<w:tbl>` capture preserved. Round 7 `reject_revision` typed clearMarker (file/API state convergence). Round 8 `accept_revision` typed clearMarker (mirror) + matrix-pin asymmetry-guard removal + `Document.repairContainerFileNames` marks `document.xml.rels` + `[Content_Types].xml` dirty. Convergence: Devil's Advocate wrote 5 adversarial tests targeting the convergence-cycle pattern; all PASSED. See [closing summary](https://github.com/PsychQuant/che-word-mcp/issues/56#issuecomment-4322638865) and [v3.13.5 release notes](https://github.com/PsychQuant/che-word-mcp/releases/tag/v3.13.5).\n- **Programmatic Track Changes (v3.12.0+, [#45](https://github.com/PsychQuant/che-word-mcp/issues/45))**: Generate Word-native reviewable redlines via `insert_text_as_revision` / `delete_text_as_revision` / `move_text_as_revision`, plus `as_revision: true` flag on `format_text` / `set_paragraph_format`. Emits `<w:ins>` / `<w:del>` / `<w:moveFrom>` / `<w:moveTo>` / `<w:rPrChange>` / `<w:pPrChange>` markup. Side-effect contract: `as_revision: true` requires track changes enabled; throws `track_changes_not_enabled` otherwise (no silent auto-enable). Author resolution: explicit arg → `revisions.settings.author` → `\"Unknown\"`.\n- **Tables / Hyperlinks / Headers extensions (v3.11.0+, [#49](https://github.com/PsychQuant/che-word-mcp/issues/49) [#50](https://github.com/PsychQuant/che-word-mcp/issues/50) [#51](https://github.com/PsychQuant/che-word-mcp/issues/51))**: 16 new tools — table conditional styles (10 region types) / nested tables (max 5 deep) / explicit layout / table indent; three typed hyperlinks (URL / bookmark / email); even/odd header toggle / link-to-previous / `get_section_header_map`.\n- **Styles + Numbering + Sections foundation (v3.10.0+, [#46](https://github.com/PsychQuant/che-word-mcp/issues/46) [#47](https://github.com/PsychQuant/che-word-mcp/issues/47) [#48](https://github.com/PsychQuant/che-word-mcp/issues/48))**: 19 new tools + 6 extended args — `get_style_inheritance_chain`, `link_styles`, `set_latent_styles`, `add_style_name_alias`, full Numbering CRUD lifecycle (definitions / overrides / list continuity / GC), section vertical alignment / page-number format / break-type / title-page distinction / per-section header references.\n- **Content Controls (SDT) read/write (v3.9.0+, [#44](https://github.com/PsychQuant/che-word-mcp/issues/44))**: 7 new tools covering 12-type discrimination (richText / plainText / picture / date / dropDownList / comboBox / checkBox / bibliography / citation / group / repeatingSection / repeatingSectionItem). Nested SDT trees, deterministic max+1 SDT id allocator, `keep_content` unwrap on delete, whitelist-validated XML replacement.\n- **Save Durability Stack (v3.5.3+)**: atomic-rename save ([#36](https://github.com/PsychQuant/che-word-mcp/issues/36)), actor-based concurrency safety ([#39](https://github.com/PsychQuant/che-word-mcp/issues/39)), `keep_bak` opt-in rollback ([#38](https://github.com/PsychQuant/che-word-mcp/issues/38)), `autosave_every` Design B pre-mutation snapshot with explicit `recover_from_autosave` ([#37](https://github.com/PsychQuant/che-word-mcp/issues/37), [#40](https://github.com/PsychQuant/che-word-mcp/issues/40) v3.7.0). Default `autosave_every: 1` (every mutation snapshots prior state). Pass `autosave_every: 0` to opt out.\n- **Dual-Mode Access**: Direct Mode (read-only, one step via `source_path`) and Session Mode (full lifecycle via `doc_id`)\n- **True Byte-preservation Round-trip Fidelity (v3.5.0+)**: `save_document` overlay mode uses `WordDocument.modifiedParts` dirty tracking — untouched typed parts (`document.xml`, `styles.xml`, `fontTable.xml`, `header*.xml`, `footer*.xml`, `comments.xml`, `footnotes.xml`, `endnotes.xml`) and unknown parts (`theme/`, `webSettings.xml`, `people.xml`, `commentsExtended/Extensible/Ids`, `glossary/`, `customXml/`) byte-for-byte preserved. NTPU thesis no-op `save_document` round-trip retains 13 fontTable entries + 6 distinct headers + 4 footers + three-segment PAGE field + `<w15:presenceInfo>` identity.\n- **Theme + Header/Footer/Watermark CRUD (v3.3.0+)**: `word/theme/theme1.xml` editing, header/footer enumeration + deletion, watermark VML detection. NTPU thesis Chinese font fix path: `update_theme_fonts({ minor: { ea: \"DFKai-SB\" } })`.\n- **Comment Threads + People + Notes Update + Web Settings (v3.4.0+)**: 13 tools for collaborative comment metadata, `people.xml` author records (dual identity: GUID + legacy author), in-place endnote/footnote editing (preserves IDs), `webSettings.xml` configuration.\n- **Full LaTeX Subset for `insert_equation` (v3.2.0+)**: Delegated to [`latex-math-swift`](https://github.com/PsychQuant/latex-math-swift). Supports `\\frac`, `\\sqrt`, `\\hat`/`\\bar`/`\\tilde` accents, `\\left/\\right` delimiters, `\\sum`/`\\int`/`\\prod` n-ary with bounds, function names, limits, `\\text{}`, all Greek letters (including `\\varepsilon` variants), and common operators.\n- **Text-Anchor Insertion**: Insert captions / images relative to matched text (`after_text` / `before_text`), no pre-search call required\n- **Batch Operations**: `replace_text_batch` / `search_text_batch` collapse N round-trips into one\n- **Session State API**: SHA256 + mtime-based disk drift detection, `revert_to_disk` / `reload_from_disk` / `check_disk_drift`\n- **Structural Readback**: `list_captions` / `list_equations` / `update_all_fields` (F9-equivalent) for manuscript review workflows\n- **Cross-platform**: Works on macOS (universal binary `x86_64 + arm64` since v3.5.1)\n\n## Version History\n\n| Version | Date | Changes |\n|---------|------|---------|\n| **v4.0.0** | 2026-08-19 | **`execute_script` 契約修正（breaking）** — 驗證失敗改為 tool error（[#180](https://github.com/PsychQuant/che-word-mcp/issues/180)）；新增 `overwrite` 參數且**預設拒絕**覆寫既有 `output_path`（[#181](https://github.com/PsychQuant/che-word-mcp/issues/181)）。覆寫閘移進 ooxml-swift 的共用入口 `scriptPipelineExecute`，兩面由結構取得保護；重建結果改為寫同目錄暫存路徑、驗過才搬進位，所以驗證失敗不再破壞輸出路徑。需 ooxml-swift 3.0.1。5-lens verify（Codex leg 因配額未執行，已記錄）。 |\n| **v3.22.0** | 2026-07-18 | **Self-produced docx upgrades to typed DSL** (closes-via-idd [#173](https://github.com/PsychQuant/che-word-mcp/issues/173), PR [#174](https://github.com/PsychQuant/che-word-mcp/pull/174)). Bumps ooxml-swift 1.4.0 → 1.5.0 (upstream [ooxml-swift#85](https://github.com/PsychQuant/ooxml-swift/issues/85): transcoder-canonical authoring — stamped `w14:paraId`, no inter-element whitespace, full Word-canonical root cloud). `export_script` on MCP-authored pure-paragraph docs now reports `document.xml` on the `dsl` channel (ratio 1.0); `slots` anchor on stamped paraIds. Part-level boundary documented in tool descriptions: rich tables / legacy paraId-less content demote the whole part to raw pending [ooxml-swift#86](https://github.com/PsychQuant/ooxml-swift/issues/86). Consumer regression `Issue173SelfProducedDSLUpgradeTests` (RED on 1.4.0 / GREEN on 1.5.0). 6-AI verify PASS. |\n| **v3.13.5** | 2026-04-27 | **R5 stack-completion** (closes [#56](https://github.com/PsychQuant/che-word-mcp/issues/56) silent corruption). Bumps ooxml-swift v0.19.3 → v0.19.5 (v0.19.4 held back per verify-gate). 30 findings closed (16 P0 + 21 P1) across 5 sub-stacks (R5 / R5-CONT / R5-CONT-2 / R5-CONT-3 / R5-CONT-4) and rounds 4-8 of 6-AI cross-verification. **Round 4** walker symmetry across headers/footers/footnotes/endnotes (`accept_revision` / `reject_revision` / `get_hyperlinks` / `replace_text` reach all parts). **Round 5** per-container relationships round-trip (`update_hyperlink` URL sync targets owning part rels). **Round 6** `delete_hyperlink` mirror + container `<w:tbl>` capture preserved. **Round 7** `reject_revision` typed clearMarker (file/API state convergence). **Round 8** `accept_revision` typed clearMarker (mirror) + matrix-pin asymmetry-guard removal + `repairContainerFileNames` rels-dirty. Convergence: Devil's Advocate wrote 5 adversarial tests targeting the convergence-cycle pattern; all PASSED. **No che-word-mcp source changes** — entire fix architecture in ooxml-swift. See [closing summary](https://github.com/PsychQuant/che-word-mcp/issues/56#issuecomment-4322638865). |\n| v3.13.4 | 2026-04-26 | **(skipped — held back per verify-gate)**. R3 stack content rolled into v3.13.5. |\n| v3.13.3 | 2026-04-26 | Bumps ooxml-swift v0.19.2 → v0.19.3. Closes 8 P0 + 3 must-fix P1 from #56 round-2 verify (Hyperlink API path visual-style restoration / tgtFrame / docLocation Reader filter / ordered children source-order preservation; sort-path contentControls + commentIds / footnoteIds / endnoteIds / hasPageBreak emission; non-text wrapper preservation; nested hyperlink/SDT/fieldSimple round-trip; nextBookmarkId calibration; bookmark wrap-around restoration). No source changes. |\n| v3.13.2 | 2026-04-26 | Bumps ooxml-swift v0.19.1 → v0.19.2. Closes 4 blocking findings from #56 round-1 verify (F1 `Hyperlink.toXML()` emits Reader-collected runs/rawAttributes/rawChildren; F2 `add_bookmark`/`delete_bookmark` sync `bookmarkMarkers`; F3 ins/del/moveFrom/moveTo round-trip preserves position+revisionId+wrapper; F4 namespace preservation extends from `document.xml` to header/footer/footnote/endnote). No source changes. |\n| v3.13.1 | 2026-04-25 | `pPr` double-emission silent regression on sort-by-position round-trip — hot-fix (ooxml-swift v0.19.1). |\n| v3.13.0 | 2026-04-25 | **`document.xml` lossless round-trip + tool-mediated wrapper edits** (closes [#56](https://github.com/PsychQuant/che-word-mcp/issues/56) P0). Hybrid model preserves namespace map (34 xmlns), bookmarks, structural wrappers (`<w:hyperlink>` / `<w:fldSimple>` / `<mc:AlternateContent>`). |\n| v3.12.0 | 2026-04-25 | **Programmatic Track Changes generation** (closes [#45](https://github.com/PsychQuant/che-word-mcp/issues/45)) — 3 new tools (`insert_text_as_revision` / `delete_text_as_revision` / `move_text_as_revision`) + `as_revision` flag on `format_text` / `set_paragraph_format`. Emits `<w:ins>` / `<w:del>` / `<w:moveFrom>` / `<w:moveTo>` / `<w:rPrChange>` / `<w:pPrChange>` markup. |\n| v3.11.0 | 2026-04-25 | **Tables / Hyperlinks / Headers extensions** (closes [#49](https://github.com/PsychQuant/che-word-mcp/issues/49) [#50](https://github.com/PsychQuant/che-word-mcp/issues/50) [#51](https://github.com/PsychQuant/che-word-mcp/issues/51)) — 16 new tools: table conditional styles (10 region types) / nested tables (max 5 deep) / explicit layout / table indent; three typed hyperlinks (URL / bookmark / email); even/odd header toggle / link-to-previous / `get_section_header_map`. |\n| v3.10.0 | 2026-04-24 | **Styles + Numbering + Sections foundation** (closes [#46](https://github.com/PsychQuant/che-word-mcp/issues/46) [#47](https://github.com/PsychQuant/che-word-mcp/issues/47) [#48](https://github.com/PsychQuant/che-word-mcp/issues/48)) — 19 new tools + 6 extended args. `get_style_inheritance_chain`, `link_styles`, `set_latent_styles`, `add_style_name_alias`; full Numbering CRUD lifecycle; section vertical alignment / page-number format / break-type / title-page distinct / per-section header refs. |\n| v3.9.0 | 2026-04-24 | **Content Controls (SDT) read/write** (closes [#44](https://github.com/PsychQuant/che-word-mcp/issues/44)) — 7 new tools, 12-type discrimination (richText / plainText / picture / date / dropDownList / comboBox / checkBox / bibliography / citation / group / repeatingSection / repeatingSectionItem). Nested SDT trees, deterministic id allocator, `keep_content` unwrap, whitelist-validated XML replacement. |\n| v3.8.0 | 2026-04-24 | **Header/footer raw-element preservation + counter-isolation flag** (closes [#52](https://github.com/PsychQuant/che-word-mcp/issues/52)). |\n| v3.7.2 | 2026-04-24 | 3-issue bundle from #42 verification (closes [#53](https://github.com/PsychQuant/che-word-mcp/issues/53), [#54](https://github.com/PsychQuant/che-word-mcp/issues/54), [#55](https://github.com/PsychQuant/che-word-mcp/issues/55) path traversal hardening). |\n| v3.7.1 | 2026-04-24 | `update_all_fields` no longer strips headers/footers (closes [#42](https://github.com/PsychQuant/che-word-mcp/issues/42)). |\n| v3.7.0 | 2026-04-24 | **Insert crash hardening + autosave Design B** (closes [#40](https://github.com/PsychQuant/che-word-mcp/issues/40), [#41](https://github.com/PsychQuant/che-word-mcp/issues/41)). v3.6.0 shipped autosave_every Design A (post-mutation counter) which couldn't preserve K-1 mutations on crash at K when K%N≠0. v3.7.0 switches to **Design B** (snapshot fires at the START of every mutating handler before the mutation runs); default `autosave_every` flipped from `0` to `1` (every mutation snapshots prior state). Pass `autosave_every: 0` to opt out. **BREAKING (effective)**: callers who relied on Design A semantics or default disabled. Also adds Phase A `CHE_WORD_MCP_LOG_LEVEL=debug` structured logging gate for #41 investigation. Built on ooxml-swift 0.13.3 which kills `DocxReader.concurrentPerform` (parsing determinism prerequisite for `recover_from_autosave`) and refactors `nextImageRelationshipId` to use the rId allocator. **Migration from v3.6.0**: code passing `autosave_every: 0` explicitly is unaffected; code that omitted the arg now gets `1` (full safety) — to restore v3.6.0 disabled-by-default behavior, add `autosave_every: 0` to `open_document` calls. |\n| v3.6.0 | 2026-04-23 | **Autosave + checkpoint + recover_from_autosave** (closes [#37](https://github.com/PsychQuant/che-word-mcp/issues/37)). `open_document` gains `autosave_every: Int = 0` parameter — when N > 0, every Nth mutation triggers a checkpoint write to `<source>.autosave.docx` (separate file, NOT eager-save to source). New tools: `checkpoint(doc_id, path?)` for manual snapshot, `recover_from_autosave(doc_id, discard_changes?)` to replace in-memory state with autosave bytes. `get_session_state` adds `autosave_detected` + `autosave_path` fields. Successful `save_document` / `finalize_document` cleans up `<source>.autosave.docx`. Phase 4 of save-durability-stack SDD. |\n| v3.5.5 | 2026-04-23 | **`keep_bak` opt-in for rollback escape hatch** (closes [#38](https://github.com/PsychQuant/che-word-mcp/issues/38)). `save_document` gains optional `keep_bak: Bool = false`; when `true` and target exists, server renames target → `<path>.bak` BEFORE atomic-rename save (single slot, overwrites prior `.bak`). User can `mv <path>.bak <path>` to roll back if a future save ships silent OOXML damage. `.bak` lives at server layer NOT ooxml-swift — `macdoc` CLI users don't get unwanted `.bak` files. Phase 3 of save-durability-stack SDD. |\n| v3.5.4 | 2026-04-23 | **`class WordMCPServer` → `actor WordMCPServer`** (closes [#39](https://github.com/PsychQuant/che-word-mcp/issues/39)). 8 mutable session state dictionaries become actor-isolated; compiler enforces every cross-actor access via `await`. Eliminates the Dictionary hash-table corruption race that pre-v3.5.4 12-parallel `insert_image_from_path` calls triggered. Phase 2 of save-durability-stack SDD. |\n| v3.5.3 | 2026-04-23 | **Atomic-rename save** (closes [#36](https://github.com/PsychQuant/che-word-mcp/issues/36)). Bumps to ooxml-swift 0.13.2 which refactors `DocxWriter.write` to write `<url>.tmp.<UUID>` + `fsync` + `replaceItemAt`. Any throw or process kill mid-write leaves the original byte-preserved (POSIX `rename(2)` is kernel-atomic; cross-volume falls back to copy+delete). 397/397 ooxml-swift tests pass; concurrent-observer regression test added. Phase 1 of save-durability-stack SDD. |\n| v3.5.2 | 2026-04-23 | **Rels overlay merge** (closes [#35](https://github.com/PsychQuant/che-word-mcp/issues/35)) — Reader-loaded NTPU thesis no-op `save_document` round-trip now preserves theme / webSettings / people / customXml / commentsExtended / commentsIds rels. v3.5.0/v3.5.1 fixed the parts layer; v3.5.2 fixes the rels layer. No che-word-mcp source change — fix entirely in ooxml-swift v0.13.1 (`RelationshipsOverlay` + relationship-driven `extractImages`). |\n| v3.5.1 | 2026-04-23 | **Universal binary** (`x86_64 + arm64`) — restores Intel Mac compatibility. v3.5.0 was arm64-only because release-build skipped the documented `lipo -create` step. No source changes — drop-in replacement. |\n| v3.5.0 | 2026-04-23 | **True byte-preservation via dirty tracking** (closes [#23 round-2](https://github.com/PsychQuant/che-word-mcp/issues/23) + [#32](https://github.com/PsychQuant/che-word-mcp/issues/32) [#33](https://github.com/PsychQuant/che-word-mcp/issues/33) [#34](https://github.com/PsychQuant/che-word-mcp/issues/34)). Reader-loaded NTPU theses survive no-op `save_document` round-trip with all 13 fontTable + 6 distinct headers + 4 footers + three-segment PAGE field + `<w15:presenceInfo>` identity preserved. Built on ooxml-swift 0.13.0 (`modifiedParts: Set<String>` + `Header.originalFileName` + overlay-mode skip-when-not-dirty). `list_people` returns dual identity: `person_id` (GUID, stable across rename) + `display_name_id` (= author legacy). |\n| v3.4.0 | 2026-04-23 | **Phase 2B + 2C combined** (closes #24 #25 #29 #30 #31): comment threads (`list_comment_threads` / `get_comment_thread` / `sync_extended_comments`), people (`list_people` / `add_person` / `update_person` / `delete_person`), notes update (`get_endnote` / `update_endnote` / `get_footnote` / `update_footnote` — preserves note IDs), web settings (`get_web_settings` / `update_web_settings`). 13 new MCP tools. |\n| v3.3.0 | 2026-04-23 | **Phase 2A** (closes #26 #27 #28): theme tools (`get_theme` / `update_theme_fonts` / `update_theme_color` / `set_theme`), headers (`list_headers` / `get_header` / `delete_header`), watermarks (`list_watermarks` / `get_watermark`), footers (`list_footers` / `get_footer` / `delete_footer`). 12 new MCP tools. Bumped to ooxml-swift 0.12.x for preserve-by-default round-trip. |\n| v3.2.0 | 2026-04-23 | **`insert_equation` LaTeX parser delegated to `latex-math-swift`** (closes #22). Full LaTeX subset: `\\frac`, `\\sqrt`, `\\hat`/`\\bar`/`\\tilde`, `\\left`/`\\right`, `\\sum`/`\\int`/`\\prod` with bounds, `\\ln`/`\\sin`/`\\cos`/`\\tan`/`\\log`/`\\exp`/`\\max`/`\\min`/`\\det`, `\\sup`/`\\inf`/`\\lim`, `\\text{}`, all Greek letters (incl. `\\varepsilon` variants), common operators. 18 econometrics fixture equations now all parse. Adds `MathAccent` via ooxml-swift 0.11.0. |\n| v3.1.0 | 2026-04-22 | 9 readback tools: Caption CRUD (`list_captions` / `get_caption` / `update_caption` / `delete_caption`), `update_all_fields` (F9-equivalent SEQ recount), Equation CRUD (`list_equations` / `get_equation` / `update_equation` / `delete_equation`). Built on new ooxml-swift 0.10.0 `FieldParser` + `OMMLParser`. |\n| v3.0.0 | 2026-04-22 | **BREAKING**: session state API. New tools `get_session_state` / `revert_to_disk` / `reload_from_disk` / `check_disk_drift`. `open_document` track_changes default flipped from true to false. `close_document` dirty-check now returns `E_DIRTY_DOC` text response with recovery options (`save_document` / `discard_changes: true` / `finalize_document`). |\n| v2.3.0 | 2026-04-22 | Text-anchor compound tool — `insert_caption` / `insert_image_from_path` accept `after_text` / `before_text` / `text_instance`. Eliminates the `search_text + insert_*` two-call pattern (~50% RPC reduction for thesis caption workflows). |\n| v2.2.0 | 2026-04-22 | Batch API — `replace_text_batch` (sequential, single save at end, `dry_run`/`stop_on_first_failure` flags) + `search_text_batch` (aggregated multi-query response, Direct + Session Mode). |\n| v2.1.0 | 2026-04-22 | Expose v2.0.0 params via `inputSchema` — schemas for `insert_caption` / `insert_equation` / `insert_image_from_path` / `replace_text` now advertise new params (Chinese labels, `components`, `into_table_cell`, `scope`, `regex`). |\n| v2.0.0 | 2026-04-22 | **BREAKING**: `word-mcp-insertion-primitives` Spectra change. Real OOXML SEQ fields (was literal text), OMML `MathComponent` AST (was string substitution), auto-aspect image sizing + table-cell target, cross-run-safe `replace_text` with `scope` + regex backreferences. |\n| v1.19.0 | 2026-04-15 | Manuscript review markdown export: `export_revision_summary_markdown` / `compare_documents_markdown` / `export_comment_threads_markdown`. **BREAKING**: `get_revisions` + `compare_documents` `full_text` param replaced by `summarize` (inverted default). |\n| v1.18.0 | 2026-04-14 | Fix `get_revisions` hardcoded 30-char truncation (bug since v1.2.0); add `full_text` opt-in. |\n| v1.17.0 | 2026-03-11 | Session state management: dirty tracking, autosave, `finalize_document`, `get_document_session_state`, shutdown flush (contributed by [@ildunari](https://github.com/ildunari)) |\n| v1.16.0 | 2026-03-10 | Dual-Mode: 15 read-only tools now support `source_path` (Direct Mode); MCP server instructions added |\n| v1.15.2 | 2026-03-07 | Improve `list_all_formatted_text` tool description for better LLM parameter handling |\n| v1.15.1 | 2026-03-01 | Fix heading heuristic style fallback (resolve fontSize from style inheritance chain) |\n| v1.15.0 | 2026-03-01 | Practical Mode: EMF→PNG auto-conversion + heading heuristic for style-less documents |\n| v1.14.0 | 2026-03-01 | Embed `word-to-md-swift` library: no external macdoc binary needed, restore `doc_id` support |\n| v1.13.0 | 2026-03-01 | Upgrade ooxml-swift to v0.5.0: parallel multi-core parsing (~0.64s for large docs) |\n| v1.12.1 | 2026-03-01 | Upgrade ooxml-swift to v0.4.0: large document performance fix (>30s → ~2.3s) |\n| v1.12.0 | 2026-02-28 | `export_markdown` uses `source_path` only, removes `doc_id`, adds lock file check |\n| v1.11.1 | 2026-02-28 | Fix `export_markdown` stdout mode (pipe fsync issue) |\n| v1.11.0 | 2026-02-28 | `export_markdown` delegates to `macdoc` CLI; removed `word-to-md-swift` dependency |\n| v1.9.0 | 2026-02-28 | `export_markdown` upgraded to use `word-to-md-swift` for high-quality output (145 total) |\n| v1.8.0 | 2026-02-03 | Remove hard diff limit, add `max_results` & `heading_styles` params to `compare_documents` |\n| v1.7.0 | 2026-02-03 | Add `compare_documents` tool for server-side document diff (105 total) |\n| v1.2.1 | 2026-01-16 | Fix MCP SDK compatibility (actor→class, add capabilities) |\n| v1.2.0 | 2026-01-16 | Add 12 new tools (95 total): search, hyperlinks, bookmarks, footnotes, endnotes, revisions, properties |\n| v1.1.0 | 2026-01-16 | Fix MCPB manifest.json format for Claude Desktop |\n| v1.0.0 | 2026-01-16 | Initial release with 83 tools, refactored to use ooxml-swift |\n\n## Quick Start\n\n### For Claude Desktop\n\n#### Option A: MCPB One-Click Install (Recommended)\n\nDownload the latest `.mcpb` file from [Releases](https://github.com/PsychQuant/che-word-mcp/releases) and double-click to install.\n\n#### Option B: Manual Configuration\n\nEdit `~/Library/Application Support/Claude/claude_desktop_config.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"che-word-mcp\": {\n      \"command\": \"/usr/local/bin/CheWordMCP\"\n    }\n  }\n}\n```\n\n### For Claude Code (CLI)\n\n#### Option A: Install as Plugin (Recommended)\n\nThe plugin bundles a version-aware wrapper that **auto-downloads the binary** on first use (and re-downloads whenever the plugin itself is updated — no `swift build` needed).\n\nTwo steps — register the marketplace once, then install the plugin:\n\n```bash\n# 1. Register the marketplace (one-time)\nclaude plugin marketplace add PsychQuant/psychquant-claude-plugins\n\n# 2. Install the plugin\nclaude plugin install che-word-mcp@psychquant-claude-plugins\n```\n\n> **Inside Claude Code?** The slash-command equivalents `/plugin marketplace add PsychQuant/psychquant-claude-plugins` and `/plugin install che-word-mcp@psychquant-claude-plugins` work the same way.\n\n> **Note:** The plugin wraps the MCP binary with auto-download. If the binary is missing from `~/bin/CheWordMCP` (or the sidecar `~/bin/.CheWordMCP.version` is older than the plugin's pinned version), it will be downloaded from GitHub Releases on next invocation.\n\n#### Option B: Install as standalone MCP\n\nIf you only need the MCP server without plugin features (slash commands, skills, SessionStart hooks):\n\n```bash\n# Create ~/bin if needed\nmkdir -p ~/bin\n\n# Download the latest release\ncurl -L https://github.com/PsychQuant/che-word-mcp/releases/latest/download/CheWordMCP -o ~/bin/CheWordMCP\nchmod +x ~/bin/CheWordMCP\n\n# Register with Claude Code\n# --scope user    : available across all projects (stored in ~/.claude.json)\n# --transport stdio: local binary execution via stdin/stdout\n# --              : separator between claude options and the command\nclaude mcp add --scope user --transport stdio che-word-mcp -- ~/bin/CheWordMCP\n```\n\n> **💡 Tip:** Install the binary into a local directory like `~/bin/`. Avoid cloud-synced folders (Dropbox, iCloud, OneDrive) — their sync operations can break MCP connections.\n\n### Build from Source (Optional)\n\nUse this only if you want to track `main` or contribute patches.\n\n#### Prerequisites\n\n- macOS 13.0+ (Ventura or later)\n- Swift 5.9+\n\n```bash\ngit clone https://github.com/PsychQuant/che-word-mcp.git\ncd che-word-mcp\nswift build -c release\n\n# Install\ncp .build/release/CheWordMCP ~/bin/\n```\n\n## Two Modes of Operation\n\n### Direct Mode (`source_path`) — Read-only, no state\n\nPass a file path directly. No need to call `open_document` first. Best for quick inspection.\n\n```\n# Just pass source_path — one step\nlist_images: { \"source_path\": \"/path/to/file.docx\" }\nsearch_text: { \"source_path\": \"/path/to/file.docx\", \"query\": \"keyword\" }\nget_document_info: { \"source_path\": \"/path/to/file.docx\" }\n```\n\n**19 tools support Direct Mode:**\n\n| Category | Tools |\n|----------|-------|\n| Read content | `get_text`, `get_document_text`, `get_paragraphs`, `get_document_info`, `search_text` |\n| List elements | `list_images`, `list_styles`, `get_tables`, `list_comments`, `list_hyperlinks`, `list_bookmarks`, `list_footnotes`, `list_endnotes`, `get_revisions` |\n| Properties | `get_document_properties`, `get_section_properties`, `get_word_count_by_section`, `estimate_paragraph_for_page` |\n| Export | `export_markdown` |\n\n### Session Mode (`doc_id`) — Full read/write lifecycle\n\nCall `open_document` first, then use `doc_id` for all subsequent operations. Required for editing.\n\n```\nopen_document: { \"path\": \"/path/to/file.docx\", \"doc_id\": \"mydoc\" }\ninsert_paragraph: { \"doc_id\": \"mydoc\", \"text\": \"Hello World\" }\nsave_document: { \"doc_id\": \"mydoc\", \"path\": \"/path/to/output.docx\" }\nclose_document: { \"doc_id\": \"mydoc\" }\n```\n\n> **Dual-mode tools** accept both `source_path` and `doc_id`. If you already have a document open, use `doc_id` to avoid re-reading from disk.\n\n## Usage with AI Agents\n\n### Just ask the agent\n\n```\nUse che-word-mcp to read all images from ~/Documents/report.docx\n```\n\nThe agent will automatically use Direct Mode (no need to open/close).\n\n### AGENTS.md / CLAUDE.md\n\n```markdown\n## Word Document Manipulation\n\nUse `che-word-mcp` for reading and writing Microsoft Word (.docx) files.\n\n**Read-only** (Direct Mode — one step):\n- `get_document_text` / `get_paragraphs` — read content\n- `list_images` / `search_text` — inspect elements\n- `export_markdown` — convert to Markdown\n\n**Edit** (Session Mode — open→edit→save):\n1. `open_document` → get doc_id\n2. `insert_paragraph` / `replace_text` / `format_text` — modify\n3. `save_document` → write to disk\n4. `close_document` → release memory\n```\n\n### Claude Code Skill\n\n```bash\nmkdir -p .claude/skills/che-word-mcp\ncurl -o .claude/skills/che-word-mcp/SKILL.md \\\n  https://raw.githubusercontent.com/PsychQuant/che-word-mcp/main/skills/che-word-mcp/SKILL.md\n```\n\n## Available Tools (234 Total)\n\n### Paragraph Index Conventions\n\n`paragraph_index` / `index` are historical parameter names and do not always\ncount the same OOXML surface. **Different insert / mutate / readback tools\nuse different conventions** — there is no universal default to assume.\nThree coordinate systems coexist:\n`body.children` insertion index (used by some inserts), top-level paragraph\nordinal (used by most mutate operations and inline equation insertion),\nand `get_paragraphs` readback order (for inspection). See\n[docs/paragraph-index-conventions.md](docs/paragraph-index-conventions.md)\nfor the per-tool inventory before reusing an index across tools.\n\n### Document Management (6 tools)\n\n| Tool | Description |\n|------|-------------|\n| `create_document` | Create a new Word document |\n| `open_document` | Open an existing .docx file (track_changes default `false` since v3.0.0) |\n| `save_document` | Save document to .docx file |\n| `close_document` | Close an open document (pass `discard_changes: true` to drop dirty edits) |\n| `finalize_document` | Save and close in one guarded step |\n| `list_open_documents` | List all open documents |\n\n### Session State API (5 tools, v3.0.0+)\n\n| Tool | Description |\n|------|-------------|\n| `get_session_state` | Snapshot `{ source_path, disk_hash_hex, disk_mtime_iso8601, is_dirty, track_changes_enabled }` |\n| `get_document_session_state` | Legacy session snapshot (preserved for backward compat) |\n| `revert_to_disk` | Re-read source path, discard in-memory edits (destructive-by-design) |\n| `reload_from_disk` | Cooperative reload; requires `force: true` on dirty doc |\n| `check_disk_drift` | Informational — returns `{ drifted, disk_mtime, stored_mtime, disk_hash_matches }` |\n\n### Content Operations (9 tools)\n\n| Tool | Description |\n|------|-------------|\n| `get_text` | Get plain text content |\n| `get_paragraphs` | Get all paragraphs with formatting |\n| `estimate_paragraph_for_page` | **v3.18.0+** — estimate a Word UI page number to a `get_paragraphs` candidate range (heuristic JSON with confidence + warning) |\n| `insert_paragraph` | Insert a new paragraph |\n| `update_paragraph` | Update paragraph content |\n| `delete_paragraph` | Delete a paragraph |\n| `replace_text` | Cross-run-safe find & replace with `scope` (body\\|all) + `regex` + `$1..$N` backreferences |\n| `replace_text_batch` | **v2.2.0** — sequential N-replacement batch, single save at end, `dry_run` / `stop_on_first_failure` |\n| `search_text_batch` | **v2.2.0** — aggregated multi-query search, works in Direct + Session Mode |\n\n### Formatting (3 tools)\n\n| Tool | Description |\n|------|-------------|\n| `format_text` | Apply text formatting (bold, italic, color, font) |\n| `set_paragraph_format` | Set paragraph formatting (alignment, spacing) |\n| `apply_style` | Apply built-in or custom styles |\n\n### Tables (15 tools, **v3.11.0+ extensions** [#49](https://github.com/PsychQuant/che-word-mcp/issues/49))\n\nCore (6):\n| Tool | Description |\n|------|-------------|\n| `insert_table` | Insert a table with optional data |\n| `get_tables` | Get all tables information |\n| `update_cell` | Update cell content |\n| `delete_table` | Delete a table |\n| `merge_cells` | Merge cells horizontally or vertically |\n| `set_table_style` | Set table borders and shading |\n\nRow / column / cell (8):\n| Tool | Description |\n|------|-------------|\n| `add_row_to_table`, `delete_row_from_table` | Row management |\n| `add_column_to_table`, `delete_column_from_table` | Column management |\n| `set_cell_width`, `set_cell_vertical_alignment` | Cell sizing + alignment |\n| `set_row_height`, `set_table_alignment` | Row height + table alignment |\n\nAdvanced (5, **v3.11.0**):\n| Tool | Description |\n|------|-------------|\n| `set_table_conditional_style` | Apply firstRow / lastRow / bandedRows etc. (10 region types) via `<w:tblStylePr>` |\n| `insert_nested_table` | Insert table-in-cell, depth-limited to 5 (throws `nested_too_deep`) |\n| `set_table_layout` | Switch fixed / autofit |\n| `set_header_row` | Mark row as `<w:tblHeader/>` for repeat-on-page-break |\n| `set_table_indent` | Table-level left indent (`<w:tblInd>`) |\n\n### Style Management (8 tools + 6 extended args, **v3.10.0+** [#48](https://github.com/PsychQuant/che-word-mcp/issues/48))\n\nCore (4):\n| Tool | Description |\n|------|-------------|\n| `list_styles` | List all available styles (Direct Mode supported) |\n| `create_style` | Create custom style — extended with 6 v3.10 args: `based_on`, `linked_style_id`, `next_style_id`, `q_format`, `hidden`, `semi_hidden` |\n| `update_style` | Update style definition — same 6 extended args |\n| `delete_style` | Delete custom style |\n\nInheritance + linkage (4, **v3.10.0**):\n| Tool | Description |\n|------|-------------|\n| `get_style_inheritance_chain` | Traverse `basedOn` chain upward to root with cycle detection |\n| `link_styles` | Bidirectional `<w:link>` between paragraph and character style pair |\n| `set_latent_styles` | Control Quick Style Gallery defaults via `<w:latentStyles>` block |\n| `add_style_name_alias` | Localized `<w:name>` alias per BCP 47 lang code |\n\n### Numbering / Lists (12 tools, **v3.10.0+ definition lifecycle** [#46](https://github.com/PsychQuant/che-word-mcp/issues/46))\n\nInline list creation (4):\n| Tool | Description |\n|------|-------------|\n| `insert_bullet_list` | Insert bullet list |\n| `insert_numbered_list` | Insert numbered list |\n| `set_list_level` | Set list indentation level |\n| `set_outline_level` | Set paragraph outline level (TOC inclusion) |\n\nDefinition CRUD (8, **v3.10.0**):\n| Tool | Description |\n|------|-------------|\n| `list_numbering_definitions` | Enumerate every abstractNum + num pair |\n| `get_numbering_definition` | Fetch single num by id |\n| `create_numbering_definition` | New abstractNum + paired num (max 9 levels) |\n| `override_numbering_level` | `<w:lvlOverride>` for per-level start values |\n| `assign_numbering_to_paragraph` | `<w:numPr>` attachment by paragraph index |\n| `continue_list` | Resume numbering across paragraphs |\n| `start_new_list` | Reset numbering to start |\n| `gc_orphan_numbering` | Sweep unreferenced num definitions (abstractNums preserved) |\n\n### Sections / Page Setup (12 tools, **v3.10.0+ extensions** [#47](https://github.com/PsychQuant/che-word-mcp/issues/47))\n\nBasic page setup (5):\n| Tool | Description |\n|------|-------------|\n| `set_page_size` | Set page size (A4, Letter, etc.) |\n| `set_page_margins` | Set page margins |\n| `set_page_orientation` | Set portrait or landscape |\n| `insert_page_break` | Insert page break |\n| `insert_section_break` | Insert section break |\n\nSection properties (7, **v3.10.0**):\n| Tool | Description |\n|------|-------------|\n| `get_all_sections` | Return SectionInfo array per section in document order |\n| `set_section_break_type` | `nextPage` / `continuous` / `evenPage` / `oddPage` |\n| `set_section_vertical_alignment` | `<w:vAlign>` for cover pages |\n| `set_page_number_format` | `<w:pgNumType w:fmt>` for Roman numerals etc. |\n| `set_line_numbers_for_section` | `<w:lnNumType>` for legal documents |\n| `set_title_page_distinct` | Toggle `<w:titlePg/>` per section |\n| `set_section_header_footer_references` | Assign per-type rId (default/first/even) |\n\n### Headers & Footers (17 tools, **v3.11.0+ even/odd + section map** [#51](https://github.com/PsychQuant/che-word-mcp/issues/51))\n\nWrite tools (5):\n| Tool | Description |\n|------|-------------|\n| `add_header` | Add header content (uses `RelationshipIdAllocator` since v3.3.0+ — collision-free rIds in overlay mode) |\n| `update_header` | Update header content (preserves filename + rId; in-place tempDir overwrite) |\n| `add_footer` | Add footer content |\n| `update_footer` | Update footer content |\n| `insert_page_number` | Insert page number field |\n\nRead + delete tools (8, **v3.3.0+**, closes #26 #27):\n| Tool | Description |\n|------|-------------|\n| `list_headers` | Enumerate header parts with type (default/first/even) + section_id + has_watermark |\n| `get_header` | Read text + full XML + watermark structure |\n| `delete_header` | Remove typed model entry + tempDir file + Relationship + Content_Types Override |\n| `list_watermarks` | Scan all headers for VML `PowerPlusWaterMarkObject` shapes (text or image) |\n| `get_watermark` | Single-header watermark detail (returns `null` if no watermark) |\n| `list_footers` | Enumerate footer parts with type + section_id + has_page_number |\n| `get_footer` | Read text + XML + parsed field structure (PAGE / NUMPAGES / REF / STYLEREF) |\n| `delete_footer` | Symmetric with delete_header |\n\nEven/odd + section linkage (4, **v3.11.0**):\n| Tool | Description |\n|------|-------------|\n| `enable_even_odd_headers` | Toggle document-level `<w:evenAndOddHeaders/>` flag |\n| `link_section_header_to_previous` | Word-compat clone semantics |\n| `unlink_section_header_from_previous` | Symmetric unlink |\n| `get_section_header_map` | Return per-section header / footer file assignments |\n\n### Theme Editing (4 tools, **v3.3.0+**, closes #28)\n\n| Tool | Description |\n|------|-------------|\n| `get_theme` | Read major/minor font slots (latin/ea/cs) + color scheme (accent1-6, hyperlink, followedHyperlink) from `word/theme/theme1.xml` |\n| `update_theme_fonts` | Partial-update font slots — e.g. `{ minor: { ea: \"DFKai-SB\" } }` for NTPU thesis Chinese font fix |\n| `update_theme_color` | Slot-named hex color update with validation (rejects invalid slot + non-6-char-hex) |\n| `set_theme` | Low-level escape hatch — replace theme1.xml verbatim (validates `<a:theme>` root + well-formed XML) |\n\n### Images (7 tools)\n\n| Tool | Description |\n|------|-------------|\n| `insert_image` | Insert inline image (PNG, JPEG) |\n| `insert_image_from_path` | **v2.0.0+** — width/height optional (auto-aspect via `ImageDimensions.detect`), supports `into_table_cell` + `after_text` / `before_text` anchors |\n| `insert_floating_image` | Insert floating image with text wrap |\n| `update_image` | Update image properties |\n| `delete_image` | Delete image |\n| `list_images` | List all images |\n| `set_image_style` | Set image border and effects |\n\n### Captions (5 tools)\n\n| Tool | Description |\n|------|-------------|\n| `insert_caption` | **v2.0.0+** — real OOXML SEQ field (not literal text). Accepts English + Chinese labels (`Figure`/`Table`/`Equation`/`圖`/`表`/`公式`), 5-way anchor (`paragraph_index` / `after_image_id` / `after_table_index` / `after_text` / `before_text`), optional `STYLEREF` chapter number prefix |\n| `list_captions` | **v3.1.0** — enumerate caption paragraphs with label / sequence_number / caption_text / paragraph_index |\n| `get_caption` | **v3.1.0** — detailed single caption info including optional `chapter_number` from STYLEREF |\n| `update_caption` | **v3.1.0** — modify caption text or label without breaking the SEQ field structure |\n| `delete_caption` | **v3.1.0** — remove caption paragraph |\n\n### Equations (5 tools)\n\n| Tool | Description |\n|------|-------------|\n| `insert_equation` | **v2.0.0+** — emits structurally correct OMML via `MathComponent` AST (9 types). Primary: `components:` tree; fallback: `latex:` subset (`\\frac`, `\\sqrt`, `x^{y}`, Greek, ∑/∫/∏) |\n| `list_equations` | **v3.1.0** — enumerate `<m:oMath>` runs with display_mode flag |\n| `get_equation` | **v3.1.0** — detailed single equation info with component summary |\n| `update_equation` | **v3.1.0** — replace target equation's components tree |\n| `delete_equation` | **v3.1.0** — remove equation run or empty paragraph |\n\n### Export (5 tools)\n\n| Tool | Description |\n|------|-------------|\n| `export_text` | Export as plain text |\n| `export_markdown` | Export as Markdown (uses embedded `word-to-md-swift`) |\n| `export_revision_summary_markdown` | **v1.19.0** — per-document revision timeline for manuscript review |\n| `compare_documents_markdown` | **v1.19.0** — multi-document cumulative revision timeline |\n| `export_comment_threads_markdown` | **v1.19.0** — comment threading with author alias normalization |\n\n### Hyperlinks & Bookmarks (10 tools, **v3.11.0+ typed variants** [#50](https://github.com/PsychQuant/che-word-mcp/issues/50))\n\nGeneric + bookmarks (7):\n| Tool | Description |\n|------|-------------|\n| `insert_hyperlink` | Insert external hyperlink |\n| `insert_internal_link` | Insert link to bookmark |\n| `insert_cross_reference` | Insert cross-reference |\n| `update_hyperlink` | Update hyperlink |\n| `delete_hyperlink` | Delete hyperlink |\n| `insert_bookmark` | Insert bookmark |\n| `delete_bookmark` | Delete bookmark |\n\nTyped hyperlinks (3, **v3.11.0**, auto-create Hyperlink character style):\n| Tool | Description |\n|------|-------------|\n| `insert_url_hyperlink` | External URL with optional tooltip + history flag |\n| `insert_bookmark_hyperlink` | Internal anchor link (`w:anchor`, no rId) |\n| `insert_email_hyperlink` | `mailto:` with optional URL-encoded subject |\n\n### Comments & Revisions (13 tools)\n\nComment write + read (7):\n| Tool | Description |\n|------|-------------|\n| `insert_comment` | Insert comment |\n| `update_comment` | Update comment text |\n| `delete_comment` | Delete comment |\n| `list_comments` | List all comments |\n| `reply_to_comment` | Reply to existing comment |\n| `resolve_comment` | Mark comment as resolved |\n| `list_comment_threads` | **v3.4.0** — enumerate threads (root_comment_id + replies + resolved + durable_id) using typed `Comment.parentId` from `commentsExtended.xml` |\n\nComment thread tools (2, **v3.4.0+**, closes #29):\n| Tool | Description |\n|------|-------------|\n| `get_comment_thread` | Read root + walk children for full reply tree |\n| `sync_extended_comments` | Report typed comment count for triplet sync planning |\n\nRevision tracking — accept/reject side (7):\n| Tool | Description |\n|------|-------------|\n| `enable_track_changes` | Enable track changes (sets `revisions.settings.author` for default author resolution) |\n| `disable_track_changes` | Disable track changes |\n| `get_revisions` | Enumerate all revisions (Direct Mode supported) |\n| `accept_revision` | Accept revision by id |\n| `reject_revision` | Reject revision by id |\n| `accept_all_revisions` | Bulk accept |\n| `reject_all_revisions` | Bulk reject |\n\nRevision tracking — programmatic write side (3, **v3.12.0** [#45](https://github.com/PsychQuant/che-word-mcp/issues/45)):\n| Tool | Description |\n|------|-------------|\n| `insert_text_as_revision` | Insert text wrapped in `<w:ins>` revision markup. Splits straddling runs at `position` (preserves prior + post text + formatting). Args: `doc_id`, `paragraph_index`, `position`, `text`, optional `author`, `date`. |\n| `delete_text_as_revision` | Mark `[start, end)` runs with `<w:del>` and substitute `<w:t>` → `<w:delText>`. Single-paragraph only (cross-paragraph delete out of scope). |\n| `move_text_as_revision` | Emit paired `<w:moveFrom>` / `<w:moveTo>` with adjacent revision ids. Single-paragraph moves rejected (callers should use delete + insert). |\n\nPlus 2 extended args on existing tools (additive, default `false`):\n- `format_text` gains `as_revision: bool` — produces `<w:rPrChange>` revision instead of silent format mutation. Also accepts `run_index`, `author`, `date`.\n- `set_paragraph_format` gains `as_revision: bool` — produces `<w:pPrChange>` revision.\n\n**Side-effect contract**: `as_revision: true` requires `enable_track_changes` to have been called. Disabled track changes throws `track_changes_not_enabled` instead of silent auto-enable. **Author resolution chain**: explicit non-empty `author` arg → `revisions.settings.author` → literal `\"Unknown\"`.\n\n### People — Comment Authors (4 tools, **v3.4.0+**, closes #30)\n\n| Tool | Description |\n|------|-------------|\n| `list_people` | Parse `<w15:person>` entries from `word/people.xml` |\n| `add_person` | Add new entry; auto-create `people.xml` part when absent; duplicate-name `_2` suffix |\n| `update_person` | Update display_name (author attribute swap) |\n| `delete_person` | Remove entry; report `comments_orphaned` count |\n\n### Footnotes & Endnotes (10 tools)\n\nWrite + delete (4):\n| Tool | Description |\n|------|-------------|\n| `insert_footnote` | Insert footnote |\n| `delete_footnote` | Delete footnote |\n| `insert_endnote` | Insert endnote |\n| `delete_endnote` | Delete endnote |\n\nList + read + update (6, **v3.4.0+**, closes #24 #25):\n| Tool | Description |\n|------|-------------|\n| `list_footnotes` | Direct Mode supported |\n| `list_endnotes` | Direct Mode supported |\n| `get_footnote` | Read text + runs by integer ID |\n| `update_footnote` | In-place text replacement, preserves footnote_id (cross-references stay valid) |\n| `get_endnote` | Read text + runs by integer ID |\n| `update_endnote` | In-place text replacement, preserves endnote_id |\n\n### Web Settings (2 tools, **v3.4.0+**, closes #31)\n\n| Tool | Description |\n|------|-------------|\n| `get_web_settings` | Parse `word/webSettings.xml` flag elements (`relyOnVML`, `optimizeForBrowser`, `allowPNG`, `doNotSaveAsSingleFile`); returns `{ error: \"no webSettings part\" }` when absent |\n| `update_web_settings` | Partial update by key; auto-create part if absent |\n\n### Field Codes (7 tools)\n\n| Tool | Description |\n|------|-------------|\n| `insert_if_field` | Insert IF conditional field |\n| `insert_calculation_field` | Insert calculation (SUM, AVERAGE, etc.) |\n| `insert_date_field` | Insert date/time field |\n| `insert_page_field` | Insert page number field |\n| `insert_merge_field` | Insert mail merge field |\n| `insert_sequence_field` | Insert auto-numbering sequence |\n| `update_all_fields` | **v3.1.0** — F9-equivalent SEQ recount across body + headers + footers + footnotes + endnotes. Supports chapter-reset when `pStyle==\"Heading N\"` matches SEQ `resetLevel` |\n\n### Content Controls / SDT (10 tools, **v3.9.0+ full read/write** [#44](https://github.com/PsychQuant/che-word-mcp/issues/44))\n\nInsert + form helpers (5):\n| Tool | Description |\n|------|-------------|\n| `insert_content_control` | 12-type discrimination (`richText` / `plainText` / `picture` / `date` / `dropDownList` / `comboBox` / `checkBox` / `bibliography` / `citation` / `group` / `repeatingSection` (rejected — use `insert_repeating_section`) / `repeatingSectionItem`). Optional args: `list_items` (required for dropDown/comboBox), `date_format`, `lock_type`. |\n| `insert_repeating_section` | Insert repeating section (Word 2012+); accepts `allow_insert_delete_sections: bool` (default `true`) |\n| `insert_checkbox` | Insert checkbox SDT |\n| `insert_dropdown` | Insert dropdown SDT |\n| `insert_text_field` | Insert plain-text SDT |\n\nRead tools (3):\n| Tool | Description |\n|------|-------------|\n| `list_content_controls` | Enumerate every SDT, flat (default) or nested tree mode (Direct Mode supported) |\n| `get_content_control` | Fetch single SDT by `id`, `tag`, or `alias`. Returns full metadata + `<w:sdtContent>` XML. Surfaces `not_found` / `multiple_matches` errors. |\n| `list_repeating_section_items` | Enumerate items inside a repeating-section SDT in document order |\n\nModify tools (4):\n| Tool | Description |\n|------|-------------|\n| `update_content_control_text` | Replace text content of plainText / richText / date / bibliography / citation SDTs. Preserves `<w:sdtPr>` byte-identical. Returns `unsupported_type` for picture / dropdown / combo / checkbox / group / repeatingSection. |\n| `replace_content_control_content` | Replace full `<w:sdtContent>` XML with whitelist validation (rejects input containing `<w:sdt>`, `<w:body>`, `<w:sectPr>`, or XML declaration) |\n| `delete_content_control` | Remove SDT, optionally unwrapping children (`keep_content: true` default) |\n| `update_repeating_section_item` | Replace text of single item by index (`out_of_bounds` for invalid index) |\n\nSDT id allocation uses deterministic max+1 (was random in pre-v3.9.0). `list_custom_xml_parts` ships as empty-list stub for forward compat (real impl in `che-word-mcp-customxml-databinding` Change B).\n\n### Advanced Features (10 tools)\n\n| Tool | Description |\n|------|-------------|\n| `insert_toc` | Insert table of contents |\n| `insert_table_of_figures` | Insert table of figures |\n| `insert_index`, `insert_index_entry` | Index generation |\n| `set_paragraph_border` | Set paragraph border |\n| `set_paragraph_shading` | Set paragraph background color |\n| `set_character_spacing` | Set character spacing |\n| `set_text_effect` | Set text animation effect |\n| `insert_horizontal_line`, `insert_drop_cap`, `insert_symbol` | Decorative elements |\n\n> **Note**: The counts above cover key tool categories. Total surface is **233 tools** as of v3.13.5 including Document Comparison, Track Changes (read + programmatic write side via `<w:ins>` / `<w:del>` / `<w:moveFrom>` / `<w:moveTo>` / `<w:rPrChange>` / `<w:pPrChange>`), Content Controls (12-type SDT discrimination), Field Codes, Theme Editing, Header/Footer/Watermark CRUD with even/odd + section linkage, Comment Threads + People (dual identity), Notes Update, Web Settings, Styles (inheritance + linkage + latent + alias), Numbering (full definition lifecycle), Sections (vertical alignment + page-number format + title-page distinct + per-section refs), Tables (conditional / nested / layout / indent), Hyperlinks (typed url/bookmark/email), and Formatting helpers (with `as_revision` flag). Run the server and call `tools/list` for the complete, authoritative set.\n\n## Usage Examples\n\n### Create a Document with Headings and Text\n\n```\nCreate a new Word document called \"report\" with:\n- Title: \"Quarterly Report\"\n- Heading: \"Introduction\"\n- A paragraph explaining the report purpose\nSave it to ~/Documents/report.docx\n```\n\n### Create a Document with Table and Images\n\n```\nCreate a document with:\n- A title \"Product Catalog\"\n- Insert an image from ~/images/logo.png\n- A 4x3 table with product information\n- Apply borders to the table\nSave it to ~/Documents/catalog.docx\n```\n\n### Create a Professional Report\n\n```\nCreate a document with:\n- Custom page margins (1 inch all around)\n- A header with company name\n- A footer with page numbers\n- Table of contents\n- Multiple sections with headings\n- Footnotes for references\nSave it as ~/Documents/annual_report.docx\n```\n\n## Technical Details\n\n### OOXML Structure\n\nThe server generates valid Office Open XML documents with complete structure:\n\n```\ndocument.docx (ZIP)\n├── [Content_Types].xml\n├── _rels/\n│   └── .rels\n├── word/\n│   ├── document.xml      # Main content\n│   ├── styles.xml        # Style definitions\n│   ├── settings.xml      # Document settings\n│   ├── fontTable.xml     # Font definitions\n│   ├── numbering.xml     # List definitions\n│   ├── comments.xml      # Comments\n│   ├── footnotes.xml     # Footnotes\n│   ├── endnotes.xml      # Endnotes\n│   ├── header1.xml       # Header content\n│   ├── footer1.xml       # Footer content\n│   ├── media/            # Embedded images\n│   │   └── image*.{png,jpeg}\n│   └── _rels/\n│       └── document.xml.rels\n└── docProps/\n    ├── core.xml          # Metadata\n    └── app.xml           # Application info\n```\n\n### Dependencies\n\n- [MCP Swift SDK](https://github.com/modelcontextprotocol/swift-sdk) (v0.12.0+) — Model Context Protocol implementation\n- [ooxml-swift](https://github.com/PsychQuant/ooxml-swift) (**v0.12.0+**) — OOXML parsing + **preserve-by-default round-trip architecture** (PreservedArchive, RelationshipIdAllocator, ContentTypesOverlay), `FieldParser`, `OMMLParser`, `updateAllFields()`, `MathAccent`\n- [latex-math-swift](https://github.com/PsychQuant/latex-math-swift) (**v0.1.0+**) — LaTeX subset → OMML `MathComponent` AST parser (used by `insert_equation` v3.2.0+)\n- [markdown-swift](https://github.com/PsychQuant/markdown-swift) (v0.2.0+) — Markdown generation\n- [word-to-md-swift](https://github.com/PsychQuant/word-to-md-swift) (v0.4.0+) — Word to Markdown conversion\n\n### Developer Notes — Real-World Fixture Testing\n\n`Tests/CheWordMCPTests/RealWorldDocxRoundTripSmokeTests.swift` validates the\nooxml-swift Reader / Writer pair against real-world Word output (e.g., academic\ntheses, contracts) rather than synthesized fixtures. Drop confidential `.docx`\nfiles into `test-files/` (gitignored — they never reach version control), then:\n\n```bash\ncd mcp/che-word-mcp\nswift test --filter RealWorldDocxRoundTripSmokeTests\n```\n\nPer-fixture assertions: `xmllint --noout` clean, bookmark / hyperlink /\nfldSimple / AlternateContent count parity, SHA256 of concatenated `<w:t>`\ncontent matches. The test silently `XCTSkip`s when `test-files/` is empty so\nclean clones / CI do not false-fail. Mirrors the `.note` smoke pattern from\n[PsychQuant/macdoc#81](https://github.com/PsychQuant/macdoc/issues/81).\n\n## Comparison with Other Solutions\n\n| Feature | Anthropic Word MCP | python-docx | docx npm | **che-word-mcp** |\n|---------|-------------------|-------------|----------|------------------|\n| Language | Node.js | Python | Node.js | **Swift** |\n| Backend | AppleScript | OOXML | OOXML | **OOXML** |\n| Requires Word | Yes | No | No | **No** |\n| Runtime | Node.js | Python | Node.js | **None** |\n| Single Binary | No | No | No | **Yes** |\n| Tools Count | ~10 | N/A | N/A | **233** |\n| Images | Limited | Yes | Yes | **Yes** |\n| Comments | No | Limited | Limited | **Yes** |\n| Track Changes | No | No | No | **Yes** |\n| TOC | No | Limited | No | **Yes** |\n| Form Fields | No | No | No | **Yes** |\n\n## Performance\n\nBenchmarks on Apple Silicon (M4 Max, 128GB RAM):\n\n### Read Performance\n\n| File Size | Time |\n|-----------|------|\n| 40 KB (thesis outline) | **72 ms** |\n| 431 KB (complex document) | **31 ms** |\n\n### Write Performance\n\n| Operation | Content | Time |\n|-----------|---------|------|\n| Basic write | Create + 3 paragraphs + Save | **19 ms** |\n| Complex document | Title + Paragraphs + Table + List | **21 ms** |\n| Bulk write | **50 paragraphs** + Save | **28 ms** |\n\n### Why So Fast?\n\n- **Native Swift binary** - No interpreter startup overhead\n- **Direct OOXML manipulation** - No Microsoft Word process\n- **Efficient ZIP handling** - ZIPFoundation for compression\n- **In-memory operations** - Only writes to disk on save\n\nCompared to python-docx (~200ms startup) or docx npm (~150ms startup), che-word-mcp is **10-20x faster**.\n\n## License\n\nMIT License\n\n## Author\n\nChe Cheng ([@PsychQuant](https://github.com/PsychQuant))\n\n### Contributors\n\n- [@ildunari](https://github.com/ildunari) — session state management (v1.17.0)\n\n## Related Projects\n\n- [che-apple-mail-mcp](https://github.com/PsychQuant/che-apple-mail-mcp) - Apple Mail MCP server\n- [che-ical-mcp](https://github.com/PsychQuant/che-ical-mcp) - macOS Calendar MCP server\n",
  "bytes": 55493,
  "sha": "e5c3c1594afd11517a0b676d66763c224ff4f1efc313afcfeeb7b3b3c7503e60",
  "repo_slug": "psychquant/che-word-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_kiki830621_che_word_mcp_9ad7bde5/readme"
}