Reported issues for Google Workspace by aaronsb
Pod holds 23 of 57 GitHub reports that passed its relevance review. This can include external user reports, maintainer-confirmed bugs, and concrete feature gaps. Treat them as evidence to inspect, not a count of distinct defects.
Back to Google Workspace by aaronsb.
Most discussed
[BUG] OOB Deprecated
This repo looks great!
Bug Description
I've looked at your detailed setup guide but don't see how to configure a redirect URI for a desktop app?
- Create OAuth 2.0 credentials:
- Choose "Desktop application" type
- Note your Client ID and Client Secret
- Use "urn:ietf:wg:oauth:2.0:oob" as the redirect URI (this enables out-of-band authentication)
Steps To Reproduce
- Go to Google Clients
- Create Client
- Select "Deskto
Read the thread · 2025-04-19 · closed · external user · 3 comments
manage_scratchpad json-mode doc import reads the first tab only
manage_scratchpad import with mode: 'json' calls documents.get without
includeTabsContent, so a multi-tab document imports as its FIRST TAB ONLY —
the same defect as #152, on a different surface. mode: 'markdown' is fine: it
goes through Drive's files.export, which returns every tab.
src/server/scratchpad/adapters/import-doc.ts:93
This was left out of the #152 fix deliberately, because the obvious change breaks
something. Measured live: with includeTabsContent=true, Google **re
Read the thread · 2026-07-30 · closed · 2 comments
Legacy streamable-http: credential refresh triggers session rebinding error for multi-account use
Bug Description
When using Google Workspace MCP in legacy streamable-http multi-user mode, stored credentials are successfully refreshed after a server restart, but the request fails because the MCP session attempts to rebind to a different Google identity.
The server then incorrectly starts a new OAuth flow even though valid refreshed credentials already exist.
This appears to affect environments where a single MCP server is used with multiple Google accounts by supplying user_google_ema
Read the thread · 2026-07-10 · closed · external user · 2 comments
Proposal: opt-in read-only OAuth scopes (access: 'read')
Proposal
Add an opt-in access: 'read' | 'readwrite' option to account authentication. When set to 'read', it requests the read-only variant of each service scope (gmail.readonly, drive.readonly, calendar.readonly, …) instead of the current read/write scopes (gmail.modify, drive, calendar, …).
The default stays 'readwrite' — fully backward-compatible. No behavior changes unless a user opts in.
Motivation
In multi-account setups it's common to want least privile
Read the thread · 2026-06-03 · open · external user · 2 comments
manage_calendar.create fails: package emits --attendees, gws CLI takes --attendee (singular)
Bug
manage_calendar operation create returns validationError whenever the attendees param is provided. The package emits --attendees <comma-string> to the gws CLI, but gws calendar +insert only accepts --attendee <EMAIL> (singular, can be repeated). The unknown plural flag is rejected at validation time.
Reproduction
{
"operation": "create",
"email": "user@example.com",
"summary": "Test",
"start": "2026-05-01T00:00:00+05:30",
"end": "2026-05-01T01:00:00
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/116) · 2026-04-30 · closed · external user · 2 comments
### # Bug Report: Unauthorized Email Sent Without Approval
# GitHub Issue for google-workspace-mcp
**File at:** https://github.com/aaronsb/google-workspace-mcp/issues/new
**Title:** draft_gmail_message sends email instead of creating draft
**Labels:** bug
---
## Summary
The `draft_gmail_message` function appears to be sending emails immediately instead of creating drafts in the Gmail drafts folder.
## Steps to Reproduce
1. Call `draft_gmail_message` with valid parameters:
```json
{
"user_google_email": "user@example.com",
"to": "recipient@e
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/52) · 2026-01-20 · closed · external user · 2 comments
### [FEATURE] Create/update contacts
## Problem Statement
Contacts creation and update are not supported yet.
## Proposed Solution
Implement the required MCP tools.
## Benefits
Using that in Claude and other clients.
## Checklist
- [X] I have searched for similar feature requests
- [X] This feature aligns with the project's scope
- [X] I'm willing to help implement this feature
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/51) · 2025-11-08 · closed · external user · 2 comments
### Glama listing is missing Dockerfile
Your MCP server is currently listed on the [Glama MCP directory](https://glama.ai/mcp/servers/aaronsb/google-workspace-mcp), but it is not available for others to use because it does not have a Dockerfile.
It takes only a few minutes to fix this:
1. Go to your server's listing: [aaronsb/google-workspace-mcp](https://glama.ai/mcp/servers/aaronsb/google-workspace-mcp)
2. Click "Claim" to verify ownership.
3. Once claimed, navigate to the [admin `Dockerfile` page](https://glama.ai/mcp/servers/aar
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/41) · 2025-04-20 · closed · external user · 2 comments
## Most recent
### Expose contact groups — list, get, and add/remove members
Google publishes seven `contactGroups` methods and `manage_contacts` exposes none of them. Contact groups are how Gmail labels people — "Family", "Team" — and they are the natural follow-on to the contact operations that shipped in v4.3.0.
## The surface
contactGroups.list contactGroups.get contactGroups.batchGet contactGroups.create contactGroups.update contactGroups.delete contactGroups.members.modify
`members.modify` is the interesting one: it adds and removes
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/186) · 2026-08-17 · open · 0 comments
### Service account domain-wide delegation as a second auth mode, alongside OAuth
Roadmap idea. Today every account authenticates the same way: interactive OAuth, one browser round trip per account, a refresh token on disk. That is right for a person on their own machine and wrong for two cases it currently cannot serve.
## What it would enable
**Workspace administrators acting across a domain.** With domain-wide delegation, one service account can impersonate any user in the domain without each of them consenting individually. "Search every mailbox for this invoice" is not
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/184) · 2026-08-17 · open · 0 comments
### Spotlighting only wraps Gmail HTML — Drive, Docs, Meet and Contacts text is unwrapped
Spotlighting (ADR-305) is applied to Gmail HTML bodies and nothing else. Every other source of attacker-controlled text reaches the agent unwrapped.
## Measured
`sanitizeHtmlForAgent` has exactly two callers, both Gmail:
src/server/formatting/markdown.ts:75 sanitizeHtmlForAgent(decoded, { source: 'gmail' }) src/server/formatting/markdown.ts:89 sanitizeHtmlForAgent(html, { source: 'gmail' })
Zero references in `src/services/drive/patch.ts`, `src/services/docs/patch.ts`, `src/se
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/183) · 2026-08-17 · open · 0 comments
### manage_email reports "Email sent" with Message ID: unknown when Gmail did not confirm a send
`manage_email send` reports success on a Gmail response that never confirmed one.
## The defect
`src/services/gmail/patch.ts:309`:
```js
text: `Email sent to ${to}.\n\n**Subject:** ${subject}\n**Message ID:** ${data.id ?? 'unknown'}`
Same shape at :269 (forward), :303 (draft) and :366 (draft reply).
If Gmail returns a body without an id, the agent is told "Email sent to alice@example.com" with an id of unknown. Nothing distinguishes that from a real send, so the agent repo
Read the thread · 2026-08-17 · closed · 0 comments
Google Slides: expose it through the scratchpad, the way Docs and Sheets work
Roadmap idea. Related to #151, which asks for slides.presentations.batchUpdate specifically — this is the wider shape that would make it useful.
The idea
Docs and Sheets aren't exposed as raw API calls. They're authored through manage_scratchpad: compose or edit content in a buffer, addressed by line or JSON path, then send it — and in JSON mode the buffer live-syncs back to the document. Slides could use the same machinery rather than growing its own editing surface.
That matters beca
Read the thread · 2026-08-17 · open · 0 comments
Advertise the .mcpb bundle in the MCP Registry, not just the npm package
We build google-workspace-mcp.mcpb and attach it to every release, but server.json advertises only the npm package. Other Google Workspace servers in the registry list both, so Claude Desktop users can install straight from the registry listing.
Noticed while adding repository metadata (#179).
What the entry would gain
{
"registryType": "mcpb",
"identifier": "https://github.com/aaronsb/google-workspace-mcp/releases/download/v4.4.0/google-workspace-mcp.mcpb",
"version": "4
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/180) · 2026-08-17 · open · 0 comments
### Batch many edits into one documents.batchUpdate / spreadsheets.batchUpdate call
The second bulk axis, found while building the first (ADR-308, #10).
## What's happening now
`manage_docs` and `manage_sheets` already call Google's `batchUpdate` — but each tool call sends exactly one request inside it:
- `src/services/docs/patch.ts:411`, `:439`, `:473` — `requests: [{ … }]`
- `src/services/sheets/patch.ts:334` — `requests: [request]`
Google's `batchUpdate` accepts an **array**. So five edits to one document cost five HTTP calls carrying one request each, where they could c
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/175) · 2026-08-17 · open · 0 comments
### manage_scratchpad writes to Google without going through the safety-policy layer
`manage_scratchpad` writes to Google without consulting the safety-policy layer in `src/factory/safety.ts`. Found during code review of #170.
Only factory-generated handlers run `evaluatePolicies` (`src/factory/generator.ts`). `manage_scratchpad` is hand-registered in `src/server/handler.ts`, so its adapters reach Google directly:
| File | Call |
|---|---|
| `src/server/scratchpad/adapters/send-task.ts:52` | `tasks.insert` |
| `src/server/scratchpad/adapters/send-calendar.ts:55` | `events.inse
[Read the thread](https://github.com/aaronsb/google-workspace-mcp/issues/171) · 2026-08-17 · closed · 0 comments
### Per-param `required: true` never reaches the tool schema
Same class as #161 — the manifest carries information the model never sees.
## The mechanism
`generateSchema` builds the schema's `required` array from **one** thing (`src/factory/generator.ts:156`):
```ts
const required = service.requires_email ? ['operation', 'email'] : ['operation'];
The required: true flag declared on individual params is read nowhere. Every manifest uses it — documentId, eventId, fileId, messageId, spreadsheetId, taskId and dozens more are marked requi
Read the thread · 2026-08-17 · open · 1 comment
docs tab handling: hoist the duplicated parse, extract the traversal, anchor the repeated description
Three simplifications raised in the review of #160 and deliberately deferred rather than reshaping files in a branch that was about to merge. None is a bug; all three are in code the tab-addressing work (ADR-306) just made load-bearing.
1. Both docs-sync translators parse the buffer, and so does the caller
translateTextContent and translateParagraphStyle (src/server/scratchpad/docs-sync.ts) each do their own JSON.parse(intent.beforeJson) and each call resolveTabId. applyMutation
Read the thread · 2026-08-17 · open · 0 comments
Param descriptions dropped by generateSchema — 75 collisions, some load-bearing
The mechanism
generateSchema (src/factory/generator.ts:126-138) flattens every operation's params into one tool schema and keeps the first declaration of each param name:
if (!allParams[paramName]) { allParams[paramName] = { ...paramDef }; }
Later declarations are dropped with no warning. So a param used by several operations is described to the model exactly once, by whichever operation happens to appear first in the YAML — and reordering operations silently changes what
Read the thread · 2026-08-17 · closed · 0 comments
manage_docs get: no way to request a single tab, response unbounded
manage_docs get now returns every tab (#152), which is correct — and makes the response
unbounded with no way to ask for less.
The manifest exposes only documentId, so an agent that reads **Tabs:** 40 in the header
has no way to narrow the next read. A document holding one meeting transcript per tab —
exactly the shape #152 came from — is a single ~200 KB tool response. The bug was
accidentally capping this at one tab.
Measured during #152: a 3-tab document went from 10,213 to 14,884 cha
Read the thread · 2026-07-30 · closed · 1 comment
manage_docs write/insertText always target the first tab
manage_docs write operations always target the FIRST tab of a multi-tab document,
and now that get returns every tab (#152) the two sides disagree about what a
character index means.
Google's reference, for both Location and EndOfSegmentLocation: "If omitted, the
request applies to the first tab in the document." Neither call site sends a tabId:
write—endOfSegmentLocation: { segmentId: '' }(src/services/docs/patch.ts)insertText—location: { index }(same file)
`
Read the thread · 2026-07-30 · closed · 1 comment
[BUG] manage_docs get only returns the first tab of a multi-tab Google Doc
manage_docs with operation get returns the content of the first tab only. There's no error and nothing in the response to indicate the document has other tabs, so the partial content reads like the whole file.
Steps To Reproduce
- Create a Google Doc with several tabs and put different text in each one.
- Call
manage_docswithoperation: get, the document ID, and an authenticated account email. - Compare what comes back against the document. Only the first tab is there.
**Expec
Read the thread · 2026-07-27 · closed · external user · 0 comments
Expose slides.presentations.batchUpdate
Method: slides.presentations.batchUpdate (POST)
Google's description: Applies one or more updates to the presentation. Each request is validated before being applied. If any request is not valid, then the entire request will fail and nothing will be applied. Some requests have replies to give you some information about how they are applied. Other requests do not need to return information; these each return an empty reply. The order of replies matches that of the requests. For examp
Read the thread · 2026-07-27 · open · external user · 1 comment
The remaining reports are on the project's issue tracker.