Skip to main content
Glama

doc-agent-mcp

CI PyPI Python License: MIT

Un servidor de Model Context Protocol que brinda a los agentes de IA operaciones estables y semánticas sobre documentos, en lugar de hacer que manipulen texto sin formato.

Human ─────┐
           ↓
        Document          ← Markdown (.md/.markdown) and DOCX today,
           ↑                 Tiptap / SuperDoc / Shimo / Google Docs tomorrow
AI Agent ──┘

Los agentes LLM que editan documentos como una gran cadena de texto rompen cosas: estropean el formato que no pueden ver, pierden imágenes y comentarios, y no pueden expresar "insertar un párrafo después de la sección 3". doc-agent-mcp expone el documento como una estructura normalizada y direccionable (encabezados, párrafos, elementos de lista, tablas con IDs estables) y permite que los agentes trabajen en un bucle seguro:

read  →  propose change  →  inspect diff  →  apply  →  export

Nada toca tu archivo hasta que se llama a apply_changes. Cada lectura acepta un doc_hash, de modo que si el archivo cambia debajo del agente a mitad de tarea, las ediciones posteriores fallan de forma ruidosa (stale_document) en lugar de corromper el archivo.


El problema que esto resuelve

Edición de texto sin formato (típica hoy)

doc-agent-mcp

El agente reescribe todo el archivo para cambiar una palabra

El agente reemplaza un rango exacto de caracteres en un bloque

Los viajes de ida y vuelta de DOCX a través de convertidores de texto destruyen estilos/comentarios

Las ediciones se aplican dentro del paquete OOXML original; el contenido no tocado pasa intacto

No hay forma de revisar qué cambiará antes de que cambie

Cada edición se prepara con un diff unificado; la aplicación es explícita

Conflictos silenciosos cuando los humanos editan concurrentemente

Bloqueo optimista por hash de contenido; las ediciones obsoletas se rechazan

Trucos específicos de formato codificados en los prompts

Una superficie de herramientas, cualquier backend

Related MCP server: docx-mcp-server

Arquitectura

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)

Propiedad clave: las herramientas MCP nunca saben qué backend hay debajo. Agregar un nuevo backend de edición significa implementar dos métodos — ver ADAPTER_GUIDE.md.

Instalación

Desde PyPI (recomendado para usuarios):

pip install doc-agent-mcp

Requiere Python 3.10+.

Desde el código fuente (desarrollo):

git clone https://github.com/xyyyang97/doc-agent-mcp.git
cd doc-agent-mcp

python3 -m venv .venv
.venv/bin/pip install -e ".[dev]"

Verificar:

doc-agent-mcp --version
# doc-agent-mcp 0.1.0

Configuración de MCP

El servidor habla MCP estándar sobre 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 ~/Documents

Cliente MCP genérico (JSON)

{
  "mcpServers": {
    "doc-agent": {
      "command": "/absolute/path/to/doc-agent-mcp/.venv/bin/doc-agent-mcp",
      "args": [],
      "env": {}
    }
  }
}

--roots DIR [DIR ...] opcionalmente restringe todas las lecturas/escrituras a esos directorios (recomendado). Sin él, el servidor puede tocar cualquier ruta que su proceso pueda alcanzar — trata la configuración del servidor como credenciales del sistema de archivos.

Herramientas disponibles

Operaciones de lectura (nunca mutan)

Herramienta

Propósito

read_document(path, section_id?, include_spans?, doc_hash?)

Bloques estructurados con IDs; vista opcional de una sola sección; informa unmodeled_features

get_outline(path, doc_hash?)

Encabezados planos + árbol anidado con rutas

find_text(path, query, scope_element_id?, is_regex?, case_sensitive?, doc_hash?)

Ocurrencias exactas con desplazamientos (element_id, start, end) listos para propose_replace_text; los resultados de tablas se marcan editable: false

get_comments(path, doc_hash?)

Comentarios nativos (autor, cuerpo, elemento ancla, rango citado)

Operaciones de propuesta (preparan un cambio; nada se escribe aún)

Herramienta

Propósito

propose_replace_text(path, element_id, start, end, text)

Reemplaza un rango de caracteres dentro de un bloque; devuelve vista previa del diff

propose_insert_block(path, anchor_id, position, kind, text, level?)

Inserta párrafo/encabezado/elemento de lista antes o después de cualquier elemento (cubre insertar-antes/después/añadir)

propose_delete_block(path, element_id)

Elimina un bloque completo

propose_add_comment(path, anchor_id, body, quote?, author?)

Comentario nativo de Word (DOCX); solo de sesión para Markdown (ver limitaciones)

Confirmar y revisar

Herramienta

Propósito

get_changes(path)

Todos los cambios preparados con diffs unificados

discard_changes(path, change_ids?)

Descartar cambios preparados (todos o seleccionados)

apply_changes(path, change_ids?, doc_hash?)

Escribir en disco atómicamente; devuelve nuevo doc_hash + advertencias

export_document(path, target_format, output_path?, title?)

Convertir mediante el modelo: md↔docx en ambas direcciones

list_backends()

Backends registrados y conversiones soportadas

Cada llamada de mutación/lectura acepta el doc_hash que obtuviste de la llamada anterior. Si el archivo cambió desde entonces (incluso por otro proceso), obtienes {"code": "stale_document", ...} y tus cambios preparados se descartan — vuelve a leer primero.

Ejemplo de flujo de trabajo

Este es el bucle exacto que ejecuta examples/demo_workflow.py (contra archivos reales):

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")

Sobre MCP, los mismos pasos son una llamada de herramienta cada uno — ver la tabla de herramientas anterior.

Ejecuta la demo completa (Markdown + DOCX + exportación + guardia de obsoleto, todo verificado):

.venv/bin/python examples/demo_workflow.py

Los documentos de muestra viven en examples/documents/: sample.md y sample.docx (este último con dos comentarios nativos de Word, regenerables mediante scripts/make_sample_docx.py).

Manejo de errores

Todos los errores son JSON estructurado — sin tracebacks a través del cable:

{
  "code": "element_not_found",
  "message": "Element 'p-99' not found. Call get_outline ...",
  "details": {"element_id": "p-99"}
}

Código

Significado

document_not_found

La ruta no existe

unsupported_format

No hay backend para esta extensión

element_not_found

ID de elemento obsoleto/desconocido

match_not_found / ambiguous_match

La búsqueda no encontró nada / reservado para desambiguación

validation_error

Rango incorrecto, ancla de cita incorrecta, reemplazo de celda de tabla, ruta fuera de las raíces...

stale_document

El archivo cambió desde tu instantánea; los cambios preparados se descartaron

change_not_found

change_id desconocido o ya descartado

export_error

Par de conversión no soportado

Pruebas

.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 checking

La suite incluye pruebas de ida y vuelta de DOCX (ediciones verificadas al reabrir el archivo guardado con python-docx y a nivel de OOXML crudo) y una prueba MCP de extremo a extremo que inicia el servidor sobre stdio y habla mensajes de protocolo reales.

Limitaciones (por diseño, no por accidente)

El modelo normalizado cubre lo que Markdown y DOCX pueden representar de manera confiable. Todo lo demás se expone explícitamente como unmodeled_features en cada lectura — nunca se destruye silenciosamente:

  • DOCX: imágenes/dibujos, encabezados y pies de página, notas al pie/finales, controles de contenido, cambios rastreados presentes en la fuente se conservan intactos pero invisibles para el modelo. Las tablas son celdas de texto plano (el formato de celda no se modela). replace_text rechaza párrafos que contienen hipervínculos (la reescritura los destruiría).

  • Markdown: la serialización es fiel al modelo, no fiel al byte — el contenido sobrevive a los viajes de ida y vuelta, el ajuste de línea original/estilo de marcador puede no sobrevivir. Las citas en bloque se aplanan a sus párrafos (marcadas). Las definiciones de enlaces de estilo referencia se resuelven y se insertan en línea. Los comentarios no tienen hogar nativo: propose_add_comment los almacena solo de sesión y lo dice.

  • Tablas: buscables (marcadas editable: false) pero la edición a nivel de celda no está implementada aún — eliminar/reinsertar en su lugar.

  • Agentes concurrentes: el último escritor gana por archivo, protegido por verificaciones de hash; no hay motor de fusión.

Ideas de hoja de ruta

  • Operaciones de celda de tabla (update_table_cell)

  • Adaptadores Tiptap/SuperDoc sobre sus modelos JSON

  • Adaptador de Google Docs mediante la API de Drive (los comentarios se mapean de forma nativa)

  • Modo de sugerencias ancladas para Markdown (bloques <!-- suggestion -->)

  • Espacios de trabajo de múltiples archivos y sesiones seguras para renombrar

Licencia

MIT

A
license - permissive license
A
quality
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

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.

View all MCP Connectors

Latest Blog Posts

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