Other formats agents might prefer:
markdownjsonllms.txt

Agent? You probably want markdown or json, or Pod over MCP.

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?

  1. Create OAuth 2.0 credentials:
    1. Choose "Desktop application" type
    2. Note your Client ID and Client Secret
    3. Use "urn:ietf:wg:oauth:2.0:oob" as the redirect URI (this enables out-of-band authentication)

Steps To Reproduce

  1. Go to Google Clients
  2. Create Client
  3. 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:

  • writeendOfSegmentLocation: { segmentId: '' } (src/services/docs/patch.ts)
  • insertTextlocation: { 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

  1. Create a Google Doc with several tabs and put different text in each one.
  2. Call manage_docs with operation: get, the document ID, and an authenticated account email.
  3. 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.