Open Source••8 min read•

Google Workspace MCP Server for Claude (871 Tools)

How I built an open-source, multi-account MCP server that gives AI assistants write-controlled access to the entire Google Workspace API surface, 871 tools across 28 services, from a single npm install.

Google Workspace MCP
multi-account MCP
MCP tool discovery
Model Context Protocol
Claude Code tools
Gmail automation
Google Drive API
AI developer tools
npm package

AI coding assistants like Claude Code are remarkably capable when it comes to writing code, managing git repositories, and navigating file systems. But the moment you need to check an email, find a document on Google Drive, or schedule a meeting, you hit a wall. The assistant can't reach outside its sandbox. The Model Context Protocol (MCP) changes this by letting AI assistants call external tools through a standardized interface. When I first looked for an MCP server that could handle Google across multiple accounts, nothing came close, so I built mcp-google-multi.

What started as a 47-tool server for Gmail, Drive, and Calendar is now something much larger: an npm package that exposes 871 tools across 28 Google services, with exhaustive coverage of the OAuth-reachable API surface, deny-by-default write control on every mutating operation, encrypted local token storage, and full multi-account support. This is the story of how it got there and the design decisions that made that scale usable rather than overwhelming.

The Landscape Changed, and the Case Got Stronger

Since the first version shipped, both Google and Anthropic entered this space. Google now offers official remote Workspace MCP servers in developer preview, and Anthropic ships built-in Google connectors in Claude. Both are genuinely useful for casual use, and both stop exactly where real work begins. They are single-account. Google's preview servers expose a shallow, read-heavy slice (a few dozen tools total, mostly search and draft). Anthropic's Gmail connector can draft but cannot send. Neither reaches Docs, Sheets, Slides, Forms, Tasks, the Admin SDK, or the long tail of Workspace APIs.

That is the gap mcp-google-multi fills: exhaustive breadth, multiple accounts at once, the ability to actually complete write operations, and a policy layer that keeps those writes safe. It runs locally, uses your own OAuth credentials, and keeps your tokens on your machine.

Why Multi-Account Support Matters

Most developers and founders don't live in a single Google account. I juggle three: a company account, a personal account, and a client-facing account. Each has its own inbox, Drive, and calendar. Most Google MCP implementations, including the official ones, bind to a single account. You would run separate server instances, manage separate configs, and manually tell the assistant which one to use. That defeats the purpose of an assistant that can operate fluidly across your actual workflow.

With mcp-google-multi, you define every account in one place:

bash
GOOGLE_ACCOUNTS=work:[email protected],personal:[email protected]

Every tool takes an account parameter, so the assistant switches accounts mid-conversation without friction. "Search my work inbox for invoices from last week, then check my personal Drive for the contract template" becomes a single, uninterrupted interaction. Read tools also accept account:"*", which fans the call out across every configured account at once and merges the results, so "find that thread in any of my inboxes" is one call, not three.

From 47 Tools to 871: Exhaustive Coverage

The original version was a curated set: I hand-wrote a tool for each operation I thought people would want. That approach caps out fast. Google's Workspace APIs expose hundreds of methods, and the ones I skipped were exactly the ones a power user eventually needs.

So the current version pairs two layers. A curated layer (182 tools) covers the everyday operations with ergonomic, purpose-built interfaces: gmail_search, drive_read, sheets_append, calendar_quick_add, and their siblings. Underneath it, a generated layer (689 tools) covers everything else, produced directly from Google's own machine-readable API descriptions (the Discovery documents) so that every OAuth-reachable method becomes a real, named, individually addressable tool. Nothing is left behind a generic escape hatch unless you want it.

Generating the long tail rather than hand-writing it means coverage stays honest and current. When Google publishes a new method, regenerating picks it up. Each generated tool carries its own metadata: parameters, an explicit read-or-write classification, and a description, so it behaves like a first-class tool to the assistant, not a thin proxy.

871 Tools Without the Context Cost

The obvious objection to 871 tools is that an AI assistant drowns in them. It would, if they were all loaded at once. At rest, mcp-google-multi shows the assistant about a dozen small discovery tools, one per service, and reveals a service's operational tools only when the assistant reaches for it. Having all of Google Workspace available costs about a thousand tokens of context instead of tens of thousands. How that works, and why the long tail is generated rather than hand-written, is the subject of a separate engineering deep-dive.

Deny-by-Default Write Control

Exhaustive coverage means the server can also delete calendars, remove Drive permissions, and modify Admin SDK settings. Handing an AI assistant that much reach without a safety layer would be reckless. So every operation that creates, updates, or deletes is gated, and the default is deny.

Write access is one setting: a profile of read-only, safe-writes, or full-writes, with glob patterns for finer overrides where deny always wins. Reads are always allowed. safe-writes is computed from each tool's own destructive classification, so hundreds of write tools needed no configuration of their own. A mutating tool the policy has not enabled is simply not exposed, so the assistant never even learns it exists, which is both safer and cleaner than letting it try and fail.

Enforcement lives in the server, on each tool's classification, never on its name or on client-side hints, and the generic "call any method" tool is gated exactly like the named ones, so it can't be used to route around the policy. That rigor earned its keep: an adversarial review caught that Gmail's POST-based deletes, like batchDelete, would have slipped through safe-writes if classification had trusted the HTTP verb. They're now classified as the deletes they are.

Secure-by-Default Token Storage

The first version wrote each account's OAuth token to a plaintext JSON file. That was fine for a demo and wrong for anything real. The current version keeps all tokens in a single encrypted store, sealed with AES-256-GCM under a master key you provide through the environment. Tokens are encrypted at rest, refreshed transparently before they expire, and never logged. Security is the default even when you run entirely on your own laptop, with no extra infrastructure to stand up.

Stdio Transport, Your Own OAuth Client

Two decisions from the original design held up and are worth keeping. The server uses stdio transport, running as a local subprocess spawned by your MCP client over stdin and stdout. No ports, no network exposure, no CORS. For a local tool server this is the simplest and most secure model.

And it uses a single OAuth client with separate tokens per account rather than a separate client per account. You authenticate each account once through a browser flow, the token is stored encrypted, and refreshes happen automatically. Adding an account is a line of config and one sign-in, not a code change.

Install in One Command

The original setup was clone, configure, build, authenticate, register. Publishing to npm collapsed that. Point your MCP client at the package, list your accounts, and let it run:

json
{ "mcpServers": { "google-multi": { "command": "npx", "args": ["-y", "mcp-google-multi"], "env": { "GOOGLE_ACCOUNTS": "work:[email protected],personal:[email protected]" } } } }

The one-time pieces (your Google OAuth client credentials and the encryption key) are covered step by step in the repository's setup docs. After that, authenticating a new account is a single browser sign-in.

What It Looks Like in Practice

Here is a workflow that would otherwise mean switching between three browser tabs and copy-pasting by hand:

"Check my work inbox for any emails from the accountant this week. Download any invoice attachments to my local machine. Then look at my personal calendar and find a free slot tomorrow afternoon to review them."

The assistant searches Gmail on the work account, downloads the attachments, queries free/busy on the personal calendar, and proposes a time. One conversation, two accounts, three services. Because reads can fan out with account:"*", "did anyone send me the signed contract, on any account?" is a single question, and because writes are policy-gated, "archive everything from this sender older than 30 days" runs only if you have granted that reach.

This cross-account, cross-service orchestration is where the design pays off. The assistant sees the account list and the service vocabulary, understands the context, and picks the right tool and the right account without being told.

Open Source, and What's Next

I open-sourced mcp-google-multi because the MCP ecosystem is still young, and the best way to push it forward is to build tools people can use, fork, and extend. It is MIT-licensed and installable from npm in a single line.

The exhaustive-coverage milestone that defines this version is complete, and the project is now in a deliberate feedback period: real usage decides what the next major version prioritizes. If you build with MCP or work with Google APIs in an AI-assisted workflow, I would welcome issues, ideas, and contributions on GitHub.