Skip to main content

gdocs-patch

Efficient Google Doc editing for agents

Overview

When you ask an agent to edit a Google Doc, they would typically need to assemble Google Docs API requests manually. This involves finding the right order of operations, managing document indices, and keeping track of styles. It is all quite error-prone and could lead to data loss if the agent makes a mistake.

gdocs-patch is a CLI and MCP that allows agents to efficiently edit Google documents by representing documents as XHTML and allowing the agent to make targeted edits, just like editing a normal file locally.

Install

Install the CLI with uv:

uv tool install gdocs-patch

Alternatively, install it with pip:

pip install gdocs-patch

gdocs-patch supports Python 3.10 and newer.

How it works

gdocs-patch exposes a few commands for agents to use:

read    Read a Google document as canonical XHTML.
edit    Edit exact text in canonical XHTML.
write   Write canonical XHTML to a Google document.
syntax  Explore the XHTML document syntax.
skill   Show best practices for coding agents using gdocs-patch.
auth    Manage Google authentication.

The editing commands (read, edit, and write) all operate using a custom XHTML dialect that represents every Google doc element as a tag or attribute. The agents can learn the dialect by reading documents, or through the syntax and skill commands.

gdocs-patch at its core is a source doc + target doc = google doc batch update request compiler. The agent reads the source document, edits the XHTML locally, and calls write to apply the edits to the Google Doc. Alternatively, agents can call edit to make targeted replacements without a local copy.

Authenticating with Google

You need to give the tool access to the Google Docs API. To do this, create a Google Cloud project, enable the Google Docs API in the project, configure its OAuth consent screen, and create an OAuth client with application type Desktop app. Download its client JSON and save it in ~/.config/gdocs-patch/client_secret.json:

mkdir -p ~/.config/gdocs-patch
cp ~/Downloads/client_secret.json ~/.config/gdocs-patch/client_secret.json

The client_secret.json file allows gdocs-patch to log you in via OAuth.

gdocs-patch auth login

This command opens the OAuth authorization screen. Authorize the app. Once done, gdocs-patch should say you're good to go.

If you need to run the tool non-interactively, you can copy the OAuth authorization URL from the terminal and paste it into your local browser. After finishing authorization, copy the complete callback URL from your browser's address bar and paste it back into the terminal.

MCP server

A Streamable HTTP MCP server is also available that exposes the read, edit, and write commands over MCP. To use it, install gdocs-patch[mcp]:

uv tool install 'gdocs-patch[mcp]'

The server uses the same Google credentials as the CLI.

The MCP server is secured via a static Bearer token. Generate a token and set it to the GDOCS_PATCH_MCP_TOKEN environment variable. Then start the server with gdocs-patch-mcp:

export GDOCS_PATCH_MCP_TOKEN="$(openssl rand -hex 32)"
gdocs-patch-mcp --host 127.0.0.1 --port 8000

Every request must include Authorization: Bearer with the value of GDOCS_PATCH_MCP_TOKEN. There's no built-in TLS, though, so you'd still need your own reverse proxy and potentially more security if you want to expose the MCP server over the open internet.

Google Docs support

This table shows what you can currently change with gdocs-patch and whether the Google Docs batchUpdate API provides enough support for the feature.

  • ✅ Supported
  • ⚠️ Supported with limitations
  • ❌ Unsupported
Google Docs feature Can add Can edit Can delete batchUpdate supports it Notes
Text and formatting ✅ ✅ ✅ ✅ Includes links and common character formatting.
Paragraphs and headings ✅ ✅ ✅ ✅ Includes common paragraph styling. Heading IDs and tab stops are preserved but not editable.
Bulleted, numbered, and checklist items ✅ ✅ ✅ ✅ Includes nesting and Google's standard presets.
Custom list appearance ❌ ⚠️ ✅ ❌ Editing requires opt-in conversion to the closest Google preset, which may change its appearance.
Page breaks ✅ ✅ ✅ ✅ New page breaks can only be inserted in the document body.
Sections ✅ ⚠️ ✅ ✅ Most section formatting is editable, but some existing settings cannot be changed or cleared.
Tables ✅ ✅ ✅ ✅ Includes rows, columns, merged cells, nested content, and cell styling.
Repeating table header rows ❌ ❌ ❌ ✅ Existing settings are preserved, but gdocs-patch cannot change them yet.
Headers and footers ❌ ✅ ❌ ✅ Content in existing headers and footers is editable.
Footnotes ❌ ✅ ✅ ✅ Existing footnote content is editable.
Document tabs ❌ ⚠️ ❌ ✅ Content in existing tabs is editable, but tabs cannot be created, moved, renamed, or deleted yet.
Images, drawings, and other embedded objects ❌ ❌ ✅ ⚠️ Existing objects are preserved. Google supports some image operations, but not every kind of embedded object.
Dates, people, and rich links ❌ ❌ ✅ ✅ Existing elements are preserved. Google supports inserting these, but gdocs-patch does not yet expose it.
Equations ❌ ❌ ✅ ❌ Existing equations are preserved. Google does not expose their contents or provide requests to create or edit them.
Table of contents ❌ ❌ ✅ ❌ Existing tables of contents are preserved. Google does not provide requests to create or update them.
Column breaks, horizontal rules, and auto text ❌ ❌ ✅ ❌ Existing elements are preserved. Google does not provide requests to create them.
Document-wide and named style definitions ❌ ❌ ❌ ✅ Existing definitions are preserved. Applying a named style to a paragraph is supported.
Named ranges ❌ ❌ ❌ ✅ Named ranges are currently ignored by gdocs-patch.
Comments ❌ ❌ ❌ ❌ Text edits try to preserve comment anchors. Comments are managed through the Google Drive API instead.
Suggestions ❌ ❌ ❌ ❌ Suggested changes are not currently modeled.
Document metadata ❌ ❌ ❌ ⚠️ IDs and revision information are preserved. Google does not provide Docs requests for changing all metadata.

Development

Install Python 3.14 and synchronize all development dependencies:

uv sync --dev --all-extras

Run the test and static-analysis tools:

uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run fixit lint .
uv run pyright

Install and run the Git hooks:

uv run pre-commit install
uv run pre-commit run --all-files

See RELEASING.md for package build, versioning, and PyPI publication instructions.

License

MIT

Metadata

Release files for gdocs-patch 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for gdocs-patch 0.2.0
File Size Uploaded
gdocs_patch-0.2.0.tar.gz 78.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for gdocs-patch 0.2.0
File Interpreter ABI Platform
gdocs_patch-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 177.9 kB

Release files / gdocs_patch-0.2.0.tar.gz

Download URL gdocs_patch-0.2.0.tar.gz
Size 78.7 kB
Tags Source
SHA-256 checksum
How to use checksums
52430d08cb0a1a8558ea7e7e835e005d7dc3129f212cdaf915e94c9321150bce
BLAKE2b-256 checksum
How to use checksums
2c34916cc56f77b3cec68d77da2b72227244babd4d77c593088b6153c6881e18
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release files / gdocs_patch-0.2.0-py3-none-any.whl

Download URL gdocs_patch-0.2.0-py3-none-any.whl
Size 99.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
a1487a59e76e0be32cffcd8bd6d56e185d63f8237affbf5e2c8549e3598cc48a
BLAKE2b-256 checksum
How to use checksums
1131c93cca6364a26946be455c56ecc540792291701578f11383d574ae92ee6d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 21, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page