Model or dataset
a-bonus/google-docs-mcp avatar
a-bonus/google-docs-mcp

google-docs-mcp turns a Google account into MCP tools

The Ultimate Google Docs, Sheets, Drive, Gmail, & Google Calendar MCP Server. This MCP (primarily for use in Claude Desktop) gains full access to your google suite and lets claude do its thing.

676 stars225 forksTypeScriptMIT

At a glance

What is it?
The a-bonus google-docs-mcp server exposes Google Docs, Sheets, Drive, Gmail and Calendar as tool calls for Claude Desktop, Cursor or any MCP client. It is unusually complete on the edit side of Docs and Sheets, and it asks for a broad set of Google OAuth scopes to do it.
Who is it for?
Adopt google-docs-mcp if your work happens inside Google Docs and Sheets and you want an assistant to read, restructure and format documents rather than just answer questions about them, and if you are comfortable with a single OAuth grant covering Docs, Sheets, Drive, Gmail and Calendar at once.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One MCP server over five Google APIs

The a-bonus google-docs-mcp project is a Model Context Protocol server that connects Claude Desktop, Cursor or any other MCP client to Google Docs, Google Sheets, Google Drive, Gmail and Google Calendar. The value proposition is stated in the README's opening line: it lets the client gain access to the Google suite so it can act on documents rather than ask about them.

MCP is the delivery mechanism, not the product. The server exposes named tools, each one mapping onto a Google API operation, and the client decides when to call them. That design matters for the scope question, because the tools are listed explicitly and the list is long. A user of this server is effectively granting an assistant a structured editing hand inside their documents.

The implementation is TypeScript on the Node side. The package is published under the name @a-bonus/google-docs-mcp, with a bin entry named google-docs-mcp that points at dist/index.js, and the repository builds from src through tsc. The declared runtime dependencies give a fair picture of the architecture: fastmcp for the MCP server layer, googleapis for the Google clients, google-auth-library for OAuth, zod for input schemas, markdown-it for the markdown handling in the document tools, and @google-cloud/firestore for the remote token store.

The repository also carries an apps_script directory and a pages directory, which shows the project is not a single narrow bridge but a workspace of TypeScript sources, tests and helper material.

The Docs tools edit structure, not just text

Most tools for this kind of server stop at reading a document and appending a paragraph. This one does not. The documented Docs surface includes readDocument, which returns plain text, JSON or markdown, and a full editing set: appendText, insertText at a position, deleteRange by index range, modifyText for replace, prepend or transform, and findAndReplace.

Then it goes further into document structure. findElement locates text occurrences with their index ranges or lists paragraphs and tables. listTabs, addTab and renameTab handle the tabbed documents that Google Docs now supports, which matters because an assistant that only knows how to write into one tab will corrupt the others.

The markdown family is a second axis. replaceDocumentWithMarkdown rewrites the entire document content from markdown, replaceRangeWithMarkdown targets a specific range, and appendMarkdown adds markdown-formatted content. That combination is the most practical thing here for a human: the assistant works in markdown, which it writes well, and the server maps that onto Docs structure.

Formatting is handled by two style tools. applyTextStyle covers bold, italic, colors, font size and links, while applyParagraphStyle handles alignment, spacing and indentation. Structural insertion covers insertTable, insertTableWithData, insertPageBreak, insertSectionBreak with a NEXT_PAGE or CONTINUOUS choice, and updateSectionStyle for orientation and margins. insertImage takes URLs or local files.

Comments are handled as a separate group with listComments, getComment, addComment, replyToComment, resolveComment and deleteComment. An assistant that can resolve the comments a reviewer left is materially more useful than one that can only edit the body text.

Sheets tools work in A1 ranges and write in batches

The Sheets side is smaller than the Docs side but follows the same philosophy of covering the operations people actually need. readSpreadsheet reads from a range using A1 notation, writeSpreadsheet writes to a range, and batchWrite writes to multiple ranges in one call, which is the difference between one request and thirty when you are reshaping a report.

Row and tab management are covered directly. appendRows adds rows, clearRange clears cell values, createSpreadsheet makes a new file, and addSheet, deleteSheet, duplicateSheet, copySheetTo and renameSheet handle the workbook structure, including moving a sheet into another spreadsheet.

The A1 notation is worth calling out because it is a familiar convention rather than a project specific invention. A client that already knows spreadsheet addressing needs no special training, and an assistant that reasons in cell ranges can be handed a spreadsheet reference in a chat message without translation.

What is not visible in the documentation is equally worth noting. The README lists Sheets tools in detail and stops partway through the table, and the Gmail and Calendar surfaces are announced in the project description and in the OAuth scope step, but their tool tables are not shown here. If your plan depends on specific Gmail or Calendar operations, that list is where you need to check before committing.

Three steps to a running server: OAuth client, authorize, configure

The setup path is documented in three numbered steps, and step one is on Google's side. You create or select a project in the Google Cloud Console, enable the Google Docs API, Google Sheets API, Google Drive API, Gmail API and Google Calendar API, configure the OAuth consent screen as External with your email added as a test user, and add the gmail.modify and calendar.events scopes alongside the Docs, Sheets and Drive scopes. Then you create an OAuth client ID of Desktop app type and copy the client ID and client secret.

Step two is the one command that runs on your machine:

bash
GOOGLE_CLIENT_ID="your-client-id" \
GOOGLE_CLIENT_SECRET="your-client-secret" \
npx -y @a-bonus/google-docs-mcp auth

This opens a browser for Google authorization, and after you approve, the refresh token is saved to ~/.config/google-docs-mcp/token.json. That file path is worth remembering, since it is where your credentials live for the local workflow.

Step three registers the server with the client:

json
{
  "mcpServers": {
    "google-docs": {
      "command": "npx",
      "args": ["-y", "@a-bonus/google-docs-mcp"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id",
        "GOOGLE_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

The server starts automatically when the client needs it, so there is no long running process to babysit in the local setup.

One practical warning about the scopes. Because the consent screen step asks for Gmail modify and calendar events alongside the document scopes, the grant you approve is broad even if you only intend to edit documents. There is no narrower scope set documented in the setup steps.

Cloud Run turns it into a shared team service with Firestore tokens

The remote deployment path runs the same server on Google Cloud Run so a team can share one instance without local installs. The README says the server uses MCP OAuth 2.1 in that mode, so the MCP client handles authentication instead of the npx auth flow, and the user gets a Google sign-in prompt on first connection.

The deployment command sets the pieces explicitly:

bash
gcloud run deploy google-docs-mcp \
  --source . \
  --region europe-west3 \
  --port 8080 \
  --allow-unauthenticated \
  --set-env-vars "^|^MCP_TRANSPORT=httpStream|BASE_URL=https://your-service.run.app|GOOGLE_CLIENT_ID=...|GOOGLE_CLIENT_SECRET=...|TOKEN_STORE=firestore|JWT_SIGNING_KEY=your-secret-key"

The environment variables carry the real design decisions. MCP_TRANSPORT switches the transport to httpStream, BASE_URL tells the server its public address so it can build OAuth redirect URLs correctly, TOKEN_STORE=firestore moves refresh tokens out of the local filesystem into Firestore, and JWT_SIGNING_KEY is the secret used to sign the tokens the service issues.

Each user then points their client at the URL:

json
{
  "mcpServers": {
    "google-docs": {
      "type": "streamableHttp",
      "url": "https://your-service.run.app/mcp"
    }
  }
}

Two things to weigh. The service is deployed with --allow-unauthenticated, so the endpoint itself is open and the application layer handles identity. And with tokens in Firestore, the service becomes a credential store for every user who connects, which is a different security posture from a token file under one person's home directory.

A Node 22 container that runs as an unprivileged user

The Dockerfile is a two stage build on node:22-slim. The builder copies the package manifests and runs npm ci, copies tsconfig.json and src, then runs npm run build to produce the TypeScript output. The runtime stage installs production dependencies only with npm ci --omit=dev, copies the built dist directory from the builder, and then hands ownership to the node user:

dockerfile
FROM node:22-slim AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
dockerfile
USER node
EXPOSE 8080
CMD ["node", "dist/index.js"]

So the service listens on 8080, matching the --port 8080 in the Cloud Run command, and it runs as the unprivileged node user rather than root. The image does not set a HEALTHCHECK or define a default entrypoint script beyond the CMD, and it does not pin the base image to a digest, so a rebuild can pick up a newer node:22-slim.

The local development picture matches the same stack. The scripts section defines build as tsc, test as vitest run, format as prettier, and prepublishOnly as npm run build, with a separate live test script targeting a Docs clone table test. There is a vitest.config.ts and a .prettierrc at the root, so the project treats formatting and tests as part of the workflow rather than an afterthought.

What you are granting, and where the boundaries are

The honest way to evaluate this server is to look at the permission surface rather than the tool count. A single consent grants access to five APIs, and the documented scopes include gmail.modify and calendar.events, so a server that can append text to a document is running with a credential that can also modify mail and create calendar events.

That is inherent to the design. There is no documented per tool permission model, no read only mode, and no separate credentials per operation. The mitigation is scope selection at the consent screen and at the OAuth client level, not inside the server.

The second boundary is the Apps Script alternative that the repository itself carries. An apps_script directory in the tree suggests a route that runs inside the Google account, next to the document, where access is governed by the script's own scopes and by Google's own execution model. The MCP server takes the opposite path: it runs outside, holds a refresh token, and calls the APIs over HTTP. The script route is a better fit when you want the logic to live inside the Google account and the access to stay narrow. The server route is a better fit when you want one assistant to work across Docs, Sheets, Drive, mail and calendar from a chat client.

A third, smaller limitation: the local workflow writes a refresh token to disk at ~/.config/google-docs-mcp/token.json, and that file is the entire authorisation state for that user. Anyone who can read it has the grant.

Licensing, release pace and the cost of upgrading

The licensing metadata is inconsistent, and you should check the files rather than trust a badge. The project is tagged with the MIT license and the repository ships a LICENSE file at the root. The package.json, however, declares a different identifier:

json
  "license": "ISC",

For a package published to a registry, the package.json field is what tooling reads, so an organisation with automated license scanning will see ISC while the repository page says MIT. Both are permissive grants with no fee and no per-user obligation, so the practical difference is small, but the discrepancy is worth resolving before you put the dependency in a compliance inventory.

On cadence, the project is moving quickly. Releases v1.11.0, v1.11.2 and v1.11.3 landed on 2026-06-10, 2026-07-24 and 2026-07-27, with the package.json version at 1.11.3, and the last push was on 2026-10-11. Rapid patch releases mean the tool list and behaviour can shift between versions, so pin the version your client resolves rather than tracking the latest tag.

The upgrade cost is mostly re-authorisation. Because permissions live in a Google grant and a token store rather than in a config file, an upgrade that changes scopes asks every connected user to approve again, and in the Firestore mode that means an existing installation is not simply reusable.

Editorial conclusion

Adopt google-docs-mcp if your work happens inside Google Docs and Sheets and you want an assistant to read, restructure and format documents rather than just answer questions about them, and if you are comfortable with a single OAuth grant covering Docs, Sheets, Drive, Gmail and Calendar at once. Do not adopt it for a tenant with strict data residency rules, for a Google Workspace account that also carries sensitive mail, or if you need the local npx workflow to be the only deployment path, because the Cloud Run option runs with --allow-unauthenticated and delegates sign-in to MCP OAuth 2.1 with a Firestore token store. Before deploying, verify which scopes you actually need, decide between a local token file at ~/.config/google-docs-mcp/token.json and a Firestore token store, and check which license applies, since the project is tagged MIT while package.json declares ISC.

Frequently asked questions

How do I set up google-docs-mcp for Claude Desktop or Cursor?

Create a Google Cloud OAuth client of Desktop app type with the Docs, Sheets, Drive, Gmail and Calendar APIs enabled, run the auth command to store a refresh token, then add the server to your client config with the command `npx` and the args `-y @a-bonus/google-docs-mcp`, passing GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in the env block.

Where does google-docs-mcp store my Google credentials?

In the local setup, the auth flow saves the refresh token to `~/.config/google-docs-mcp/token.json`. In the Cloud Run deployment you set TOKEN_STORE=firestore, which moves tokens into Firestore so each connected user signs in through MCP OAuth 2.1.

Can google-docs-mcp edit Google Sheets ranges?

Yes. The documented Sheets tools include readSpreadsheet and writeSpreadsheet using A1 notation, batchWrite for multiple ranges in one call, appendRows, clearRange, and sheet management tools such as addSheet, deleteSheet, duplicateSheet, copySheetTo and renameSheet.

What license does google-docs-mcp use?

The project is tagged with the MIT license and the repository includes a LICENSE file, while package.json declares ISC. Both are permissive licenses, so check the files directly before recording the dependency in a compliance inventory.

Official sources

  1. a-bonus/google-docs-mcp on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/a-bonus-google-docs-mcp.svg)](https://hysenlabs.com/projects/a-bonus-google-docs-mcp)

Was this useful?