mcpField
M
mcp-ooxml-ledger

mcp-ooxml-ledger

本地服务
github.com/Anselmoo生产力03 周前更新

关于 mcp-ooxml-ledger

mcp-ooxml-ledger 是用于编辑 Office 文档并记录每项修改的 MCP 服务,适合需要可核查文档变更的团队。提交前会重放记录的操作并与磁盘文件比对;无法解释的变更会导致提交被拒。

主要功能

  1. 01读取、查找和编辑 Office 文档
  2. 02提交前重放操作并核对文件
  3. 03批量编辑全成或全败
  4. 04生成并验证修改回执
  5. 05限制工具访问指定根目录
  6. 06支持 Word、PowerPoint 和 Excel 验证

适用场景

  1. 01审查并提交 Word 文档修改
  2. 02核验 Office 文件是否存在未记录变更
  3. 03通过 CI 或提交钩子检查文档回执
  4. 04导入、编辑并导出聊天中上传的文档

MCP 相关

该 MCP 服务向客户端提供文档读取、编辑、提交、验证和传输工具。文档可作为 MCP 内嵌资源导出,并可配置只读部署。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"anselmoo-mcp-ooxml-ledger": {
"command": "uvx",
"args": [
"mcp-ooxml-ledger"
]
}
}
}
启动命令uvx mcp-ooxml-ledger

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
pypimcp-ooxml-ledger0.3.0
ocighcr.io/anselmoo/mcp-ooxml-ledger:0.3.0

工具

14

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

mcp-ooxml-ledger

CI codecov PyPI TestPyPI Python License: MIT MCP

一个可编辑 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/。

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。