gdsync Documentation
Everything you need to read and edit Google Docs from the command line — built for AI agents, usable by anyone.
Overview
gdsync mirrors a Google Doc to a local file. You (or an AI agent) edit that file, run one command, and the changes appear in the live document. The sync engine handles all the Google Docs API complexity — character indexes, named ranges, formatting, tables, lists, images, and comments.
gdsync fetch # pull the Google Doc into content.txt
# edit content.txt
gdsync commit # push your changes to the live doc, and verify
Your documents are accessed through your own Google Cloud project — gdsync's infrastructure never has ongoing access to your files. The only setup cost is a one-time, guided project creation.
Install
npm install -g @gdsync/gdsync
Requires Node.js 18 or newer. Verify the install:
gdsync --version
1. Set up a GCP project
gdsync accesses Google Docs through a Google Cloud project that belongs to you. Run the guided wizard once:
gdsync setup # prints a setup URL, then exits
gdsync setup check # confirm setup is complete
The wizard opens in your browser and walks you through:
- Signing in with a Google account (we recommend a dedicated agent account, e.g.
my-agent@gmail.com). - Creating (or reusing) a Google Cloud project and enabling the Docs & Drive APIs.
- Creating an OAuth client — choose Web application and add
https://auth.gdsync.dev/callbackas an authorized redirect URI. When the credentials pop up, click Download JSON, then OK, and paste/upload them into the wizard.
setup check: 0 = complete, 1 = still pending (finish the browser steps), 2 = the session expired (run gdsync setup again).Manual setup
Prefer to do it entirely by hand, or already have a project? Use the step-by-step guide:
gdsync setup manual
This never touches your Google Cloud account automatically — it just shows you what to create, and detects credentials you place at ~/.gdsync/client_secret.json or set via the GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRET environment variables.
2. Authenticate
Once setup is done, sign in for document access:
gdsync auth # prints a sign-in URL, then exits
gdsync auth check # validate the sign-in (checks the live token)
gdsync logout # sign out — clears the token, keeps your setup
Sign in with the account you want the agent to act as. It can only access documents that are shared with that account. Document access uses your own project's OAuth client — gdsync's app is never in the loop for your document data.
gdsync auth check reports it and gdsync clears the dead token automatically; just run gdsync auth again to reconnect (no manual reset). Use gdsync auth --force to re-authenticate at any time.3. Open a document
List the documents your account can reach, then initialize a sync session:
gdsync docs # list accessible docs
gdsync docs --search "keyword" # filter by name
gdsync init --doc <documentId> # start editing (auth + first fetch)
The document ID is the long string in the doc's URL: https://docs.google.com/document/d/THIS_PART/edit.
init creates a working directory layout:
content.txt ← the file you edit
comments.txt ← open comment threads (read-only)
assets/ ← images live here
.gdsync ← doc config
.gdsync-session ← block map & sync state
The editing loop
Every edit follows the same four steps, in order:
- Fetch —
gdsync fetchpulls the latest document state intocontent.txt. Always fetch before editing. - Edit — change
content.txtwith any editor. - Commit —
gdsync commitpushes your changes and re-verifies against the live doc. - Confirm — commit reports what changed and whether verification passed.
Check pending changes any time with gdsync status. If things ever look out of sync, gdsync reset clears local state and re-fetches clean.
Content file format
After a fetch, content.txt is a sequence of blocks. Each block is a paragraph, list item, table, or image, separated by a delimiter line:
---blk_1 paragraph---
# Document Title
---blk_2 paragraph---
A normal paragraph with **bold** and *italic* text.
---blk_3 list_item---
- First bullet
---blk_4 table---
| Name | Role |
| --- | --- |
| Alice | Engineer |
The blk_N IDs and type tokens are assigned by gdsync. You edit the content between delimiters. To change the structure:
| Action | How |
|---|---|
| Edit content | Change the text under a block's delimiter. |
| Add a block | Insert a bare --- delimiter (no ID) where you want new content. |
| Delete a block | Remove its delimiter and content. |
| Reorder | Move a block's delimiter + content to a new position. |
--- for new blocks and let gdsync assign IDs.Paragraphs & headings
Plain text is a paragraph. Prefix with # markers for headings:
---
# Heading 1
---
## Heading 2
---
### Heading 3
---
Just a normal paragraph.
Inline formatting
These work anywhere text appears — paragraphs, list items, and table cells:
| Syntax | Result |
|---|---|
**bold** | bold |
*italic* | italic |
`code` | monospace / code |
[text](https://url) | a link |
Lists
Use - for bullets and 1. for numbered lists. Each item is its own block. Indent by two spaces per level to nest:
---
- Top-level bullet
---
- Another bullet
- Nested bullet
---
1. First numbered item
---
2. Second numbered item
Tables
Tables use standard markdown: a header row, a | --- | separator, then data rows.
---
| Name | Role | Team |
| --- | --- | --- |
| Alice | Engineer | Core |
| Bob | Designer | UX |
Editing cells
Just change the cell text and commit. You can edit one cell, several, or all at once.
Formatting inside cells
Cells support the same inline formatting as everywhere else:
| Field | Value |
| --- | --- |
| **bold label** | plain value |
| link | [docs](https://gdsync.dev/docs) |
Adding & removing rows and columns
Edit the markdown grid directly — add or delete rows and columns, and gdsync applies the new shape (existing cell content and formatting are preserved):
# add a column and a row:
| Name | Role | Team | → | Name | Role | Team | Location |
| --- | --- | --- | | --- | --- | --- | --- |
| Alice | Engineer | Core | | Alice | Engineer | Core | NYC |
| Bob | Designer | UX | LA |
Pipes in cell text
To include a literal | inside a cell, escape it as \|:
| Expression | Meaning |
| --- | --- |
| a \| b | a or b |
readonly and can't be edited through gdsync — edit those directly in Google Docs.Images
Images appear as markdown image references pointing into the assets/ folder:
---

To add an image, place the file in assets/ first, then reference it. The file must exist before you commit.
Edit modes
Auto (default) applies changes directly to the document. Suggestions mode is a visual review preview — old/removed text is struck through and new text is shown in red. The Google Docs API can't create native suggestions, so this is a simulation, not Google's "Suggesting" mode (there are no Accept/Reject buttons).
gdsync config mode suggestions
gdsync config mode auto
~~...~~ in content.txt. To accept a change, delete the struck-through block; to reject it, delete the new text.Configuration
gdsync config # view current settings
gdsync config mode auto # or: suggestions
gdsync config comment_filter on # or: off (only @mentioned comments)
CLI reference
| Command | Description |
|---|---|
gdsync setup | Set up your GCP project (guided wizard) |
gdsync setup manual | Manual GCP project setup guide |
gdsync setup check | Check whether setup is complete |
gdsync auth | Authenticate for document access (auto re-auths if the token is revoked; --force to always re-auth) |
gdsync auth check | Validate the sign-in (detects a revoked/expired token) |
gdsync logout | Sign out — clear stored credentials (keeps your setup; --backup to save a copy) |
gdsync docs | List accessible Google Docs |
gdsync docs --search "x" | Search docs by name |
gdsync init --doc <id> | Initialize a sync session (auth + fetch) |
gdsync fetch | Pull the latest doc into content.txt |
gdsync commit | Push content.txt changes and verify |
gdsync status | Show pending changes and sync state |
gdsync reset | Clear local state and re-fetch clean |
gdsync config | View or change settings |
gdsync comment reply <id> "msg" | Reply to a comment thread |
gdsync comment create <blk> "msg" | Create a comment (optionally --anchor) |
gdsync comment resolve <id> | Resolve a thread (optionally --reply) |
Error recovery
| Problem | Fix |
|---|---|
| "Not set up" | Run gdsync setup, then gdsync setup check. |
| "Not authenticated" | Run gdsync auth, then gdsync auth check. |
| Sign-in expired / revoked | Google expires refresh tokens after 7 days for apps in "Testing" status. gdsync auto-clears the dead token — just run gdsync auth again (or gdsync logout then gdsync auth). No setup needed. |
OAuth client removed / deleted_client | The OAuth client itself was deleted — re-run gdsync setup then gdsync auth. |
| Commit failed | Read the error, fix the content, and gdsync commit again. |
| Content looks wrong | gdsync fetch to pull the current state, or gdsync reset to start clean. |
| Doc not listed | Share the document with the authenticated account. |
| Table won't edit (readonly) | It's a complex table — edit it directly in Google Docs. |
For AI agents
gdsync is designed to be driven by an AI agent. The agent runs the CLI itself and only hands a URL to a human for the browser-gated steps (project setup and sign-in). Because setup and auth print a URL and exit — no blocking processes — the agent can surface the link, wait, then continue.
The quickest way to teach an agent the full workflow is the skill package:
Download gdsync-skill.zip — add it to Claude Code or any agent that supports skills.
The local file format (blocks, delimiters, IDs) is agent-internal — agents should talk to users about the Google Doc, not about content.txt.
Comments
Open comment threads appear in
comments.txt(read-only) after a fetch, each with a thread ID, the block it's anchored to, and the highlighted text:Act on comments with CLI commands:
gdsync config comment_filter onto only see threads that @mention the agent's account.