# How to Handle DOCX Files (Outline vs Raw XML) in Desktop Commander MCP

> Learn how to handle DOCX files in Desktop Commander MCP. Choose between outline view for readability or raw XML for precise editing of your Word documents.

- Repository: [Eduard Ruzga/DesktopCommanderMCP](https://github.com/wonderwhy-er/DesktopCommanderMCP)
- Tags: how-to-guide
- Published: 2026-07-15

---

**Desktop Commander MCP treats Word documents as virtual text files, exposing either a concise structural outline or paginated raw XML to balance readability with precision editing capabilities.**

The repository `wonderwhy-er/DesktopCommanderMCP` implements a specialized handler in [`src/utils/files/docx.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/docx.ts) that unzips Office Open XML packages and translates binary DOCX files into editable text representations. This dual-mode approach allows AI agents to quickly grasp document structure or perform surgical XML edits without overwhelming context windows.

## Two Read Modes for DOCX Files

The handler exposes every `.docx` file through two distinct interfaces, selectable via read parameters.

### Outline Mode (Default)

When you read a DOCX without specifying pagination parameters, the handler returns a **structural outline** generated by `extractOutline()`. This mode parses the `<w:body>` element and lists every top-level child—paragraphs (`<w:p>`), tables (`<w:tbl>`), images, and structured document tags—with their associated text content and style attributes.

The outline includes a summary header showing counts of paragraphs, tables, and images, followed by indexed entries. Each line displays the raw XML tag (e.g., `w:p style="Heading1"`) so you can target specific elements for later editing. This mode is optimal for navigation and understanding document structure without processing thousands of XML lines.

### Raw XML Mode (Offset/Length)

For granularity, specify `offset` and `length` parameters to receive **pretty-printed XML** from [`document.xml`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/document.xml). The `prettyPrintXml()` function splits tags onto individual lines with indentation, making the file searchable and editable. The response includes a status header indicating the line range and remaining content.

Use raw mode when the outline lacks sufficient detail—such as when editing complex drawing attributes, precise style definitions, or nested formatting that requires exact XML fragments.

## Core Implementation Architecture

The DOCX workflow relies on several specialized utilities within [`src/utils/files/docx.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/docx.ts).

### Loading the ZIP Package

The `loadDocxZip()` function uses **pizzip** to read every `.xml` and `.rels` entry in the DOCX archive (which is a standard ZIP file). It returns the main `documentXml` string plus a map of all XML parts, including headers and footers. This occurs at lines 74-94 of the source file.

### XML Processing Pipeline

Two complementary functions handle XML formatting:

- **`prettyPrintXml()`** (lines 31-51): Splits XML tags and adds indentation, ensuring each tag occupies one line for precise offset-based pagination.
- **`compactXml()`** (lines 55-61): Removes whitespace and indentation after edits, preparing the XML for repackaging into the ZIP container.

### Outline Extraction Logic

The `extractOutline()` function (lines 143-225) walks the children of `<w:body>` using `splitTopLevelElements()` to identify paragraphs, tables, and drawings. It also calls `extractHeaderFooterOutline()` (lines 13-33) to preview content from header and footer parts. The resulting summary provides counts and contextual hints, suggesting when to request raw XML for bulk operations.

## Editing DOCX Files Programmatically

Desktop Commander MCP enables surgical edits through the `editRange()` method, which operates on the same pretty-printed XML returned by raw read mode.

The editing workflow follows these steps:

1. **Load**: The handler loads the pretty-printed XML representation of the document and any header/footer parts.
2. **Search**: It searches for the exact `old_string` within the XML.
3. **Validate**: It verifies the replacement matches the `expected_replacements` count to prevent unintended modifications.
4. **Substitute**: Performs the string replacement.
5. **Compact**: Runs `compactXml()` to strip indentation.
6. **Repack**: Writes the compacted XML back into the ZIP archive.

```typescript
await fileHandler.editRange(
  'report.docx',
  '',
  {
    old_string: '<w:t>Quarterly Results</w:t>',
    new_string: '<w:t>Annual Results</w:t>',
    expected_replacements: 1,
  }
);

```

This approach guarantees that fragments copied from a raw XML read are valid search strings for subsequent edits.

## Creating New Documents

The handler supports DOCX generation from markdown-style text via the `write()` method. Lines beginning with `#` convert to Word heading styles (`Heading1`, `Heading2`, etc.), while plain lines become standard paragraphs. Blank lines generate empty `<w:p/>` elements.

```typescript
const content = `

# Executive Summary

Q4 exceeded targets by 15%.

## Details

Revenue grew across all sectors.
`;
await fileHandler.write('new_report.docx', content);

```

## Summary

- **Outline mode** (default) provides indexed summaries of paragraphs, tables, and images with XML tag hints, ideal for navigation and context gathering.
- **Raw XML mode** delivers pretty-printed, paginated [`document.xml`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/document.xml) via `offset` and `length` parameters, enabling precise editing of complex structures.
- The **editing pipeline** uses `editRange()` to substitute strings in pretty-printed XML, then compacts and repackages the ZIP via `compactXml()`.
- **Implementation** resides in [`src/utils/files/docx.ts`](https://github.com/wonderwhy-er/DesktopCommanderMCP/blob/main/src/utils/files/docx.ts), utilizing `loadDocxZip()`, `extractOutline()`, and `prettyPrintXml()` for transformation logic.
- **File creation** accepts markdown-style input, automatically mapping heading levels to Word styles.

## Frequently Asked Questions

### How do I switch from outline view to raw XML in Desktop Commander MCP?

Pass `offset` and `length` parameters when calling the read method. Setting `offset: 0` and specifying a line count returns the pretty-printed XML instead of the structural outline. The response includes a header indicating which lines you are viewing and how many remain.

### Can I edit headers and footers using the raw XML mode?

Yes. The `loadDocxZip()` function extracts all XML parts including headers and footers. When using `editRange()`, the handler can target these parts if your search string includes content from those sections, though the outline view provides limited preview information for header/footer text via `extractHeaderFooterOutline()`.

### Why does the editing process require pretty-printed XML?

Pretty-printing ensures each XML tag occupies exactly one line, making string-based search and replacement reliable. After editing, `compactXml()` removes the added whitespace to restore valid Office Open XML before repackaging the DOCX ZIP container. This guarantees that copied fragments from raw reads match the source exactly.

### What happens if my search string appears multiple times in the document?

The `expected_replacements` parameter in `editRange()` acts as a safety check. If the count of occurrences does not match your specified expectation, the operation aborts without modifying the file. This prevents accidental mass replacements when you intend to edit a single specific instance.