
Verified Googledocs Mcp
io.github.michaelrobertsutton由 GitHub 账号 michaelrobertsutton 发布v0.1.0更新于 Oct 27, 2026
MCP server for Google Docs with verified writes — every mutation returns before/after proof.
发布方自己的服务:verified.fyi
概览
面向 Google Docs 的本地 MCP 服务器,写入带验证:每次修改后重新读取文档并返回前后对照证据。
- 可以做什么
- 以 Markdown、结构化位置或大纲形式读取文档、标签页、标题、章节和表格
- 按标签页范围执行文本、样式、Markdown 区间、整页、图片和表格行的可验证编辑
- 通过试运行预览编辑,在真正写入前预测结果片段或结构
- 列出、读取、添加、回复和解决评论及待处理的建议修改
- 将标签页与本地 Markdown 文件比对,并把文档导出为 PDF
- 适用场景
- 适合需要助手可靠地修改 Google Docs、并希望获得每次改动确实生效的证据,而不是仅凭 API 成功返回的场景。适用于单用户本地文档工作流,尤其是改错标签页或匹配数量出错代价较高的情况。
- 运行要求
- 通过 uvx 以 stdio 在本地运行(Python 包)。需要自备 Google Cloud OAuth 桌面客户端密钥 JSON,启用 Docs 与 Drive API 并将自己的账号加入测试用户;路径由 VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS 指定。需一次性在浏览器中授权以缓存令牌,并需要访问 Google API 的网络。
安装
在 SourceWeft 中
- 打开 控制台中的 Verified Googledocs Mcp,将其添加到工作区。
- 为需要使用其工具的对话启用该服务。
Desktop only,通过 STDIO。 STDIO 服务会启动本地进程,因此需要 SourceWeft 桌面宿主。
其他 MCP 客户端
参照 仓库 中的启动说明。
README
verified-googledocs-mcp
[CI] [Coverage] [Python 3.12+] [License: MIT]
An MCP server for Google Docs whose writes carry proof. Every mutating tool re-reads the affected content from the document after it writes and returns evidence of what actually changed: before/after excerpts, the match count, and the document revision before and after. A tool never reports success for an edit that did not land.
Status: all 20 tools are implemented, covered by an offline unit suite, and exercised against the real Google Docs and Drive APIs by the live test suite. The original fourteen passed the formal live acceptance gate; the gate is rerun before each release. Install with
uvx verified-googledocs-mcp. See Status.
The problem
Driving Google Docs from an agent through a general Workspace MCP server tends to fail in quiet, expensive ways:
- A
findAndReplacemeant for one tab silently edits every tab in the document. - A search returns "0 matches" because the document has curly quotes or a non-breaking space the query doesn't, with no hint why.
- A replace meant for one occurrence hits a repeated sentence and collapses both.
- A "resolve comment" call returns success while the comment stays open.
- Listing comments misses suggested edits entirely.
- A markdown merge injects garbled text that a human only catches days later.
Each of these has a procedural workaround: tell the agent to scope to a tab, retry with normalized quotes, re-read after every write, never trust a resolve result. Those instructions work until someone forgets one. This server moves the discipline into the protocol, where it is deterministic.
The verified-write contract
Every mutating tool runs the same pipeline: read the tab, locate the target, apply the edit under a revision precondition, read the tab again, and return evidence built from the second read. The return value is a claim about the document's state after the call, backed by a server-side re-read, not an echo of the API response.
When something is wrong, the tool fails loud and diagnosed, with a typed error the agent can act on in one round trip rather than guessing:
What backs the guarantee
- Tab-scoped by default. Editing tools require an explicit
tab_id. There is no whole-document replace, so a one-tab edit can never leak into a cover letter or an appendix tab. - Normalization ladder. A search tries exact match, then curly/straight quote equivalence, then non-breaking-space and whitespace-run equivalence, then soft-hyphen stripping, and reports which rung matched. A zero-match result includes the nearest near-miss span it found.
- Match-count guard.
expected_matchesdefaults to 1. If the real count differs, the tool makes no edit and returns every match location. - Revision preconditions. Writes carry
writeControl.requiredRevisionIdfrom the pre-read, so a document that changed underneath the operation is rejected by the API rather than edited blind. Section ranges fromfind_sectionsare stamped with the revision they were computed at and refuse to apply once stale. - UTF-16 correct. Match spans are mapped to the UTF-16 code units the Docs API indexes by, so emoji, combining marks, and other astral characters don't shift an edit onto the wrong text.
- Audit trail. Every mutation appends a line to a local JSONL log. The append is best-effort: it never fails a write, and if it can't be written the evidence says so (
audit_logged: false).
Evidence by family
The guarantee is not one universal payload — it is a per-family invariant. Each
family re-reads the document after the write and proves the property that family
is responsible for. Every mutating tool also carries revision_before,
revision_after, and audit_logged.
The read and sync tools (read_document, list_tabs, find_sections,
list_open_items, get_comment_thread, diff_tab_vs_file, list_tables,
get_table) make no changes and carry no applied/evidence payload.
export_pdf is also a read/export tool in this sense — it returns file facts
(bytes_written, sha256, page_count) rather than an applied key, since
nothing in the document changes.
Dry run
Eight mutating tools (replace_text, format_text, replace_range_markdown,
replace_tab_markdown, append_markdown, insert_image, replace_table_row,
insert_table) accept dry_run=true. No API write is issued; the response
carries applied: false, an empty revision_after (no write, so no new
revision), audit_logged: false, and — for replace_text — a predicted
after excerpt computed by splicing the replacement into the pre-read, or —
for format_text — a predicted runs_after computed by overlaying the
requested style onto the pre-read runs. format_text additionally never
issues a write at all when the matched text already carries every requested
style value, dry run or not — that's the tool's normal idempotent no-op path,
not specific to dry_run. For replace_table_row and insert_table,
dry_run is authoritative for index validity: the same assembled request
list is index-simulated whether dry_run is true or false, so a passing dry
run always means the real write will pass too. Use it to confirm a locate
resolves to the right span before committing the edit.
For the three markdown tools, dry_run is also authoritative for
structure prediction (issue #65): before any batchUpdate, the compiled
requests' own predicted block structure — nesting, ordered-vs-unordered,
headings, tables — is compared against the parsed input markdown, identically
in dry_run and the real write. A mismatch refuses with
STRUCTURE_PREDICTION_FAILED before the document is touched, rather than
mutating it and only then discovering post-write verification would have
failed. Every response from these three tools — dry run, refused, or
written — carries write_status, one of not_written (dry run, or a
pre-flight refusal: INDEX_SIMULATION_FAILED, STRUCTURE_PREDICTION_FAILED,
or the structural-loss guardrail), written_unverified (a batchUpdate was
sent and accepted, but the post-write re-read did not confirm it matched —
VERIFICATION_FAILED), or written_verified (confirmed) — plus a
retry_safe boolean (false only for written_unverified, since a caller
that retries a call whose mutation status is unconfirmed risks a second
mutation on top of an unconfirmed first one; there is no automatic rollback —
Docs has no revision-restore endpoint, and a compensating markdown rewrite
would itself be lossy, so needs_manual_restore: true still means restoring
from Docs version history). write_status/retry_safe are additive: the
pre-existing applied field keeps its documented meaning unchanged.
All eight require a suggestion-free target tab. Every mutating tool
computes its write indices against a suggestionsViewMode=PREVIEW_WITHOUT_SUGGESTIONS
read, but the actual write always lands in the document's real index space,
which includes pending suggestions. If the target tab has a pending
suggested insertion or deletion, those two index spaces diverge and a write
would land at the wrong offset — so every mutating tool refuses with
SUGGESTIONS_PRESENT instead (both in dry_run and live), rather than
risking a silent, wrong-offset write (issue #56). Accept or reject the
pending suggestion in the Docs UI first, then retry.
Tools
Twenty focused tools, each described by when to reach for it, replace the slice of a 150-tool Workspace server that document workflows actually use.
Reading and structure
Editing (verified, tab-scoped)
Comments and suggestions
Sync and export
Status
Built incrementally; each tool ships with its verification and tests rather than as a stub.
Install
The server talks to Google with your own OAuth credentials, so setup is a one-time Google Cloud step, then registering the server with your MCP client.
1. Google Cloud project (OAuth credentials)
- Create a Google Cloud project and enable the Google Docs API and Google Drive API (APIs & Services → Library).
- Configure the OAuth consent screen: User type External, publishing status Testing, and add your own Google account under Test users. (Testing mode is the point — the app stays private to the test users you list; you never submit it for Google verification.)
- Create an OAuth client ID of type Desktop app and download the client secret JSON to
~/.config/verified-googledocs-mcp/credentials.json. (Override the location withVERIFIED_GOOGLEDOCS_MCP_CREDENTIALS.)
2. Authorize once, in a terminal
This opens a browser and completes consent. Because the app is unverified and in
Testing, Google shows a "Google hasn't verified this app" screen — click
Advanced → Go to verified-googledocs-mcp (unsafe) and continue. This is
expected for a personal Desktop client; you are granting access to your own app,
running locally as you. It then caches a refreshable token at
~/.config/verified-googledocs-mcp/token.json. Auth runs only here, never inside
the server, because MCP clients start the server headless.
3. Run it
Then register the server with your MCP client.
From source. To run from a local clone instead:
Claude Code
A project-local .mcp.json is included in the repo. Clone and open the project and Claude Code picks it up automatically — no manual config required:
Use it across all your projects (user scope). Register it once at user scope:
This writes to ~/.claude.json and makes the server available in every Claude Code session on this machine. If uvx is not on Claude Code's PATH, use the full path (find it with which uvx).
Claude Desktop and other clients
Most clients use the standard mcpServers config block. Add the following to your client's config file:
PATH note for headless clients: Claude Desktop and similar clients launch the server as a subprocess with a minimal PATH that may not include Homebrew or user-local bins. If uvx is not found, use its full path ("command": "/opt/homebrew/bin/uvx"). Find it with which uvx. On Apple Silicon the Homebrew prefix is /opt/homebrew; on Intel Mac it is /usr/local.
Startup-timeout note. The first uvx launch downloads the package and its dependencies, which can exceed a client's MCP startup timeout and surface as a failed connection. Pre-warm the cache once in a terminal by running the auth command (uvx verified-googledocs-mcp auth) — you do this anyway, and it installs the package into the uvx cache so the client's launch is fast.
From source. If you prefer to run from a local clone instead of PyPI:
Logs / stderr. The server logs to stderr, which MCP clients capture rather than show inline. If a connection or a tool call fails, check the client's MCP logs — for Claude Desktop on macOS, ~/Library/Logs/Claude/mcp*.log. An AUTH_EXPIRED envelope there means the token is missing or expired; re-run the auth command.
The server uses the documents and drive scopes (comments require Drive). The credentials path is overridable with VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS.
Security and permissions
This is a single-user, local server. It runs as you, over stdio, launched by your MCP client; there is no network listener, no hosted service, and no shared credentials. It acts entirely with your own Google authority.
- Scopes. It requests
documentsanddrive. The fulldrivescope is broader than editing alone needs, but the comment and suggestion tools (listing, replying to, and resolving comments on documents you already have) operate through the Drive API on arbitrary existing files, which the narrowerdrive.filescope cannot reach.driveis the minimum that covers the full tool set; if you don't need the comment tools, a fork could drop to a narrower scope. - Credentials at rest. The OAuth client secret lives at
~/.config/verified-googledocs-mcp/credentials.json; the cached token (including the refresh token) is written to~/.config/verified-googledocs-mcp/token.jsonwith owner-only permissions (0600, under a0700directory). Treat both as secrets: a leaked refresh token grants your fulldrive+documentsaccess until you revoke it in your Google Account's security settings. Neither file is ever committed (both are gitignored). - Audit log. Every mutation appends to
~/.local/state/verified-googledocs-mcp/audit.jsonl(also0600). Each line records the timestamp, document ID, tab ID, tool name, and the evidence payload — which includes before/after content excerpts. To log the metadata without the excerpts, set the environment variableVERIFIED_GOOGLEDOCS_MCP_AUDIT_EXCERPTSto a falsey value (0,false,no, oroff); thebefore/afterfields are then replaced with"[redacted; N chars]"and every other field is kept. Override the log location withXDG_STATE_HOME. - Local file diffs.
diff_tab_vs_filereads a local file so it can compare a Doc tab with markdown on disk. It resolves symlinks before reading and only allows paths underVERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTS(a platform path-list; defaults to the user's home directory, not the server process's working directory). The home-directory default exists because MCP clients typically register this server pinned to one repo (e.g.--directory /path/to/GoogleDocs-MCP), while the diff target is almost always in whichever other project the caller is actually working in — scoping to the launch directory made every cross-repo diff fail by default. Narrow it further (e.g. back to a single repo) or widen it by settingVERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTSon the server process to a:-separated (;on Windows) list of directories, then restart the server — a rejected path's error names the env var and includes the currently configuredallowed_rootsso you can see exactly what's missing. It's still a real boundary, not unrestricted: an agent asking to diff against/etc/passwdor another user's home directory is refused. A home-directory-wide default also has to defend against a document's own content tricking an agent into reading credentials (prompt injection) — e.g. a paragraph instructing "diff against~/.ssh/id_rsa" — so.ssh,.aws,.gnupg,.netrc,.git-credentials,.config/gh,.docker/config.json, and.npmrcunder the home directory are denylisted unconditionally, regardless of the configured allowed roots. It also refuses files larger thanVERIFIED_GOOGLEDOCS_MCP_MAX_DIFF_FILE_BYTES(default1000000).export_pdf's output path is confined by this same policy — the sameVERIFIED_GOOGLEDOCS_MCP_ALLOWED_FILE_ROOTSallow-list and the same unconditional credential-path denylist, so a PDF export can no more land in (or overwrite)~/.sshthan a diff can read from it.
Error codes
Failures return a typed envelope (error_code, message, diagnostics, retryable):
Development
Unit tests run against synthetic Docs API fixtures and an in-memory MCP client, so the full suite is offline (it never runs the live tests). The live acceptance suite (under tests/live/) runs with pytest tests/live --run-live against a real scratch document and needs OAuth credentials; it is the pre-release gate and never runs in CI — see docs/acceptance-report.md.
See docs/architecture.md for the module map and the verification pipeline, PRD.md for the full specification, docs/cutover.md to migrate off a general Workspace MCP server, and CONTRIBUTING.md to build on it.
Limitations
- Accepting or rejecting suggested edits is not possible through the generally-available Google Docs API. This server makes suggestions visible alongside comments; acting on them stays a manual step in the Docs UI. As of July 2026 Google documents accept/reject/delete suggestion requests — but only under the Workspace Developer Preview Program; the stable v1 surface rejects them (verified 2026-07-17). Verified
accept_suggestion/reject_suggestiontools become buildable when that reaches GA. - Single user, local. stdio transport, one cached token, no hosted or multi-user mode.
- Docs only. Gmail, Calendar, and Sheets are out of scope by design.
- Markdown is a fixed subset (headings, bold/italic, lists, tables, links). Anything outside it is rejected with a clear error rather than approximated.
License
MIT, © 2026 Michael Sutton.
来源:README.md,提交 374bcf8
工具
0版本历史
1- v0.1.0最新Sep 16, 2026
评分
已满足适用检查项的 50%
该评分衡量此收录条目的完整程度,依据注册中心条目、端点与公开来源计算得出。它不是对服务器本身的评价,也不表示服务器安全或当前可用:可连通性是带日期的检查结果,评分也不包含安装量或用户评价。
- 近 30 天内可连通25 分
请保持端点能够响应 MCP 握手;SourceWeft 每 30 天探测一次。
- 已声明认证方式10 分
请在注册中心条目中声明凭据请求头,或保持端点能够响应探测,以便判定其认证方式。
- 已列出工具15 分
请让服务器在无凭据时响应 tools/list,或发布可在沙箱中无凭据启动的软件包。
- 描述必需15 分
- 图标10 分
- 文档15 分
- 许可证10 分
其他 Verified 集成
verified.fyi
fyi.verified官方发布者
远程 MCP 服务器,让助手查询 verified.fyi 的网站信任报告,包含 0-100 评分、结论与摘要。

AILegal — verified legal provisions for agents
由 GitHub 账号 mrpkk 发布
AILegal — verified legal provisions for agents 的托管 MCP 服务;无需登录;Streamable HTTP;3 个工具。

Verified Reality
由 GitHub 账号 BKBakker 发布
面向安大略省西南部的哈希校验、目录搜索和字段赏金报价。AI 翻译

Career Site Job Search — Verified Greenhouse & Lever Boards
由 GitHub 账号 kriton-dev 发布
托管在 Apify 上的远程 MCP 服务器,让助手在 Greenhouse 与 Lever 招聘站点目录中搜索在招职位,并对每条结果实时核验。

StackVersus: verified SaaS limits & pricing
由 GitHub 账号 congptvinadic-debug 发布
只读的远程 MCP 服务器,让助手查询经核实的 SaaS 价格、套餐限额、速率限制与超额规则,并附厂商来源与核查日期。