Skip to main content
Glama

@dasasian/gdocs-mcp

An MCP server that lets an AI agent (like Claude Code) treat a Google Doc like a local file — read it, edit it by content, review and resolve suggestions, manage comments, and work across tabs and multiple Google accounts.

Status: beta. The tool surface is complete and every change is verified against the live API, not just unit tests.

Why this exists

Most Google Docs MCP servers treat a doc as flat text. This one fills the gap nobody else does:

  • Suggestions you can read and act on. list_suggestions shows each pending tracked change with Docs' own summary, the change in its sentence (Pay within [30→45] days), its author and time; apply_suggestions accepts or rejects each one on its own, as the check and the cross do in Docs. read_doc can render them inline as <ins>/<del>.

  • File-like editing. edit_doc matches a unique snippet of text (like a local Edit) and rewrites it — indices are never exposed.

  • Comments on their text. Read threads (author, time, the text each is on, replies, resolved status), reply, resolve, and add a comment on the text you quote, which stays on that text as it moves.

  • Tabs as sub-files. A doc is a folder of tabs: drive ls <doc> lists them, drive mv renames, reorders and nests them.

  • Multiple accounts. Authorize several Google accounts; pick a default per project.

Related MCP server: LLM2Docs (Unofficial)

What you can ask for

You don't call tools. You ask in plain language and the agent drives them.

Fill a template without rebuilding it

"Copy the Proposal Template into /Clients/Acme, name it 'Acme Q3 Proposal', then fill in the client name, the dates, and the pricing table."

The copy keeps the letterhead, the logo at its exact size, the fonts and the page setup — everything a markdown round-trip cannot rebuild. Then only the words that change are edited. The alternative is retyping a document you already have.

A whole review pass in one instruction

"Show me the pending suggestions as a diff, accept the typo fixes, reject anything that changes meaning, then reply to the open comments and resolve the ones that are settled."

Four tools, one sentence, and the judgement in the middle is the part you wanted help with. Most Docs integrations cannot see tracked changes at all, let alone act on them safely.

More: publishing a folder of markdown as a Drive tree, auditing many docs for style drift, pulling a doc back into your repo with its images → docs/recipes.md.

Install

npm install -g @dasasian/gdocs-mcp

Or from source:

git clone https://github.com/dasasian/gdocs-mcp && cd gdocs-mcp
npm install && npm run build
npm link   # makes `gdocs-mcp` available globally, same as the published package

Then follow the setup below exactly as an installed user would. (npm link symlinks the gdocs-mcp binary to your build; see CONTRIBUTING.md for the dev workflow.)

Setup

You need a Google Cloud OAuth client (one-time). Each user creates their own — this keeps your credentials yours and avoids Google app-verification for the restricted Drive scope.

  1. Create a project + enable APIs (or use the setup guide):

    gcloud projects create my-gdocs-mcp
    gcloud config set project my-gdocs-mcp
    gcloud services enable docs.googleapis.com drive.googleapis.com
  2. OAuth consent screen (Cloud Console → APIs & Services → OAuth consent screen): User type External, add yourself as a Test user. For long-lived tokens, set publishing status to In production (avoids the 7-day refresh-token expiry).

  3. OAuth client → Create credentials → OAuth client ID → Desktop app. Download the JSON and save it as ~/.config/gdocs-mcp/client_secret.json.

  4. Authorize an account (opens a browser):

    gdocs-mcp add-account

    Repeat for each Google account you want to use.

Configure your MCP client

In a project's .mcp.json (Claude Code) or equivalent:

{
  "mcpServers": {
    "gdocs": {
      "command": "gdocs-mcp",
      "env": { "GDOCS_DEFAULT_ACCOUNT": "you@example.com" }
    }
  }
}

GDOCS_DEFAULT_ACCOUNT sets which authorized account this project uses by default — so a work project and a personal project can point at different accounts without re-authorizing. Any tool call can override it with an account argument.

Prefer it available in every project? Register once at user scope: claude mcp add gdocs -s user -e GDOCS_DEFAULT_ACCOUNT=you@example.com -- gdocs-mcp. Then a project can pin its own defaults with a .gdocs-mcp.json — the account, and a default folder for new docs:

{ "account": "work@company.com", "folder": "https://drive.google.com/drive/folders/…" }

write_doc creates only from a path (/Reports/Q3 Report). Given a bare name (Q3 Report) it creates nothing: it refuses, tells the agent to tell you the doc will go in the default folder, and hands back the full path to call. A new doc at the top of My Drive (/Q3 Report) is refused once the same way, and the identical call repeated goes through if you want it there. The default folder's path is also in write_doc's description, read when the server starts. With no default it says to name a folder (~/Q3 Report). See docs/setup.md for the full resolution order.

You don't have to edit that file by hand — just tell the agent "make damithsc@gmail.com my default account for this project" or "make my Manuscripts folder the default here," and it writes the .gdocs-mcp.json for you via set_project_default (searching for the folder by name if needed).

Tools

The table below is the reference. For what to actually ask for, see What you can ask for above, or the full set in docs/recipes.md.

Tool

Description

read_doc

Read as markdown + inline HTML. Opens with a <style> block (the named styles as CSS: p, h1–h6, .title, .subtitle); a paragraph shows style="…" only where it differs from its rule — alignment, spacing, line height, indent — and text color/size/font come back as <span style="…">, so styling is visible and round-trips. Modes: clean · tracked (<ins>/<del>) · accepted · rejected. segment: body (default) / header / footer / all — a body read always reports what the headers/footers hold, so a letterhead never reads as empty. Document text that would parse as markup is marked literal — <p>4. Term</p>, 5 \* 3, \\ for a real backslash; a line that starts or ends with a space or tab reads as <p>⇥Indented clause</p> and the writer keeps every space and tab inside <p>, so a read written back gives the same document. A page break reads as <div style="page-break-after:always"></div> on its own line, and writes back as one. Every element in a paragraph reads (#58): a footnote as [^1] with its note as a [^1]: … line at the end, a date as <time datetime="2026-11-15">Nov 15, 2026</time>, a person or Drive link chip as <a class="chip" href="mailto:jane@x.com">Jane Doe</a>, a dropdown as <input class="chip" list="kix.…" value="Draft"> with its list once as a <datalist> after the <style> block, a horizontal rule as ---, a column break as <span style="break-after:column"></span>, an equation and a page-number field as an empty <span class="equation"> / <span class="page-number"> whose title says to edit them in Docs. A table of contents is not read

edit_doc

Replace a unique text snippet (string-anchored, markup-tolerant; a table matches as its rows, a pipe table or the HTML <table> of a styled one). new_string is the full markdown write_doc takes — headings, lists, tables, images, page breaks — with contentFile for long text and baseDir for relative image paths. Inserting is an edit: quote the anchor and write it back with the new content after it. Text that comes back unchanged is kept (its style, comments and suggestions stay), a match that ends in a table puts new blocks after the table, an anchor mid-paragraph splits the paragraph, and a new block carries its own style rather than its anchor's. An empty doc, tab, header or footer has no anchor: use write_doc. suggest: true sends the edit as suggestions for a person to accept or reject in Docs, and the result lists their ids in suggestions; it defaults to false, a direct edit. Same words with different markup is a style-only edit — no delete, no insert. A table edit that changes rows, columns or merges is a comparison: quote the rows around the change and write the rows you want, and only the difference is sent (insertTableRow, deleteTableRow, insertTableColumn, deleteTableColumn, mergeTableCells, unmergeTableCells, plus the text of the cells that changed), so the other cells keep their comments and style; a new row or column copies its neighbour's style, a moved row or column is a delete and an insert and asks (confirmLoss) when comments quote its text, and a change that cannot be read cleanly is refused with what to quote. A table is never rewritten whole. Editing a rule in the <style> block restyles the whole doc through one updateNamedStyle. A page break is a line of its own, so new_string Title page\n<div style="page-break-after:always"></div> puts the next paragraph on a new page, and an anchor can span one. Elements: one an edit gives back unchanged is kept (a person chip inside a sentence you reword, a footnote, a dropdown, a rule), one it drops is deleted, a new one is created (createFootnote, insertDate, insertPerson, insertRichLink, insertDropdown), and one the API cannot make (a column break, an equation, a page-number field, a link chip to anything but a Drive file) is refused before anything is sent, saying what to write instead. A footnote's note is edited by quoting its [^1]: … line, a dropdown's list by quoting its <datalist> line. A chip's text is Google's: a chip given other words is refused

get_page_setup / set_page_setup

Read / set document-level page setup: margins, page size (preset or explicit), orientation (File > Page setup)

write_doc

Write like the local Write: a path that names nothing is created — a doc in a folder (/Work/Contract), a tab in a doc (/Work/Contract/Notes), a child tab (/Work/Contract/Part 2/Ch.4) — and never asks. A path that names something is replaced, and the first call is refused with a loss summary: paragraphs, comments, suggestions, tab stops, links to bookmarks, page-number fields, section breaks, a table of contents, column breaks, equations, dates in a format the API can only read and link chips to anything but a Drive file, plus a confirmLoss string. Footnotes, person chips, dates, Drive link chips and dropdowns are written back; --- is written as an empty paragraph with a thin grey bottom border. Tell the user; call again with that string to replace. If the doc changed in between (the string carries its revision and the counts), it is refused again. Markdown in (the same CSS read_doc shows: <style> block, <p style>, <span style>; an unsupported property fails the write before anything is sent; a page break is <div style="page-break-after:always"></div> on its own line, and <hr style="page-break-before:always">, break-before: page and break-after: page work too, while any other <div> or <hr> is refused); contentFile for long text; baseDir for relative image paths; a centered image is <p style="text-align:center"><img …></p>; returns images { src, objectId }. Asks only when there is something to lose: an empty doc, tab, header or footer is written without the refusal, and suggest: true never asks, because nothing is lost until a person accepts (rejecting brings back the text, images, tables and comments as they were); it needs a path that already names something. `segment: "header"

export_doc

Export a doc to a local file — pdf (default), docx, odt, rtf, txt, html, epub, md (rendered server-side by Google). A doc path exports every tab; a tab path (/Work/Contract/Ch.4) exports just that tab (not its child tabs) through an undocumented, rate-limited Google endpoint, and is refused rather than widened if that fails

list_suggestions

Pending suggestions in document order: id, summary (Docs' words, e.g. Replace: “30” with “45”), context (the change in its sentence, [deleted→inserted]), author and time — segment to read a header/footer's

apply_suggestions

Accept or reject one or more suggestions, each on its own (Docs' acceptSuggestion / rejectSuggestion, in one batch), after expectTitle and each expectContext — the title and context list_suggestions gave — match the live doc. Style-only suggestions work; segment to resolve a header/footer's

download_images

Download a doc’s embedded images to a local folder (pairs with read_doc’s image markers — the inverse of publishing)

list_comments / add_comment / resolve_comment

Comments, written and read through the Docs API so each sits on a range. list_comments gives each comment's quotedText, context (the sentence around it), author, time, status, replies and range. add_comment(quotedText) comments on the one place the quote matches, found the way edit_doc finds old_string (two matches are refused with context); tab comes from path, a header or footer from segment; replyTo replies instead. resolve_comment resolves or reopens, and requires expectQuotedText, the quotedText list_comments gave

drive

Drive as a filesystem: ls find mkdir cp mv. Paths are / or ~ (My Drive), /shared/<drive>, /shared-with-me, /lost+found; anything else is an id. cp preserves what markdown can’t round-trip (headers/footers, image sizing, exact formatting), so prefer it over rebuilding a template. See Drive as a filesystem. A doc is a folder of its tabs: ls <doc> lists them, ls <folder> shows each doc's tab count, a path continues into tabs (/Work/Contract/Part 2/Ch.4), and mv renames, nests (dst is another tab), un-nests (dst is the doc) and, with index, reorders a tab (mv <doc>/Summary <doc>/Summary with index: 0 reorders it in place). A tab cannot leave its doc and cp of a tab is refused

list_permissions / share_doc / unshare_doc

Sharing (share_doc handles both people and anyone-with-link). list_permissions names every audience, including domain-wide grants a Workspace adds on creation; unshare_doc revokes those by permissionId, and requires expectRole since a revocation appears in no version history

list_accounts

Authorized Google accounts

set_project_default / get_project_config

Set/show this project’s default account + folder (writes .gdocs-mcp.json)

Every doc tool takes one path for the doc — an id, a URL, /Work/Contract or /Work/Contract/Ch.4 — and an optional account (override the default). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab's path. Two tabs (or a folder and a doc) with one name are refused with each candidate's id.

Drive as a filesystem

Drive navigation is one tool speaking shell, because the model already knows shell. Arguments are positional and differ per command, exactly as they do in a terminal.

{ "cmd": "ls",    "args": ["/Work/2026"] }
{ "cmd": "find",  "args": ["quarterly report", "-type", "d"] }
{ "cmd": "mkdir", "args": ["-p", "/Work/2027/Q1"] }
{ "cmd": "cp",    "args": ["/Work/Template", "/Work/2027/Q1/Report"] }
{ "cmd": "mv",    "args": ["/Work/Roof", "/Archive"], "expectName": "Roof" }

path

is

/… or ~/…

My Drive

/shared/<drive name>/…

a shared drive

/shared-with-me

files others shared with you, which you never filed

/lost+found

files you own that are in no folder — see below

anything else

a Drive id or URL, so ids from any other tool paste straight in

Flags and operands parse in any order (cp -r a b, cp a b -r, cp a -r b), and -- ends the options.

Three places Drive is not a filesystem. The vocabulary is borrowed only where it is honest, and refuses where it is not:

  • Two files may share a name in one folder, and matching folds case. No filesystem the model learned from does either, so it would not think to check. A path matching more than one thing is refused with the candidates listed, never guessed — and cp/mv refuse to create that state too, rather than manufacturing an ambiguity the resolver would then decline to resolve.

  • cp -r does not exist. Drive's files.copy refuses folders (its own web UI cannot copy one either), so cp on a folder explains that rather than half-working.

  • mv into /shared/… gives the file away. Shell mv across filesystems leaves you owning the file; moving into a shared drive transfers ownership to that organization and cannot be undone from your side. It requires acceptOwnershipTransfer: true.

Paths see less than find does. A file with no parent still opens and still turns up in a search, but no path can name it — nothing that browses the tree will ever show it. find is the complete view; /lost+found is where those files surface.

There is no rm. See #47.

Known limitations

These are Google-API constraints, not bugs — the highlights are below; the complete reference (with the API reason and the workaround for each) is in docs/limitations.md.

  • Some changes cannot be suggested. edit_doc and write_doc take suggest: true to send an edit as suggestions, but Docs cannot suggest a new tab or doc, a table column width, deleting a header or footer, or a named range; an edit that needs one is refused before anything is sent, and is never split into a suggested part and a direct part. A header or footer that does not exist yet cannot be created as a suggestion either.

  • A comment made in Drive has no range, only its quote, and the author is a display name, never an email. Docs has no comment on the whole doc, so add_comment needs a quotedText.

  • Images are inline only (no floating/x,y positioning), and Google downscales/re-encodes embedded images, so pulled copies aren't byte-identical.

  • Headers and footers are separate content trees — not part of the body. Every content tool (read_doc, edit_doc, write_doc, list_suggestions, apply_suggestions) takes segment: "header" | "footer" to reach them, and page when a doc defines more than one.

  • Style is CSS inside the markdown — read_doc opens with a <style> block of the named styles and shows style="…" where a paragraph or run differs from its rule; edit_doc changes it (same words with new markup is a style-only edit) and the write tools accept the same CSS. It is a small set (text-align, line-height, margin-*, text-indent, font-*, text-decoration, color, in pt); anything else is refused before a request is sent. A table with nothing but Docs defaults reads as a pipe table; one with any cell or row style, set column widths or row heights, pinned header rows or merged cells reads as an HTML <table> with the same CSS (border, padding, background, vertical-align, width on <col>, height on <tr>, colspan, rowspan) and edit_doc changes it, a style-only edit sending only style requests. Lines follow CommonMark: a single newline inside a paragraph, list item or quote is a space, so a hard-wrapped file keeps its structure; a fenced or four-space-indented code block is one Courier New paragraph with its line breaks and spaces, and reads back as a fence; a > quote is a paragraph indented 36pt with a gray left border, a bare > line separating its paragraphs (>>, and a list or code block inside a quote, are refused).

See docs/limitations.md for the full table, including how each is mitigated or surfaced.

Roadmap

The "manuscript sync" use case (chapter files ⇄ tabs, reviewing suggestions, merging) is intentionally not a server feature — an AI agent orchestrates it over these primitives. See DESIGN.md §10b.

Development

npm install
npm run build      # tsc
npm test           # vitest
npm run typecheck
npm run eval:agent              # a real agent does each task in eval/tasks/; graded from the doc
npm run eval:agent -- --full    # Sonnet and Haiku, 3 runs each, before a merge
npm run eval:agent -- --tag tables
npm run eval:agent -- --check-graders   # every grader must fail on an untouched doc

eval:agent is not part of npm test: it uses real model calls and a real Google account. Each run creates its docs through the API, runs claude -p from a temp folder with only the gdocs tools and no skills, reads the result through the API, and trashes every doc it made, even after a failure. A run that fails with "Quota exceeded" in its log is retried once on its own after 60 s and reported as a quota hit, not a plain failure; a run that passed despite a quota error is a pass. Each claude -p is killed, process group included, after 10 minutes and reported as a failure ("timed out after 10 min"); GDOCS_EVAL_RUN_TIMEOUT_MS overrides that, for testing only. Every Google call the harness itself makes (setup, grading, trashing) waits 60 s and retries up to 3 times on a quota error; a run whose harness call still fails is reported as "could not run", apart from passes and failures, and still exits non-zero. --full runs 3 at a time (5 by default) to keep that rare.

See DESIGN.md for the full architecture and the empirical findings behind it.

Acknowledgements

Architecture and approach informed by prior open-source Google Docs MCP servers — notably @a-bonus/google-docs-mcp and taylorwilsdon/google_workspace_mcp.

License

MIT © Dasasian

Available Tools

19 tools
add_commentAdd a comment or replyA

Comment on text in a Google Doc: quotedText is the text the comment sits on, found the way edit_doc finds old_string (markup-tolerant; text that matches more than once is refused with the context of each match, so quote more of it). The comment stays on that text as it moves. Docs has no comment on the whole doc, so quotedText is required; put overall feedback on the title, or on its first words. The tab comes from path, and segment: "header" or "footer" comments in the page header or footer. To reply to an existing comment instead, pass replyTo (a comment id from list_comments) and no quotedText; the reply goes to the doc named by path, whatever its tab.

NameRequiredDescriptionDefault
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
contentYesthe comment, or the reply
replyToNoa comment id (from list_comments) to reply to; omit to start a new comment
segmentNowhich content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.
quotedTextNothe text to comment on; required unless replyTo is given

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the behavioral burden well: it explains that comments stay attached as text moves, ambiguous quotedText matches are refused with match context, and tab/header/footer behavior comes from path and segment. It does not cover permission requirements, notification behavior, or rate limits, so it is strong but not fully exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense and front-loads the core behavior, but some sentences are long and pack multiple constraints together. It is appropriately sized for a 7-parameter commenting tool with no annotations, and no sentence is clearly wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 7 parameters, no annotations, and no output schema, the description is largely complete: it covers the main comment action, reply mode, quoting semantics, tab resolution, and header/footer targeting. It could be slightly more complete by mentioning auth/account expectations or any side effects around comment creation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents each parameter. The description adds meaningful cross-parameter semantics: quotedText is required unless replyTo is given, replyTo takes a comment id from list_comments, path determines the tab, and segment controls body versus header/footer targeting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: commenting on text in a Google Doc, with a distinct reply mode. It also distinguishes the tool from edit_doc and list_comments, so an agent can identify its role without opening sibling schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly explains when to use quotedText versus replyTo, and gives the workaround for overall document feedback because Google Docs lacks whole-doc comments. It also routes agents to list_comments for reply IDs and edit_doc for understanding quotedText matching.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

apply_suggestionsAccept/reject one or more suggestionsA

Accept or reject pending suggestions (from list_suggestions) in one update. Each one is resolved on its own, exactly as clicking the check or the cross in Docs: accept keeps the proposed change, reject restores the original. Two suggestions that touch each other (by different people) are decided one at a time, and the text comes out as Docs makes it; to decide them together, pass both. A style-only suggestion resolves like any other. expectTitle is checked against the live document first (status "wrong_doc" on a mismatch, e.g. an id from a different, similarly-titled document), and each expectContext is checked against the live suggestion (status "error" on a mismatch or an id that is gone); nothing is changed unless all match. Pass the title and each suggestion’s context from list_suggestions, verbatim.

NameRequiredDescriptionDefault
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
segmentNowhich content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.
expectTitleYesthe document’s title, from list_suggestions; checked before anything is changed
resolutionsYesone entry per suggestion to resolve

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it explains per-suggestion resolution, accept versus reject effects, how touching suggestions are decided, style-only suggestions, preflight title/context validation with wrong_doc and error statuses, and the all-or-nothing guarantee.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first clause, and each subsequent sentence adds distinct behavioral or validation information. There is no filler or repetition; the length is justified by the tool's complexity.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations, no output schema, and a fully described input schema, the description is complete enough: it covers preconditions, atomicity, edge cases, and status behavior. Missing permission details are not material here because the schema and tool context supply account/path handling.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all parameters. The description reinforces expectTitle and expectContext semantics and verbatim sourcing from list_suggestions, but adds little parameter syntax or meaning beyond the structured schema, making baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb pair (accept/reject), resource (pending suggestions), and scope (in one update), and explicitly ties the tool to list_suggestions. An agent can distinguish it from read/list/comment-resolution siblings without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly says to use this for pending suggestions from list_suggestions and instructs passing title and each suggestion's context verbatim. It does not explicitly name when not to use it or contrast it with alternatives such as edit_doc or resolve_comment, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

download_imagesDownload a doc’s imagesA

Download every embedded image in a Google Doc to a local folder. Returns the objectId→filename mapping, which correlates with read_doc’s <img src="image:<objectId>"> markers so you can rewrite them to local paths (the inverse of publishing).

NameRequiredDescriptionDefault
dirYesabsolute local folder to save images into (created if missing)
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description must carry the burden and does disclose the meaningful behavioral facts: it writes files to a local folder and returns an objectId→filename mapping whose format is tied to read_doc's markers. It stays silent on collision/overwrite behavior for existing files and on partial-failure semantics, which are the notable remaining gaps for a filesystem-writing tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, no filler, with the core action front-loaded and the return-value detail immediately after. Every clause carries information an agent needs.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly spells out the return value and its downstream use. Combined with the fully documented schema it is nearly complete; only overwrite/error behavior for the target folder is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already explains path resolution (id/URL, folder/doc/tab), the multi-tab refusal, and that dir is created if missing. The description adds no parameter-level detail beyond that, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with a clear scope: 'Download every embedded image in a Google Doc to a local folder.' It also positions itself relative to read_doc by naming the exact marker format its output maps to, so an agent can tell what it produces and how it complements a sibling rather than duplicating it.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete downstream use case: the objectId→filename mapping lets you rewrite `<img src="image:<objectId>">` markers to local paths, framed as 'the inverse of publishing.' That is clear context for when to reach for it, but it never names an alternative (e.g., export_doc) or states when this is the wrong choice (e.g., whole-document export instead of per-image extraction).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

driveDrive as a filesystemA

Navigate and reorganise Google Drive with shell commands: ls, find, mkdir, cp, mv. Arguments are positional and follow the usual shell forms. ls [path] — list a folder (default My Drive root). find [-type d|f] — search everything by name, including files no path can reach. mkdir [-p] — create a folder. cp — duplicate a file (preserves headers/footers, image sizing and exact formatting, which a markdown round-trip cannot rebuild). mv — move and/or rename, as on a filesystem: an existing folder as means "into it", anything else means "to that name". Paths start with / or ~ (My Drive); /shared/ is a shared drive, /shared-with-me the files others shared with you, and /lost+found the files you own that are in no folder at all. Anything not starting with / or ~ is read as a Drive id or URL, so ids from any other tool can be pasted straight in. Drive permits two files with the same name in one folder and folds case when matching, unlike any real filesystem — a path that matches more than one thing is refused with the candidates listed, never guessed. A doc is a folder of tabs: ls lists its tabs, ls shows each doc with its tab count, and a path continues into tabs (/Work/Contract/Part 2/Ch.4; a tab step may also be a tabId). mv on a tab renames it, nests it (dst is another tab, or a new name under one) or un-nests it (dst is the doc), and index reorders it; a tab cannot leave its doc, and cp of a tab is refused. Content is edited with edit_doc and written with write_doc, not here; there is no rm, and nothing here deletes a tab. A tab is made by write_doc to a new path.

NameRequiredDescriptionDefault
cmdYes
argsNopositional arguments for cmd, e.g. ["/Work/Roof", "/Archive"] for mv
indexNomv of a tab only: its position among its new siblings, 0 first. Without it a tab keeps its place, or goes first when nested.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
expectNameNomv only: the name the source is expected to have; the move is refused if it resolved to something else
acceptOwnershipTransferNomv only: required to move into /shared/… , which hands ownership to that drive's organisation and cannot be undone

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full disclosure burden, and it does: ambiguity is refused with candidates listed rather than guessed, duplicate names and case-folding are called out as deviations from a real filesystem, cp preserves formatting a markdown round-trip would lose, and tabs cannot leave their doc, nor can they be copied. It also flags the non-obvious destructive edge (moving into /shared/ hands ownership to the drive's organisation), matching the schema note without contradicting it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, then commands, then path model, then tab model, then exclusions — a sensible order for a dispatcher tool. It is dense and long, with the tab paragraph packed into a single block, but nearly every clause carries a decision-relevant constraint rather than repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter, five-subcommand tool with no annotations and no output schema, the description covers commands, path grammar, the tab model, refusal behavior and out-of-scope operations. It does not describe what ls or find actually return, which is the main remaining gap given the absence of an output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 83%, so the baseline is 3, but the description adds real meaning: positional-argument conventions per command, path prefix semantics (/ and ~ for My Drive, /shared/, /shared-with-me, /lost+found), tab-step path continuation, and the rule that a non-prefixed value is treated as a Drive id or URL. It leaves expectName and account to the schema, so it stops short of full coverage.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource: "Navigate and reorganise Google Drive with shell commands," then enumerates the five subcommands. It explicitly demarcates itself from siblings by stating that content is edited with edit_doc and written with write_doc, not here, and that there is no rm. An agent can distinguish this from read_doc/edit_doc/write_doc without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states when to use this tool (navigation, reorganisation, folder creation), when not to (content editing and writing belong to edit_doc/write_doc), and names the alternatives. It also covers the creation path for tabs ("A tab is made by write_doc to a new path") and the absence of deletion, which are exactly the wrong assumptions an agent would otherwise make.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

edit_docEdit a Google DocA

Replace an exact unique snippet of text in a Google Doc (like a local file Edit). old_string is matched markup-tolerantly; ambiguous matches return surrounding context to disambiguate; a table is matched as its rows, in the form read_doc shows it (a pipe table, or the HTML of a styled one). Elements read_doc shows are kept when old_string and new_string both hold them as read (a person chip inside a sentence you reword survives), deleted when new_string leaves them out, and created when new_string adds one: [^label] with a [^label]: note line, Nov 15, 2026 (the text’s shape picks the date format), for a person or for a Drive file, with its line, and --- for a rule. A column break, equation, page-number field, or link chip to anything but a Drive file cannot be made: it is refused before anything is sent, and a chip’s text is Google’s (a chip given other words is refused). A footnote’s note is edited by quoting its [^1]: line, and a dropdown’s list by quoting its line. INSERTING IS AN EDIT: quote the text to add after (or before), write it back in new_string, and add the new content to it. Text from old_string that comes back unchanged is kept as it is, with its style, comments and suggestions, so old_string | Total | $4,200 | and new_string | Total | $4,200 |\n\nPayment due within 30 days. leaves the table alone and adds the paragraph after it; a match that ends in a table puts the new blocks after the whole table. An anchor in the middle of a paragraph splits the paragraph there. A new block carries its own style, not its anchor’s: a paragraph added after a heading, a Title or a list item is Normal text with no bullet unless the markdown says otherwise, while text added inside an existing paragraph keeps that paragraph’s style. An empty doc, tab, header or footer has nothing to anchor on: use write_doc. new_string is the same markdown and inline HTML write_doc takes: headings, lists, tables, images (<img src width height> or ![alt](src); a centered one is <p style="text-align:center"><img …></p>, local files resolve against baseDir), page breaks, and inline constructs (bold, italic, code, text, <u>, <span style="color:…;font-size:…pt">, <p style="…">, <p class="title">, and a page break as a line of its own: <div style="page-break-after:always"></div>, so new_string Title page\n<div style="page-break-after:always"></div> puts what follows on a new page; old_string can span a break) — the same spelling read_doc emits, so a read can be edited and written back. STYLE IS CSS, and this is the only way to change it. Restyle text you are not otherwise changing by giving the same words with different markup: old_string <p>4. Term, new_string <p style="margin-left:36pt; text-indent:-18pt">4. Term sends only style requests — no delete, no insert, so a long paragraph is never retyped and its words cannot change; markup missing from new_string is cleared (drop the wrapper to remove an indent). To restyle a whole named style, edit its rule in read_doc’s block: old_string p { font-family: Arial; font-size: 11pt, new_string p { font-family: Arial; font-size: 12pt becomes one updateNamedStyle and every paragraph that does not override it follows. An unsupported property (border, float, a px length, a typo) fails the edit before any request is sent, listing every offending line and the supported set. TABLE STYLE is CSS on the table’s HTML, changed the same way: read_doc shows a table with any cell or row style, wide or short columns, pinned rows or merged cells as with , (a minimum), (exactly the pinned rows), (border, padding, background, vertical-align) and colspan or rowspan, one row per line, while a table with nothing but Docs defaults stays a pipe table. old_string <td>Client</td>, new_string <td style="background:#eeeeee">Client</td> sends only the style request, and every cell whose words come back unchanged is kept, not retyped; styling a pipe table is giving the whole table back as HTML with the same words. A table edit that changes rows, columns or merges is a comparison: quote the rows around the change, write the rows you want, and only the difference is sent, an insertTableRow, deleteTableRow, insertTableColumn, deleteTableColumn, mergeTableCells or unmergeTableCells plus the text of the cells that changed, so cells you did not change keep their comments and style. A new row or column copies the style of the row above (the row below when the row above is a header row) or the column to its left (to its right for a new first column), and a style you write on it wins; links are not copied. A row or column you move is a delete and an insert: when comments quote its text the first call is refused with a confirmLoss string, so ask the user and pass it back as confirmLoss after their yes. A change that cannot be read cleanly (a row that could be an edit of either of two new rows, a table that shares no row with the old one, a column added without its line) is refused and says what to quote; a table is never rewritten whole. SUGGEST: pass suggest: true to send the edit as suggestions, for a person to accept or reject in Docs, when the user wants to review the change or the doc is not theirs; the result lists in suggestions the ids of the suggestions that now hold the edited text (a change next to your own pending suggestion joins it, and then its id is the one listed). It defaults to false, and then the edit is applied as live text: if the doc has pending suggestions from other reviewers, tell the user your edit sits alongside them as an accepted change. A change Docs cannot suggest (a table column width, for one) refuses the whole edit before anything is sent.

NameRequiredDescriptionDefault
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
baseDirNoabsolute dir to resolve relative local image paths and contentFile against
segmentNowhich content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.
suggestNosend the edit as suggestions for a person to accept or reject, instead of applying it (default false)
new_stringNoreplacement markdown (or use contentFile)
old_stringYesexact text to replace (quote a unique slice from read_doc)
confirmLossNothe confirmLoss string from the refusal of a table edit that moves a row or column whose text comments quote, passed back exactly, after the user has agreed that those comments are lost. Never needed otherwise.
contentFileNopath to a local markdown/text file to use as new_string, read directly by the server — preferred for long text. Absolute, or relative to baseDir. Mutually exclusive with new_string.
replace_allNoreplace every occurrence (default false)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full behavioral burden and does so extensively: markup-tolerant matching, ambiguity handling, element preservation/deletion/creation, atomic refusal for unsupported constructs, table comparison edits, comment-loss confirmation, and suggestion behavior are all disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is front-loaded and many details are relevant, but the description is a dense block with no paragraph or heading structure, making key rules hard to scan. It is overlong for easy agent consumption even if much of the content is valuable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex, 11-parameter mutation tool with no annotations and no output schema, the description covers creation/insertion, empty-document handoff, headers/footers, table and style editing, refusals, suggestions, and result shape. An agent has enough context to invoke it correctly in the described scenarios.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds substantial meaning for old_string matching, new_string markdown/HTML, suggest, and confirmLoss. It adds little beyond the schema for page, segment, account, baseDir, or replace_all.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a precise verb and resource: replace an exact unique text snippet in a Google Doc. It also distinguishes the operation from write_doc for empty documents and from read_doc by requiring a quoted slice from a read.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names alternatives in several conditions, such as read_doc for quoting and write_doc for empty docs/tabs/headers, and explains suggest:true for review or non-owned docs. However, the when-to-use guidance is spread throughout rather than stated as a concise upfront rule, and there is no broad exclusion beyond empty content.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

export_docExport a doc to a fileA

Export a Google Doc to a real file on disk — pdf (default), docx, odt, rtf, txt, html, epub, or md. Google renders it server-side (File > Download in the UI), so page setup, pagination and layout match the editor. A doc path exports every tab; a tab path (/folder/doc/tab) exports only that tab, through an endpoint Google does not document and rate-limits — if it fails the call is refused and says so, it never falls back to the whole doc. Returns the local path and byte size. Note: Drive refuses to export files larger than 10 MB.

NameRequiredDescriptionDefault
dirYesabsolute local folder to save the export into (created if missing)
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
formatNodefault pdf
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
filenameNooverride the filename (default: the doc’s title + extension)

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses server-side rendering, the undocumented and rate-limited tab endpoint, a refusal-without-fallback failure mode, and the 10 MB Drive export limit. It also states the return values (local path and byte size), which is important given there is no output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Despite covering formats, rendering behavior, tab semantics, failure mode, return values, and size limits, every sentence is front-loaded and information-dense with no filler. The ordering moves from what the tool does to how it behaves to what it returns.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter export tool with no output schema and no annotations, the description supplies everything needed: format defaults, tab-path behavior, rate-limit and size constraints, failure semantics, and return values. Nothing an agent needs in order to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: it explains that a doc path exports every tab while a tab path exports only that tab, and that pdf is the default format. The remaining parameters (dir, account, filename) are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource ('Export a Google Doc to a real file on disk'), enumerates supported formats, and clearly distinguishes its output from siblings like read_doc by emphasizing a real file on disk. An agent can identify exactly what this tool produces without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear context for when to use it (saving a doc as a file with editor-faithful layout) and explains the tab-path vs doc-path distinction. It stops short of explicitly naming alternatives such as read_doc for in-memory reading, so it earns a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_page_setupRead document page setupA

Read a doc’s (or tab’s) page setup — margins, page size (in points, plus a preset name if it matches letter/legal/a4/tabloid), and orientation. The read counterpart to set_page_setup; use it to mirror another document’s layout onto a new doc.

NameRequiredDescriptionDefault
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description still makes clear this is a read operation and describes the observable result fields and preset matching behavior. It does not cover permissions or error handling, but for a read-only single-object tool the behavioral profile is reasonably well disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is two front-loaded sentences with no wasted text. It states the operation first, then the return details, then the sibling relationship and use case.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description usefully names the key return values and explains preset-name matching. It is nearly complete for a simple read tool, though it does not describe permissions, error cases, or full response shape.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the path and account parameters are already well documented in the schema. The description adds only the general notion that the target may be a doc or tab, which is already captured by the path schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb-resource pair, “Read … page setup,” and immediately enumerates the returned properties: margins, page size, preset name, and orientation. It also explicitly distinguishes itself from sibling set_page_setup by calling itself the read counterpart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative set_page_setup and gives a concrete use case: mirroring another document’s layout onto a new document. It does not explicitly state when not to use it, but the read/write split is clear from the counterpart framing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_project_configShow this project’s gdocs defaultsA

Show the effective .gdocs-mcp.json defaults (account/folder) for the current working directory, and where the file is.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full burden. It discloses that the tool reads a project configuration file and shows the effective defaults and file location. 'Show' implies no side effects, and the specificity about output (account/folder and file path) is transparent. It doesn't cover edge cases like a missing config, but for a simple getter this is adequate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single sentence that front-loads the action and then specifies the resource and additional output (file location). Every word earns its place; there is no redundancy, and it is appropriately sized for a tool with no parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity (no params, no output schema), the description is complete enough. It explains what the tool does and what it shows (defaults and file location), which serves as a high-level return description. It could mention error behavior or fallback defaults, but this is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the baseline is 4. The input schema is empty and fully covers the parameter surface. The description adds no parameter-specific details because none exist, but it clarifies what the tool returns in context of the project configuration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Show'), the specific resource ('.gdocs-mcp.json defaults'), and the scope ('current working directory'). It also distinguishes itself from siblings like 'set_project_default' by focusing on the read/display side, and from 'list_accounts' by targeting project-level configuration.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context for when to use the tool: when you need to see the effective project defaults (account/folder) and the config file location. It doesn't explicitly name alternatives or exclusions, but the read-only nature is distinguishable from write-style siblings like 'set_project_default'.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsList authorized Google accountsA

List the Google accounts that have been authorized for this server.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries full responsibility. It clearly indicates a read-only action by using 'List,' and there are no side effects or hidden behaviors to disclose. However, it adds no context beyond the obvious purpose—no mention of what the output looks like, whether accounts are returned as emails, or if authorization status has any caveats. This is a baseline acceptable transparency for a simple read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, concise sentence: 'List the Google accounts that have been authorized for this server.' It is front-loaded with the action verb and resource, contains no filler, and every word earns its place. Properly sized for the tool's trivial parameter surface.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter tool with no output schema, the description is complete. It tells the AI agent exactly what the tool does, and because there are no parameters to configure or complex return values to explain, no additional information is needed. The context is fully covered by this single sentence.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema is trivially complete. The description does not need to explain any parameters. Per the rubric, 0 params receives a baseline of 4, and nothing in the description detracts from this. The description correctly focuses on the tool's purpose rather than inventing parameter detail.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb 'List' with a clear resource: 'Google accounts that have been authorized for this server.' This distinguishes it from sibling list tools like list_folder, list_tabs, or list_comments, which target different resources. The phrasing is unambiguous and matches the title exactly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus the many sibling tools, nor does it mention any exclusions or alternatives. It simply restates the purpose without context about scenarios where checking authorized accounts would be appropriate. There is no 'when to use' or 'instead' language.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_commentsList comments on a docA

List the comments on a Google Doc, each with the text it is on (quotedText), the sentence around it (context, the text in ⟦⟧), its author (a display name, never an email) and time, whether it is open or resolved, its body and its replies. A comment with a range is on that part of the doc, in the body or in a header or footer, and moves with its text; a comment with none was made in Drive and has only its quoted text. Pass a comment’s id as replyTo to add_comment, and its quotedText as expectQuotedText to resolve_comment.

NameRequiredDescriptionDefault
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden and does well: it discloses that authors are display names never emails, that status is open or resolved, and that comments with a `range` track their text in body/header/footer while rangeless ones came from Drive. It omits permission requirements and whether resolved comments are included by default or any pagination behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Lists the returned fields first, then the range/Drive distinction, then the hand-off to sibling tools — well front-loaded with no filler. It is dense to the point of being a long single sentence in places, which slightly taxes parsing but every clause carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates fully by describing the shape of each returned comment (quotedText, context with ⟦⟧ markers, author, time, open/resolved, body, replies). Combined with the schema-covered inputs, an agent has everything needed to call and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both `path` and `account` are already documented in the schema (including the /folder/doc and tab-path forms). The description adds no parameter-level detail beyond that, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the comments on a Google Doc') and immediately enumerates the returned fields, so an agent knows exactly what it gets. It also names the sibling tools add_comment and resolve_comment and the exact fields that bridge to them, distinguishing it from the write-side siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides concrete workflow routing: pass a comment's `id` as replyTo to add_comment, and its `quotedText` as expectQuotedText to resolve_comment — effectively telling the agent when to use this tool (discovery before replying/resolving). It does not state explicit exclusions or a when-not-to-use case, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_permissionsList who a doc is shared withA

List the permissions on a Google Doc (people, groups, domain, anyone-with-link) with their roles. Each entry carries a subject naming who it covers — an email, " (domain)", or "anyone with the link" — since a domain or link grant has no email. For those, allowFileDiscovery: true means the file also surfaces in that audience's search, not merely that it opens with the link. Note a doc created under a Workspace domain may already carry a domain grant before you share it.

NameRequiredDescriptionDefault
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden well: it discloses the return model (subject naming scheme), explains the non-obvious allowFileDiscovery semantics, and warns that a doc may already carry a domain grant. It stops short of stating permissions/auth requirements or that the operation is non-mutating, but the read-only nature is strongly implied by 'List'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action is front-loaded in the first sentence, followed by tightly scoped clarifications on subject formatting and grant semantics. Dense but every sentence adds interpretation the agent needs; only the final 'note' is somewhat peripheral.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description correctly compensates by explaining the entry shape (subject values, roles, allowFileDiscovery). Little is missing for an agent to call and interpret this tool, though pagination/ordering behavior is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters (path, account) are fully documented in the schema, so baseline is 3. The description adds no parameter-level detail beyond what the schema already provides.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'List the permissions on a Google Doc ... with their roles', and enumerates the grant types (people, groups, domain, anyone-with-link). This clearly differentiates it from the mutating siblings share_doc and unshare_doc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied — it's an inspection tool you'd call before/after share_doc or unshare_doc — but the description never explicitly states when to use this versus those alternatives, nor any preconditions. The closing note about pre-existing domain grants hints at a use case without framing it as guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_suggestionsList suggestions in a docA

List the pending suggestions (tracked changes) in a Google Doc, in document order. Each has an id, a summary (Docs’ own words for it, as in the Docs sidebar, e.g. Replace: “30” with “45”), a context (the change in its sentence, [deleted→inserted], so two suggestions with the same summary can be told apart), and its author and time. Returns the doc title. Pass the title as expectTitle and each context as expectContext to apply_suggestions. segment: "header" or "footer" lists that one’s suggestions.

NameRequiredDescriptionDefault
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
segmentNowhich content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description does the heavy lifting well: it enumerates the returned fields (id, summary, context, author, time, doc title), states ordering, and explains why context exists (to disambiguate identical summaries). It omits any mention of permission requirements or errors, which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return shape, then chaining guidance, with zero filler. The trailing "segment:" sentence is compressed almost to the point of being a schema echo, but it is short enough not to cost much.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates by describing return fields, ordering, and the destination tool for the values. Given a 4-param tool with full schema coverage, only edge cases (empty results, suggestion-only tabs) are unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description earns above that by explaining that segment: header or footer scopes the listing to that one tree, and by pairing doc title with expectTitle. It doesn't clarify page/account semantics, but those are covered in-schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List the pending suggestions (tracked changes) in a Google Doc") plus the ordering ("in document order"), which cleanly separates it from list_comments and read_doc. The scope qualifier "pending" and the parenthetical gloss of tracked changes make it unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent forward: "Pass the title as expectTitle and each context as expectContext to apply_suggestions," which is actionable chaining guidance rather than vague context. It lacks an explicit exclusion statement (e.g. when to use list_comments instead), which keeps it off a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

read_docRead a Google DocA

Read a Google Doc as markdown + inline HTML. The read opens with a block — one CSS rule per named style (p = Normal text, h1–h6, .title, .subtitle), in pt — and a paragraph or run shows style="…" only where it differs from its rule (text-align, line-height, margin-top/bottom/left/right, text-indent; a hanging indent is margin-left:36pt with a negative text-indent). Title and Subtitle paragraphs read as . A page break reads as on its own line, where the break is. Every element in a paragraph reads, so an edit that quotes one can give it back: a footnote is [^1] with its note as a [^1]: line at the end; a date is Nov 15, 2026; a person or a link chip is Jane Doe (the text is Google’s); a dropdown is with its list as a Draft line after the block; a horizontal rule is --- on a line of its own; a column break is ; an equation and a page-number field are empty and whose title says to edit them in Google Docs. A table of contents is not read. List items show no indent: their nesting owns it. mode: clean (committed text, default) · tracked (suggestions shown as /) · accepted · rejected. segment picks the content tree: body (default), header, footer, or all (body plus every header/footer, each labelled). Text that would otherwise read as markup is marked as literal: a paragraph wrapped in … ("4. Term" is a paragraph, not a list) or a backslash before a character (5 * 3), and \ is a real backslash — write them back as read, and the document keeps only the words. A body read always reports which headers/footers exist and what they hold, since their content — a letterhead logo, a page number — is NOT part of the body and would otherwise be invisible.

NameRequiredDescriptionDefault
modeNoread mode (default clean)
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
segmentNocontent tree to read (default body)

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations to lean on, the description carries the full burden and does so unusually well: it discloses output structure (style block, class-based paragraphs), how every inline element serializes (footnotes, time, chips, dropdowns, rules, column breaks, equations), and explicit limitations ('A table of contents is not read', 'List items show no indent'). It also warns that a body read reports headers/footers because their content is 'NOT part of the body and would otherwise be invisible', which is exactly the non-obvious behavior an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded and purposeful, and given there is no output schema most of the format detail earns its place. However it is delivered as one very long run-on paragraph of semicolon-chained clauses with no breaks or structure, making it hard to scan for the parts an agent needs at call time.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description must define the return format, and it does so exhaustively — styling rules, literal-escaping semantics, every inline element type, and what is deliberately omitted. For a 5-parameter read tool at this complexity, an agent has everything needed to call it and interpret the result correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning to the enums that the schema only labels: mode is explained as clean (committed text, default) vs tracked (suggestions as <ins>/<del>) vs accepted/rejected, and segment as body/header/footer/all with 'all' defined as body plus every labelled header/footer. page and account are left entirely to the schema, so it stops short of a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource plus the output contract: 'Read a Google Doc as markdown + inline HTML.' An agent can immediately distinguish this from write_doc, edit_doc, or export_doc without inspecting the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the note that 'an edit that quotes one can give it back' hints at round-tripping with edit_doc, and mode/segment values imply selection contexts, but there is no explicit when-to-use / when-not-to-use guidance or named alternative (e.g., export_doc, get_page_setup). The agent must infer routing from sibling names alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

resolve_commentResolve or reopen a commentA

Resolve (or reopen) a comment thread by comment id. expectQuotedText is REQUIRED: the quotedText list_comments gave for that comment, exactly. It is checked against the live comment first, so a stale or wrong id is refused instead of resolving the wrong thread.

NameRequiredDescriptionDefault
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
reopenNoreopen instead of resolve
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
commentIdYes
expectQuotedTextYesthe comment’s quotedText from list_comments; verified before the comment is changed

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does disclose the key behavioral trait: expectQuotedText is verified against the live comment before mutation, so a stale id is refused rather than resolving the wrong thread. That is genuinely valuable safety context. Remaining gaps, such as required permissions or the shape of the follow-up read, keep it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the action and the required-parameter rule; every clause carries usable information and nothing is repeated from the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and no output schema, the description covers the main correctness risk (wrong thread resolved via stale id) and points to the sibling that produces the required value. It leaves permissions and any returned confirmation unstated, which is a minor but real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 80%, so most parameters are already documented, but commentId has no schema description and the description supplies its origin (the commentId from list_comments) along with the contract for expectQuotedText. It clarifies why the verification parameter exists and what happens when it fails, adding meaning beyond the schema text rather than restating it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Resolve (or reopen) a comment thread by comment id'), immediately distinguishing it from the read-only siblings list_comments and add_comment. The title and first sentence together let an agent place it precisely in the comment workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description routes the agent to list_comments as the source of the required `quotedText`, which is a concrete usage precondition rather than vague context. It doesn't cover access prerequisites or when a resolve should be skipped in favor of add_comment, so it stops short of naming exclusions explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_page_setupSet document page setupA

Set document-level page setup for a doc (or tab): page margins, page size, and orientation — the File > Page setup controls. Margins and explicit page sizes are in points (72 pt = 1 inch). pageSize is a preset (letter/legal/a4/tabloid) or an explicit {width,height} in points; orientation (portrait/landscape) swaps the page dimensions. Always a direct change: page geometry is a document-style change, so there is no suggest option.

NameRequiredDescriptionDefault
pathYesThe doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
pageSizeNoa preset name, or {width,height} in points
marginTopNotop margin in points (72 = 1 inch)
marginLeftNoleft margin in points
marginRightNoright margin in points
orientationNoportrait or landscape (orders the page width/height)
marginBottomNobottom margin in points

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are supplied, so the description carries the full burden, and it does disclose real behavioral traits: units (72 pt = 1 inch), that orientation reorders width/height, and that the change is always applied directly with no suggest mode. It does not say whether omitted parameters are left untouched or reset, nor what permissions or return value to expect, which are the remaining gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences: purpose first, then units and parameter semantics, then the mutation-mode caveat. No restatement of the tool name and no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter mutation tool with no annotations and no output schema, the description covers units, enum/object duality, orientation behavior, and mutation semantics adequately. It is only missing what a successful call returns and whether the update is partial or full — the one area the absent output schema would otherwise cover.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above baseline by explaining that pageSize accepts a preset name or an explicit {width,height} in points and by clarifying that orientation "swaps the page dimensions" rather than being a no-op. The tab-path disambiguation is left entirely to the schema's path description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Set document-level page setup") and enumerates exactly what is changed: margins, page size, orientation. The "File > Page setup controls" mapping plus the doc-or-tab scope makes it immediately distinguishable from the read-side sibling get_page_setup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for when this applies (document-level page geometry on a doc or tab) and an explicit exclusion: "there is no suggest option," so the agent knows not to route this through the suggestion workflow used by edit_doc/apply_suggestions. It stops short of naming get_page_setup as the read counterpart, but the scope statement implies it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

set_project_defaultSet this project’s default account/folderA

Write this project’s defaults to a .gdocs-mcp.json in the current working directory (or update an existing one up the tree). Set a default account and/or a default folder (URL or id). The folder is where write_doc is told new docs go: a new doc given as a bare name or at the top of My Drive is refused once, naming the folder and the full path to call. It is read when the server starts, so write_doc’s description shows a change after a restart; the refusal reads it fresh. To set a folder by name, find it first with drive({ cmd: 'find' }) and pass its id.

NameRequiredDescriptionDefault
folderNodefault Drive folder (URL or id): where write_doc says a bare-named new doc will go
accountNodefault Google account email (must be authorized)

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so well: it discloses the on-disk side effect (writes/updates `.gdocs-mcp.json` up the tree), the restart semantics for write_doc's description versus the freshly-read refusal path, and the auth requirement on the account field. That is exactly the behavioral context an agent needs before mutating project state.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded: the write target and file location come first, then behavior, then the how-to. It is dense and mostly earns its space, though the sentence about restart versus fresh-read refusal is tangled and takes a second pass to parse.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter mutation tool with no annotations and no output schema, the description covers file location, side effects, downstream behavior in write_doc, and the id-lookup workaround. Only the response shape (confirmation of what was written) is left implicit, which is a minor gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3. The description adds genuine meaning beyond the schema: folder accepts a URL or id, either parameter alone is sufficient ("and/or"), and a folder given by name must first be resolved to an id via drive({ cmd: 'find' }).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a concrete verb+resource: it writes the project's defaults to a `.gdocs-mcp.json` file in the cwd or an existing one up the tree. It names exactly what is being set (default account and/or default folder) and how that differs from siblings like get_project_config and set_page_setup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly states when the setting takes effect and how to resolve a folder given only a name (use drive({ cmd: 'find' }) and pass the id). It doesn't explicitly contrast with get_project_config for reading, but the usage context is otherwise unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

share_docShare a doc (person or link)A

Grant access to a Google Doc. With email, share with that person as reader/commenter/writer (optionally sending a notification). Without email, set anyone-with-link access to that role, or role "none" to disable link sharing. (To revoke a specific person’s access, use unshare_doc.)

NameRequiredDescriptionDefault
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
roleNoaccess level; default writer. "none" (link only) disables link sharing.
emailNoperson to share with; omit to set anyone-with-link access instead
notifyNowhen sharing with a person, send a notification email (default true)
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the behavioral burden and does well by disclosing that this is an access-granting mutation, that person sharing can optionally send a notification, and that role "none" disables link sharing. It does not mention required account permissions, idempotence, or what the operation returns, but the core state-changing behavior is clear.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is three tight sentences with no filler. The main action is front-loaded, followed by the person-sharing and link-sharing branches, with the alternative tool noted parenthetically at the end.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a five-parameter tool with 100% schema description coverage and no output schema, the description supplies the missing behavioral context: the distinction between person and link sharing, notification behavior, and the meaning of role "none". Nothing essential for correct invocation is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaningful semantics beyond the schema by explaining the `email` presence/absence branching and the effect of role "none" on link sharing. The `notify` behavior for person sharing is also clarified, though `path` and `account` semantics are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: "Grant access to a Google Doc." It clearly distinguishes the person-sharing mode (`email`) from the link-sharing mode (no `email`) and explicitly names the sibling tool for revocation, `unshare_doc`. An agent can identify the tool's function and boundaries without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is explicitly conditional: provide `email` to share with a person, omit `email` to set anyone-with-link access. It also states that role "none" disables link sharing and directs revocation of a specific person's access to `unshare_doc`, covering both when to use this tool and when to use an alternative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

unshare_docRemove someone’s accessA

Revoke a grant on a Google Doc. Pass email for a person or a group. A grant with no email — a domain-wide grant, or anyone-with-link — has no email to pass, so address it by permissionId from list_permissions (run that first; it also tells you the role you are about to remove). Refuses to touch the owner. expectRole is REQUIRED — run list_permissions first and echo the role back; a permission change is recorded nowhere and cannot be restored from version history, so this is the only thing standing between a misaimed call and a silent, unrecoverable revocation. Note a doc created under a Workspace domain may carry a domain grant nobody explicitly added.

NameRequiredDescriptionDefault
pathYesThe doc: a Drive id or URL, or /folder/doc. A tab path names its doc.
emailNoperson or group to revoke; omit when using permissionId
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
expectRoleYesREQUIRED — the grant's current role as list_permissions reported it (reader/commenter/writer). Verified first: if it changed since you looked, nothing is removed. Revoking leaves no record anywhere, so this makes you look before you cut.
expectTitleNothe doc’s title; verified before revoking so a wrong id is refused
permissionIdNoid from list_permissions — the only way to revoke a domain or anyone-with-link grant

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses that revocation is unrecorded and unrecoverable from version history, that expectRole/expectTitle act as verified pre-conditions that fail closed, that the owner is protected, and that hidden domain grants may exist to surprise the agent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then addressing modes, then safety rationale — a sensible order with no filler sentences. It loses a point because the expectRole warning largely restates the schema's own expectRole description, which is mild duplication of structured data.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive 6-parameter mutation with no annotations and no output schema, the description supplies the pre-conditions, the safety model, the grant-addressing edge cases, and the failure behavior. Nothing material is left for the agent to guess.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description goes beyond it by explaining the email/permissionId routing decision and why expectRole must be echoed from a prior list_permissions call. It adds decision-relevant meaning, not just labels.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb and resource ('Revoke a grant on a Google Doc'), which cleanly separates it from the sibling share_doc. The rest of the paragraph clarifies the two addressing modes, so the agent knows exactly what operation is being selected.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states when to use `email` versus `permissionId`, mandates list_permissions first for both the id and the role, and calls out the owner-refusal boundary. That is a full when/when-not/prerequisite statement rather than an implied one.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

write_docWrite a doc or a tabA

Write markdown-rendered content to a path, like the local Write tool. A path that names nothing is CREATED and never asks, but only an absolute path (or a Drive id or URL start) creates: a bare name like Contract is refused with the full path to call. When the project has a default folder for new docs, a new doc at the top of My Drive (/Contract) is refused once too, with the default folder’s full path to call, so the user is told where it goes first; the same call repeated goes through: /Work/Contract creates a doc in the folder /Work, /Work/Contract/Notes a tab in that doc, /Work/Contract/Part 2/Ch.4 a child tab under Part 2 (only the last step may be new; make the folder with drive mkdir first). A path that names something is REPLACED, and the first call is refused with a loss summary — the paragraphs of text and everything a read cannot carry that the replace would take with it: comments, suggestions, tab stops, links to bookmarks, section breaks, a table of contents, column breaks, equations, page-number fields, a date in a format the API can only read, and a link chip to anything but a Drive file — plus a confirmLoss string. Ask the user before anything else — show them what would be lost and wait for a yes; never pass confirmLoss on your own. Only after their yes, call again with the same content and confirmLoss set to that string exactly. If the doc changed in between, the string no longer matches and the call is refused again with a fresh summary. A doc with several tabs needs a tab step (the refusal lists them); a doc with one tab means that tab. Nothing to lose, nothing to ask: an empty doc, tab, header or footer is written without the refusal. segment: "header" or "footer" writes the page header or footer of an existing doc instead of its body: a missing default one is created and written, an existing one with content is replaced after the same confirmLoss round-trip, and a missing first-page or even-page one (page: "first" / "even") is refused with the instruction to turn on Different first page in Docs. Replacing keeps the doc’s title, sharing and other tabs but the new paragraphs start unstyled, so anything not in the markdown (including indents) is gone; prefer edit_doc to change a document, which keeps everything its anchor does not cover. Style is CSS, in the spelling read_doc emits: a leading block sets the named styles (p, h1–h6, .title, .subtitle), / / style a paragraph, a run. Supported: text-align, line-height, margin-top/bottom/left/right, text-indent (pt; text-indent is relative to margin-left), and on spans/rules font-family, font-size, font-weight, font-style, text-decoration, color. Any other property fails the whole write before anything is sent, listing every offending line. Footnotes, dates, person chips, Drive link chips and dropdowns are written back as read_doc spells them ([^1] and a [^1]: note line; ; ; with its line); --- is written as an empty paragraph with a thin grey bottom border. A new column break, equation, page-number field, or link chip to anything but a Drive file (YouTube, Calendar, Maps, a web page) is refused before anything is sent: the API cannot make it, so write text for a link, or ask the user to insert the rest in Google Docs. A chip’s text is Google’s, so a chip given other words is refused. A page break is on a line of its own (also accepted: , break-before: page, break-after: page); any other or is refused. For long documents, pass contentFile instead of content so the server reads the body directly (retyping a long doc inline can silently drop text). Returns images ({src, objectId}) for pushed images. suggest: true sends the replace as suggestions for a person to accept or reject in Docs, and never asks for confirmLoss: nothing is lost until a person accepts, and rejecting brings back the text, images, tables and comments as they were. It needs a path that already names something (a new doc or tab cannot be a suggestion), refuses a table column width (Docs cannot suggest one) before anything is sent, and lists the suggestion ids in suggestions; use it when the user wants to review the rewrite or the doc is not theirs. It defaults to false: the replace is applied as live text.

NameRequiredDescriptionDefault
pageNowhich header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.
pathYesThe doc or tab to write: /folder/doc, /folder/doc/tab, /folder/doc/tab/child, or a doc id or URL followed by tab steps. A path that does not exist yet is created (only its last step may be new).
accountNoGoogle account email to use. Defaults to GDOCS_DEFAULT_ACCOUNT, or the sole account.
baseDirNoabsolute dir to resolve relative local image paths against (e.g. the markdown file’s folder)
contentNomarkdown content (or use contentFile)
segmentNowhich content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.
suggestNosend the replace as suggestions for a person to accept or reject, instead of applying it (default false)
confirmLossNothe confirmLoss string from the refusal, passed back exactly, after the user has agreed to what it lists. Never needed when creating, or with suggest.
contentFileNopath to a local markdown/text file to use as the body, read directly by the server — preferred for long documents so the body is passed through mechanically rather than retyped inline (which can silently drop text). Absolute, or relative to baseDir. Mutually exclusive with content.

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the full burden and does so: it discloses the two-step refusal/confirmLoss loss-summary protocol, what exactly would be destroyed (comments, suggestions, tab stops, TOC, equations, chips), that replacement resets paragraph styling, that unsupported CSS fails the whole write before anything is sent, and that suggest mode is reversible. This is a genuinely rare level of mutation-risk disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Almost every clause earns its place, but the body is a single very long paragraph mixing path semantics, styling rules, chip encoding, refusal behavior, and suggest mode, which makes it hard to scan under context pressure. It is front-loaded correctly (create/replace first), but structure could be improved with grouping.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation tool with no annotations and no output schema, coverage is strong: creation, replacement, headers/footers, styling, special elements, long-content handling, and suggestion mode are all covered. The only modest gap is that the return value is described in a single clause ('Returns images') without indicating what a successful write otherwise returns.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, but the description adds real semantics on top: path creation rules (absolute/id/URL only, bare names refused with the full path to call), the default-folder second refusal, tab-step nesting rules, segment header/footer behavior including the first/even refusal, page-type behavior, and page-break encodings. Nothing critical is left to schema inference alone.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource: 'Write markdown-rendered content to a path', and immediately establishes the create-vs-replace dichotomy that defines the tool. It also explicitly routes away from the closest sibling ('prefer edit_doc to change a document'), so an agent can distinguish it from edit_doc/read_doc without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete when-to-use rules: use contentFile for long documents, use suggest when the user wants to review or the doc isn't theirs, use edit_doc for in-place changes, and use drive mkdir before creating nested folders. It also states when NOT to act (never pass confirmLoss on your own; ask the user first) and enumerates what gets refused.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 31 tool updatesv1.0.0
    • Changedadd_comment8 fields changed
      • addedInput schema / properties / content / description
        Added value: +"the comment, or the reply"
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • addedInput schema / properties / quotedText
        Added value: +{
        +  "description": "the text to comment on; required unless replyTo is given",
        +  "type": "string"
        +}
      • changedInput schema / properties / replyTo / description
        Previous value: -"a comment id (from list_comments) to reply to; omit to start a new top-level comment"New value: +"a comment id (from list_comments) to reply to; omit to start a new comment"
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "content"
        -]New value: +[
        +  "path",
        +  "content"
        +]
    • Removedadd_tab
    • Changedapply_suggestions9 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • removedInput schema / properties / documentTitle
        Removed value: -{
        -  "description": "The document's title, from list_suggestions. Shown for confirmation only.",
        -  "type": "string"
        -}
      • addedInput schema / properties / expectTitle
        Added value: +{
        +  "description": "the document’s title, from list_suggestions; checked before anything is changed",
        +  "type": "string"
        +}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • addedInput schema / properties / resolutions / items / properties / expectContext
        Added value: +{
        +  "description": "the suggestion’s `context` from list_suggestions, verbatim",
        +  "type": "string"
        +}
      • removedInput schema / properties / resolutions / items / properties / expectedChange
        Removed value: -{
        -  "description": "the suggestion's `preview` from list_suggestions",
        -  "type": "string"
        -}
      • changedInput schema / properties / resolutions / items / required
        Previous value: -[
        -  "suggestionId",
        -  "decision",
        -  "expectedChange"
        -]New value: +[
        +  "suggestionId",
        +  "decision",
        +  "expectContext"
        +]
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "documentTitle",
        -  "resolutions"
        -]New value: +[
        +  "path",
        +  "expectTitle",
        +  "resolutions"
        +]
    • Removedcreate_doc
    • Removeddelete_tab
    • Changeddownload_images4 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "dir"
        -]New value: +[
        +  "path",
        +  "dir"
        +]
    • Changeddrive1 field changed
      • addedInput schema / properties / index
        Added value: +{
        +  "description": "mv of a tab only: its position among its new siblings, 0 first. Without it a tab keeps its place, or goes first when nested.",
        +  "minimum": 0,
        +  "type": "integer"
        +}
    • Changededit_doc9 fields changed
      • addedInput schema / properties / baseDir
        Added value: +{
        +  "description": "absolute dir to resolve relative local image paths and contentFile against",
        +  "type": "string"
        +}
      • addedInput schema / properties / confirmLoss
        Added value: +{
        +  "description": "the confirmLoss string from the refusal of a table edit that moves a row or column whose text comments quote, passed back exactly, after the user has agreed that those comments are lost. Never needed otherwise.",
        +  "type": "string"
        +}
      • addedInput schema / properties / contentFile
        Added value: +{
        +  "description": "path to a local markdown/text file to use as new_string, read directly by the server — preferred for long text. Absolute, or relative to baseDir. Mutually exclusive with new_string.",
        +  "type": "string"
        +}
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • changedInput schema / properties / new_string / description
        Previous value: -"replacement text"New value: +"replacement markdown (or use contentFile)"
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • addedInput schema / properties / suggest
        Added value: +{
        +  "description": "send the edit as suggestions for a person to accept or reject, instead of applying it (default false)",
        +  "type": "boolean"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "old_string",
        -  "new_string"
        -]New value: +[
        +  "path",
        +  "old_string"
        +]
    • Removededit_table
    • Changedexport_doc3 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "dir"
        -]New value: +[
        +  "path",
        +  "dir"
        +]
    • Changedget_page_setup4 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Removedget_style
    • Removedget_table_style
    • Removedinsert_content
    • Removedinsert_image
    • Removedinsert_table
    • Changedlist_comments3 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Changedlist_permissions3 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Changedlist_suggestions4 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Removedlist_tabs
    • Removedoverwrite_doc
    • Changedread_doc4 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Removedrename_tab
    • Changedresolve_comment5 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • removedInput schema / properties / expectQuote
        Removed value: -{
        -  "description": "snippet of the comment’s quoted text/body; verified before resolving",
        -  "type": "string"
        -}
      • addedInput schema / properties / expectQuotedText
        Added value: +{
        +  "description": "the comment’s quotedText from list_comments; verified before the comment is changed",
        +  "type": "string"
        +}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "commentId"
        -]New value: +[
        +  "path",
        +  "commentId",
        +  "expectQuotedText"
        +]
    • Changedset_page_setup4 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "description": "Google Doc id",
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc or tab: a Drive id or URL, /folder/doc, or /folder/doc/tab (nested: /folder/doc/tab/child). A doc with one tab needs no tab step; a doc with several is refused until one is named, and the refusal lists every tab path.",
        +  "type": "string"
        +}
      • removedInput schema / properties / tab
        Removed value: -{
        -  "description": "Target a specific tab by tabId or title (from list_tabs). Defaults to the first tab.",
        -  "type": "string"
        -}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Changedset_project_default1 field changed
      • changedInput schema / properties / folder / description
        Previous value: -"default Drive folder (URL or id) for new docs"New value: +"default Drive folder (URL or id): where write_doc says a bare-named new doc will go"
    • Removedset_style
    • Removedset_table_style
    • Changedshare_doc3 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId"
        -]New value: +[
        +  "path"
        +]
    • Changedunshare_doc3 fields changed
      • removedInput schema / properties / documentId
        Removed value: -{
        -  "type": "string"
        -}
      • addedInput schema / properties / path
        Added value: +{
        +  "description": "The doc: a Drive id or URL, or /folder/doc. A tab path names its doc.",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "expectRole"
        -]New value: +[
        +  "path",
        +  "expectRole"
        +]
    • Addedwrite_doc
  2. 6 tool updatesv0.6.0
    • Removedcopy_doc
    • Removedcreate_folder
    • Addeddrive
    • Removedlist_folder
    • Removedsearch_drive
    • Removedupdate_doc
  3. 16 tool updatesv0.5.0
    • Changedapply_suggestions2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Addedcopy_doc
    • Addedcreate_folder
    • Changededit_doc2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Changededit_table2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Addedexport_doc
    • Changedget_style2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Addedget_table_style
    • Addedinsert_content
    • Changedinsert_image5 fields changed
      • addedInput schema / properties / baseDir
        Added value: +{
        +  "description": "absolute dir to resolve a relative local `uri` against",
        +  "type": "string"
        +}
      • addedInput schema / properties / createSegment
        Added value: +{
        +  "description": "when segment is header/footer and the doc has none, create it first (the letterhead case). Only the default header/footer can be created via the API.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / uri / description
        Previous value: -"public image URL"New value: +"public image URL, or a path to a local image file (absolute, or relative to baseDir)"
    • Changedinsert_table4 fields changed
      • addedInput schema / properties / align
        Added value: +{
        +  "description": "per-column text alignment, e.g. [\"left\",\"right\"]; null or \"left\" leaves a column at the default",
        +  "items": {
        +    "anyOf": [
        +      {
        +        "enum": [
        +          "left",
        +          "center",
        +          "right",
        +          "justify"
        +        ],
        +        "type": "string"
        +      },
        +      {
        +        "type": "null"
        +      }
        +    ]
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / createSegment
        Added value: +{
        +  "description": "when segment is header/footer and the doc has none, create it first. Only the default header/footer can be created via the API.",
        +  "type": "boolean"
        +}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Changedlist_suggestions2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Changedread_doc2 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "content tree to read (default body)",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer",
        +    "all"
        +  ],
        +  "type": "string"
        +}
    • Changedset_style3 fields changed
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
      • changedInput schema / properties / whole_document / description
        Previous value: -"style the entire document (or tab) instead of a selection — e.g. to set one font throughout. Mutually exclusive with from/to."New value: +"style the entire document (or tab, or the targeted header/footer) instead of a selection — e.g. to set one font throughout. Mutually exclusive with from/to."
    • Changedset_table_style4 fields changed
      • addedInput schema / properties / border
        Added value: +{
        +  "additionalProperties": false,
        +  "description": "cell borders, over the same scope as padding/background",
        +  "properties": {
        +    "color": {
        +      "description": "hex, e.g. #cccccc (default #000000)",
        +      "type": "string"
        +    },
        +    "dashStyle": {
        +      "enum": [
        +        "SOLID",
        +        "DOT",
        +        "DASH"
        +      ],
        +      "type": "string"
        +    },
        +    "sides": {
        +      "description": "which edges to set (default all four)",
        +      "items": {
        +        "enum": [
        +          "top",
        +          "bottom",
        +          "left",
        +          "right"
        +        ],
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    "width": {
        +      "description": "points; 0 hides the border (borders cannot be transparent)",
        +      "type": "number"
        +    }
        +  },
        +  "type": "object"
        +}
      • addedInput schema / properties / headerRows
        Added value: +{
        +  "description": "repeat the top N rows on every page (Docs’ \"pin header rows\"); 0 unpins. Independent of scope.",
        +  "type": "number"
        +}
      • addedInput schema / properties / page
        Added value: +{
        +  "description": "which header/footer, when a doc defines more than one (default-page, first-page, even-page). Omit to use whichever exists.",
        +  "enum": [
        +    "default",
        +    "first",
        +    "even"
        +  ],
        +  "type": "string"
        +}
      • addedInput schema / properties / segment
        Added value: +{
        +  "description": "which content tree to target: body (default), or the page header/footer. Header/footer content is invisible to a body read — a letterhead logo lives there.",
        +  "enum": [
        +    "body",
        +    "header",
        +    "footer"
        +  ],
        +  "type": "string"
        +}
    • Changedunshare_doc5 fields changed
      • addedInput schema / properties / email / description
        Added value: +"person or group to revoke; omit when using permissionId"
      • addedInput schema / properties / expectRole
        Added value: +{
        +  "description": "REQUIRED — the grant's current role as list_permissions reported it (reader/commenter/writer). Verified first: if it changed since you looked, nothing is removed. Revoking leaves no record anywhere, so this makes you look before you cut.",
        +  "type": "string"
        +}
      • addedInput schema / properties / expectTitle
        Added value: +{
        +  "description": "the doc’s title; verified before revoking so a wrong id is refused",
        +  "type": "string"
        +}
      • addedInput schema / properties / permissionId
        Added value: +{
        +  "description": "id from list_permissions — the only way to revoke a domain or anyone-with-link grant",
        +  "type": "string"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "documentId",
        -  "email"
        -]New value: +[
        +  "documentId",
        +  "expectRole"
        +]
  4. 31 tool updatesv0.1.1
    • First observedadd_comment
    • First observedadd_tab
    • First observedapply_suggestions
    • First observedcreate_doc
    • First observeddelete_tab
    • First observeddownload_images
    • First observededit_doc
    • First observededit_table
    • First observedget_page_setup
    • First observedget_project_config
    • First observedget_style
    • First observedinsert_image
    • First observedinsert_table
    • First observedlist_accounts
    • First observedlist_comments
    • First observedlist_folder
    • First observedlist_permissions
    • First observedlist_suggestions
    • First observedlist_tabs
    • First observedoverwrite_doc
    • First observedread_doc
    • First observedrename_tab
    • First observedresolve_comment
    • First observedsearch_drive
    • First observedset_page_setup
    • First observedset_project_default
    • First observedset_style
    • First observedset_table_style
    • First observedshare_doc
    • First observedunshare_doc
    • First observedupdate_doc

TDQS

A4.1/5.0

Scored across 19 tools

Disambiguation4/5

Most tools target clearly distinct resources or actions: document reading, snippet editing, comments, suggestions, permissions, page setup, and Drive navigation are well separated. The main potential confusion is between write_doc and edit_doc for writing markdown, and read_doc versus export_doc, though the descriptions make the intended boundaries mostly clear.

Naming Consistency4/5

Nearly all tools use a consistent snake_case verb_noun pattern such as read_doc, edit_doc, list_comments, add_comment, and share_doc. The single noun-only tool, drive, is a deliberate command multiplexer but is the one clear deviation from the pattern.

Tool Count4/5

At 19 tools the surface is slightly heavier than the ideal compact set, but the server covers a broad Google Docs domain including editing, comments, suggestions, sharing, page setup, export, Drive navigation, and configuration. Each tool corresponds to a meaningful operation, and drive usefully bundles several filesystem commands.

Completeness4/5

The tool set covers the core document lifecycle well: create, read, edit, replace, export, comments, suggestions, sharing, page setup, images, and Drive navigation. Notable gaps remain around deleting documents, tabs, or comments and around revision history, but these are relatively minor for the main Docs workflows.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues

Related MCP Connectors

Related MCP Servers