Skip to main content
Glama
Mavline

docx_mcp_server_ts

by Mavline

DOCX MCP Server

A comprehensive TypeScript-based MCP (Model Context Protocol) server for universal DOCX processing with full OOXML support. Process Word documents programmatically with support for text, tables, images, headers/footers, SDTs, comments, and more.

Features

  • Complete OOXML Access: Read/write DOCX parts at ZIP level with full namespace support

  • Text Operations: Extract, find, and replace text with minimal diff preservation

  • Table Management: Insert/delete rows, modify cells, merge/split operations

  • Image Handling: Add inline/positioned images with EMU-based sizing

  • Structured Data Tags (SDT): Access content controls by tag or alias

  • Headers/Footers: List and modify section headers and footers

  • Track Changes: Accept/reject revisions, handle insertions/deletions

  • Comments: Manage document comments

  • Metadata: Read/write core and app properties

  • LRU Caching: Efficient memory management with part caching

  • Lossless XML: Preserves document structure with fast-xml-parser

Installation

npm install
npm run build

Quick Start

Start the Server

npm start

The server will listen on stdin/stdout for MCP protocol messages.

Installation & Configuration

Claude Code CLI

claude mcp install docx \
  --command node \
  --args /full/path/to/docx_mcp_server_ts/dist/index.js \
  --env LOG_LEVEL=INFO

~/.claude.json (для Claude Code)

Отредактировать ~/.claude.json добавить в раздел "projects":

{
  "projects": {
    "/full/path/to/docx_mcp_server_ts": {
      "mcpServers": {
        "docx": {
          "command": "node",
          "args": ["/full/path/to/docx_mcp_server_ts/dist/index.js"],
          "env": {
            "LOG_LEVEL": "INFO"
          }
        }
      }
    }
  }
}

Пример для Linux/WSL:

{
  "projects": {
    "/mnt/c/Users/pavelk/Desktop/Projects/MCP-servers/docx_mcp_server_ts": {
      "mcpServers": {
        "docx": {
          "command": "node",
          "args": ["/mnt/c/Users/pavelk/Desktop/Projects/MCP-servers/docx_mcp_server_ts/dist/index.js"],
          "env": {
            "LOG_LEVEL": "INFO"
          }
        }
      }
    }
  }
}

MCP Tools

Document Management

docx.open

Open a DOCX document from file or base64 buffer.

Input:

{
  "path": "/path/to/document.docx",
  "bufferBase64": "..."  // OR provide base64 data
}

Output:

{
  "docId": "uuid-string",
  "parts": ["word/document.xml", ...],
  "props": { "core": {}, "app": {} }
}

docx.close

Close a document and release resources.

Input: { "docId": "uuid" }

docx.save

Save document to file or return as base64.

Input:

{
  "docId": "uuid",
  "path": "/output/path.docx",  // optional
  "returnBase64": true  // optional
}

docx.list_parts

List all parts in document.

docx.part_read / docx.part_write

Read/write individual XML parts for low-level access.

Text Operations

docx.get_text

Extract all text from document.

Input: { "docId": "uuid", "scope": "document|headers|footers|all" }

docx.replace_text

Replace text preserving run structure.

Input:

{
  "docId": "uuid",
  "match": "search text",
  "replace": "replacement",
  "mode": "literal|regex",
  "where": "document|headers|footers|all"
}

Output: { "replaced": 5 }

docx.find

Find text with context.

Output:

{
  "hits": [
    {
      "text": "found text",
      "context": "...found text...",
      "offset": 150
    }
  ]
}

Table Operations

docx.tables_list

List all tables with dimensions.

Output:

{
  "tables": [
    {
      "tableXPath": "//w:tbl[1]",
      "rows": 5,
      "colsApprox": 3
    }
  ]
}

docx.table_edit

Perform table operations.

Input:

{
  "docId": "uuid",
  "tableXPath": "//w:tbl[1]",
  "op": {
    "kind": "setCellText",
    "row": 0,
    "col": 0,
    "text": "new value"
  }
}

Supported operations:

  • { "kind": "setCellText", "row": number, "col": number, "text": string }

  • { "kind": "insertRow", "at": number }

  • { "kind": "deleteRow", "at": number }

  • { "kind": "insertCol", "at": number }

  • { "kind": "deleteCol", "at": number }

Structured Data Tags (SDT)

docx.sdt_get

Get content control content.

Input: { "docId": "uuid", "tagOrAlias": "control_tag" }

Output:

{
  "xml": "<w:p>...</w:p>",
  "textPreview": "Control content..."
}

docx.sdt_put

Update content control.

Input:

{
  "docId": "uuid",
  "tagOrAlias": "control_tag",
  "xmlFragment": "<w:p>...</w:p>"
}

Image Operations

docx.images_list

List all images with metadata.

Output:

{
  "images": [
    {
      "rId": "rId4",
      "path": "word/media/image1.png",
      "sizeEMU": { "cx": 914400, "cy": 914400 }
    }
  ]
}

docx.image_add

Insert image inline or anchored.

Input:

{
  "docId": "uuid",
  "target": {
    "afterParagraphXPath": "//w:p[1]",
    "sdtTagOrAlias": "imageControl"  // OR use SDT
  },
  "image": {
    "path": "/local/image.png",
    "base64": "...",  // OR base64 data
    "filename": "image.png",
    "contentType": "image/png"
  },
  "placement": {
    "kind": "inline"  // OR { "kind": "anchor", "xEMU": 0, "yEMU": 0 }
  },
  "size": {
    "widthMM": 50,
    "heightMM": 50
  },
  "altText": "Description"
}

docx.image_update_position

Update anchored image position/size.

Advanced Operations

docx.styles_get / docx.styles_set

Read/write styles.xml

docx.numbering_get / docx.numbering_set

Read/write numbering.xml

docx.headers_footers_list

List headers and footers with section info.

docx.headers_footers_get / docx.headers_footers_set

Read/write specific header or footer.

docx.comments_list / docx.comments_add / docx.comments_delete

Manage document comments.

docx.changes_accept_all

Accept all tracked changes (remove w:del, unwrap w:ins).

Output: { "removedDel": 3, "flattenedIns": 5 }

docx.metadata_get / docx.metadata_set

Read/write document properties (core.xml, app.xml).

Size Conversions

The server handles EMU (English Metric Unit) conversions internally:

  • 1 inch = 914,400 EMU

  • 1 mm ≈ 36,000 EMU

  • 1 point ≈ 12,700 EMU

Examples

Extract and Replace Text

// Open document
const openResult = await client.call('docx.open', {
  path: '/tmp/document.docx'
});
const docId = openResult.docId;

// Get text
const textResult = await client.call('docx.get_text', { docId });
console.log(textResult.text);

// Replace text
await client.call('docx.replace_text', {
  docId,
  match: 'old text',
  replace: 'new text',
  mode: 'literal'
});

// Save
await client.call('docx.save', {
  docId,
  path: '/tmp/document-modified.docx'
});

// Close
await client.call('docx.close', { docId });

Modify Table

// List tables
const tablesResult = await client.call('docx.tables_list', { docId });
const tableXPath = tablesResult.tables[0].tableXPath;

// Update cell
await client.call('docx.table_edit', {
  docId,
  tableXPath,
  op: {
    kind: 'setCellText',
    row: 0,
    col: 0,
    text: 'Updated Value'
  }
});

// Insert row
await client.call('docx.table_edit', {
  docId,
  tableXPath,
  op: {
    kind: 'insertRow',
    at: 1
  }
});

Add Image

const fs = require('fs').promises;

const imageBuffer = await fs.readFile('/path/to/image.png');
const base64 = imageBuffer.toString('base64');

await client.call('docx.image_add', {
  docId,
  target: {
    afterParagraphXPath: '//w:p[1]'
  },
  image: {
    base64,
    filename: 'image.png',
    contentType: 'image/png'
  },
  placement: {
    kind: 'inline'
  },
  size: {
    widthMM: 100,
    heightMM: 75
  },
  altText: 'My image'
});

Architecture

src/
├── index.ts              # MCP server entry point
├── logger.ts             # Logging utility
├── errors.ts             # Error types and codes
├── ooxml/
│   ├── namespaces.ts     # OOXML constants and namespaces
│   ├── emu.ts            # Unit conversion utilities
│   ├── dom.ts            # XML DOM utilities (xmldom + fontoxpath)
│   ├── xmlParser.ts      # FXP parser with order preservation
│   ├── parts.ts          # ZIP part reading/writing
│   ├── rels.ts           # Relationship management
│   ├── text.ts           # Text operations with diff-match-patch
│   ├── tables.ts         # Table manipulation
│   ├── sdt.ts            # Structured Data Tags
│   ├── drawings.ts       # Image handling
│   ├── headersFooters.ts # Header/footer operations
│   ├── comments.ts       # Comment management
│   ├── changes.ts        # Track changes handling
│   ├── styles.ts         # Styles XML access
│   └── numbering.ts      # Numbering XML access
├── store/
│   ├── types.ts          # Store type definitions
│   └── docStore.ts       # Document store with LRU cache
└── mcp/
    └── tools.ts          # MCP tool implementations

Performance

  • Memory: LRU cache limits per-document parts to 50 cached items

  • Total Size: Supports documents up to 100MB in-memory

  • Partial Access: Only requested parts are parsed from ZIP

  • Minimal Diffs: Text replacements preserve run structure when possible

Limitations

  • Page layout calculations are not performed (Word's rendering engine needed)

  • Advanced DrawingML transformations are read-only

  • VBA macros and embedded OLE objects not supported

  • Extremely large documents (>500MB) may require streaming

Development

# Install dependencies
npm install

# Type check
npm run type-check

# Build
npm run build

# Run dev server
npm run dev

# Debug with inspector
npm run dev:debug

Logging

Control log level via environment variable:

LOG_LEVEL=DEBUG npm start     # Verbose
LOG_LEVEL=INFO npm start      # Default
LOG_LEVEL=WARN npm start      # Warnings only
LOG_LEVEL=ERROR npm start     # Errors only

Protocol Support

  • Transport: stdio

  • Protocol: MCP (Model Context Protocol)

  • Handler: @modelcontextprotocol/sdk

License

MIT

Resources