docx_mcp_server_ts
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 buildQuick Start
Start the Server
npm startThe 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 implementationsPerformance
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:debugLogging
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 onlyProtocol Support
Transport: stdio
Protocol: MCP (Model Context Protocol)
Handler: @modelcontextprotocol/sdk
License
MIT