docs-mcp

by gossipauthorxpm

Not rated
GitHub

About

MCP for work with docx files. Make copy format from docx files.

Details

Author
gossipauthorxpm
Categories
Productivity, Other

Setup

Install docs-mcp in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/gossipauthorxpm/docs-mcp

Follow the installation instructions in the repository README, then restart your MCP client.

MCP server for reading and writing.docxfiles. Exposes four paginated tools so agents can batch-read document content and styles, write content, and union style definitions — without a monolithic reformat tool.

Primary use case:reformat a draft document using a template's styles— the agent orchestrates four tool calls with pagination.

Layered design: MCP tools delegate to services, services use adapters, adapters translate to/from domain models.

flowchart TB subgraph mcpLayer [MCP Layer] Server[FastMCP Server] Tools["4 Tools: get/write contents & styles"] end subgraph serviceLayer [Service Layer] ReadSvc[ReadService] WriteSvc[WriteService] end subgraph adapterLayer [Adapter Layer] DocxAdapter[DocxAdapter] ContentWriter[ContentWriter] StyleMigrator[StyleMigrator] ContentExtractor[ContentExtractor] StyleExtractor[StyleExtractor] end subgraph domainLayer [Domain Layer] DocModel[DocumentModel] StyleProfile[StyleProfile] BlockModel[ParagraphBlock / TableBlock] end Agent[Cursor Agent] -->|batch tool calls| Server Server --> Tools Tools --> ReadSvc Tools --> WriteSvc ReadSvc --> DocxAdapter WriteSvc --> DocxAdapter DocxAdapter --> ContentExtractor DocxAdapter --> StyleExtractor DocxAdapter --> ContentWriter DocxAdapter --> StyleMigrator ReadSvc --> domainLayer WriteSvc --> domainLayer

Dependency direction is always downward:MCP → Service → Adapter → Domain.

SeeAGENTS.mdfor contributor guidelines.

- python-docx—.docxI/O
-
MCP Python SDK(mcp>=1.12.0) — FastMCP server
-
uv— package manager and runner

git clone <repo-url> docs-mcp cd docs-mcp uv sync --extra dev

The process listens on stdio (JSON-RPC). Press Ctrl+C to stop.

Replace/absolute/path/to/docs-mcpwith your clone path. Cursor MCP config requiresabsolute paths.

{ "mcpServers": { "docs-mcp": { "command": "uv", "args": [ "run", "--directory", "/absolute/path/to/docs-mcp", "docx-mcp" ] } } }

Build once from the repo root (no file paths in the image or build command):

MCP config — only how to start the server process.Which files to read/write is not configured here; every tool receivesfile_pathfrom the MCP client (agent/user) at call time:

{ "mcpServers": { "docs-mcp": { "command": "docker", "args": ["run", "--rm", "-i", "docs-mcp"] } } }

With Docker, the default config above has no bind mounts — tool paths must exist inside the container unless you extendargs. To read/write host files, add a volume mount that matches the paths you pass in tools, for example:

"args": ["run", "--rm", "-i", "-v", "/home/user/docs:/home/user/docs", "docs-mcp"]

Then the agent callsget_contents_from_docx(file_path="/home/user/docs/report.docx")— same path string on host and in the container.

One container runs for the entire MCP session (not per tool call). The host spawns the process on connect and tears it down on disconnect;--rmremoves the container automatically.

All tools return JSON-serializable dicts. On failure, the response contains structured error fields instead of raising an unhandled exception:

{ "code": "FILE_NOT_FOUND", "message": "File not found: /path/missing.docx", "details": { "path": "/path/missing.docx" } }

Error codes:FILE_NOT_FOUND,FILE_NOT_READABLE,FILE_NOT_WRITABLE,INVALID_PATH,PARSE_ERROR,STYLE_NOT_FOUND,REFORMAT_ERROR,INTERNAL_ERROR.

Return a paginated batch of document content blocks.

{ "items": [ { "block_type": "paragraph", "runs": [ { "text": "ЛАБОРАТОРНАЯ РАБОТА №3 (Java)", "bold": null, "italic": null, "font_name": null, "font_size_pt": null } ], "style": { "name": "Heading 1", "style_type": "paragraph" } } ], "total": 48, "offset": 0, "limit": 10, "has_more": true, "source_path": "/path/plain.docx" }

Blocks carry astyle name reference(StyleHint), not full style definitions. See.agents/skills/docx-mcp/references/blocksfor the full schema.

Return a paginated batch of paragraph styles from a.docxfile.

Example response (first batch,offset=0):

{ "paragraph_styles": [ { "name": "Heading 1", "base_style": "Normal", "font_name": null, "font_size_pt": null, "font_color": "000000", "bold": null, "italic": null, "alignment": null, "line_spacing": 1.0, "space_before_pt": 18.0, "space_after_pt": 12.0, "left_indent_cm": null, "right_indent_cm": null, "first_line_indent_cm": null } ], "section": { "page_width_cm": 21.0, "page_height_cm": 29.7, "left_margin_cm": 2.5, "right_margin_cm": 1.0, "top_margin_cm": 1.5, "bottom_margin_cm": 1.5 }, "total": 33, "offset": 0, "limit": 25, "has_more": true, "source_path": "/path/format.docx" }

sectionis included only whenoffset == 0; later batches omit it. Mergeparagraph_stylesclient-side across batches.

Write content blocks to a.docxfile.Creates a new fileif the path does not exist; replaces the document body if it exists.

{ "file_path": "/path/output.docx", "blocks_written": 48, "created": true }

Union style definitions onto anexisting.docxfile. Incoming styles win on name conflict.

{ "file_path": "/path/output.docx", "styles_added": 5, "styles_updated": 12, "styles_unchanged": 8 }

ReturnsFILE_NOT_FOUNDif the target file does not exist — callwrite_contents_to_docxfirst.

Reformatreport_draft.docxto matchcompany_template.docx. Save asreport_final.docx.

report_draft.docx company_template.docx │ │ ├─ get_contents_from_docx (batches) ├─ get_styles_from_docx (batches) │ │ └──────────────────┬───────────────────┘ ▼ write_contents_to_docx(report_final.docx) ← creates file ▼ write_styles_to_docx(report_final.docx) ← union; template wins ▼ formatted output

-

Read content— paginateget_contents_from_docx(draft, offset, limit)untilhas_moreis false. Collect allitems.

Read styles— paginateget_styles_from_docx(template, offset, limit)untilhas_moreis false. Merge allparagraph_styles; keepsectionfrom the first batch (offset=0).

Write contentwrite_contents_to_docx(output, contents)with the collected blocks.

Union styleswrite_styles_to_docx(output, styles)with the merged style profile.

# Contents items = [] offset = 0 while True: batch = get_contents_from_docx(path, offset=offset, limit=50) items.extend(batch["items"]) if not batch["has_more"]: break offset += batch["limit"] # Styles paragraph_styles = [] section = None offset = 0 while True: batch = get_styles_from_docx(path, offset=offset, limit=50) if offset == 0: section = batch.get("section") paragraph_styles.extend(batch["paragraph_styles"]) if not batch["has_more"]: break offset += batch["limit"] styles = {"paragraph_styles": paragraph_styles, "section": section}

Applied bywrite_styles_to_docxviaStyleProfile.union_with(incoming, master="other"):

Styles withnullfield values inherit frombase_styleat write time (StyleProfile.resolve_inherited()). For the run-level overridesbold,italic, andfont_color, a resolvednullis an explicit reset: the corresponding override is cleared in the target style so draft theme artifacts (e.g. blue, bold headings) do not survive a reformat.

When mapping source style names to a template catalog (used internally during reformat):
- Exact name match in template styles
- Entry in optionalcustom_map
- Nearest heading fallback (Heading NHeading min(N, available))
- Fallback toNormal, or first available template style

Unmapped styles are tracked inunmapped_styles.

- Headers and footers (content)
- Floating images
- Text boxes
- Footnotes and endnotes
- Numbering restart / list numbering preservation
- Run-level formatting when a named paragraph style exists (deferred — styles applied in step 4 override inline hints)
- Paragraph-level direct formatting (e.g. a centered title set on the paragraph, not in the style) — not carried by content blocks;ParagraphAlignercovers only the title/conclusions heuristic used in the reformat tests
- Document parse caching — each batch call re-reads the file from disk

uv sync --extra dev uv run pytest uv run docx-mcp
docs-mcp/ ├── README.md ├── AGENTS.md ├── Dockerfile ├── pyproject.toml ├── src/docx_mcp/ │ ├── server.py # MCP tools (thin handlers) │ ├── errors.py │ ├── domain/ # DocumentModel, StyleProfile, blocks │ ├── adapters/ # python-docx isolation │ └── services/ # ReadService, WriteService ├── tests/ │ └── assets/ # plain.docx, format.docx fixtures └── .agents/skills/docx-mcp/ # Agent skill for MCP workflow

- tests/assets/plain.docx— sample content (draft)
- tests/assets/format.docx— sample styles (template)

End-to-end pipeline test:tests/test_reformat_pipeline.py.

Convert files (DOCX, XLSX, PPTX, images), HTML, and Markdown to pixel-perfect PDFs — npx stdio or hosted Streamable HTTP, free API key in one click.

Universal document generation and conversion MCP. Generate PDF/DOCX/XLSX from templates+JSON (invoices, contracts, reports), batch generation, 100+ format conversions.

A server for reading and converting documents between PDF, DOCX, and Markdown formats using marker-pdf and pandoc.

Convert Excel and Apple Numbers files to PDF format.

Convert any file or URL to clean AI-ready Markdown. Supports PDF, Word, Excel, PowerPoint, YouTube, ArXiv, Wikipedia, and 18 more formats. Up to 63% fewer tokens for ChatGPT and Claude. Free, no API key required.

A server that converts various file types, including documents, images, audio, and web pages, into Markdown format.

MCP-MD-PDF: Markdown to Word/PDF Converter

A simple, reliable Model Context Protocol (MCP) server that converts Markdown files into professional Word (.docx) and PDF documents — with full support for .dotx templates.

A server for converting document formats using Pandoc.

Turn messy text into clean output fast—GUI for humans, MCP tools for AI IDEs (Cursor/Claude). 33 deterministic text utilities.

MCP server for BulkRender — generate bulk DOCX and PDF documents from Claude, Cursor, Windsurf, and any MCP-compatible AI assistant

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.