Workflow for Surgical XML Editing in DOCX Files with DesktopCommanderMCP

DesktopCommanderMCP enables precise surgical XML editing in DOCX files through a three-step workflow: generate an outline to locate content, inspect raw XML with a non-zero offset, and execute targeted replacements using edit_block with exact string fragments.

The DocxFileHandler in src/utils/files/docx.ts treats DOCX files as ZIP archives containing XML parts, exposing three distinct operating modes through the MCP server. This workflow for surgical XML editing in DOCX files allows you to modify document contents—including headers and footers—without corrupting the archive structure.

Overview of the DOCX Editing Architecture

DesktopCommanderMCP leverages pizzip via loadDocxZip to unpack the DOCX container. The system collects all XML parts (document body, headers, footers, and relationships) and applies pretty-printing (prettyPrintXml) to split tags onto separate lines. This line-based formatting enables precise pagination when viewing raw content and supports the surgical editing mechanism through exact string matching.

The three access modes are:

  • Outline mode: Human-readable index of paragraphs, tables, and headings
  • Raw XML mode: Pretty-printed markup when using non-zero offset parameters
  • Surgical edit mode: Fragment replacement via editRange

Step-by-Step Workflow

1. Generate an Outline to Locate the Target Section

Call read_file without an offset parameter to receive a structured outline. The extractOutline function (lines 25-34 in src/utils/files/docx.ts) indexes each body child element with [0], [1], etc., displaying text fragments and style information.

{
  "tool": "read_file",
  "args": {
    "path": "/home/user/report.docx"
  }
}

The response lists entries like [23] w:p style="Heading1" with accompanying text, allowing you to identify the specific index or heading requiring modification.

2. Inspect Raw XML with Non-Zero Offset

Once you identify the target section, request the raw XML by providing any non-zero offset (commonly offset=1). According to the read method implementation in src/utils/files/docx.ts (lines 27-33), this triggers the raw XML view instead of the outline.

{
  "tool": "read_file",
  "args": {
    "path": "/home/user/report.docx",
    "offset": 1,
    "length": 200
  }
}

The handler returns pretty-printed XML with line numbers, making it easy to identify precise markup boundaries:

<w:p>
  <w:pPr>
    <w:pStyle w:val="Heading2"/>
  </w:pPr>
  <w:r>
    <w:t>Executive Summary</w:t>
  </w:r>
</w:p>

3. Copy the Exact XML Fragment

Select and copy the specific XML snippet you intend to modify (e.g., <w:t>Executive Summary</w:t>). The surgical editing process requires character-level precision—whitespace and tag structure must match exactly as displayed in the pretty-printed view.

4. Execute the Surgical Edit with edit_block

Invoke edit_block with the old_string and new_string parameters. The editRange routine (lines 218-227 and 240-250 in src/utils/files/docx.ts) searches across the document and its header/footer parts for the exact fragment, validates the occurrence count against expected_replacements, and performs the replacement.

After replacement, compactXml removes indentation to restore valid Office Open XML formatting, and the file is repacked into a valid DOCX archive.

{
  "tool": "edit_block",
  "args": {
    "file_path": "/home/user/report.docx",
    "old_string": "<w:t>Executive Summary</w:t>",
    "new_string": "<w:t>Project Overview</w:t>",
    "expected_replacements": 1
  }
}

The response confirms the operation: { "success": true, "editsApplied": 1 }.

5. Verify the Changes

Re-read the file using either outline or raw XML mode to confirm the edit applied correctly.

{
  "tool": "read_file",
  "args": {
    "path": "/home/user/report.docx",
    "offset": 1,
    "length": 200
  }
}

Key Implementation Details

  • Multi-part editing: The system searches and replaces across all XML parts, including word/document.xml plus headers and footers found in the ZIP structure.
  • Validation: The editRange function enforces expected_replacements to prevent accidental mass replacements.
  • Pretty-printing: The prettyPrintXml utility enables line-based pagination for the raw view, while compactXml ensures the final document meets strict XML formatting requirements.
  • Server documentation: The high-level API description in src/server.ts (lines 95-103) explicitly documents that non-zero offsets are required to obtain raw XML, as implemented in the request handling logic.

Summary

  • DesktopCommanderMCP treats DOCX files as ZIP archives containing XML parts, enabling direct markup manipulation.
  • The three-phase workflow involves: (1) outline generation via read_file without offset, (2) raw XML inspection with offset=1, and (3) precise replacement via edit_block.
  • The DocxFileHandler in src/utils/files/docx.ts handles unzipping with pizzip, pretty-printing for readability, and compacting for output validation.
  • Surgical edits require exact string matching against pretty-printed XML fragments, with support for headers, footers, and controlled replacement counts.

Frequently Asked Questions

Why is a non-zero offset required to view raw XML?

The read method in src/utils/files/docx.ts (lines 27-33) uses the offset parameter as a mode selector. When offset === 0, it returns the human-readable outline; any non-zero value triggers the raw XML pretty-printing path. This design consolidates file reading functionality while distinguishing between navigational and editing contexts.

Can I edit headers and footers using this workflow?

Yes. The editRange implementation (lines 218-227 in src/utils/files/docx.ts) searches across all XML parts extracted from the DOCX archive, including header (header*.xml) and footer (footer*.xml) files. When you provide an XML fragment from these sections, the replacement occurs in the appropriate part before repacking.

What happens if the old_string appears multiple times?

The edit_block tool accepts an expected_replacements parameter that validates the occurrence count before applying changes. If the actual count differs from your expectation, the operation aborts without modifying the file, preventing unintended bulk replacements. The editRange logic enforces this validation at lines 240-250 in src/utils/files/docx.ts.

Is the XML pretty-printing preserved in the final DOCX?

No. While prettyPrintXml expands tags for the viewing phase, the compactXml function removes indentation and extraneous whitespace before writing the XML back to the ZIP archive. The final DOCX contains standard compact Office Open XML markup required by Microsoft Word and other compatible applications.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →