# DOCX OOXML package fallback

Use `office-mcp-server` for supported Word operations. Use the bundled OOXML
CLI only when MCP is unavailable, package diagnostics are needed, or the
requested operation is not exposed by MCP.

Milestone 2 adds `outline` plus `section` actions for `read`,
`replace_content`, `append`, `prepend`, `delete` and `rename`. Select a section
by stable ID where possible; title selectors are exact and ambiguity stops the
operation. Section edits always write a separate output DOCX.

The section fragment renderer supports headings, paragraphs, basic
bold/italic/inline code, and simple bullet or numbered lists. It rejects
tables, images, hyperlinks and code blocks rather than silently degrading
them. Relationships, comments and Markdown synchronization are handled by
their dedicated actions rather than by the fragment renderer.

The tool accepts regular stored/deflated ZIP archives and rejects encrypted,
macro-enabled, ZIP64, path traversal and ZIP-bomb-like input. A manifest keeps
the expected package part hashes so validation can report preservation of parts
that were not changed.

## Incremental Markdown synchronization

`sync link_source` embeds a versioned Sophia manifest in `customXml/`; it maps
matching Markdown and DOCX headings and records source/target baselines.
`plan_from_markdown` is read-only and reports `unchanged`, `modified_source`,
`modified_target`, `modified_both` and unmapped states. `apply_from_markdown`
updates only `modified_source` sections. A simultaneous source/target change
raises `SECTION_SYNC_CONFLICT` unless `prefer_markdown` is explicitly chosen.

## Advanced DOCX operations

Prefer `word_document` whenever `office-node` is available. The standalone
CLI mirrors the advanced DOCX contract only for unavailable MCP, unsupported
MCP capabilities or package diagnostics; it never edits the input in place.

- `replace-text` works on visible text across Word runs; use `--dry-run` before
  a write and opt in explicitly to `--allow-multiple true`.
- `revisions` supports `track_replace`, `accept`, `reject` and
  `validate_author`. Tracked replacement intentionally accepts only a single
  text run.
- `comments` supports an anchored comment or `--parent-id` reply and creates
  comments, commentsExtended, content-type overrides and document
  relationships as needed.
- `images --intent replace` preserves the existing document relationship and
  accepts only a same-extension PNG/JPEG replacement.
- `relationships` validates internal OPC relationship parts throughout the
  package. `render` is best-effort: it reports a structured unavailable warning
  when LibreOffice is not installed. When `soffice` is installed outside the
  server PATH, set `LIBREOFFICE_PATH` (or `SOFFICE_PATH`) to the executable,
  then restart `office-node`. `node scripts/install-user-runtime.js` detects
  the executable where supported (including standard and Snap locations on
  Ubuntu) and emits `LIBREOFFICE_PATH` only in the generated
  `office-mcp-server` environment; it never mutates the global PATH.

## Manual interoperability evidence

On 2026-08-03 the MCP `word_document` interface was exercised against the
real DOCX supplied in `D:\tmp\docx`, without modifying the source file:

- `inspect/outline` returned four top-level headings;
- `section/read` returned the requested section content;
- `validate/relationships` checked 26 internal relationships and found none
  broken;
- after configuring `LIBREOFFICE_PATH`, `validate/render` invoked
  `D:\programmi\LibreOffice\program\soffice.exe` successfully and produced
  an eight-page PDF. Metadata inspection reported LibreOffice Writer 26.2.4.2
  as the producer.

This is a package and semantic-read check, **not** a Word or LibreOffice round
trip certification. A round-trip record may be added only after opening and
saving the same output with the relevant application, then verifying the
manifest, bookmarks and relationship graph again.

### LibreOffice round trip — 2026-08-03

The same real DOCX was opened and saved as a distinct DOCX in
`D:\tmp\docx\mcp-roundtrip` using LibreOffice Writer 26.2.4.2. The derived
package reopened through `word_document`; its internal relationship validation
again reported 26 relationships and no broken targets. LibreOffice normalized
the document styles, so the semantic outline exposed additional headings that
the original outline did not classify as headings. This is expected
normalization, not a claim of byte-for-byte preservation.

The source document did not contain a Sophia synchronization manifest or
heading bookmarks. This round trip therefore validates ordinary DOCX package
readability and relationship integrity only; it does **not** certify persistence
of the planned manifest/bookmark identity mechanism.
