关于 mcp-ooxml-ledger
mcp-ooxml-ledger 是用于编辑 Office 文档并记录每项修改的 MCP 服务,适合需要可核查文档变更的团队。提交前会重放记录的操作并与磁盘文件比对;无法解释的变更会导致提交被拒。
主要功能
- 01读取、查找和编辑 Office 文档
- 02提交前重放操作并核对文件
- 03批量编辑全成或全败
- 04生成并验证修改回执
- 05限制工具访问指定根目录
- 06支持 Word、PowerPoint 和 Excel 验证
适用场景
- 01审查并提交 Word 文档修改
- 02核验 Office 文件是否存在未记录变更
- 03通过 CI 或提交钩子检查文档回执
- 04导入、编辑并导出聊天中上传的文档
MCP 相关
该 MCP 服务向客户端提供文档读取、编辑、提交、验证和传输工具。文档可作为 MCP 内嵌资源导出,并可配置只读部署。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
14收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
mcp-ooxml-ledger
一个可编辑 Office 文档的 MCP 服务;如果某项编辑未被记录,就拒绝写入文档。
在封存会话之前,它会将所有已记录的操作应用于文档基线并重新执行,然后将结果与磁盘上的实际内容进行比较。如果某项更改无法由任何操作解释,就会拒绝提交。在大约 18 个同类 MCP 文档编辑项目中,没有一个会根据这项检查来决定是否写入。拒绝写入就是本项目的核心价值。
设置
uv add mcp-ooxml-ledger
添加到 .mcp.json(项目级)或 claude_desktop_config.json(桌面端——请使用绝对路径,因为 ${CLAUDE_PROJECT_DIR} 不会在那里展开):
{
"mcpServers": {
"ooxml-ledger": {
"command": "uv",
"args": ["run", "--project", "${CLAUDE_PROJECT_DIR}", "ooxml-ledger-mcp"],
"env": { "OOXML_LEDGER_ROOTS": "${CLAUDE_PROJECT_DIR}" }
}
}
}
需要在 PATH 中提供 uv;无需在全局安装其他内容。直接调用 ooxml-ledger-mcp 脚本会导致 ENOENT——它位于项目虚拟环境中,不在 shell 的 PATH 里。
**
OOXML_LEDGER_ROOTS是安全边界。**这是一个以os.pathsep分隔的列表;任何工具接收的路径都会被解析为位于其中,路径在其外部时则会被拒绝。未设置时,默认使用服务的工作目录——请有意设置,因为export_receipt可以写入根目录内的任何位置。
工具
| 工具 | ||
|---|---|---|
| 会话 | open_document · close_document | 写入 |
| 读取 | describe_structure · find_text | 只读 |
| 编辑 | preview_edits · apply_edits · delete_paragraph · insert_paragraph | 写入 |
| 封存 | commit_document | 写入 · 执行门禁检查 |
| 无状态 | server_info · digest · verify · list_receipts | 只读 |
export_receipt | 写入 | |
| 传输 | import_document | 写入——仅写入 _inbox/ |
export_document | 只读 |
典型流程:
open_document → find_text → preview_edits → apply_edits → commit_document → verify
sid = open_document(document="report.docx")["session_id"]
find_text(sid, query="Q3 revenue") # → part, para_id, para_hash
preview_edits(sid, edits=[...], author="alice") # → what WOULD happen; writes nothing
apply_edits(sid, edits=[...], author="alice", mode="tracked")
commit_document(sid) # → refuses if anything is unaccounted for
verify("report.docx") # → verified | unknown | failed
preview_edits 会在临时副本上调用与 apply_edits 相同的引擎函数,因此二者的结果不会不一致。批量操作要么全部成功,要么全部失败:任何编辑失败,文档的字节内容都不会改变。
mode="tracked" 会生成 Word 修订标记,供审阅者在文档中查看。mode="direct" 则会直接重写文本,不带修订标记——但操作仍会被完整记录,收据也会披露直接编辑触及了支持修订的部分,因此它绝不会与普通保存悄然混为一谈。
聊天和托管客户端
上传到聊天中的文件位于客户端的沙盒中,而不是服务器的文件系统中,
因此 open_document 会正确拒绝该路径。扩大 OOXML_LEDGER_ROOTS 也无法访问它。
请改为发送文件字节:
import_document → open_document → … → commit_document → export_document
p = import_document(name="report.docx", content_base64="UEsDB…")["path"] # → <root>/_inbox/report.docx
sid = open_document(document=p)["session_id"]
... # edit as usual
commit_document(sid) # → receipt schema ooxml-ledger/2
export_document(document=p) # → file + receipt as embedded resources
- 文件存放位置。
import_document接受一个不带路径的文件名,并将文件写入第一个根目录下的_inbox/<name>。它绝不会覆盖现有文件,并会在发布任何内容之前验证这些字节是否构成真实的 Office 软件包。 - 大文件。 模型必须自行输出 base64,因此单次调用能够承载的数据远低于上限。请分块发送:
final=false会返回一个upload_id;后续分块使用该 ID 和offset(已接收的字节数);final=true调用必须包含整个文件的sha256。丢失或重复的分块会被拒绝,绝不会变成另一个文档。 - 大小上限。
OOXML_LEDGER_IMPORT_MAX_BYTES设置这两个工具接受的最大文档大小,以解码后的字节数计。默认值为 25 MiB。 - 来源证明。 此主机上导入文档的首批字节来自工具调用,而非用户的文件系统。因此,该文档沿袭中的每份回执都会以
ooxml-ledger/2格式封存,并包含一个绑定到链的provenance块(docs/superpowers/specs/receipt-format-v2.md)。verify会将其打印为一行PROVENANCE,且绝不会因此改变判定结果。其他所有文档的回执仍保持ooxml-ledger/1,与之前逐字节相同。 - 取回文件。
export_document会将文件作为 MCP 嵌入式资源返回,并附上其 Office 媒体类型和回执。默认情况下,如果没有匹配的已存储回执,它会拒绝该文档,因此未经封存的编辑绝不会被交付;传入require_receipt=false可覆盖此限制。
格式矩阵
| 格式 | 验证 | 编辑 |
|---|---|---|
Word .docx | 是 | 是 — 修订 + 直接编辑、段落插入/删除 |
PowerPoint .pptx | 是 | 仅直接编辑 — PresentationML 没有修订模型,因此每次编辑都必须附带披露 |
Excel .xlsx | 是 | 否 — 编辑操作会拒绝,并指出该格式 |
验证、摘要、门控和回执模型与格式无关。只有编辑引擎因格式而异:wml.py(Word)和 pml.py(PowerPoint)。
只读部署
OOXML_LEDGER_READ_ONLY=1 只保留以下工具:server_info、digest、verify、list_receipts、
export_document。
其他工具不只是被隐藏——调用时会返回 Unknown tool。根目录内完全没有写入接口。
CLI
ooxml-ledger verify report.docx # exit 0 only when verified
无需服务或会话——它会计算文件摘要,按内容地址查找其回执并进行检查。将其接入 CI 或提交前钩子,任何未记账的更改都会导致构建失败。
桌面应用捆绑包(.mcpb)
每个 GitHub Release 都会附带一个 .mcpb 文件,可一键安装到 Claude Desktop:将其拖到
应用上,Desktop 就会通过
uv run --directory <bundle> --frozen --no-dev ooxml-ledger-mcp
启动它。捆绑包不包含任何 vendored 内容——其中只有 manifest.json、pyproject.toml、uv.lock、
README.md、LICENSE 和 src/。主机需要在 PATH 中配置 uv,首次启动时
会从 PyPI 获取 uv.lock 锁定的确切依赖版本,这需要网络连接;
--frozen 表示只安装测试套件运行时使用的确切版本,不会重新解析依赖;--no-dev 则确保 dev 组(pytest、ruff、pre-commit)不会被安装。mcpb/manifest.json 将文档根目录和只读开关作为安装时设置公开,而非环境变量;工具列表与 stdio 服务的一致。
CI 仅在 macos-latest 上构建并对捆绑包进行冒烟测试,且清单的
compatibility.platforms 仅声明 darwin——该捆绑包只在
macOS/arm64 上构建并验证过,其他平台均未验证。 由于没有 vendored 内容,
uv 本身会选择满足 requires-python = ">=3.13" 的 Python,并为主机自身平台安装
uv.lock 锁定的 wheel——包括 pydantic-core 和 cryptography 等原生 wheel。这部分并非
darwin 专属,但这里只在 darwin 上端到端验证过启动流程。
明确的限制
- 未签名的收据只能发现意外改动,无法发现恶意篡改。 它能发现 Agent 退回到通用文件写入、经过 Office 往返处理或协作者疏忽等情况,但无法发现有人 连同文档一起重写收据。将其哈希锚定到持有人无法控制的位置(git 提交、DOI、提交门户),才能实现防篡改。
- 导入的来源记录保存在
_inbox/旁边。 导入记录存放在存储区中,与导入文件相邻。 如果在首次提交之前将该文件移出_inbox/,记录就会丢失,因此第一张收据会写为 v1。 提交之后,来源链会随收据存储区一起移动。来源记录记载的是收到的内容,并不证明其与用户的 原始上传一致:如果这点很重要,请另行比较其sha256。 - v0.3.0 验证器会拒绝
ooxml-ledger/2。 这是有意为之。它无法检查 genesis 规则,因此拒绝比悄然接受不理解的链更好。 verify从不重放。 它会检查摘要和收据的内部一致性;重放仅在提交时运行一次, 而verify会报告该次运行的判定,而不会重新计算。- pptx 和 xlsx 没有人类可见的记录。 Word 修订是文档内部的第二层记录;这两种格式没有这类记录,因此账本是唯一记录。
- Word 引擎只处理段落文本(
w:p/w:r/w:t)。样式、编号、 设置和关系均不可编辑,只由问责检查覆盖。
贡献与安全
CONTRIBUTING.md 介绍环境搭建、CI 强制执行的分支和提交命名规范, 以及发布流程。SECURITY.md 介绍私下报告漏洞的方式,并明确说明本项目所述的哪些限制属于设计选择,而非缺陷。
采用 MIT 许可证。设计说明和规范位于 docs/superpowers/。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。