mcp-google-multiCAUTION
Multi-account Google MCP server for Claude Code: Gmail, Drive, Calendar, Sheets, Docs, Contacts, Search Console, and more. ~871 tools with OAuth2 multi-account switching.
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
The most complete local Google Workspace MCP server: Gmail, Drive, Calendar, Sheets, Docs, Slides, Forms, Contacts, Tasks, Chat, Meet, Analytics (GA4), Search Console, Classroom, Vault, Admin and more — every OAuth-reachable API method as a tool, across multiple Google accounts at once, from Claude Code or any MCP client.
[](https://www.npmjs.com/package/mcp-google-multi)
- 🧰 Exhaustive — 940 tools across 29 services, now including Google Analytics (GA4), + an escape hatch for anything else → COVERAGE.md
- 🔑 Multi-account — drive any number of Google accounts by alias, or fan one call out across all of them
- 🔒 Private by design — your own OAuth app, tokens encrypted at rest (AES-256-GCM), writes deny-by-default, no telemetry, no metering — it talks only to Google
- 🌐 Local or remote — runs locally over stdio, or self-hosted over HTTP with its own built-in OAuth 2.1 server (Claude Code's
/mcplogin and the claude.ai connector, zero custom UI). Pull-and-up Docker Compose with optional automatic HTTPS → remote setup - ✉️ Built for real work — send and read email in Markdown with attachments and one-call replies, an interactive setup wizard with a
doctorself-check, and per-account scope profiles → features tour
Quick setup
New to all this? It's written for someone who just installed Claude Code and has never made an API key. Copy-paste each step; it says what you'll see. (Already technical? The Configuration reference is the terse version.)
- Install it. Get Node.js (the green "LTS" button, version 22 or newer), then run:
npm install -g mcp-google-multi
Claude Desktop user? You can skip npm entirely: download the mcp-google-multi.mcpb bundle from the [latest release](https://github.com/ba
38735a1be523OBSERVED · 2026-10-11Connect
Built from this server's own package name, version and transport as found in its source — not copied from anyone's documentation, so it cannot drift against a page we do not control. Replace the environment placeholders with a token scoped to the least it needs.
claude mcp add mcp-google-multi --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} --env MASTER_KEY=${MASTER_KEY} --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} --env MASTER_KEY=${MASTER_KEY} -- npx -y [email protected]claude mcp add mcp-google-multi:0.0.0 --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} --env MASTER_KEY=${MASTER_KEY} --env GOOGLE_CLIENT_SECRET=${GOOGLE_CLIENT_SECRET} --env MASTER_KEY=${MASTER_KEY} -- docker run -i --rm ghcr.io/bakissation/mcp-google-multi:0.0.0:NoneExposed tools (189)
90 read · 72 write · 27 destructive. Blast radius: 27 tools can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
admin_group_members_list | read | |
admin_groups_list | read | |
admin_users_get | read | |
admin_users_list | read | |
admin_users_update | write | |
analytics_account_summaries | read | |
analytics_get_metadata | read | |
analytics_run_realtime_report | write | |
analytics_run_report | write | |
big | read | |
calendar_create_calendar | write | |
calendar_create_event | write | |
calendar_delete_event | destructive | |
calendar_get_event | read | |
calendar_get_freebusy | read | |
calendar_list_calendars | read | |
calendar_list_events | read | |
calendar_list_instances | read | |
calendar_move_event | write | |
calendar_quick_add | write | |
calendar_update_event | write | |
chat_messages_create | write | |
chat_messages_list | read | |
chat_spaces_get | read | |
chat_spaces_list | read | |
contacts_create | write | |
contacts_delete | destructive | |
contacts_get | read | |
contacts_group_create | write | |
contacts_group_members | read | |
contacts_groups_list | read | |
contacts_list | read | |
contacts_resolve | read | |
contacts_search | read | |
contacts_update | write | |
docs_add_tab | write | |
docs_batch_update | write | |
docs_create | write | |
docs_create_footer | write | |
docs_create_header | write | |
docs_create_named_range | write | |
docs_create_paragraph_bullets | write | |
docs_delete_footer | destructive | |
docs_delete_header | destructive | |
docs_delete_named_range | destructive | |
docs_delete_paragraph_bullets | destructive | |
docs_delete_range | destructive | |
docs_delete_tab | destructive | |
docs_get | read | |
docs_insert_inline_image | write | |
docs_insert_page_break | write | |
docs_insert_section_break | write | |
docs_insert_table | write | |
docs_insert_text | write | |
docs_modify_table | write | |
docs_read | read | |
docs_replace_named_range_content | read | |
docs_replace_text | read | |
docs_update_document_style | write | |
docs_update_paragraph_style | write | |
docs_update_style | write | |
docs_update_tab_properties | write | |
drive_access_proposal_list | read | |
drive_access_proposal_resolve | read | |
drive_comment_create | write | |
drive_comment_delete | destructive | |
drive_comment_get | read | |
drive_comment_list | read | |
drive_comment_update | write | |
drive_copy | read | |
drive_create_folder | write | |
drive_delete | destructive | |
drive_empty_trash | read | |
drive_get_about | read | |
drive_list | read | |
drive_list_permissions | read | |
drive_move | write | |
drive_permission_update | write | |
drive_read | read | |
drive_remove_permission | destructive | |
drive_reply_create | write | |
drive_reply_delete | destructive | |
drive_reply_list | read | |
drive_reply_update | write | |
drive_revision_delete | destructive | |
drive_revision_list | read | |
drive_revision_update | write | |
drive_search | read | |
drive_share | read | |
drive_shared_drive_get | read | |
drive_shared_drives_list | read | |
drive_transfer | write | |
drive_trash | read | |
drive_untrash | read | |
drive_update | write | |
forms_batch_update | write | |
forms_create | write | |
forms_get | read | |
forms_response_get | read | |
forms_responses_list | read | |
forms_set_publish_settings | write | |
forms_watches_list | read | |
gmail_batch_delete | destructive | |
gmail_batch_modify | write | |
gmail_create_draft | write | |
gmail_create_label | write | |
gmail_delete | destructive | |
gmail_delete_label | destructive | |
gmail_get_draft | read | |
gmail_get_profile | read | |
gmail_get_vacation | read | |
gmail_list_drafts | read | |
gmail_list_history | read | |
gmail_list_labels | read | |
gmail_modify_labels | write | |
gmail_read | read | |
gmail_read_batch | read | |
gmail_read_thread | read | |
gmail_search | read | |
gmail_send | write | |
gmail_send_draft | write | |
gmail_set_vacation | write | |
gmail_trash | read | |
held | read | |
heldBig | read | |
meet_conference_record_get | read | |
meet_conference_records_list | read | |
meet_recordings_list | read | |
meet_transcript_entries_list | read | |
meet_transcripts_list | read | |
ping | read | |
reports_activities_list | read | |
searchconsole_searchanalytics_query | read | |
searchconsole_sitemaps_delete | destructive | |
searchconsole_sitemaps_get | read | |
searchconsole_sitemaps_list | read | |
searchconsole_sitemaps_submit | write | |
searchconsole_sites_add | write | |
searchconsole_sites_delete | destructive | |
searchconsole_sites_get | read | |
searchconsole_sites_list | read | |
searchconsole_url_inspect | read | |
sheets_add_conditional_format_rule | write | |
sheets_add_named_range | write | |
sheets_add_sheet | write | |
sheets_append_rows | read | |
sheets_auto_resize_dimensions | read | |
sheets_batch_clear | destructive | |
sheets_batch_read | read | |
sheets_batch_update | write | |
sheets_batch_write | write | |
sheets_clear_basic_filter | destructive | |
sheets_clear_range | destructive | |
sheets_create | write | |
sheets_delete_dimension | destructive | |
sheets_delete_named_range | destructive | |
sheets_delete_sheet | destructive | |
sheets_duplicate_sheet | read | |
sheets_find_replace | read | |
sheets_format_cells | read | |
sheets_get | read | |
sheets_insert_dimension | write | |
sheets_merge_cells | write | |
sheets_read_range | read | |
sheets_set_basic_filter | write | |
sheets_set_data_validation | write | |
sheets_sort_range | read | |
sheets_unmerge_cells | read | |
sheets_update_borders | write | |
sheets_update_sheet_properties | write | |
sheets_write_range | write | |
slides_batch_update | write | |
slides_create | write | |
slides_get | read | |
slides_page_get | read | |
slides_page_thumbnail | read | |
tasks_clear | destructive | |
tasks_delete | destructive | |
tasks_get | read | |
tasks_insert | write | |
tasks_list | read | |
tasks_list_delete | destructive | |
tasks_list_get | read | |
tasks_list_insert | write | |
tasks_list_update | write | |
tasks_lists_list | read | |
tasks_move | write | |
tasks_update | write | |
write | write |
Trust audit
CAUTIONgrade D · trust 67/100 Install with care. The audit found things worth knowing before you trust its output.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | WARN |
| L1 | Static analysis of the code | WARN |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (11 observation(s))
- Network
- declared (4 observation(s))
- Shell
- declared (1 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- found
Findings (25)
client.ts
token-store.ts
console.log(`Token saved (encrypted) for ${alias}.`);console.log(`Wiped ${wiped} token file(s).`);console.log(`• ${alias}: encrypted token already exists, skipping`);const TOKEN = 'r1.EBESExQVFhcYGRobHB0eHwECAwSgoaKjpKWmp6ipqqusra6vae0HPY7R1kpwyrnP9flryVjpAG54fFMHUKGK8Sgywi0';
calendar_delete_event, contacts_delete, docs_delete_footer, docs_delete_header, docs_delete_named_range, docs_delete_paragraph_bullets, docs_delete_range, docs_delete_tab, drive_comment_delete, drive_
.mcpbignore
.releaserc.json
const render = yaml.load(read('render.yaml')) as { services: RenderService[] };const compose = yaml.load(read('deploy/compose.yaml')) as ComposeFile;expect(path.basename('/home/user/.ssh/authorized_keys')).toBe('authorized_keys');"import type { ToolRegistry } from '../../registry.js';","import type { ToolRegistry } from '../../registry.js';",import { accountAliasSchema, accountAliasSchemaFor, accountArgLive } from '../../accounts.js';import { executeApiMethod, type ApiMethodRef, type ExecuteDeps, type QueryParams } from '../../executor.js';import type { Cud, ToolRegistry } from '../../registry.js';it('a file inside the config/token dir is refused (secret-exfil guard)', async () => {for (const ip of ['0.0.0.0', '10.1.2.3', '127.0.0.1', '169.254.169.254', '172.16.0.1', '172.31.255.255', '192.168.1.1', '100.64.0.1', '224.0.0.1', '240.0.0.1']) {for (const ip of ['::1', '::', 'fc00::1', 'fd12::1', 'fe80::1', '::ffff:127.0.0.1', '::ffff:169.254.169.254', '::ffff:7f00:1', '64:ff9b::7f00:1', '2002:a9fe::1', 'ff02::1']) {await expect(assertPublicHttpsUrl('https://evil.example', { resolveAll: async () => ['169.254.169.254'] })).rejects.toThrow(SsrfBlockedError);ssrf: { resolveAll: async () => ['169.254.169.254'] },-e [email protected] -e MCP_PUBLIC_URL=http://127.0.0.1:4243 \
service: http://127.0.0.1:4243
| `MCP_PUBLIC_URL` | `https://mcp.example.com` | Metadata advertises `http://127.0.0.1:4243`; `resource`/`aud` mismatch; **every `/mcp` call 401-loops**. |
Gates applied: no_behavioural_pass.
38735a1be523full audit observations/trust-audit/mcp-server/bakissation__mcp-google-multi.json · Report an issue / request a re-scanAudit history
Every audit this server has had. A grade with a past is a grade somebody is still checking.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-11 | 38735a1be523 | CAUTION | D | 67 | first audit |
Questions
What is the mcp-google-multi MCP server?
Multi-account Google MCP server for Claude Code: Gmail, Drive, Calendar, Sheets, Docs, Contacts, Search Console, and more. ~871 tools with OAuth2 multi-account switching.
What tools does mcp-google-multi expose?
189 in total: 90 read-only, 72 that write, and 27 that can delete or overwrite (calendar_delete_event, contacts_delete, docs_delete_footer, docs_delete_header, docs_delete_named_range). Every one is listed on this page with its risk.
Is mcp-google-multi safe to connect to an agent?
With care. The audit graded it D (67/100) and found 25 things worth knowing before you trust this server, listed below with the exact line each was found on. Separately from the audit: 27 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does mcp-google-multi need?
It reads GOOGLE_CLIENT_SECRET, MASTER_KEY, MCP_TRANSFER_PASSPHRASE and TOKEN_STORE_PATH from the environment. Give it a token scoped to the least it needs — an agent that can be talked into calling a tool can be talked into calling it with your credentials.
How does mcp-google-multi run?
It speaks stdio and streamable-http, so it runs as a local process your client starts. It is published on npm as mcp-google-multi at 0.0.0-semantically-released.
How current is this page?
The grade is for one exact copy of the source (38735a1be523), read on 2026-10-11. The repository is watched and re-audited when it changes.