google-docs-mcp
Provides tools for reading, editing, suggesting, and commenting on Google Docs documents, including handling tables, headers, footnotes, formatting, and suggestions.
Enables searching for documents in Google Drive by title, content, owner, or modification date, and exporting documents to various formats.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@google-docs-mcpSuggest changing the heading in my budget doc to '2026 Budget'."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
google-docs-mcp
Google Docs as MCP tools. Read, edit, suggest and comment on documents from Claude or any MCP client.
A single Go binary that speaks Model Context Protocol over stdio. It runs as a subprocess of your client, on your own machine, against your own Google account. There is no server to host, no shared deployment and no service account: you create a Google OAuth client, log in once, and the refresh token stays in your OS keyring.
It works inside a document the way a careful colleague does — reads it at the right granularity, edits in place without damaging what surrounds the edit, proposes changes as suggestions, comments on passages, and handles tables, tabs, headers, footnotes and formatting.
Why google-docs-mcp
Existing servers hand the model raw UTF-16 indices, convert markdown in
ways that silently corrupt documents, and anchor comments through the
Drive API where they never render inline. This server keeps index math on
the server, addresses content by exact text and stable heading ids, edits
by minimal diff, refuses to overwrite anchored content, and uses the Docs
API's suggestion mode where the project is enrolled. The reasoning and
evidence are in docs/architecture.md.
Reading, searching, creating, exporting, editing with minimal diffs in
suggest, direct or comment mode, formatting, reviewing suggestions,
comment threads, revision history and diffs, tables, tabs, headers,
footers, footnotes, images, chips, named ranges, page and section layout,
named styles, gdocs:// resources, large-document performance and agent
evals are all in. Every GA member of the Docs API's Request union is
emitted; §16 of the architecture says which fields those tools expose and
which they deliberately do not.
Related MCP server: gdoc MCP
Install
go install github.com/mmedum/google-docs-mcp/cmd/google-docs-mcp@latestThat puts google-docs-mcp in $(go env GOPATH)/bin, which is the path
to give your MCP client. Or take a signed archive from the
latest release
— Linux, macOS and Windows, on amd64 and arm64 — and verify it before you
run it:
tar xzf google-docs-mcp_*_linux_amd64.tar.gz
sha256sum -c checksums.txt --ignore-missing
# The checksum file is signed with a keyless Sigstore certificate tied to
# the release workflow's identity. The bundle carries both.
cosign verify-blob checksums.txt \
--bundle checksums.txt.bundle \
--certificate-identity-regexp 'https://github\.com/mmedum/google-docs-mcp/' \
--certificate-oidc-issuer https://token.actions.githubusercontent.com
# And the archive itself carries build provenance.
gh attestation verify google-docs-mcp_*_linux_amd64.tar.gz --repo mmedum/google-docs-mcpEvery archive also ships an SBOM (.sbom.json), so you can see what is
inside a binary you did not build. go install needs none of this: the
module proxy and sum.golang.org verify the source before it is built.
google-docs-mcp --version reports the release it came from either way.
Set up Google
Every deployer uses their own Google Cloud project and OAuth client. There is no shared app and nothing to verify with Google.
Create or pick a Google Cloud project.
Enable the Google Docs API and the Google Drive API (APIs & Services → Library).
Configure the OAuth consent screen (Google Auth Platform → Audience):
Internal if your account is in a Google Workspace organisation. Tokens then never expire.
External with publishing status Testing for a consumer account. Add yourself as a test user. Google expires refresh tokens for such apps after 7 days, so you will run
loginweekly.
Add scopes (Google Auth Platform → Data Access):
.../auth/documents,.../auth/documents.readonly,.../auth/drive,.../auth/drive.readonly.All four, though one login never asks for more than two of them: a normal login requests
documentsanddrive, andGDOCS_READ_ONLY=truerequestsdocuments.readonlyanddrive.readonlyinstead. The consent screen lists what the client may ask for, so it has to cover both, and a scope it has not been given is refused at the moment somebody first tries read-only mode. Google grants only what is requested, so listing the read-only pair costs a normal login nothing.Create an OAuth client (Google Auth Platform → Clients) of type Desktop app, download its JSON, and store it as
~/.config/google-docs-mcp/client_secret.json(Linux; thegoogle-docs-mcpfolder under your OS config directory elsewhere). Keep it out of any repository.Run:
google-docs-mcp login
google-docs-mcp doctor https://docs.google.com/document/d/<some doc you can open>/editThe document is optional: doctor on its own checks credentials, scopes
and API reachability, and reads the document when given one.
google-docs-mcp status --json prints the same state as one JSON object
on stdout, for a script that needs to know whether this server is
authorised before starting it. credentials.resolved is the field to
branch on, schema_version changes only when a field is removed or its
meaning changes, and the account is masked to its domain exactly as the
text output masks it. A label in the human output is free to be reworded
in any release; the object is not.
login opens a browser, completes Google's desktop OAuth flow on a
loopback port, and stores the refresh token in your OS keyring (Secret
Service, Keychain or Credential Manager), falling back to a 0600 file
with a warning when no keyring is available. doctor checks every step
and tells you exactly what is missing.
Logging in over SSH
The callback goes to the remote host's loopback address and your
browser is local, so the port has to be forwarded. It is drawn at random
and appears only in the URL login prints, percent-encoded as
127.0.0.1%3A<port>:
google-docs-mcp login --no-browserRead the port out of that URL, forward it from a second local terminal, then open the URL in your own browser:
ssh -N -L <port>:127.0.0.1:<port> you@remote-hostIf ssh says bind: Address already in use, stop the login with Ctrl-C
and start it again to draw a different port. --timeout sets how long
login waits; the default is five minutes.
Optional: Developer Preview
Suggestion mode (mode: suggest), comments anchored to a text range, and
accepting or rejecting suggestions use Docs API features that are in the
Google Workspace Developer Preview Program.
Apply with the form on that page, giving your Cloud project id. Once
enabled for your project, set GDOCS_PREVIEW=true. The programme terms
allow use inside your own organisation; do not offer a preview-enabled
deployment to people outside it.
These features sit outside the version promise below. They are the
one part of this server built on an API Google may change or withdraw
while it is in preview, and a change there is not something this project
can absorb without changing behaviour. Everything reachable with
GDOCS_PREVIEW unset follows semver as stated; the preview-gated
features follow Google's preview programme, and if it moves, they move.
Connect a client
Claude Code:
claude mcp add --transport stdio google-docs -- google-docs-mcpClaude Desktop (claude_desktop_config.json) or Cursor (mcp.json):
{
"mcpServers": {
"google-docs": {
"command": "/absolute/path/to/google-docs-mcp",
"env": { "GDOCS_LOG_LEVEL": "info" }
}
}
}Claude Desktop rewrites claude_desktop_config.json from its own state
while it runs, dropping edits made behind its back: quit it fully, then
edit, then start it. It also loads tool definitions lazily, so give it a
moment before expecting the tools in a chat.
All settings are environment variables; see
docs/configuration.md. Nothing needs to be set
for the defaults.
Tools
Tool | What it does |
| Title, tabs, revision id, owner, last change, counts, and this server's capabilities (available write modes, default). Per tab it also reports the page setup, the floating objects, the named ranges and the named style definitions its paragraphs carry — everything a read of the text cannot show. Cheap; call it first. |
| Heading tree per tab with stable |
| Scoped, budgeted read as markdown, plain text, or raw Docs JSON. Scope by |
| Text or regex search returning handles, offsets and context. |
| Locate documents by title or content, owner, or modification date. |
| Google's own md, txt, html inline; pdf, docx, odt, rtf, epub as files under |
| New document, optionally with markdown content. |
| Atomic batch of |
|
|
| Pending suggested edits with ids, text and handles, including the formatting-only ones that add and remove nothing. |
| Accept, reject or discard suggestions by id or all (Developer Preview). |
| Comment threads with every reply, resolved and deleted state, quoted text and the block they sit on. |
| Comment on a passage (pinned with Developer Preview, quoted otherwise) or on the document. |
| Reply to, resolve, reopen a thread, or rewrite a comment or reply of your own. |
| Version history: revision ids, times, authors. |
| Unified diff of Google's markdown or text export between two revisions. |
|
|
| Insert an inline image from a public URL, a person chip, a rich-link chip or a date chip at a location; replace an image's source in place; or delete an object, including a floating image no text range covers. |
|
|
| Add (with content), rename, move or nest tabs. Always direct: the API cannot suggest tab changes. |
Two more tools register only with GDOCS_ENABLE_DESTRUCTIVE=true:
delete_comment (a thread or one reply) and delete_tab (a tab with its
content and child tabs). Both carry the destructive annotation and ask the
client to involve the person.
Documents are identified by id or any docs.google.com URL.
Resources
Clients that attach context as MCP resources can read a document without a tool call. Each is markdown with no handles, suggestions or comments; the read tools are for scoped, budgeted reads.
gdocs://<id>— every tab's body, cut at 400000 characters with a note saying whereread_documentcan continue.gdocs://<id>/outline— the heading treeget_outlinereturns.gdocs://<id>/tabs/<tab>— one tab's body;tabis an id, title or number.
How edits are addressed
The model never sees index numbers. A target is exact text quoted from a
read (curly quotes, dashes and spacing are normalised; it must occur
once, or occurrence / within disambiguates), a whole section by its
stable heading_id, a block by handle (p12, valid for the revision it
came from and re-checked on use), a table cell, or a named range, which
is the one anchor that outlives an edit: Google moves it with the text it
covers, so create_named_range now and target: {named_range: …} in a
later call reach the same passage. New content is written as markdown. A
replace is applied as the smallest diff between the old and new text, so
untouched words keep their formatting and anchored comments.
Tables are named by handle (tbl1) and cells as r2c3; a table that
gets a data grid is inserted empty and filled in a second batch once it
exists. Table ops read in order: once one changes the grid, the ops after
it on that table are applied in a batch of their own, so their row,
column and cell numbers mean the grid as it is by then. Old revisions are
read and diffed through Google's export, so they have no handles.
Safety
Read tools are annotated read-only. Write tools take a
modechosen by the person:suggest(tracked change),direct, orcomment(the proposal is posted as a comment and nothing is edited). Every write is guarded by the revision it was planned against; a concurrent edit is re-planned once, then refused.Direct edits never delete a range that holds a comment anchor, a pending suggestion, an image or a footnote unless explicitly forced.
Destructive tools (deleting comments or tabs) are not registered unless
GDOCS_ENABLE_DESTRUCTIVE=true.GDOCS_READ_ONLY=trueregisters only read tools and requests read-only scopes.The server talks only to Google (
googleapis.com, anddocs.google.comfor the revision export links Google's API returns). No telemetry. Logs (stderr) never contain document text.Refresh tokens live in the OS keyring;
logoutrevokes and deletes.
How it works
MCP client ──stdio──► google-docs-mcp
├── tools one handler per tool; shapes the reply
├── service orchestration and scope resolution
├── plan write planning and all the index math
├── doc model, handles, sections
├── render markdown, text, outline
├── gapi raw REST client for Docs and Drive
└── auth refresh token → access tokenIndex math never leaves the server: the model addresses content by exact
text, heading_id or handle, and internal/plan turns that into the
UTF-16 offsets the Docs API wants. The wire types in internal/gdocs are
this project's own, held to Google's published discovery document by a
gate, rather than the generated client.
Getting help
google-docs-mcp doctor checks credentials, scopes and API reachability
and names what is missing; most first-run trouble is an API that was
never enabled or a consent screen without you on it. If that does not
explain it, open an issue
— the bug form asks for the doctor output and the version.
Never paste a document id or URL, document content, a
client_secret.json or a token into an issue; describe the shape of the
document instead. Security problems go through
SECURITY.md, privately.
Versioning
From v1.0.0, semver as you would expect: a tool removed or renamed, an argument that becomes required, or a change to what a tool returns is a major version. New tools and new optional arguments are minor. The schema diff in CI is what enforces it, and it runs on every pull request — the tool surface cannot change without the diff naming it.
The two exclusions, both stated so they are decisions rather than
surprises: the Developer Preview features above, and the exact prose of
a tool's text output, which is written for a model to read and will be
reworded when a model reads it badly. The structuredContent a tool
returns is covered; the sentence wrapped around it is not.
Each release's notes are the matching section of
CHANGELOG.md; a change needing you to act — a new
scope, another login, a different command in your client config — is
marked Breaking: there.
Development
make build # the binary
make test # race detector, coverage floor
make check # everything CI runsmake check is the definition of done: formatting, go vet under every
build tag, golangci-lint, race tests with a per-package coverage floor,
govulncheck, a licence check, a secret scan, an API-coverage gate and
an API-fields gate that fail when a Google API method or field has no
verdict on it, a schema diff against the released tool surface, a stdio
smoke test, and a staleness gate that fails when this README, the docs or
the changelog drift from the code.
Test fixtures are synthetic. Never add content, ids or URLs from real
documents. make bench measures the large-document paths;
go test -tags=evals ./internal/evals runs the agent evals against your
own account (see the package comment).
Documentation
docs/architecture.md— the design, the request flow, the evidence log behind every convention, and the decisions a contributor should not undo.docs/configuration.md— every environment variable and flag.docs/security.md— the threat model: what reaches a log, whatdoctorprints, what the drivers write. Each claim is held by a test.
Contributing
Questions and bugs go in
issues; pull requests
are welcome. CONTRIBUTING.md covers the branch and
review flow, and make check is what has to pass.
Security
SECURITY.md says what is in scope and how to report a
vulnerability privately. Do not open a public issue for one.
Code of conduct
CODE_OF_CONDUCT.md — Contributor Covenant 3.0.
License
Apache-2.0 — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Google Docs MCP Pack — read, create, and edit Google Docs via OAuth.
Team docs served to AI agents over MCP - search, Markdown reads, version pinning, read audit.
Document processing over MCP: merge, split and compress PDFs, run OCR, extract document text.
MCP-native collaborative markdown editor with real-time AI document editing
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to interact with collaborative Docs instances, providing document management, content editing, access control, and AI-powered transformations via MCP.1MIT
- AlicenseBqualityAmaintenanceEnables interaction with Google Docs through typed MCP tools, supporting reading, writing, searching, and managing documents via OAuth integration.22MIT
- AlicenseAqualityBmaintenanceA read/write MCP server for Google Drive, Docs & Sheets with bounded reads, gated mutations, and consistent argument naming.26MIT
- AlicenseNot gradedqualityCmaintenanceEnables reading and editing Google Docs via the Docs API, including structure/outline retrieval, text export, section/range/table editing, text replacement, document creation, and raw batch updates, with dry-run previews before destructive changes.MIT