A local Model Context Protocol server that gives Claude Desktop (or any
stdio MCP client) access to multiple Google accounts. Each tool call takes
an explicit account label so the agent can operate across accounts in the
same conversation.
Scope:
- Gmail: search, read, send, modify labels (incl. trash)
- Google Calendar: list, read, create, update, delete events
- Google Drive: search, read, upload, update, delete files
Designed for personal local use on a single machine. Tokens live under
~/.config/multi-google-mcp/. Not for hosting or sharing.
- macOS, Linux, or WSL
- Python 3.11+
uv(recommended) orpipx- A Google account with admin access to a GCP project (free tier is fine)
If you have an AI agent running this repo locally (Claude Desktop, Codex CLI, etc.), you can ask it to install this server for you end-to-end — including the Google Cloud setup. Just tell your agent:
"Install this server. The runbook is in
agents/install/."
It will pick the right runbook for your harness and walk you through every step, including Google Cloud project setup if you haven't done it yet.
Currently supported harnesses:
- Claude Desktop —
agents/install/claude-desktop.md - Codex CLI —
agents/install/codex.md
For manual setup, see the "Manual install" section below.
Hand these steps to anyone using this server for the first time.
- Open https://console.cloud.google.com
- Project picker → New Project → name it (e.g. "multi-google-mcp")
- Wait for the project to be created and select it
In the project, go to APIs & Services → Library and search/enable each:
- Gmail API
- Google Calendar API
- Google Drive API
- APIs & Services → OAuth consent screen
- User type: External, then Create
- App information:
- App name:
multi-google-mcp(anything is fine) - User support email: your email
- Developer contact: your email
- App name:
- Save and continue
- Scopes screen: click Save and continue (we'll request scopes from the app, not here)
- Test users: Add users — add every Gmail address you intend to connect. In Testing publishing status, only these emails can authenticate.
- Save and continue → Back to dashboard
Keep publishing status as Testing. For personal use this is fine.
Heads up — free Gmail (
@gmail.com) accounts re-auth every 7 days. In Testing publishing status, Google expires refresh tokens issued to consumer Gmail accounts after 7 days. There is no way to extend this without verifying the app for production, which a single-user local server can't reasonably do. Every connected@gmail.comaccount will needmulti-google-mcp-auth add <label>rerun once a week — expect this and don't treat it as a bug.Google Workspace accounts (custom domain managed by a Workspace admin) are not affected — refresh tokens issued to Workspace identities don't expire on the 7-day clock, so a Workspace account stays connected until you explicitly revoke it.
- APIs & Services → Credentials
- Create credentials → OAuth client ID
- Application type: Desktop app
- Name:
multi-google-mcp(anything is fine) - Create
- Download JSON (the small download icon next to your client)
- Move that file to:
Create the directory if it doesn't exist:
~/.config/multi-google-mcp/client_secret.jsonmkdir -p ~/.config/multi-google-mcp
# from a clone of this repo
uv tool install .This puts two commands on your PATH:
multi-google-mcp— the MCP server (started by Claude Desktop)multi-google-mcp-auth— manage local OAuth tokens
multi-google-mcp-auth add personalA browser window opens. Sign in, accept the scopes. The CLI writes
~/.config/multi-google-mcp/accounts/personal.json.
To add another account use a different label:
multi-google-mcp-auth add workList configured accounts:
multi-google-mcp-auth listRemove an account:
multi-google-mcp-auth remove personalEdit ~/Library/Application Support/Claude/claude_desktop_config.json and
add an entry under mcpServers:
{
"mcpServers": {
"multi-google": {
"command": "multi-google-mcp"
}
}
}Restart Claude Desktop. You should see the tools listed; ask Claude something like:
"Search my work Gmail for unread mail from yesterday."
Claude will call gmail_search with account="work".
Add a dedicated test account (e.g. a throwaway Gmail) and run the end-to-end smoke script. It boots the actual MCP server as a subprocess, drives every tool surface over stdio against real Google APIs, and cleans up after itself.
multi-google-mcp-auth add test-account
MCP_E2E_ACCOUNT=test-account uv run python scripts/e2e_smoke.pyTakes ~30 seconds. If everything passes, your local setup is good.
- New account: rerun
multi-google-mcp-auth add <label>. - Changed scopes: edit
SCOPESinsrc/multi_google_mcp/config.py, rerunmulti-google-mcp-auth add <label>for each account — Google requires re-consent when scopes change.
| Error | What it means | Fix |
|---|---|---|
Account 'work' not configured |
No token file for that label | multi-google-mcp-auth add work |
Account 'work' needs reauthentication |
Refresh token rejected (revoked, scope changed, or 7d test-mode expiry) | multi-google-mcp-auth add work |
OAuth client not configured |
~/.config/multi-google-mcp/client_secret.json missing |
Re-download from GCP Credentials |
Google 403: insufficient permissions |
Scope wasn't requested or wasn't granted | Add the scope in config.py, re-auth |
Browser hangs on localhost:<port> after consent |
Local callback failed | Re-run add; firewall/VPN may be intercepting localhost |