@aaronsb/google-workspace-mcp 4.0.0 → 4.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -5,21 +5,119 @@
5
5
  [![Node](https://img.shields.io/node/v/@aaronsb/google-workspace-mcp?logo=node.js&label=node)](https://nodejs.org)
6
6
  [![License](https://img.shields.io/github/license/aaronsb/google-workspace-mcp)](LICENSE)
7
7
 
8
- Give AI agents real access to Google Workspace — Gmail, Calendar, Drive, Docs, Sheets, Tasks, and Meet — through a single MCP server that handles multi-account credential routing, response shaping for AI consumption, and contextual next-step guidance.
8
+ **Give your AI agent real access to Google Workspace** — Gmail, Calendar, Drive, Docs, Sheets, Tasks and Meet — from one MCP server, across as many accounts as you have.
9
9
 
10
- The server talks to Google's REST APIs directly, through a client it builds **from Google's own machine-readable API specifications**. Google publishes a [Discovery document](https://developers.google.com/discovery) for every API; a build step reads them and generates the descriptor this server dispatches against. Google's API surface *is* the source of truth — not a hand-maintained wrapper, and not a third-party CLI.
10
+ Search your mail, check your calendar, write a doc, file a task — in conversation, as yourself.
11
11
 
12
- ## Why This MCP Server
12
+ ## Install
13
+
14
+ First, you need **Google OAuth credentials** — the one prerequisite common to every path:
15
+
16
+ 1. Go to [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials)
17
+ 2. Create an **OAuth 2.0 Client ID**, application type **Desktop app**
18
+ 3. Enable the APIs you want (Gmail, Calendar, Drive, Sheets, Docs, Tasks, Meet)
19
+ 4. Keep the **Client ID** and **Client Secret** handy — you'll paste them in below
20
+
21
+ Then pick the path that matches how you work. All three run the same server.
22
+
23
+ Node 22.12 or newer. (Node 18 and 20 are both end-of-life.)
24
+
25
+ ---
26
+
27
+ ### 📦 → 🤖 Claude Desktop — one-click `.mcpb` install (recommended)
28
+
29
+ Download **`google-workspace-mcp.mcpb`** from the [latest release](https://github.com/aaronsb/google-workspace-mcp/releases/latest), then **drag it onto the Claude Desktop window**, or double-click it.
30
+
31
+ Claude Desktop opens an install dialog with three fields:
32
+
33
+ | Field | |
34
+ |---|---|
35
+ | **Google OAuth Client ID** | required — from the step above |
36
+ | **Google OAuth Client Secret** | required — from the step above |
37
+ | **Workspace Directory** | optional — where attachments, downloads and exports land. Defaults to `~/.local/share/google-workspace-mcp/workspace/`. Give it a dedicated folder — not your home, Documents, Desktop, or a Google Drive folder. |
38
+
39
+ Paste, hit Save, done. No JSON to edit, no Node to install, no paths to get right — the bundle carries the server and every dependency.
40
+
41
+ **One bundle covers every platform** — macOS (Intel and Apple Silicon), Linux (x64 and ARM64), and Windows. There is nothing to choose: the server is pure JavaScript, so there is no platform-specific payload to pick between.
42
+
43
+ > *Cross-platform note:* `.mcpb` files install via Claude Desktop's bundled handler. If double-clicking doesn't trigger Claude on your system, drag the file onto the Claude Desktop window instead, or right-click → "Open with…" and pick Claude Desktop (then "always open with" if your OS offers). Behavior varies: macOS usually auto-associates, Windows may need a one-time association, Linux varies by desktop environment.
44
+
45
+ ---
46
+
47
+ ### Claude Code — one command
48
+
49
+ ```bash
50
+ claude mcp add google-workspace \
51
+ -e GOOGLE_CLIENT_ID=your-client-id \
52
+ -e GOOGLE_CLIENT_SECRET=your-client-secret \
53
+ -- npx -y @aaronsb/google-workspace-mcp
54
+ ```
55
+
56
+ That's it — no file to edit. Verify with `/mcp`.
57
+
58
+ ---
59
+
60
+ ### Other MCP clients
61
+
62
+ Add an entry to the client's MCP config file (for Claude Desktop by hand, that's `claude_desktop_config.json`; for Claude Code, `.mcp.json`):
13
63
 
14
- **For users:** One install gives your agent authenticated access to your Google accounts. Search email, check your calendar, manage Drive files, chain multi-step workflows — through natural conversation.
64
+ ```json
65
+ {
66
+ "mcpServers": {
67
+ "google-workspace": {
68
+ "command": "npx",
69
+ "args": ["-y", "@aaronsb/google-workspace-mcp"],
70
+ "env": {
71
+ "GOOGLE_CLIENT_ID": "your-client-id",
72
+ "GOOGLE_CLIENT_SECRET": "your-client-secret"
73
+ }
74
+ }
75
+ }
76
+ }
77
+ ```
78
+
79
+ Or install it globally and point at the binary directly:
15
80
 
16
- **For teams:** Multi-account support lets one agent work across personal and work accounts at once, with per-account credential isolation and XDG-compliant storage.
81
+ ```bash
82
+ npm install -g @aaronsb/google-workspace-mcp
83
+ ```
17
84
 
18
- **For developers:** Adding an operation is a YAML edit, not a code change. The manifest curates which of Google's methods to expose; the generated descriptor already knows every method's path, HTTP verb, parameters, and scopes. Nothing is transcribed by hand, so nothing drifts from Google.
85
+ ## How it fits together
86
+
87
+ ```mermaid
88
+ flowchart LR
89
+ human["🧑 You<br>ask in plain language"]
90
+ agent["🤖 Your AI agent<br>Claude Desktop, Claude Code…"]
91
+ server["⚙️ This MCP server<br>picks the right account,<br>builds the real request"]
92
+ keys[("🔑 Your accounts<br>OAuth tokens, kept<br>on your own machine")]
93
+ google["☁️ Google<br>Gmail · Calendar · Drive<br>Docs · Sheets · Tasks · Meet"]
94
+
95
+ human -->|"“what's on my calendar?”"| agent
96
+ agent -->|"tool call"| server
97
+ server <-->|"which account?"| keys
98
+ server -->|"real API call, as you"| google
99
+ google -->|"your data"| server
100
+ server -->|"shaped for an agent<br>+ what to do next"| agent
101
+ agent -->|"an answer"| human
102
+
103
+ classDef person fill:#475569,color:#ffffff,stroke:#94a3b8
104
+ classDef robot fill:#2d7d9a,color:#ffffff,stroke:#4a5568
105
+ classDef ours fill:#7c3aed,color:#ffffff,stroke:#8b5cf6
106
+ classDef secrets fill:#2d8e5e,color:#ffffff,stroke:#4a5568
107
+ classDef external fill:#f6821f,color:#1a1a1a,stroke:#d97706
108
+
109
+ class human person
110
+ class agent robot
111
+ class server ours
112
+ class keys secrets
113
+ class google external
114
+ ```
19
115
 
20
- ## What's Available
116
+ **Your credentials never leave your machine.** The server holds an OAuth token per account, on your own disk, and calls Google *as you* — there is no middleman service, no account of ours, nothing to sign up for. Add as many accounts as you like (personal and work, side by side); the server routes each request to the right one.
21
117
 
22
- **11 tools — 7 Google services (80 operations), plus accounts, batching, content authoring, and a file sandbox.**
118
+ ## What it can do
119
+
120
+ **11 tools across 7 Google services**, plus multi-account handling, batching, content authoring, and a file sandbox.
23
121
 
24
122
  | Tool | What It Does |
25
123
  |------|--------------|
@@ -37,119 +135,68 @@ The server talks to Google's REST APIs directly, through a client it builds **fr
37
135
 
38
136
  Every response carries **next-steps** guidance, so the agent always knows what it can do next.
39
137
 
40
- Those 80 operations reach 60 of the 233 methods Google publishes across these seven APIs. The rest is mapped, not guessed — see **[API coverage](docs/coverage.md)**, which is generated by diffing the manifest against Google's live Discovery documents.
41
-
42
- ## How It Works
43
-
44
- Two phases. Google's API specification is acquired at **build time** and frozen into a committed artifact; at **runtime** the server only reads it.
45
-
46
- ```
47
- BUILD TIME RUNTIME
48
- ───────────────────────────────────────── ──────────────────────────────
49
-
50
- Google Discovery documents MCP Client
51
- (the machine-readable API spec) │ stdio
52
- │ ▼
53
- ▼ ┌──────────────┐
54
- ┌──────────────────────┐ │ Factory │◀── manifest/*.yaml
55
- │ descriptor generator │ │ generator │ (which ops to expose)
56
- │ scripts/generate- │ └──────┬───────┘
57
- │ descriptor.mjs │ │ schemas + handlers
58
- └──────────┬───────────┘ ▼
59
- │ ┌──────────────┐
60
- ▼ │ Patches │ Gmail hydration,
61
- src/google/descriptor.json ──────────────▶ │ │ agenda merging,
62
- 233 methods · committed └──────┬───────┘ MIME, formatting
63
- paths · verbs · params · scopes │
64
- ▼
65
- ┌──────────────┐
66
- │ Google client│──▶ Google REST APIs
67
- │ + account │ (call / upload /
68
- │ router │ download)
69
- └──────────────┘
138
+ ## One ask, many steps
139
+
140
+ The useful part isn't any single operation — it's that your agent can **string them together**.
141
+
142
+ You ask for one thing. The agent works out that it needs four API calls, in order, each one feeding the next:
143
+
144
+ ```mermaid
145
+ sequenceDiagram
146
+ autonumber
147
+ participant H as 🧑 You
148
+ participant A as 🤖 Your agent
149
+ participant S as ⚙️ MCP server
150
+ participant G as ☁️ Google
151
+
152
+ H->>A: "file the invoice from Acme<br>and remind me to pay it Friday"
153
+ A->>S: find the email
154
+ S->>G: search Gmail
155
+ G-->>S: the message
156
+ S-->>A: found it — and here's what you can do next
157
+ A->>S: save the attachment
158
+ S->>G: download it
159
+ A->>S: put it in Drive
160
+ S->>G: upload
161
+ A->>S: create a task, due Friday
162
+ S->>G: Google Tasks
163
+ A-->>H: Done. Invoice filed, task set for Friday.
70
164
  ```
71
165
 
72
- **The descriptor** is generated from Google's Discovery documents and committed. A CI drift gate re-generates it and fails if the result differs, so the spec we dispatch against cannot silently fall behind Google.
166
+ Two things make this work. Every response tells the agent **what it can do next**, so it isn't guessing at the next step. And `queue_operations` lets it run a whole chain in **one call**, feeding each result into the next — so "find the invoice, file it, remind me" is a single round trip rather than four.
73
167
 
74
- **The client** (`src/google/client.ts`) is deliberately opinion-free: it builds the request Google's spec describes and returns exactly what Google returned. It does not reshape responses. All interpretation lives in patches and formatters, aimed at the MCP contract — which is what keeps "what Google said" and "what we chose to show" separable.
168
+ ## Ask for what's missing
75
169
 
76
- **The factory** reads the YAML manifest and generates MCP tool schemas and handlers at startup. **Patches** add behavior where an agent needs more than a raw API response — hydrating Gmail search results with senders and subjects, merging an agenda across calendars, building MIME for outbound mail. Operations without a patch get sensible defaults.
170
+ This server exposes **80 operations**, reaching 60 of the **233 methods** Google publishes across those seven APIs. It is a curated subset on purpose: an agent has to *choose* among these, and every method it must weigh is one it can pick wrongly. A tool with 233 operations isn't more capable than one with 80 — it's harder to use correctly.
77
171
 
78
- Because method names are generated into a TypeScript union, calling a method Google doesn't publish is a **compile error**, not a 404 at runtime.
172
+ But that judgement was made without you.
79
173
 
80
- ## Install
81
-
82
- ### MCPB Bundle (Claude Desktop and other MCP clients)
174
+ **→ [Browse every method Google publishes](docs/api-surface.md)**
83
175
 
84
- Download `google-workspace-mcp.mcpb` from the [latest release](https://github.com/aaronsb/google-workspace-mcp/releases).
176
+ Every method is listed — what it does, whether we expose it, and a **Request** link that opens a pre-filled issue. The descriptions are Google's own, quoted verbatim, and the page is generated from the same specification the client is built from, so it can't drift from reality.
85
177
 
86
- One bundle covers every platform — macOS (Intel and Apple Silicon), Linux (x64 and ARM64), and Windows. There is nothing to choose: the server is pure JavaScript on Node, so there is no platform-specific payload to pick between. It needs Node 22.12 or newer.
178
+ That page also lists **four whole APIs this server doesn't touch yet** — Chat, Contacts, Slides and Forms — for the same reason: *not targeted* is a decision, not a fact of nature.
87
179
 
88
- In Claude Desktop, drag the `.mcpb` file into the app — it will prompt for your Google OAuth credentials. Other MCP clients that support `.mcpb` extensions install it the same way. The bundle includes the server and all of its dependencies.
180
+ A good request **names the task, not the method**:
89
181
 
90
- ### Claude Code / npm
182
+ > *"I want the agent to file incoming invoices into a folder automatically."*
91
183
 
92
- ```bash
93
- npm install @aaronsb/google-workspace-mcp
94
- ```
184
+ That can be evaluated. It might turn out an existing operation already does it, or that the right answer is a different method than the one you found. *"Expose `users.settings.filters.create`"* is a conclusion, not a case — lead with the problem and let the method follow.
95
185
 
96
- Or run directly:
186
+ ## Why Apache 2.0, and not open core
97
187
 
98
- ```bash
99
- npx @aaronsb/google-workspace-mcp
100
- ```
188
+ **Everything is here.** There is no paid tier, no "enterprise" build, no feature held back to sell you later. What you install is what exists.
101
189
 
102
- ### Prerequisites
190
+ Open core works by keeping the good part back. The free thing is a lead magnet, and the moment your use gets serious you discover the operation you need lives behind a licence. That model would be especially rotten *here*: this is a piece of plumbing between you and **your own data**, using **your own Google credentials**, running on **your own machine**. Nothing about that arrangement should have a paywall in the middle of it, and nothing about it needs a vendor.
103
191
 
104
- 1. **Node.js** 22.12 or newer — Node 18 and 20 are both end-of-life.
105
- 2. **Google Cloud OAuth credentials** — create at [console.cloud.google.com/apis/credentials](https://console.cloud.google.com/apis/credentials):
106
- - Create an OAuth 2.0 Client ID (Desktop application)
107
- - Enable the APIs you want (Gmail, Calendar, Drive, Sheets, …)
108
- 3. Set environment variables:
109
- ```bash
110
- export GOOGLE_CLIENT_ID="your-client-id"
111
- export GOOGLE_CLIENT_SECRET="your-client-secret"
112
- ```
192
+ [Apache 2.0](LICENSE) rather than MIT for two concrete reasons:
113
193
 
114
- ## MCP Client Configuration
115
-
116
- ### Claude Desktop
117
-
118
- Add to `claude_desktop_config.json`:
119
-
120
- ```json
121
- {
122
- "mcpServers": {
123
- "google-workspace": {
124
- "command": "npx",
125
- "args": ["@aaronsb/google-workspace-mcp"],
126
- "env": {
127
- "GOOGLE_CLIENT_ID": "your-client-id",
128
- "GOOGLE_CLIENT_SECRET": "your-client-secret"
129
- }
130
- }
131
- }
132
- }
133
- ```
194
+ - **An explicit patent grant.** Contributors licence their patent claims along with their code, so using this can't become a patent problem later. MIT is silent on patents, which means the question is merely unanswered rather than settled.
195
+ - **It's safe to adopt at work.** Apache 2.0 is on essentially every corporate allow-list. Fork it, vendor it, ship it inside a commercial product — you don't owe anyone anything, and you don't need to ask.
134
196
 
135
- ### Claude Code
197
+ The one obligation is attribution: keep the notices ([`NOTICE`](NOTICE), [`LICENSE`](LICENSE)) with the code. That's it.
136
198
 
137
- Add to `.mcp.json`:
138
-
139
- ```json
140
- {
141
- "mcpServers": {
142
- "google-workspace": {
143
- "command": "npx",
144
- "args": ["@aaronsb/google-workspace-mcp"],
145
- "env": {
146
- "GOOGLE_CLIENT_ID": "your-client-id",
147
- "GOOGLE_CLIENT_SECRET": "your-client-secret"
148
- }
149
- }
150
- }
151
- }
152
- ```
199
+ Through v3.0.0 this project was MIT-licensed, and that history is preserved rather than erased — MIT-era contributions keep their original notice in [`LICENSE-MIT`](LICENSE-MIT), and their authors are credited in [`NOTICE`](NOTICE). Apache 2.0 takes back nothing MIT permitted.
153
200
 
154
201
  ## Usage
155
202
 
@@ -180,20 +227,7 @@ Chain operations with result references — the output of one step feeds the nex
180
227
  }
181
228
  ```
182
229
 
183
- ## Expanding Coverage
184
-
185
- The coverage mapper diffs what the manifest exposes against what Google actually publishes, so the frontier is always measured rather than estimated:
186
-
187
- ```bash
188
- npm run generate-descriptor # re-read Google's Discovery documents
189
- make coverage # what we expose vs. what Google offers
190
- make manifest-lint # validate the curated manifest
191
- make check # type-check, lint, test, build, smoke
192
- ```
193
-
194
- To expose a new operation, add it to the relevant `src/factory/manifest/*.yaml`. The descriptor already knows its path, verb, parameters, and scopes, and the factory generates the tool schema and handler. New operations get default formatting automatically — add a patch only when an agent needs a shaped response rather than a raw one.
195
-
196
- ## Data Storage
230
+ ## Where your data lives
197
231
 
198
232
  Follows the XDG Base Directory Specification:
199
233
 
@@ -205,19 +239,17 @@ Follows the XDG Base Directory Specification:
205
239
 
206
240
  Credentials are per-account files holding standard OAuth tokens. No secrets are stored in the project directory.
207
241
 
208
- ## Design
242
+ ## Under the hood
209
243
 
210
- The server generates its API client from Google's own Discovery documents and calls Google directly. Nothing sits between the server and the API it targets: there is no subprocess, no second response shape, and no unversioned wrapper to keep in step. The descriptor is regenerated and diffed against Google on every build, so a method that does not exist is a compile error rather than a runtime surprise.
244
+ You don't need any of this to use the server. But if you're curious, or you want to add an operation:
211
245
 
212
- On top of that sits the manifest-driven tool factory: adding an operation is a YAML edit, not a code change. The coverage mapper reads Google's real published surface, so "what we expose vs what exists" is a measured number.
246
+ The server builds its Google API client **from Google's own machine-readable API specifications**. Nothing is transcribed by hand, so the surface can't drift from reality, and adding an operation is a YAML edit rather than a code change.
213
247
 
214
- The reasoning behind this design, including what was verified and what it cost, is in **[ADR-103](docs/architecture/core/ADR-103-generate-a-google-api-descriptor-retire-the-gws-facade.md)**.
248
+ - **[How it works](docs/how-it-works.md)** — the build-time / runtime split, the descriptor, the factory
249
+ - **[API coverage](docs/coverage.md)** — what's exposed, what isn't, and how to ask for more
250
+ - **[The full API surface](docs/api-surface.md)** — every method Google publishes, plus the four APIs we don't target yet
251
+ - **[Architecture decisions](docs/architecture/)** — the ADRs, including why this server owns its Google client outright
215
252
 
216
253
  ## License
217
254
 
218
- [Apache License 2.0](LICENSE).
219
-
220
- Through v3.0.0 this project was MIT-licensed. Those contributions keep their original
221
- notice (`LICENSE-MIT`), and the contributors are credited in [`NOTICE`](NOTICE). Apache 2.0
222
- adds an explicit patent grant and a state-your-changes requirement; it does not take back
223
- anything MIT permitted.
255
+ [Apache License 2.0](LICENSE) — see [Why Apache 2.0](#why-apache-20-and-not-open-core) above.
@@ -4,6 +4,10 @@ requires_email: true
4
4
  google_service: docs
5
5
  operations:
6
6
 
7
+ # A document's text lives per-TAB, and `tabId` is the handle that addresses one — the
8
+ # same handle every write operation below takes. Reading without it spans the document;
9
+ # reading with it scopes both the text and the character indices to one tab, so an
10
+ # index measured here means the same thing to insertText (#157, #158).
7
11
  get:
8
12
  type: detail
9
13
  description: "get document content and metadata"
@@ -13,6 +17,9 @@ operations:
13
17
  type: string
14
18
  description: "Document ID"
15
19
  required: true
20
+ tabId:
21
+ type: string
22
+ description: "Tab to act on — a tabId from a previous get's tabIndex. Scopes the read on get; targets the edit on write/insertText/replaceText, which act on the FIRST tab when it is omitted (replaceText spans every tab). Character indices are per-tab."
16
23
 
17
24
  # `title` rides in the BODY — documents.create declares no parameters at all
18
25
  # (Discovery: `"parameters": {}`), so everything goes into the Document resource.
@@ -42,8 +49,11 @@ operations:
42
49
  required: true
43
50
  text:
44
51
  type: string
45
- description: "Text to append (plain text)"
52
+ description: "Text to write (plain text) — appended to the end by write, inserted at `index` by insertText"
46
53
  required: true
54
+ tabId:
55
+ type: string
56
+ description: "Tab to act on — a tabId from a previous get's tabIndex. Scopes the read on get; targets the edit on write/insertText/replaceText, which act on the FIRST tab when it is omitted (replaceText spans every tab). Character indices are per-tab."
47
57
 
48
58
  insertText:
49
59
  type: action
@@ -56,12 +66,15 @@ operations:
56
66
  required: true
57
67
  text:
58
68
  type: string
59
- description: "Text to insert"
69
+ description: "Text to write (plain text) — appended to the end by write, inserted at `index` by insertText"
60
70
  required: true
61
71
  index:
62
72
  type: number
63
- description: "Character index to insert at (1 = start of document body)"
73
+ description: "Character index to insert at (1 = start of the tab's body)"
64
74
  required: true
75
+ tabId:
76
+ type: string
77
+ description: "Tab to act on — a tabId from a previous get's tabIndex. Scopes the read on get; targets the edit on write/insertText/replaceText, which act on the FIRST tab when it is omitted (replaceText spans every tab). Character indices are per-tab."
65
78
 
66
79
  replaceText:
67
80
  type: action
@@ -84,3 +97,6 @@ operations:
84
97
  type: boolean
85
98
  description: "Case-sensitive match (default: true)"
86
99
  default: true
100
+ tabId:
101
+ type: string
102
+ description: "Tab to act on — a tabId from a previous get's tabIndex. Scopes the read on get; targets the edit on write/insertText/replaceText, which act on the FIRST tab when it is omitted (replaceText spans every tab). Character indices are per-tab."
@@ -68,13 +68,24 @@ function splitParams(svc, method, params) {
68
68
  for (const [key, value] of Object.entries(params)) {
69
69
  if (value === undefined || value === null)
70
70
  continue;
71
- const location = declared[key]?.location;
71
+ const decl = declared[key];
72
+ const location = decl?.location;
73
+ // A REPEATED parameter is sent once per value (`?h=From&h=Subject`), never as one
74
+ // comma-joined string. Google does not split it for us: asked for the single header
75
+ // named "From,Subject,Date,To", it finds none and returns a payload with no headers
76
+ // at all — which rendered a whole mail thread with empty senders and empty subjects,
77
+ // and raised no error. The descriptor already records which params are repeated, so
78
+ // accept a comma-separated string and expand it rather than trusting every caller
79
+ // to remember.
80
+ const coerced = decl?.repeated && typeof value === 'string'
81
+ ? value.split(',').map((v) => v.trim()).filter(Boolean)
82
+ : value;
72
83
  if (location === 'path')
73
- path[key] = value;
84
+ path[key] = coerced;
74
85
  else if (location === 'query')
75
- query[key] = value;
86
+ query[key] = coerced;
76
87
  else
77
- body[key] = value; // undeclared -> request body; Google validates it, not us
88
+ body[key] = coerced; // undeclared -> request body; Google validates it, not us
78
89
  }
79
90
  return { path, query, body };
80
91
  }
@@ -115,23 +126,63 @@ export async function call(service, resourcePath, params, options) {
115
126
  const doFetch = options.fetchImpl ?? fetch;
116
127
  const request = buildRequest(descriptor, service, resourcePath, params);
117
128
  const token = await getAccessToken(options.account);
118
- const response = await doFetch(request.url, {
119
- method: request.method,
120
- headers: {
121
- Authorization: `Bearer ${token}`,
122
- ...(request.body ? { 'Content-Type': 'application/json' } : {}),
123
- },
124
- ...(request.body ? { body: JSON.stringify(request.body) } : {}),
125
- });
126
- const text = await response.text();
127
- const json = parseJson(text);
128
- if (!response.ok) {
129
+ for (let attempt = 0;; attempt++) {
130
+ const response = await doFetch(request.url, {
131
+ method: request.method,
132
+ headers: {
133
+ Authorization: `Bearer ${token}`,
134
+ ...(request.body ? { 'Content-Type': 'application/json' } : {}),
135
+ },
136
+ ...(request.body ? { body: JSON.stringify(request.body) } : {}),
137
+ });
138
+ const text = await response.text();
139
+ const json = parseJson(text);
140
+ if (response.ok)
141
+ return json;
142
+ // Google throttles per user, not per process. Two clients on one account — a
143
+ // desktop app and an editor, say — share the quota, so a burst of reads can be
144
+ // rejected even though nothing is wrong with the request. That is a TRANSIENT
145
+ // condition and the documented response to it is to back off and try again:
146
+ // https://developers.google.com/workspace/gmail/api/guides/handle-errors
147
+ //
148
+ // Retrying belongs here rather than in each caller. A caller that must decide
149
+ // for itself whether a 429 is fatal will get it wrong somewhere, and the way it
150
+ // gets it wrong is by treating "I could not read this" as "there is nothing to
151
+ // read" — which is how a rate-limited inbox rendered as rows with no sender and
152
+ // no subject.
153
+ if (shouldRetry(response.status) && attempt < RETRY_ATTEMPTS) {
154
+ await sleep(retryDelayMs(attempt, response.headers.get('retry-after')));
155
+ continue;
156
+ }
129
157
  throw new GoogleApiError(response.status, json, {
130
158
  url: request.url,
131
159
  method: request.method,
132
160
  });
133
161
  }
134
- return json;
162
+ }
163
+ /** 429 = rate limited. 5xx = Google having a moment. Both are worth another go. */
164
+ const RETRY_ATTEMPTS = 4;
165
+ function shouldRetry(status) {
166
+ return status === 429 || status === 500 || status === 502 || status === 503 || status === 504;
167
+ }
168
+ /**
169
+ * Exponential backoff with full jitter. The jitter is not decoration: without it, a
170
+ * batch of calls throttled together retries together, re-creating the burst that
171
+ * caused the throttling.
172
+ *
173
+ * `Retry-After` wins when Google sends one — it is Google telling us what it wants.
174
+ */
175
+ function retryDelayMs(attempt, retryAfter) {
176
+ if (retryAfter) {
177
+ const seconds = Number(retryAfter);
178
+ if (Number.isFinite(seconds) && seconds >= 0)
179
+ return Math.min(seconds * 1000, 30_000);
180
+ }
181
+ const ceiling = Math.min(1000 * 2 ** attempt, 16_000);
182
+ return Math.random() * ceiling;
183
+ }
184
+ function sleep(ms) {
185
+ return new Promise((resolve) => setTimeout(resolve, ms));
135
186
  }
136
187
  /**
137
188
  * Download media to disk.
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/google/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/google/client.ts"],"names":[],"mappings":"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"}
package/build/index.js CHANGED
@@ -19,20 +19,24 @@
19
19
  * ERR_REQUIRE_ESM ever leaks (CI job `engines-floor-reject`), and `check-node-floor.mjs`
20
20
  * rejects a static import of the server graph outright. Those are what protect it.
21
21
  *
22
- * `./node-floor.js` imports only `node:fs` (a builtin), so it cannot trigger the failure
23
- * this file guards against. Only the SERVER GRAPH must stay behind the dynamic import.
22
+ * `./node-floor.js` and `./lifecycle.js` import only `node:fs` (a builtin), so they cannot
23
+ * trigger the failure this file guards against. Only the SERVER GRAPH must stay behind the
24
+ * dynamic import.
24
25
  */
25
26
  import { enforceNodeFloor } from './node-floor.js';
27
+ import { installLifecycle } from './lifecycle.js';
26
28
  enforceNodeFloor();
29
+ /**
30
+ * Before the server starts: notice if our client dies, and exit.
31
+ *
32
+ * This also installs the uncaughtException/unhandledRejection guards, which used to live
33
+ * here and wrote to `process.stderr` directly. That was the busy-loop in issue #149 — once
34
+ * the client died, the write raised the next uncaught exception, which re-entered the
35
+ * handler, forever, at 100% CPU. See lifecycle.ts and ADR-104.
36
+ */
37
+ installLifecycle();
27
38
  // Dynamic, and only after the floor is enforced. See the file header.
28
39
  const { startServer } = await import('./server/server.js');
29
- // Prevent unhandled rejections from crashing the server
30
- process.on('unhandledRejection', (reason) => {
31
- process.stderr.write(`[google-workspace-mcp] unhandled rejection: ${reason}\n`);
32
- });
33
- process.on('uncaughtException', (err) => {
34
- process.stderr.write(`[google-workspace-mcp] uncaught exception: ${err.message}\n${err.stack}\n`);
35
- });
36
40
  startServer().catch((err) => {
37
41
  process.stderr.write(`[google-workspace-mcp] fatal: ${err.message}\n`);
38
42
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,gBAAgB,EAAE,CAAC;AAEnB,sEAAsE;AACtE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE3D,wDAAwD;AACxD,OAAO,CAAC,EAAE,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE;IAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,+CAA+C,MAAM,IAAI,CAAC,CAAC;AAClF,CAAC,CAAC,CAAC;AAEH,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,CAAC,GAAG,EAAE,EAAE;IACtC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,8CAA8C,GAAG,CAAC,OAAO,KAAK,GAAG,CAAC,KAAK,IAAI,CAAC,CAAC;AACpG,CAAC,CAAC,CAAC;AAEH,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAElD,gBAAgB,EAAE,CAAC;AAEnB;;;;;;;GAOG;AACH,gBAAgB,EAAE,CAAC;AAEnB,sEAAsE;AACtE,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE3D,WAAW,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iCAAiC,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}