Multi-account Google Workspace (Gmail, Drive, Calendar, Sheets, Docs) + Slack MCP servers for Claude Code. Setup guide with CLAUDE.md for AI-guided installation.
SaferSkills independently audited claude-code-google-workspace (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Give Claude Code access to Gmail, Google Drive, Calendar, Sheets, Docs, and Slack — with full support for multiple Google accounts (e.g., personal + work).
Claude Desktop and Claude Cowork have built-in Google Workspace integrations — flip a toggle and you're connected. Claude Code has nothing. As of March 2026, there's no official integration, no plugin that handles multi-account, and no documentation on how to set it up.
This repo is the result of ~6 hours of research and debugging to get it working. The final solution is simple, but getting there required discovering several undocumented behaviors in Claude Code's MCP system, Google's OAuth2 implementation, and the gws CLI.
It's not one problem — it's a stack of them, each undocumented:
mcpServers in settings.local.json (where you'd expect it), servers don't start. No error. No log. You can spend hours restarting and re-checking JSON syntax. The config must go in .mcp.json at the project root. (Claude Code Issue #24477)GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE is supposed to let you point the Google Workspace CLI at different credential files, but it doesn't reliably route to the right account. You have to mint fresh access tokens and pass them via GOOGLE_WORKSPACE_CLI_TOKEN (the highest-priority auth method).gws CLI and slack-mcp-server are Go binaries. --transport stdio fails silently. It's -t stdio — or just omit it (stdio is the default).Each of these individually cost 30-120 minutes to diagnose. Together they make the setup feel broken when it's actually a solvable configuration problem.
| Approach | Why It Failed |
|---|---|
Legacy google-workspace Claude Code plugin | Single-account only, port 8000 conflict blocks second instance |
| Single OAuth client for both accounts | Google invalidates first account's refresh token on second auth |
CREDENTIALS_FILE env var per MCP server | Doesn't reliably route to the right account |
mcpServers in settings.local.json | Silently ignored — Claude Code never reads MCP config from there |
mcpServers in .claude/settings.json | Also silently ignored |
| Service account auth | Can't access personal Gmail/Drive without domain-wide delegation |
| Requesting all 85+ OAuth scopes | Google blocks unverified apps requesting too many scopes |
For the full investigation log, see docs/research-notes.md.
The working setup uses:
gws v0.7+) — Google's official CLI with built-in MCP server mode| MCP Server | Capabilities |
|---|---|
gws-personal | Gmail, Drive, Calendar, Sheets, Docs for your personal Google account |
gws-work | Same, for your work Google account (optional) |
slack | Read channels, search messages, browse threads, list users |
Once running, Claude Code can search your email, read Drive files, check your calendar, read/write spreadsheets, and search Slack — all through natural language.
npx) git clone https://github.com/YOUR_USERNAME/claude-code-google-workspace.git
cd claude-code-google-workspace
claudeThe CLAUDE.md in this repo contains machine-readable setup instructions. Claude Code will walk you through each step, prompting you only for browser-based OAuth steps that can't be automated.
If you prefer step-by-step instructions: docs/manual-setup.md.
To understand every decision and failed approach: docs/research-notes.md.
Claude Code session start
│
├─── reads .mcp.json (project root)
│
├─── starts gws-personal server:
│ │
│ ├── gws-token-wrapper.sh personal.json
│ │ │
│ │ ├── reads personal.json (client_id_A + refresh_token)
│ │ ├── POST https://oauth2.googleapis.com/token → access_token
│ │ └── exec: GOOGLE_WORKSPACE_CLI_TOKEN=<token> gws mcp -s gmail,drive,...
│ │
│ └── gws mcp ←→ Google APIs (Gmail, Drive, Calendar, Sheets, Docs)
│
├─── starts gws-work server:
│ │
│ └── (same flow, different credential file with client_id_B)
│
└─── starts slack server:
│
└── npx slack-mcp-server (SLACK_MCP_XOXP_TOKEN env var)The gws CLI stores one set of credentials at a time internally. For multiple accounts, we can't rely on its credential file routing (CREDENTIALS_FILE env var is unreliable). Instead, we:
client_id, client_secret, refresh_token)GOOGLE_WORKSPACE_CLI_TOKEN — the highest-priority auth method in the gws auth chainThis is 15 lines of shell + Python stdlib. No dependencies.
OAuth2 Desktop App clients have a behavior where issuing a new refresh token for account B invalidates the existing refresh token for account A — if they share the same client_id. Creating separate OAuth Desktop clients in the same GCP project gives each account its own independent token lifecycle.
After setup, you need two things in any project where you want these MCP servers:
Or add the mcpServers config to ~/.claude.json for global access in every project.
Always gitignore `.mcp.json` — it contains OAuth tokens.
These are ordered by how much time they'll cost you if you hit them unaware:
| # | Gotcha | Time Cost | Symptom | Fix |
|---|---|---|---|---|
| 1 | mcpServers in settings.local.json is silently ignored | 2+ hours | Servers never start, zero errors | Use .mcp.json (project root) or ~/.claude.json (global). Issue #24477 |
| 2 | Same OAuth client for two accounts | 1-2 hours | First account stops working after second account authenticates | Create separate OAuth Desktop clients per account |
| 3 | CREDENTIALS_FILE env var unreliable | 1 hour | Wrong account's data returned | Use GOOGLE_WORKSPACE_CLI_TOKEN via wrapper script |
| 4 | Work account shows "Access blocked" | 30 min | OAuth consent screen blocks non-test users | Add all accounts as test users on OAuth consent screen + grant IAM serviceUsageConsumer role |
| 5 | MCP servers only start at session launch | 15 min | Config changes don't take effect | Restart Claude Code after any .mcp.json change |
| 6 | Go binaries use single-dash flags | 15 min | --transport stdio fails silently | Use -t stdio or omit (stdio is default) |
| 7 | Access tokens expire after ~1 hour | 5 min | API calls fail on long sessions | Restart Claude Code for fresh tokens |
| 8 | gws auth login opens foreground browser | 5 min | Wrong Chrome profile = wrong account authenticated | Bring correct Chrome profile to front before running |
| 9 | Too many OAuth scopes requested | 10 min | Google blocks unverified app | Use -s drive,gmail,calendar,sheets,docs (not all scopes) |
gws CLI v0.7.0 and current Claude Codegws CLI is pre-1.0 — flags and auth behavior may changesettings.local.json silent ignore bugIssues and PRs welcome. If you hit a new gotcha, please open an issue — every undocumented behavior we capture saves someone hours.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.