Google WorkspaceBLOCK
A Model Context Protocol (MCP) server that provides authenticated access to Google Workspace APIs, offering integrated Authentication, Gmail, Calendar, and Drive functionality
Overview
From the repository's own README, as read at the audited commit. Badges and raw HTML are left out.
[](https://www.npmjs.com/package/@aaronsb/google-workspace-mcp) [](https://github.com/aaronsb/google-workspace-mcp/releases) [](https://nodejs.org) [](LICENSE)
Give your AI agent real access to Google Workspace — Gmail, Calendar, Drive, Docs, Sheets, Tasks, Meet and Contacts — from one MCP server, across as many accounts as you have.
Search your mail, check your calendar, write a doc, file a task — in conversation, as yourself.
Install
First, you need Google OAuth credentials — the one prerequisite common to every path:
- Go to console.cloud.google.com/apis/credentials
- Create an OAuth 2.0 Client ID, application type Desktop app
- Enable the APIs you want (Gmail, Calendar, Drive, Sheets, Docs, Tasks, Meet — and People API for contacts, which is what Google calls it in the console)
- Keep the Client ID and Client Secret handy — you'll paste them in below
Then pick the path that matches how you work. All three run the same server.
Node 22.12 or newer. (Node 18 and 20 are both end-of-life.)
📦 → 🤖 Claude Desktop — one-click .mcpb install (recommended)
Download `google-workspace-mcp.mcpb` from the latest release, then drag it onto the Claude Desktop window, or double-click it.
Claude Desktop opens an install dialog with three fields:
94411bc95ff7OBSERVED · 2026-10-06Connect
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 google-workspace-mcp -- npx -y @aaronsb/[email protected]
Exposed tools (10)
5 read · 4 write · 1 destructive. Blast radius: 1 tool can delete or overwrite — an agent that can be talked into calling a tool can be talked into calling this one.
| Tool | Risk | Description |
|---|---|---|
account-access | read | Refuse writes from a read-only account, naming the account and the fix |
audit-log | write | Log all write operations to stderr — no blocking |
bulk_operations | read | Do many things in one call, two ways. mode: |
draft-only-email | write | Block outbound email — agents can read but not send |
manage_accounts | read | Manage Google Workspace account lifecycle: list, authenticate, check status, refresh credentials, update scopes, or remove accounts. |
manage_orphan | read | a service with an unroutable operation |
manage_scratchpad | write | Compose, edit, and deliver text content. Use for any multi-line content: emails, documents, descriptions. Compose in the scratchpad, edit by line or JSON path, attach files, then send to any target. For short one-liners, use the service tool directly instead. |
manage_workspace | read | Manage files and directories in the workspace sandbox. Supports nested paths (e.g. |
no-delete | destructive | Block permanent deletion — trash is allowed, delete is not |
read-only | write | Block all write operations — observation only |
Trust audit
BLOCKgrade D · trust 69/100 Do not install this without reading the findings. The audit found something that could harm you or your machine.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | FAIL |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | WARN |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- declared (1 observation(s))
- Network
- declared (3 observation(s))
- Shell
- declared (6 observation(s))
- Dependencies
- not all pinned
- Secrets in source
- none-found
Findings (25)
exec(`cmd /c start "" "${url}"`, onError);redirectUri = `http://127.0.0.1:${addr.port}/callback`;no-delete
.mcpbignore
const { stdout } = await exec(GWS, args, {return createHash('sha1').update(message).digest('hex').slice(0, 12);console.log(`token acquired for ${EMAIL} (not printed)\n`);import { getAccessToken } from '../../build/accounts/token-service.js';const { loadManifest } = await import('../../build/factory/generator.js');import { getAccessToken } from '../../build/accounts/token-service.js';import { getAccessToken } from '../../build/accounts/token-service.js';import { loadManifest } from '../../../build/factory/generator.js';const out = sanitizeHtmlForAgent('<p>visiblehidden</p>', { source: 'gmail' });expect(out).not.toContain('');const dirty = 'hello';
@modelcontextprotocol/sdk, sanitize-html, yaml, @types/node, @types/sanitize-html, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint
A `SERVICE_SCOPE_MAP` constant maps service names to OAuth scope URLs. `scopesForServices("gmail,drive,meet")` produces deduplicated scope URLs plus base scopes (`openid`, `userinfo.email`). Default a- `drive` and `sheets` have GET methods with no read-only scope, so read access to those two allows less than full access but still slightly more than reading. The consent step must say so rather than
An in-memory `Map<email, {accessToken, expiresAt}>` caches short-lived access tokens for the MCP session lifetime. `getAccessToken(email)` returns a cached token if >60 seconds remain, otherwise exchaThe policy **fails open** on every uncertainty: no credential, unreadable credential, no
Google is asked for the narrower scopes, so the token itself cannot send, edit or delete — not a rule this server enforces on top of a broad token. Where a service has no read-only scope, you're told
| `users.settings.cse.keypairs.create`<br>*POST* | Creates and uploads a client-side encryption S/MIME public key certificate chain and private key metadata for the authenticated user. For administrat
The GWS MCP server currently treats every content operation as a direct API call. `manage_docs write` appends text to a live document. `manage_email send` streams the full body in a single tool call.
An in-memory `Map<email, {accessToken, expiresAt}>` caches short-lived access tokens for the MCP session lifetime. `getAccessToken(email)` returns a cached token if >60 seconds remain, otherwise excha**Wait for Google's official Workspace MCP server.** Announced, but reportedly single-user by design. Our multi-account model — an `email` parameter on every call rather than a session-bound identity
Gates applied: no_behavioural_pass.
94411bc95ff7full audit observations/trust-audit/mcp-server/aaronsb__google-workspace-3.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-06 | 94411bc95ff7 | BLOCK | D | 69 | first audit |
Questions
What is the Google Workspace MCP server?
A Model Context Protocol (MCP) server that provides authenticated access to Google Workspace APIs, offering integrated Authentication, Gmail, Calendar, and Drive functionality
What tools does Google Workspace expose?
10 in total: 5 read-only, 4 that write, and 1 that can delete or overwrite (no-delete). Every one is listed on this page with its risk.
Is Google Workspace safe to connect to an agent?
No — not without reading the findings first. The audit graded it D (69/100) and found 1 critical or high issue in the source. Each one is listed on this page with the file and line it is on. Separately from the audit: 1 of its tools can destroy data, so scope the token you give it to what you actually need.
What credentials does Google Workspace need?
It reads GOOGLE_CLIENT_SECRET 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 Google Workspace run?
It speaks stdio, so it runs as a local process your client starts. It is published on npm as @aaronsb/google-workspace-mcp at 4.6.0.
How current is this page?
The grade is for one exact copy of the source (94411bc95ff7), read on 2026-10-06. The repository is watched and re-audited when it changes.