使用说明
docx mcp
法律文件对发动机进行了红线标记。采用人工智能生成的更改(结构化JSON)
并将其作为专业跟踪的更改进行应用,并在其中添加注释 .docx
文件夹。产出与律师在
微软Word——正确 w:ins/w:del 标记、注释注释
对齐文本和保留的格式。
安装
需要Python 3.14+。
uv sync
快速开始
Python API
from docx_mcp import (
ParagraphChange, ParagraphChangeType,
TableChange, TableChangeType,
RedlineConfig, apply_redlines,
)
changes = [
# Modify a body paragraph
ParagraphChange(
kind="paragraph",
fragment_id="3", # ← str (was int in v0.1.0)
change_type=ParagraphChangeType.MODIFY,
new_text="The Company **shall** provide written notice.",
justification="Strengthened obligation language.",
),
# Delete a paragraph
ParagraphChange(
kind="paragraph",
fragment_id="5",
change_type=ParagraphChangeType.DELETE,
justification="Removed redundant clause.",
),
# Append a new paragraph
ParagraphChange(
kind="paragraph",
fragment_id="7",
change_type=ParagraphChangeType.APPEND_AFTER,
new_text="The foregoing shall survive termination.",
justification="Added survival provision.",
),
# Modify a header paragraph
ParagraphChange(
kind="paragraph",
fragment_id="header_1.1",
change_type=ParagraphChangeType.MODIFY,
new_text="CONFIDENTIAL",
justification="Updated header text.",
),
# Modify a table cell
TableChange(
kind="table",
table_id=2,
row=1,
col=1,
change_type=TableChangeType.MODIFY_CELL,
new_text="Updated **cell** content",
justification="Corrected table entry.",
),
# Clear a table cell
TableChange(
kind="table",
table_id=2,
row=3,
col=2,
change_type=TableChangeType.CLEAR_CELL,
justification="Removed obsolete data.",
),
]
doc = apply_redlines("contract.docx", changes)
doc.save("contract_redlined.docx")
命令行界面
# Extract fragment text from a document
docx-mcp convert input.docx
docx-mcp convert input.docx --format json
# Apply changes
docx-mcp apply input.docx changes.json -o output.docx
# Validate a redlined document
docx-mcp validate output.docx
# Audit a document for structural issues
docx-mcp audit input.docx
docx-mcp audit input.docx --format json
注: CLI
convert命令仅提取正文内容(没有标题, 例如桌子、脚或桌子)。要提取完整文档,请使用MCPextract_fragments工具或Pythonfull_to_fragments()功能。
MCP服务器
该库包括MCP服务器,
等等)可以红线 .docx 文件直接。
# Start the server (stdio transport)
docx-mcp-server
在Claude桌面中配置 (claude_desktop_config.json):
{
"mcpServers": {
"docx-mcp": {
"command": "uv",
"args": ["run", "--directory", "/path/to/docx-mcp", "docx-mcp-server"]
}
}
}
在游标中配置 (.cursor/mcp.json):
{
"mcpServers": {
"docx-mcp": {
"command": "uv",
"args": ["run", "--directory", "/path/to/docx-mcp", "docx-mcp-server"]
}
}
}
工具
| 工具 | 说明 |
|---|---|
extract_fragments |
阅读a .docx 并将段落、表格、页眉和页脚作为标记文本返回 |
apply_changes |
应用内联列表中的跟踪更改并保存 |
apply_changes_from_file |
从磁盘上的JSON文件应用跟踪的更改 |
validate_document_tool |
运行结构验证检查 |
diff_fragments |
比较两个 .docx 逐段归档(完整文档) |
audit_document_tool |
审计a .docx 用于标题、图像、表格、分节符等 |
资源
| URI | 描述 |
|---|---|
docx-fragments://{document_path} |
浏览段落片段(URL编码路径) |
工作流程示例
LLM客户通常会:
- 呼叫
extract_fragments读取文档并获取片段ID。 - 解释内容并构建更改列表。
- 呼叫
apply_changes使用更改列表生成带红线的文档。 - 可选呼叫
diff_fragments比较原始输出与红线输出。
概念
片段
文档被分解为 碎片:段落、表格、标题和 页脚,全部按文档顺序索引。每个片段都有一个 字符串ID.
片段ID:
| 模式 | 含义 | 示例 |
|---|---|---|
"1", "2",… |
正文段落/表格 | <f=1>Introduction.</f=1> |
"header_P.I" |
标题P部分,第一段 | <f=header_1.3>Confidential</f=header_1.3> |
"footer_P.I" |
脚注P部分,第一段 | <f=footer_2.1>Page 1 of 10</f=footer_2.1> |
表和正文段落共享相同的ID空间(它们在文档中交错
订单)。片段 "3" 可能是表和片段 "4" 一个段落。
使用 extract_fragments (MCP)或 full_to_fragments() (Python)查看
任何文档的片段映射:
<f=1>Introduction paragraph.</f=1>
<f=2>**Definitions.** The following terms shall apply.</f=2>
<table=3 rows=2 cols=3>
<cell=3.1.1 span="2">Merged Header</cell=3.1.1>
<cell=3.1.3>Header C</cell=3.1.3>
<cell=3.2.1>Data 1</cell=3.2.1>
<cell=3.2.2>Data 2</cell=3.2.2>
<cell=3.2.3>Data 3</cell=3.2.3>
</table=3>
<f=4>Closing paragraph. See [Section 2](https://example.com).</f=4>
<f=header_1.1>Confidential</f=header_1.1>
<f=footer_1.1>Page 1 of 10</f=footer_1.1>
表格
简单表格
简单(矩形)表被提取为 <table=N> 阻碍。每个细胞都有
一 cell_id 在 "table_id.row.col" 格式(例如。, "3.1.2").
合并单元格表
具有水平或垂直合并单元格的表(gridSpan / vMerge)都是
现在支持。合并跨度显示为属性:
span="2"--单元格跨2列(水平合并)vspan="3"--单元格跨越3行(垂直合并)
跨越单元格(合并覆盖的位置)的是 从输出中省略.
例如,如果 cell=3.1.1 有 span="2"那么 cell=3.1.2 没有出现。
当以具有更改的合并单元格为目标时,始终以 原始细胞
(与 span/vspan 属性)。瞄准一个跨越的位置
提高a ValueError.
跳过的桌子
无法处理的表(嵌套表、格式错误的合并、内部表 页眉/页脚)显示为:
<table=5 skipped reason="table 5, cell 2.3 contains nested table"/>
页眉和页脚
页眉和页脚段落用前缀片段ID提取:
header_1.1, footer_2.1等等。第一个数字是基于1的零件索引
(通常 1 对于默认的页眉/页脚),第二个是基于1的
该部分内的段落索引。
页眉/页脚段落可以修改、删除和附加到以下内容 正文段落。 页眉/页脚内的表格不可编辑 并且是 报告为跳过的元素。
限制: 页眉/页脚更改的评论未附在 输出(Word和LibreOffice不支持这些部分的注释范围)。 他们触发了
UserWarning并被丢弃。
超链接
超链接提取为 [link text](url) 在段落文本中内联。
链接内部的格式得以保留: [**bold link**](url).
当修改现有段落时, [text] 没有 (url) 蜜饯
原始超链接URL。 [text](new_url) 创建新链接。
当附加新文本时, [text](url) 创建超链接。 [text] 没有
(url) 生成纯文本--始终指定 (url) 如果你想要一个
超链接。
跟踪更改策略
具有预先存在的跟踪更改的文档(<w:ins>, <w:del>,
<w:moveFrom>, <w:moveTo>)都是 坚决拒绝 两者都 extract_fragments
和 apply_redlines。在处理之前,接受或拒绝Word中的所有更改。
collapse_empty 模式
可选模式,禁止提取空段落并加上红线。 为LLM消费生产更清洁的产品。启用后,它 必须 是 在提取和红线之间一致使用——不匹配的值会导致 片段ID错位。
更改类型
段落更改
| 类型 | 描述 | 必填 new_text |
|---|---|---|
modify |
单词级别差异作为跟踪更改应用 | 是 |
delete |
整个段落标记为已删除 | 否 |
append_after |
在引用片段后插入新段落 | 是 |
表格单元格更改
| 类型 | 描述 | 必填 new_text |
|---|---|---|
modify_cell |
修改单元格内容(单个或多个段落) | 是 |
clear_cell |
删除单元格中的所有内容(保留结构) | 否 |
细胞修饰 使用位置对齐:如果单元格有多个
段落,新文本被拆分为换行符(\n)每条线都被应用
按照相应段落的顺序。单元格内容标记为已跟踪
更改和注释就像段落修改一样。
空白行管理
添加新段落时,可以控制周围的空白行:
Change(
fragment_id=10,
change_type=ChangeType.APPEND_AFTER,
new_text="New clause text here.",
justification="Added new provision.",
blank_lines_before=1, # Insert 1 blank line before the new paragraph
blank_lines_after=1, # Insert 1 blank line after the new paragraph
)
删除段落时,您可以自动删除尾随的空白行:
Change(
fragment_id=15,
change_type=ChangeType.DELETE,
justification="Removed obsolete clause.",
delete_next_blanks=1, # Also delete the next blank paragraph
)
所有空白行将标记为跟踪插入/删除,并将显示在 红线文件。
伪Markdown
文本内容使用简化的类似Markdown的格式进行内联格式化:
**bold**_italic___underline__
Unicode字符(智能引号、em破折号、节符号、非换行符 空间)保持原样。
字体继承:添加新段落时,字体系列、大小和 颜色会自动从参考段落的第一个文本方位复制 跑。伪Markdown的粗体、斜体和下划线格式是分层的 在继承的基本格式之上。
更改JSON
CLI接受包含裸数组或
{"changes": [...]} 包装。
段落更改示例
[
{
"fragment_id": "1",
"change_type": "modify",
"new_text": "The Seller agrees to deliver within **sixty** days.",
"justification": "Extended delivery window."
},
{
"fragment_id": "3",
"change_type": "delete",
"justification": "Removed governing law clause.",
"delete_next_blanks": 1
},
{
"fragment_id": "5",
"change_type": "append_after",
"new_text": "This Agreement shall be governed by Delaware law.",
"justification": "Added Delaware governing law.",
"blank_lines_before": 1,
"blank_lines_after": 0
},
{
"fragment_id": "header_1.1",
"change_type": "modify",
"new_text": "CONFIDENTIAL",
"justification": "Updated header marking."
}
]
表格单元格更改示例
[
{
"cell_id": "2.1.1",
"change_type": "modify_cell",
"new_text": "Updated **cell** content",
"justification": "Corrected cell value."
},
{
"cell_id": "2.3.2",
"change_type": "clear_cell",
"justification": "Cleared obsolete data."
}
]
单元格ID使用以下格式 "table_id.row.col" 其中行和列是从1开始的。
验证
这 validate_document() 功能(和 docx-mcp validate CLI)检查:
- 注释ID隔离 --跟踪的更改和注释ID不会冲突 跨组
- 评论完整性 --每一个
<w:comment>中有匹配的范围标记 文档正文,反之亦然 - 跟踪更改属性 --每一个
<w:ins>和<w:del>已要求w:id,w:author,以及w:date - 包装一致性 --存在以下内容类型和关系条目
comments.xml
from docx_mcp import validate_document
result = validate_document(doc)
if not result.ok:
for error in result.errors:
print(error)
建筑
库直接通过以下方式操纵OOXML lxml (不是 python-docx)因为
python-docx 没有跟踪更改支持。关键设计决策:
- 单词级别差异 通过
diff-match-patch使用单词到字符的映射 为了获得高质量的差异 - 保守突变 --只有修改过的段落才会被触及;一切 否则传递相同的字节
- 全局唯一的注释ID 通过单调
IdManager种子从 文档的现有最大ID python-docx仅用于测试夹具生成,不用于 图书馆本身
模块映射
src/docx_mcp/
__init__.py Public API
cli.py CLI entry point (apply, convert, validate)
models.py Pydantic data models (Change, ChangeType, RedlineConfig, ...)
document.py DocxDocument: ZIP parsing, XML tree access, serialization
converter.py Paragraph & table XML -> pseudo-Markdown conversion
table_utils.py Table inspection utilities (cell access, simplicity checks)
tokenizer.py Word-level tokenization
differ.py Word-level diff engine (diff-match-patch wrapper)
run_ops.py Diff-to-XML-run mapping, run splitting, element building
id_manager.py Monotonic annotation ID allocator
comments.py Comment creation and range marker insertion
redliner.py Main orchestrator: apply_redlines()
table_redliner.py Table cell change application
audit.py Document structural audit (headers, images, tables, etc.)
validator.py Structural validation checks
server.py MCP server (FastMCP 3.x, stdio transport)
handlers/
modify.py Word-level tracked changes on existing paragraphs
delete.py Full paragraph deletion markup
append.py New paragraph insertion markup
发展
# Run tests
uv run pytest tests/ -v
# Lint
uvx ruff check src/ tests/
# Auto-fix lint issues
uvx ruff check src/ tests/ --fix
# Type check
uvx ty check src/ tests/
431个测试涵盖了所有模块、处理程序、表操作、页眉/页脚、超链接、跟踪更改拒绝、合并单元格表、分节符、CLI、验证和MCP服务器。
许可证
麻省理工学院