mcpField
V
verified-googledocs-mcp

verified-googledocs-mcp

本地服务
github.com/michaelrobertsutton生产力011 周前更新

关于 verified-googledocs-mcp

verified-googledocs-mcp 是面向文档自动化的 Google Docs MCP 服务,提供读取、编辑、评论和导出工具。它的特点是编辑后重新读取文档,并返回变更证据及修订版本信息。

主要功能

  1. 01提供 20 个文档操作工具
  2. 02写入后重新读取并验证
  3. 03编辑时要求指定标签页
  4. 04检查匹配数量并支持规范化搜索
  5. 05支持编辑预演与 JSONL 审计日志

适用场景

  1. 01替换文档文本并核对结果
  2. 02将 Markdown 内容写入文档标签页
  3. 03检查并处理评论和待处理建议
  4. 04比较文档标签页与本地文件

MCP 相关

该项目通过 MCP 暴露 20 个 Google Docs 工具,涵盖读取、编辑、评论、同步和 PDF 导出。变更操作会在写入后重新读取内容,并返回验证结果。

配置

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

mcp.json · 通用配置
{
"mcpServers": {
"michaelrobertsutton-verified-googledocs": {
"command": "uvx",
"args": [
"verified-googledocs-mcp"
],
"env": {
"VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS": "<VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS>",
"VERIFIED_GOOGLEDOCS_MCP_AUDIT_EXCERPTS": "<VERIFIED_GOOGLEDOCS_MCP_AUDIT_EXCERPTS>"
}
}
}
}
启动命令uvx verified-googledocs-mcp
需要配置的环境变量
VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS密钥Path to the OAuth client-secret JSON. Defaults to ~/.config/verified-googledocs-mcp/credentials.json.
VERIFIED_GOOGLEDOCS_MCP_AUDIT_EXCERPTSSet to a falsey value (0/false/no/off) to redact before/after content excerpts from the local audit log.

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

安装包
pypiverified-googledocs-mcp0.1.0

工具

14

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

参数类型必填说明
doc_idstring是

详细介绍

verified-googledocs-mcp

CI Coverage Python 3.12+ License: MIT

一个用于 Google Docs、写入操作带有验证证明的 MCP 服务。每个修改工具都会在写入后重新读取文档中的受影响内容,并返回实际变更的证据:变更前后的摘录、匹配数量,以及变更前后的文档修订版本。工具绝不会将未成功应用的编辑报告为成功。

**状态:**全部 20 个工具均已实现,并通过离线单元测试套件覆盖,也由实时测试套件针对真实的 Google Docs 和 Drive API 进行测试。最初的 14 个工具已通过正式的实时验收关卡;每次发布前都会重新运行该关卡。使用 uvx verified-googledocs-mcp 安装。参见状态。

问题

通过通用 Workspace MCP 服务,让 Agent 操作 Google Docs 往往会以悄无声息却代价高昂的方式失败:

  • 原本只针对一个标签页的 findAndReplace,却悄悄修改了文档中的所有标签页。
  • 查询因为文档使用了弯引号或不换行空格,而查询中没有,结果返回“0 个匹配项”,却没有任何原因提示。
  • 原本只替换一处的操作,命中了重复句子并将两处都替换。
  • “resolve comment”调用返回成功,但评论仍处于未解决状态。
  • 列出评论时完全漏掉建议的修改。
  • 合并 Markdown 后插入乱码,直到几天后才被人发现。

这些情况各有一个流程上的变通方法:告诉 Agent 将操作限定在某个标签页、用规范化的引号重试、每次写入后重新读取,以及绝不轻信解决评论的结果。这些指示在有人忘记其中一条之前都有效。此服务将这些规范落实到协议中,确保执行过程具有确定性。

可验证写入约定

每个修改工具都会运行相同的流程:读取标签页、定位目标、在修订版本前置条件下应用编辑、再次读取标签页,并根据第二次读取的内容返回证据。返回值声明的是调用之后文档的状态,且由服务端重新读取的数据提供支持,而不是 API 响应的回显。

// replace_text(doc_id, tab_id, find="teh", replace="the", expected_matches=1)
{
  "applied": true,
  "match_count": 1,
  "rung": "exact",                 // which normalization rung matched
  "before": "...±200 chars around the edit, pre-write...",
  "after":  "...the same span, re-read after the write...",
  "revision_before": "ALm37BX...",
  "revision_after":  "ALm37Cy...",
  "audit_logged": true
}

出现问题时,工具会明确报错并给出诊断信息,使用 Agent 可以在一次往返中处理的类型化错误,而不是让它猜测:

{
  "error_code": "MATCH_COUNT_MISMATCH",
  "message": "expected 1 match(es) but found 3 at rung 'exact'",
  "diagnostics": { "expected": 1, "actual": 3, "spans": [ /* every location */ ] },
  "retryable": false
}
保证的依据
  • **默认限定标签页。**编辑工具必须指定 tab_id。没有针对整个文档的替换操作,因此只编辑一个标签页绝不会影响封面信或附录标签页。
  • **规范化阶梯。**搜索会依次尝试精确匹配、弯引号与直引号等价匹配、不换行空格与空白字符序列等价匹配,然后尝试去除软连字符,并报告命中了哪一级。匹配数为 0 时,结果会包含找到的最接近的近似匹配片段。
  • 匹配数量保护。expected_matches 默认为 1。如果实际数量不同,工具不会进行编辑,并会返回所有匹配位置。
  • **修订版本前置条件。**写入会携带预读取时的 writeControl.requiredRevisionId,因此,如果文档在操作期间发生变化,API 会拒绝此次操作,而不会盲目编辑。find_sections 返回的章节范围会标记计算时的修订版本;一旦过期,就会拒绝应用。
  • **UTF-16 精确处理。**匹配片段会映射到 Docs API 使用的 UTF-16 代码单元索引,因此表情符号、组合标记及其他扩展平面字符不会导致编辑偏移到错误的文本。
  • **审计跟踪。**每次修改都会向本地 JSONL 日志追加一行。追加操作尽力而为:绝不会导致写入失败;如果无法写入,证据会注明这一点(audit_logged: false)。
按类别提供的证据

保证并非适用于所有情况的统一载荷,而是针对每个类别的不变量。每个类别都会在写入后重新读取文档,并验证其负责的属性。每个修改工具还会包含 revision_before、revision_after 和 audit_logged。

类别工具验证内容
文本编辑replace_textmatch_count 等于 expected_matches;rung 指明匹配时使用的规范化轮次;before/after 是编辑范围前后各 ±200 个字符的摘录,其中 after 是写入后重新读取的内容
样式编辑format_textruns_before/runs_after——与每个匹配范围重叠的实际 textRun 样式标志,而非文本差异;compiled_request_kinds 仅包含 updateTextStyle,由此证明 content_mutated: false;幂等重跑时 style_mutated 为 false(不会发出写入请求)
Markdown 范围replace_range_markdown、replace_tab_markdown、append_markdownstructural_match(写入的 Markdown 经往返转换后保持一致,包括列表嵌套深度、有序与无序列表之分,以及链接目标)、input_blocks 与 post_blocks 的数量,以及列出任何不匹配项的 structural_diff 列表;每个响应还会包含 write_status(not_written / written_unverified / written_verified)和 retry_safe
结构操作insert_imageinline_object_confirmed——写入后扫描发现锚点段落中存在内嵌对象
评论状态add_anchored_comment、reply_to_comment、resolve_comment重新查询的 resolved 标志、reply_count、content、quoted_text 和 author——如果评论未成功解决,则返回 COMMENT_STILL_OPEN,绝不会报告成功
表格replace_table_row、insert_tablereplace_table_row:重新读取 row_before/row_after,并附带 cells_match;insert_table:table_confirmed,以及已确认的维度和 first_row

读取和同步工具(read_document、list_tabs、find_sections、 list_open_items、get_comment_thread、diff_tab_vs_file、list_tables、 get_table)不会进行更改,也不包含 applied/证据载荷。 export_pdf 在此意义上也是读取/导出工具——它返回文件信息 (bytes_written、sha256、page_count),而非 applied 键,因为 文档内容不会发生变化。

干运行

八个会修改内容的工具(replace_text、format_text、replace_range_markdown、 replace_tab_markdown、append_markdown、insert_image、replace_table_row、 insert_table)支持 dry_run=true。不会发出 API 写入请求;响应包含 applied: false、空的 revision_after(没有写入,因此不会产生新修订版本)、audit_logged: false,并且对于 replace_text,还会包含通过将替换内容拼接到预读内容中计算出的预测 after 摘录;对于 format_text,则会包含通过将请求的样式叠加到预读 runs 上计算出的预测 runs_after。此外,无论是否启用干运行,只要匹配文本已经具备所有请求的样式值,format_text 就不会发出写入请求——这是该工具常规的幂等无操作路径,并非 dry_run 特有。对于 replace_table_row 和 insert_table,dry_run 对索引有效性具有权威性:无论 dry_run 为 true 还是 false,都会对组装后的同一请求列表进行索引模拟,因此干运行通过始终意味着实际写入也会通过。可用它确认定位结果解析到了正确范围,再提交编辑。

对于三个 markdown 工具,dry_run 对结构预测也具有权威性(issue #65):在执行任何 batchUpdate 之前,都会将编译后的请求自行预测出的块结构——嵌套、有序或无序列表、标题、表格——与解析后的输入 markdown 进行比较;干运行和实际写入的行为完全相同。如果不匹配,就会在触及文档之前以 STRUCTURE_PREDICTION_FAILED 拒绝,而不是先修改文档,再发现写入后验证失败。这三个工具的每个响应——干运行、拒绝或已写入——都会包含 write_status,其值为 not_written(干运行,或预检拒绝:INDEX_SIMULATION_FAILED、STRUCTURE_PREDICTION_FAILED 或结构丢失防护)、written_unverified(已发送并接受 batchUpdate,但写入后的重新读取未能确认内容匹配——VERIFICATION_FAILED),或 written_verified(已确认);此外还会包含布尔值 retry_safe(仅当状态为 written_unverified 时为 false,因为如果修改状态尚未确认,调用方重试可能会在第一次修改尚未确认的情况下再次修改;不会自动回滚——Docs 没有修订版本恢复端点,而补偿性 markdown 重写本身也可能造成数据丢失,因此 needs_manual_restore: true 仍表示需要从 Docs 版本历史记录中恢复)。write_status/retry_safe 是新增字段:原有的 applied 字段仍保持其已说明的含义不变。

所有八个工具都要求目标标签页没有建议。 每个会修改内容的工具都会基于 suggestionsViewMode=PREVIEW_WITHOUT_SUGGESTIONS 读取内容来计算写入索引,但实际写入始终使用文档的真实索引空间,其中包含待处理的建议。如果目标标签页有待处理的建议插入或删除,这两个索引空间就会出现偏差,导致写入落在错误偏移处——因此,每个会修改内容的工具都会以 SUGGESTIONS_PRESENT 拒绝(干运行和实际写入时均如此),避免发生悄无声息的错误偏移写入(issue #56)。请先在 Docs 界面中接受或拒绝待处理的建议,然后重试。

工具

20 个用途明确的工具,每个工具都说明了适用场景。它们取代了 Workspace 服务端 150 个工具中实际会用于文档工作流的那部分。

读取与结构
工具功能
read_document将标签页读取为 markdown、结构化位置和样式 runs,或仅含标题的大纲
list_tabs列出标签页 ID、标题和嵌套关系
find_sections查找标题并返回其范围,同时标记文档修订版本
list_tables列出标签页中的所有顶层表格,包括位置、大小和前置标题上下文
get_table读取一个表格的完整单元格网格
编辑(已验证,限定于单个标签页)
工具功能
replace_text在一个标签页内查找并替换,支持规范化阶梯和匹配保护
format_text仅通过 updateTextStyle 对匹配的文本范围应用粗体/斜体/下划线——不修改内容,可安全用于合并单元格表格
replace_range_markdown用 Markdown 替换一个区域
replace_tab_markdown用 Markdown 替换整个标签页的内容
append_markdown在标签页中追加 Markdown
insert_image在引用的锚点或标题处插入图片
replace_table_row在原位置用纯文本单元格覆盖现有表格的一行
insert_table根据行数据插入新表格,锚定方式与 insert_image 相同
评论和建议
工具功能
list_open_items列出未解决的评论以及待处理的建议修改;传入 tab_id 或 include_all_tabs=true
get_comment_thread查看评论的完整回复链
add_anchored_comment在引用的文本处添加评论
reply_to_comment回复评论
resolve_comment解决评论、重新查询并确认它确实已关闭
同步和导出
工具功能
diff_tab_vs_file比较标签页的 Markdown 与本地文件
export_pdf将整个文档导出为 PDF 到本地路径,并尽力根据渲染结果测算页数

状态

逐步构建;每个工具都附带验证和测试,而非仅提供空壳。

区域状态
OAuth(verified-googledocs-mcp auth)、令牌缓存已完成
read_document、list_tabs、find_sections已完成
验证内核(定位器、错误封装、审计)已完成
replace_text(已验证)+ 强制执行中间件已完成
评论工具 + list_open_items已完成
Markdown 写入工具 + diff_tab_vs_file已完成
表格工具(list_tables、get_table、replace_table_row、insert_table)+ export_pdf已完成;随 0.2.0 发布
format_text(仅样式的已验证编辑)已完成;随 0.2.0 发布
实时验收门槛首次发布已完成——报告;发布前重新运行
PyPI 打包 + 发布工作流已完成;首个版本为 v0.1.0
MCP 注册表条目已随 v0.1.0 发布

安装

该服务使用你自己的 OAuth 凭据与 Google 通信,因此只需一次性完成 Google Cloud 设置,然后将服务注册到你的 MCP 客户端。

1. Google Cloud 项目(OAuth 凭据)
  1. 创建 Google Cloud 项目,并启用 Google Docs API 和 Google Drive API(API 和服务 → 库)。
  2. 配置 OAuth 同意屏幕:用户类型选 External,发布状态选 Testing,并在 Test users 下添加你自己的 Google 账号。(测试模式正是此处所需——应用仅对你列出的测试用户开放;无需提交给 Google 验证。)
  3. 创建类型为 Desktop app 的 OAuth client ID,并将客户端密钥 JSON 下载到 ~/.config/verified-googledocs-mcp/credentials.json。(使用 VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS 覆盖此位置。)
2. 在终端中授权一次
uvx verified-googledocs-mcp auth

这会打开浏览器并完成授权。由于应用未经验证且处于测试模式,Google 会显示 “Google hasn’t verified this app” 屏幕——点击 Advanced → Go to verified-googledocs-mcp (unsafe) 并继续。对于个人桌面客户端,这是预期行为;你授予的是自己拥有的应用的访问权限,该应用以你的身份在本地运行。随后,系统会在 ~/.config/verified-googledocs-mcp/token.json 缓存可刷新的令牌。授权只在此处运行,不会在服务内部运行,因为 MCP 客户端会以无头模式启动服务。

3. 运行
uvx verified-googledocs-mcp           # downloads + runs in one step
# or: pip install verified-googledocs-mcp

然后将服务注册到你的 MCP 客户端。

从源代码运行。 若要从本地克隆运行:

git clone https://github.com/michaelrobertsutton/verified-googledocs-mcp
cd verified-googledocs-mcp
uv run verified-googledocs-mcp
Claude Code

仓库中包含项目本地的 .mcp.json。克隆并打开项目后,Claude Code 会自动加载它,无需手动配置:

git clone https://github.com/michaelrobertsutton/verified-googledocs-mcp
cd verified-googledocs-mcp
claude  # .mcp.json is loaded automatically

在所有项目中使用(用户范围)。 在用户范围内注册一次:

claude mcp add verified-googledocs-mcp --scope user -- uvx verified-googledocs-mcp

这会写入 ~/.claude.json,让此服务在这台机器上的每个 Claude Code 会话中都可用。如果 Claude Code 的 PATH 中没有 uvx,请使用完整路径(通过 which uvx 查找)。

Claude Desktop 和其他客户端

大多数客户端使用标准的 mcpServers 配置块。将以下内容添加到客户端的配置文件中:

{
  "mcpServers": {
    "verified-googledocs-mcp": {
      "command": "uvx",
      "args": ["verified-googledocs-mcp"]
    }
  }
}

无头客户端的 PATH 说明: Claude Desktop 和类似客户端会以子进程的方式启动服务,并使用精简的 PATH,其中可能不包含 Homebrew 或用户本地的二进制文件。如果找不到 uvx,请使用其完整路径("command": "/opt/homebrew/bin/uvx")。通过 which uvx 查找。在 Apple Silicon 上,Homebrew 前缀是 /opt/homebrew;在 Intel Mac 上是 /usr/local。

启动超时说明。 首次启动 uvx 时会下载软件包及其依赖项,可能超过客户端的 MCP 启动超时时间,导致连接失败。请在终端中运行一次 auth 命令(uvx verified-googledocs-mcp auth)来预热缓存——无论如何你都需要执行此操作,而且它会将软件包安装到 uvx 缓存中,让客户端快速启动。

从源码运行。 如果你更喜欢从本地克隆运行,而不是使用 PyPI:

{
  "mcpServers": {
    "verified-googledocs-mcp": {
      "command": "/opt/homebrew/bin/uv",
      "args": ["run", "verified-googledocs-mcp"],
      "cwd": "/path/to/verified-googledocs-mcp"
    }
  }
}

日志 / stderr。 服务会将日志写入 stderr,MCP 客户端会捕获这些日志,而不是直接显示。如果连接或工具调用失败,请检查客户端的 MCP 日志;对于 macOS 上的 Claude Desktop,日志位于 ~/Library/Logs/Claude/mcp*.log。如果其中出现 AUTH_EXPIRED 信封,则表示令牌缺失或已过期;请重新运行 auth 命令。

此服务使用 documents 和 drive 范围(评论需要 Drive)。可通过 VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS 覆盖凭据路径。

安全与权限

这是一个单用户本地服务。它以你的身份运行,通过 stdio 启动,并由 MCP 客户端调用;它不会监听网络、不会托管,也不共享凭据。它完全使用你自己的 Google 权限。

  • 权限范围。 它请求 documents 和 drive 权限。完整的 drive 权限范围比单纯编辑所需的更广,但评论和建议工具(列出、回复和解决你已有文档中的评论)通过 Drive API 操作任意已有文件,而范围更窄的 drive.file 无法访问这些文件。drive 是涵盖完整工具集所需的最小范围;如果不需要评论工具,可以通过分支改用更窄的权限范围。
  • 静态凭据。 OAuth 客户端密钥存放在 ~/.config/verified-googledocs-mcp/credentials.json;缓存的令牌(包括刷新令牌)写入 ~/.config/verified-googledocs-mcp/token.json,权限仅限所有者访问(0600,所在目录权限为 0700)。请将两者都视为机密:一旦刷新令牌泄露,在你通过 Google 帐户的安全设置撤销之前,泄露者就能获得你完整的 drive+documents 访问权限。这两个文件都不会被提交(均已加入 gitignore)。
  • 审计日志。 每次修改都会追加记录到 ~/.local/state/verified-googledocs-mcp/audit.jsonl(权限同样为 0600)。每行记录时间戳、文档 ID、标签 ID、工具名称和证据负载,其中包括修改前后内容摘录。若要只记录元数据而不记录摘录,请将环境变量 VERIFIED_GOOGLEDOCS_MCP_AUDIT_EXCERPTS 设为假值(0、false、no 或 off);此时 before/after 字段会替换为 "[redacted; N chars]",其他字段均会保留。可通过 XDG_STATE_HOME 覆盖日志位置。
  • 本地文件差异。 diff_tab_vs_file 会读取本地文件,以便将 Doc 标签页与磁盘上的 Markdown 进行比较。读取前会解析符号链接,并且只允许访问 VERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTS 下的路径(平台对应的路径列表;默认值为用户的主目录,而不是服务进程的工作目录)。默认使用主目录,是因为 MCP 客户端通常会将此服务固定注册到某个仓库(例如 --directory /path/to/GoogleDocs-MCP),而差异比较的目标通常位于调用者实际工作的另一个项目中——若将范围限定为启动目录,默认情况下所有跨仓库差异比较都会失败。可进一步缩小范围(例如恢复为单个仓库),也可在服务进程中设置 VERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTS,将范围扩大为以 : 分隔的目录列表(Windows 上使用 ;),然后重启服务——对于被拒绝的路径,错误信息会指出环境变量名称,并包含当前配置的 allowed_roots,便于你确切了解缺少什么。此限制仍是一条实际边界,并非不受限制:若 Agent 请求与 /etc/passwd 或其他用户的主目录进行差异比较,系统会拒绝。默认允许访问整个主目录,也意味着必须防止文档内容诱骗 Agent 读取凭据(提示词注入)——例如某段文字指示“与 ~/.ssh/id_rsa 进行差异比较”。因此,主目录下的 .ssh、.aws、.gnupg、.netrc、.git-credentials、.config/gh、.docker/config.json 和 .npmrc 始终会被列入拒绝名单,不受已配置的允许根目录影响。超过 VERIFIED_GOOGLEDOCS_MCP_MAX_DIFF_FILE_BYTES 大小的文件也会被拒绝(默认值为 1000000)。export_pdf 的输出路径也受同一策略约束——使用相同的 VERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTS 允许列表和相同的凭据路径无条件拒绝名单,因此 PDF 导出也无法保存到 ~/.ssh 中或覆盖其中的文件。

错误代码

失败时会返回一个类型化封装(error_code、message、diagnostics、retryable):

代码含义
ZERO_MATCH完整规范化流程后仍未找到目标;诊断信息包含最接近的近似匹配项
MATCH_COUNT_MISMATCH找到的数量与 expected_matches 不同;未进行任何编辑;返回所有位置
REVISION_CONFLICT文档在读取和写入之间发生了更改;请重新读取后重试
VERIFICATION_FAILED已发出写入请求,但写入后的重新读取未能验证预期的最终状态
STALE_RANGE文档发生变化后仍使用了 find_sections 返回的范围;请重新运行 find_sections
TAB_NOT_FOUNDtab_id 未知;已列出可用标签页
STRUCTURAL_BOUNDARY匹配内容跨越了段落或表格单元格边界
UNSUPPORTED_MARKDOWNMarkdown 超出支持的子集;已指出不受支持的结构
QUOTE_NOT_FOUND未找到评论锚定文本;已返回最接近的候选项
COMMENT_STILL_OPEN请求了解决评论,但重新查询后发现评论仍处于打开状态
INVALID_INPUT参数为空或相互矛盾
IMAGE_SOURCE_UNSUPPORTED图片来源是本地路径;必须使用可获取的 URL
AUTH_EXPIRED没有有效令牌;请运行 verified-googledocs-mcp auth
INDEX_SIMULATION_FAILEDMarkdown 写入编译后的请求会落在无效索引处;在 API 调用前捕获。dry_run 和实际写入会以相同方式引发此错误,因此 dry_run 通过始终意味着写入也会通过
TABLE_NOT_FOUND标签页中不存在指定的 table_index;请先调用 list_tables
SUGGESTIONS_PRESENT目标标签页存在待处理的建议插入或删除;写入会拒绝操作,而不是基于错误的索引空间计算索引(问题 #56)——请先接受或拒绝这些建议,再重试
INVALID_RANGE调用方提供的范围超出标签页当前范围,或 Docs API 本身因索引/范围无效而拒绝了写入(其中包含 API 返回的原始消息)
INDEX_MODEL_DIVERGENCE文本运行的计算 UTF-16 长度与 Docs API 报告的 endIndex 不一致;无法信任该次读取的偏移量
STRUCTURE_PREDICTION_FAILEDMarkdown 写入编译后的请求无法生成与输入相同的块结构(嵌套、有序与无序列表、标题、表格)——在 API 调用前,通过预测这些请求自身的效果并与解析后的输入进行比较来捕获(问题 #65)。dry_run 和实际写入会以相同方式引发此错误,因此 dry_run 通过始终意味着写入也会通过验证

开发

uv run --extra dev pytest                 # unit tests (offline) + coverage
uv run --extra dev ruff check src tests   # lint
uv run --extra dev ruff format src tests  # format
uv run --extra dev mypy src               # type check

单元测试使用合成的 Docs API 固件和内存中的 MCP 客户端运行,因此完整测试套件可离线运行(不会运行实时测试)。实时验收测试套件(位于 tests/live/ 下)通过 pytest tests/live --run-live 针对真实的临时文档运行,需要 OAuth 凭据;它是发布前的关卡,不会在 CI 中运行——请参阅 docs/acceptance-report.md。

模块概览和验证流程请参阅 docs/architecture.md,完整规范请参阅 PRD.md,从通用 Workspace MCP 服务迁移的说明请参阅 docs/cutover.md,在此基础上进行构建请参阅 CONTRIBUTING.md。

限制

  • 无法接受或拒绝建议的编辑:通过普遍可用的 Google Docs API 无法执行此操作。此服务会将建议与评论一同显示;是否采纳仍需在 Docs 界面中手动操作。截至 2026 年 7 月,Google 记录了接受、拒绝或删除建议的请求,但仅适用于 Workspace Developer Preview Program;稳定版 v1 接口会拒绝这些请求(已于 2026-07-17 验证)。待该功能正式发布后,经过验证的 accept_suggestion/reject_suggestion 工具即可构建。
  • **仅限单用户、本地使用。**采用 stdio 传输方式,缓存一个令牌,不提供托管模式或多用户模式。
  • **仅支持 Docs。**Gmail、Calendar 和 Sheets 按设计不在范围内。
  • Markdown 仅支持固定子集(标题、粗体/斜体、列表、表格、链接)。不在此范围内的内容会被拒绝,并给出明确错误,而不会尝试近似处理。

许可证

MIT,© 2026 Michael Sutton。

评论

支持 Markdown

第一次接触 MCP?

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

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