Atlas / MCP servers / aaronsb / Google Workspace

Google WorkspaceBLOCK

mcp/aaronsb/google-workspace-3

A Model Context Protocol (MCP) server that provides authenticated access to Google Workspace APIs, offering integrated Authentication, Gmail, Calendar, and Drive functionality

Verdict
BLOCK
Grade
D
Trust score
69 /100
Exposed tools
10 5r · 4w · 1d
Transport
stdio
License
Apache-2.0
Stars
190
01

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:

  1. Go to console.cloud.google.com/apis/credentials
  2. Create an OAuth 2.0 Client ID, application type Desktop app
  3. 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)
  4. 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:

Read from source at commit 94411bc95ff7OBSERVED · 2026-10-06
02

Connect

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-code (npm)
claude mcp add google-workspace-mcp -- npx -y @aaronsb/[email protected]
03

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.

ToolRiskDescription
account-accessreadRefuse writes from a read-only account, naming the account and the fix
audit-logwriteLog all write operations to stderr — no blocking
bulk_operationsreadDo many things in one call, two ways. mode:
draft-only-emailwriteBlock outbound email — agents can read but not send
manage_accountsreadManage Google Workspace account lifecycle: list, authenticate, check status, refresh credentials, update scopes, or remove accounts.
manage_orphanreada service with an unroutable operation
manage_scratchpadwriteCompose, 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_workspacereadManage files and directories in the workspace sandbox. Supports nested paths (e.g.
no-deletedestructiveBlock permanent deletion — trash is allowed, delete is not
read-onlywriteBlock all write operations — observation only
04

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.

LayerWhat it checksResult
L0Provenance & inventoryPASS
L1Static analysis of the codeFAIL
L2Instruction surface (what it tells the agent)PASS
L3Class-specific surfaceWARN
L4Behavioural (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)

HIGHCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
src/accounts/oauth.ts:349
exec(`cmd /c start "" "${url}"`, onError);
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
MEDIUMNetwork egress · net.raw_ip · CWE-200, CWE-319
src/accounts/oauth.ts:306
redirectUri = `http://127.0.0.1:${addr.port}/callback`;
MEDIUMFilesystem / path · mcp.destructive_tools · CWE-22, CWE-59
no-delete
Why it matters. 1 tool(s) can delete or overwrite
Fix. prefer a read-only mode or scoped tokens; the page states the blast radius
LOWInventory / provenance · inv.hidden_file · CWE-1104
mcpb/.mcpbignore
.mcpbignore
Why it matters. hidden member outside the usual dotfiles
Fix. review its purpose
LOWCode injection · code.eval_exec · CWE-78, CWE-94, CWE-95
docs/design-notes/adr-103-differential-harness.mjs:49
const { stdout } = await exec(GWS, args, {
Why it matters. evaluates text as code
Fix. remove; use a parser or a dispatch table
LOWInsecure crypto · crypto.weak_hash · CWE-327, CWE-338
src/__tests__/factory/generator.test.ts:62
return createHash('sha1').update(message).digest('hex').slice(0, 12);
LOWInformation disclosure · disclose.log_secret · CWE-209, CWE-532
docs/design-notes/adr-103-media-upload-spike.mjs:142
console.log(`token acquired for ${EMAIL} (not printed)\n`);
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
docs/design-notes/adr-103-differential-harness.mjs:28
import { getAccessToken } from '../../build/accounts/token-service.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
docs/design-notes/adr-103-differential-harness.mjs:189
const { loadManifest } = await import('../../build/factory/generator.js');
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
docs/design-notes/adr-103-media-roundtrip-spike.mjs:19
import { getAccessToken } from '../../build/accounts/token-service.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
docs/design-notes/adr-103-media-upload-spike.mjs:23
import { getAccessToken } from '../../build/accounts/token-service.js';
LOWFilesystem / path · fs.traversal · CWE-22, CWE-59
docs/design-notes/api-descriptor/check-conformance.mjs:20
import { loadManifest } from '../../../build/factory/generator.js';
LOWObfuscation / stealth · obf.rtl_override · CWE-506, CWE-94
src/__tests__/server/formatting/html-sanitize.test.ts:215
const out = sanitizeHtmlForAgent('<p>visiblehidden</p>', { source: 'gmail' });
LOWObfuscation / stealth · obf.rtl_override · CWE-506, CWE-94
src/__tests__/server/formatting/html-sanitize.test.ts:216
expect(out).not.toContain('');
LOWObfuscation / stealth · obf.zero_width · CWE-506, CWE-94
src/__tests__/server/formatting/html-sanitize.test.ts:208
const dirty = 'hello';
LOWSupply chain · supply.unpinned · CWE-829, CWE-1357
package.json
@modelcontextprotocol/sdk, sanitize-html, yaml, @types/node, @types/sanitize-html, @typescript-eslint/eslint-plugin, @typescript-eslint/parser, eslint
Why it matters. 10 dependency range(s) float
Fix. pin exact versions or ship a lockfile
LOWPrompt injection · prompt.authority_framing · CWE-94, CWE-1427
docs/architecture/auth/ADR-201-own-oauth-flow-with-token-service.md:42
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
LOWPrompt injection · prompt.authority_framing · CWE-94, CWE-1427
docs/architecture/auth/ADR-202-per-account-access-level-enforced-at-call-time.md:86
- `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
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/architecture/auth/ADR-201-own-oauth-flow-with-token-service.md:46
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
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.credential_read · CWE-94, CWE-1427
docs/architecture/auth/ADR-202-per-account-access-level-enforced-at-call-time.md:133
The policy **fails open** on every uncertainty: no credential, unreadable credential, no
Why it matters. asks the agent to read credentials
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
RELEASE-NOTES-v4.3.0.md:30
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
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/api-surface.md:193
| `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
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/architecture/api/ADR-301-scratchpad-buffer-for-service-agnostic-content-authoring.md:14
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.
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/architecture/auth/ADR-201-own-oauth-flow-with-token-service.md:46
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
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine
LOWPrompt injection · prompt.transfer_instruction · CWE-94, CWE-1427
docs/architecture/core/ADR-103-generate-a-google-api-descriptor-retire-the-gws-facade.md:327
**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
Why it matters. an instruction to move sensitive data to an outside destination
Fix. remove; a skill never needs the user's secrets off the machine

Gates applied: no_behavioural_pass.

Audited 2026-10-06 · audit v0.4.1 · source sha 94411bc95ff7full audit observations/trust-audit/mcp-server/aaronsb__google-workspace-3.json · Report an issue / request a re-scan
05

Audit history

Every audit this server has had. A grade with a past is a grade somebody is still checking.

DateSourceVerdictGradeScoreChange
2026-10-0694411bc95ff7BLOCKD69first audit
06

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.

Advertisement