A Google Docs MCP server with verified writes: every mutation re-reads the document and returns proof of what changed.
claude mcp add verified-googledocs-mcp -- uvx verified-googledocs-mcp{
"mcpServers": {
"verified-googledocs-mcp": {
"command": "uvx",
"args": ["verified-googledocs-mcp"]
}
}
}Resumen de MCP Servers
# verified-googledocs-mcp
<!-- mcp-name: io.github.michaelrobertsutton/verified-googledocs-mcp -->
[](https://github.com/michaelrobertsutton/verified-googledocs-mcp/actions/workflows/ci.yml)
[](pyproject.toml)
[](pyproject.toml)
[](LICENSE)
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 14 tools are implemented, covered by an offline unit suite, and exercised against the real Google Docs and Drive APIs — every tool and every error code passes the [live acceptance gate](docs/acceptance-report.md). Install with `uvx verified-googledocs-mcp`. See [Status](#status).
## The problem
Driving Google Docs from an agent through a general Workspace MCP server tends to fail in quiet, expensive ways:
- A `findAndReplace` meant 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.
```jsonc
// 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
}
```
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:
```jsonc
{
"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
}
```
### 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_matches` defaults to 1. If the real count differs, the tool makes no edit and returns every match location.
- **Revision preconditions.** Writes carry `writeControl.requiredRevisionId` from the pre-read, so a document that changed underneath the operation is rejected by the API rather than edited blind. Section ranges from `find_sections` are 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`.
| Family | Tools | Proves |
|--------|-------|--------|
| **Text edit** | `replace_text` | `match_count` equals `expected_matches`; `rung` names the normalization pass that matched; `before`/`after` are ±200-char excerpts of the edited span, the `after` re-read post-write |
| **Markdown range** | `replace_range_markdown`, `replace_tab_markdown`, `append_markdown` | `structural_match` (the written markdown round-trips), `input_blocks` vs `post_blocks` counts, and a `structural_diff` list naming any mismatch |
| **Structural** | `insert_image` | `inline_object_confirmed` — a post-write scan found the inline object at the anchor paragraph |
| **Comment state** | `add_anchored_comment`, `reply_to_comment`, `resolve_comment` | the re-queried `resolved` flag, `reply_count`, `content`, `quoted_text`, and `author` — a resolve that didn't land returns `COMMENT_STILL_OPEN`, never success |
The read and sync tools (`read_document`, `list_tabs`, `find_sections`,
`list_open_items`, `get_comment_thread`, `diff_tab_vs_file`) make no changes and
carry no `applied`/evidence payload.
### Dry run
The five mutating tools (`replace_text`, `replace_range_markdown`,
`replace_tab_markdown`, `append_markdown`, `insert_image`) 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. Use it to confirm a locate resolves to the right
span before committing the edit.
## Tools
Fourteen 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
| Tool | What it does |
|------|--------------|
| `read_document` | Read a tab as markdown or as structured positions and style runs |
| `list_tabs` | List tab IDs, titles, and nesting |
| `find_sections` | Find headings and return their ranges, stamped with the document revision |
### Editing (verified, tab-scoped)
| Tool | What it does |
|------|--------------|
| `replace_text` | Find/replace within a tab, with the normalization ladder and match guard |
| `replace_range_markdown` | Replace a section range with markdown |
| `replace_tab_markdown` | Replace a whole tab's content with markdown |
| `append_markdown` | Append markdown to a tab |
| `insert_image` | Insert an image at a quoted anchor or heading |
### Comments and suggestions
| Tool | What it does |
|------|--------------|
| `list_open_items` | Open comments **and** pending suggested edits in one call |
| `get_comment_thread` | Read a comment's full reply chain |
| `add_anchored_comment` | Add a comment anchored to quoted text |
| `reply_to_comment` | Reply to a comment |
| `resolve_comment` | Resolve a comment, re-query it, and confirm it actually closed |
### Sync
| Tool | What it does |
|------|--------------|
| `diff_tab_vs_file` | Diff a tab's markdown against a local file |
## Status
Built incrementally; each tool ships with its verification and tests rather than as a stub.
| Area | State |
|------|-------|
| OAuth (`verified-googledocs-mcp auth`), token cache | done |
| `read_document`, `list_tabs`, `find_sections` | done |
| Verification kernel (locator, error envelope, audit) | done |
| `replace_text` (verified) + enforcement middleware | done |
| Comment tools + `list_open_items` | done |
| Markdown write tools + `diff_tab_vs_file` | done |
| Live acceptance gate (all 14 tools, all 12 error codes) | done — [report](docs/acceptance-report.md) |
| PyPI packaging + publish workflow | done; first release `v0.1.0` |
| MCP registry listing | published with `v0.1.0` |
## 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)
1. Create a Google Cloud project and enable the **Google Docs API** and **Google Drive API** (APIs & Services → Library).
2. 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.)
3. 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 with `VERIFIED_GOOGLEDOCS_MCP_CREDENTIALS`.)
### 2. Authorize once, in a terminal
```bash
uvx verified-googledocs-mcp auth
```
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 oLo que la gente pregunta sobre verified-googledocs-mcp
¿Qué es michaelrobertsutton/verified-googledocs-mcp?
+
michaelrobertsutton/verified-googledocs-mcp es mcp servers para el ecosistema de Claude AI. A Google Docs MCP server with verified writes: every mutation re-reads the document and returns proof of what changed. Tiene 0 estrellas en GitHub y se actualizó por última vez today.
¿Cómo se instala verified-googledocs-mcp?
+
Puedes instalar verified-googledocs-mcp clonando el repositorio (https://github.com/michaelrobertsutton/verified-googledocs-mcp) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.
¿Es seguro usar michaelrobertsutton/verified-googledocs-mcp?
+
michaelrobertsutton/verified-googledocs-mcp aún no ha sido auditado por nuestro agente de seguridad. Revisa el repositorio original en GitHub antes de usarlo en producción.
¿Quién mantiene michaelrobertsutton/verified-googledocs-mcp?
+
michaelrobertsutton/verified-googledocs-mcp es mantenido por michaelrobertsutton. La última actividad registrada en GitHub es de today, con 0 issues abiertos.
¿Hay alternativas a verified-googledocs-mcp?
+
Sí. En ClaudeWave puedes explorar mcp servers similares en /categories/mcp, ordenados por popularidad o actividad reciente.
Despliega verified-googledocs-mcp en tu cloud
Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.
¿Mantienes este repo? Añade un badge a tu README
Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.
[](https://claudewave.com/repo/michaelrobertsutton-verified-googledocs-mcp)<a href="https://claudewave.com/repo/michaelrobertsutton-verified-googledocs-mcp"><img src="https://claudewave.com/api/badge/michaelrobertsutton-verified-googledocs-mcp" alt="Featured on ClaudeWave: michaelrobertsutton/verified-googledocs-mcp" width="320" height="64" /></a>Más MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!
⭐AI-driven public opinion & trend monitor with multi-platform aggregation, RSS, and smart alerts.🎯 告别信息过载,你的 AI 舆情监控助手与热点筛选工具!聚合多平台热点 + RSS 订阅,支持关键词精准筛选。AI 智能筛选新闻 + AI 翻译 + AI 分析简报直推手机,也支持接入 MCP 架构,赋能 AI 自然语言对话分析、情感洞察与趋势预测等。支持 Docker ,数据本地/云端自持。集成微信/飞书/钉钉/Telegram/邮件/ntfy/bark/slack 等渠道智能推送。