doc-agent-mcp
Planned adapter for Google Docs via Drive API, enabling the same semantic document operations (read, propose, apply) with native comment mapping.
Provides structured, addressable operations on Markdown documents, including reading, searching, proposing and applying changes, plus export to DOCX.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@doc-agent-mcpReplace second paragraph of Introduction with 'We are happy to announce our new product.'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
doc-agent-mcp
A Model Context Protocol server that gives AI agents stable, semantic operations on documents — instead of making them shuffle raw text.
Human ─────┐
↓
Document ← Markdown (.md/.markdown) and DOCX today,
↑ Tiptap / SuperDoc / Shimo / Google Docs tomorrow
AI Agent ──┘LLM agents editing documents as one big string break things: they mangle
formatting they cannot see, lose images and comments, and cannot express
"insert a paragraph after section 3". doc-agent-mcp exposes the document as
a normalized, addressable structure (headings, paragraphs, list items,
tables with stable IDs) and lets agents work in a safe loop:
read → propose change → inspect diff → apply → exportNothing touches your file until apply_changes is called. Every read accepts
a doc_hash, so if the file changes underneath the agent mid-task, further
edits fail loudly (stale_document) instead of corrupting the file.
The problem this solves
Raw-text editing (typical today) | doc-agent-mcp |
Agent rewrites the whole file to change one word | Agent replaces an exact character range in one block |
DOCX round-trips through text converters destroy styles/comments | Edits are applied inside the original OOXML package; untouched content passes through |
No way to review what will change before it changes | Every edit is staged with a unified diff; apply is explicit |
Silent conflicts when humans edit concurrently | Content-hash optimistic locking; stale edits are rejected |
Format-specific hacks hardcoded into prompts | One tool surface, any backend |
Related MCP server: docx-mcp-server
Architecture
MCP interface (13 tools)
↓
Document operation layer ← staging, diffs, hashes, search, sessions
↓ (doc_agent_mcp/service.py)
Normalized document model ← Block(h-0, p-1, li-2, tbl-0), Comment,
↓ ProposedChange (core/model.py)
Backend adapters ← parse() + serialize() per format
↓ (adapters/*_adapter.py)
Markdown · DOCX · future editors (Tiptap, SuperDoc, Shimo, Google Docs)Key property: the MCP tools never know which backend is underneath. Adding a new editor backend means implementing two methods — see ADAPTER_GUIDE.md.
Installation
From PyPI (recommended for users):
pip install doc-agent-mcpRequires Python 3.10+.
From source (development):
git clone https://github.com/xyyyang97/doc-agent-mcp.git
cd doc-agent-mcp
python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"Verify:
doc-agent-mcp --version
# doc-agent-mcp 0.1.0MCP configuration
The server speaks standard MCP over stdio.
Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"doc-agent": {
"command": "/absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp",
"args": ["--roots", "/Users/you/Documents"]
}
}
}Claude Code / Codex CLI
claude mcp add doc-agent -- /absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp --roots ~/DocumentsGeneric MCP client (JSON)
{
"mcpServers": {
"doc-agent": {
"command": "/absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp",
"args": [],
"env": {}
}
}
}--roots DIR [DIR ...] optionally restricts all reads/writes to those
directories (recommended). Without it the server can touch any path its
process can reach — treat server configuration like filesystem credentials.
Available tools
Read operations (never mutate)
Tool | Purpose |
| Structured blocks with IDs; optional single-section view; reports |
| Headings flat + nested tree with paths |
| Exact occurrences with |
| Native comments (author, body, anchor element, quoted range) |
Propose operations (stage a change; nothing written yet)
Tool | Purpose |
| Replace character range inside one block; returns diff preview |
| Insert paragraph/heading/list item before or after any element (covers insert-before/after/append) |
| Delete one whole block |
| Native Word comment (DOCX); session-only for Markdown (see limitations) |
Commit & review
Tool | Purpose |
| All staged changes with unified diffs |
| Drop staged changes (all or selected) |
| Write to disk atomically; returns new |
| Convert via the model: md↔docx both directions |
| Registered backends and supported conversions |
Every mutating/read call accepts the doc_hash you got from the previous
call. If the file changed since (including by another process), you get
{"code": "stale_document", ...} and your staged changes are dropped —
re-read first.
Example workflow
This is the exact loop examples/demo_workflow.py runs (against real files):
from doc_agent_mcp.service import DocumentService
svc = DocumentService() # same facade the MCP tools wrap
# 1. Understand the document
outline = svc.get_outline("brief.md")
summary = next(h for h in outline["headings"] if h["title"] == "Executive Summary")
section = svc.read_document("brief.md", section_id=summary["id"])
# 2. Locate exact text
hit = svc.find_text("brief.md", "30 percent")["matches"][0]
# 3. Stage a change (file is untouched)
proposal = svc.propose_replace_text(
"brief.md", hit["element_id"], hit["start"], hit["end"],
"at least 30 percent (validated with finance)",
)
# 4. Review the diff
changes = svc.get_changes("brief.md")
print(changes["changes"][0]["diff"])
# 5. Commit, then export
svc.apply_changes("brief.md", doc_hash=proposal["doc_hash"])
svc.export_document("brief.md", "docx", output_path="brief.docx")Over MCP the same steps are one tool call each — see the tool table above.
Run the full demo (Markdown + DOCX + export + stale-guard, all verified):
.venv/bin/python examples/demo_workflow.pySample documents live in examples/documents/:
sample.md and sample.docx (the latter with two native Word comments,
regenerable via scripts/make_sample_docx.py).
Error handling
All errors are structured JSON — no tracebacks across the wire:
{
"code": "element_not_found",
"message": "Element 'p-99' not found. Call get_outline ...",
"details": {"element_id": "p-99"}
}Code | Meaning |
| Path does not exist |
| No backend for this extension |
| Stale/unknown element ID |
| Search found nothing / reserved for disambiguation |
| Bad range, bad quote anchor, table-cell replace, path outside roots... |
| File changed since your snapshot; staged changes were dropped |
| Unknown or already-discarded |
| Unsupported conversion pair |
Testing
.venv/bin/pip install -e ".[dev]"
.venv/bin/pytest # unit + integration + MCP protocol tests
.venv/bin/ruff check src tests # lint
.venv/bin/ruff format --check . # formatting
.venv/bin/mypy # strict type checkingThe suite includes DOCX round-trip tests (edits verified by re-opening the saved file with python-docx and at raw OOXML level) and an end-to-end MCP test that spawns the server over stdio and speaks real protocol messages.
Limitations (by design, not by accident)
The normalized model covers what Markdown and DOCX can both represent
reliably. Everything else is explicitly surfaced as
unmodeled_features on every read — never silently destroyed:
DOCX: images/drawings, headers & footers, footnotes/endnotes, content controls, tracked changes present in source are preserved untouched but invisible to the model. Tables are plain-text cells (cell formatting not modeled).
replace_textrefuses paragraphs containing hyperlinks (the rewrite would destroy them).Markdown: serialization is model-faithful, not byte-faithful — content survives round-trips, original line wrapping/marker style may not. Blockquotes are flattened to their paragraphs (flagged). Reference-style link definitions are resolved and inlined. Comments have no native home:
propose_add_commentstores them session-only and says so.Tables: searchable (flagged
editable: false) but cell-level editing is not implemented yet — delete/re-insert instead.Concurrent agents: last-writer-wins per file, guarded by hash checks; there is no merge engine.
Roadmap ideas
Table cell operations (
update_table_cell)Tiptap/SuperDoc adapters over their JSON models
Google Docs adapter via Drive API (comments map natively)
Anchored suggestions mode for Markdown (
<!-- suggestion -->blocks)Multi-file workspaces and rename-safe sessions
License
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceEnables collaborative document authoring and composition with project-based organization, transforming Markdown and LaTeX content into professional PDFs with conflict-free multi-agent editing capabilities.620MIT
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to read, edit, and create Microsoft Word documents (.docx) with support for rich text, tables, and images, deployable locally or via SSE.3MIT
- AlicenseAqualityDmaintenanceEnables AI agents to edit Google Docs via text anchors rather than character indices, preserving version history and enabling surgical edits without full document rewrites.147MIT
- AlicenseBqualityCmaintenanceEnables AI agents to safely ingest, inspect, edit, and export manufacturing documents (Excel, PDF, Word, Markdown) with controlled patch workflows and MES entity extraction.23MIT
Related MCP Connectors
Persistent docs and memory for AI agents — read, write, organize & search a shared workspace.
MCP-native collaborative markdown editor with real-time AI document editing
AI document editing for agents: draft, edit, export .docx/PDF. 37 MCP tools; agent self-signup.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/xyyyang97/doc-agent-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server