google-services-mcp 0.1.0-beta.38 → 0.1.0-beta.388
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 +32 -15
- package/dist/auth/config.d.ts.map +1 -1
- package/dist/auth/config.js +10 -3
- package/dist/auth/config.js.map +1 -1
- package/dist/auth/manager.d.ts +1 -1
- package/dist/auth/manager.d.ts.map +1 -1
- package/dist/auth/manager.js +64 -16
- package/dist/auth/manager.js.map +1 -1
- package/dist/auth/oauth.d.ts +10 -2
- package/dist/auth/oauth.d.ts.map +1 -1
- package/dist/auth/oauth.js +16 -4
- package/dist/auth/oauth.js.map +1 -1
- package/dist/auth/store.d.ts.map +1 -1
- package/dist/auth/store.js +6 -1
- package/dist/auth/store.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +13 -4
- package/dist/cli.js.map +1 -1
- package/dist/main.js +7 -1
- package/dist/main.js.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/services/calendar.d.ts +95 -0
- package/dist/services/calendar.d.ts.map +1 -1
- package/dist/services/calendar.js +155 -5
- package/dist/services/calendar.js.map +1 -1
- package/dist/services/contacts-tasks.d.ts +74 -2
- package/dist/services/contacts-tasks.d.ts.map +1 -1
- package/dist/services/contacts-tasks.js +149 -6
- package/dist/services/contacts-tasks.js.map +1 -1
- package/dist/services/docs.d.ts +41 -6
- package/dist/services/docs.d.ts.map +1 -1
- package/dist/services/docs.js +51 -12
- package/dist/services/docs.js.map +1 -1
- package/dist/services/drive.d.ts +75 -4
- package/dist/services/drive.d.ts.map +1 -1
- package/dist/services/drive.js +149 -11
- package/dist/services/drive.js.map +1 -1
- package/dist/services/forms.d.ts +55 -5
- package/dist/services/forms.d.ts.map +1 -1
- package/dist/services/forms.js +148 -4
- package/dist/services/forms.js.map +1 -1
- package/dist/services/gmail.d.ts +210 -0
- package/dist/services/gmail.d.ts.map +1 -1
- package/dist/services/gmail.js +669 -19
- package/dist/services/gmail.js.map +1 -1
- package/dist/services/sheets.d.ts +59 -5
- package/dist/services/sheets.d.ts.map +1 -1
- package/dist/services/sheets.js +91 -0
- package/dist/services/sheets.js.map +1 -1
- package/dist/services/slides.d.ts +49 -7
- package/dist/services/slides.d.ts.map +1 -1
- package/dist/services/slides.js +89 -3
- package/dist/services/slides.js.map +1 -1
- package/dist/services/youtube.d.ts +77 -8
- package/dist/services/youtube.d.ts.map +1 -1
- package/dist/services/youtube.js +134 -2
- package/dist/services/youtube.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1297 -45
- package/dist/tools/index.js.map +1 -1
- package/dist/util/save-path.d.ts +12 -0
- package/dist/util/save-path.d.ts.map +1 -0
- package/dist/util/save-path.js +66 -0
- package/dist/util/save-path.js.map +1 -0
- package/package.json +35 -15
package/README.md
CHANGED
|
@@ -8,10 +8,24 @@ Add one account, wire the server into any MCP-compatible AI client, and your
|
|
|
8
8
|
agent can read and send email, manage your calendar, find files in Drive,
|
|
9
9
|
create documents and spreadsheets, and more — using your real Google data.
|
|
10
10
|
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g google-services-mcp # or run without installing: npx -y google-services-mcp
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Google Workspace MCP
|
|
16
|
+
|
|
17
|
+
One MCP server for your Google Workspace apps — Gmail, Calendar, Google Meet,
|
|
18
|
+
Drive, Contacts, Tasks, Sheets, Docs, Slides, YouTube, and Forms — with
|
|
19
|
+
multi-account OAuth. Every tool is prefixed `google_` (e.g. `google_gmail_list`,
|
|
20
|
+
`google_calendar_list_events`), so agents can combine services freely: read
|
|
21
|
+
email, then create a Calendar event from it, or attach a Drive file to a draft.
|
|
22
|
+
|
|
11
23
|
## Features
|
|
12
24
|
|
|
13
|
-
- **Gmail** — send, list, read,
|
|
14
|
-
|
|
25
|
+
- **Gmail** — full Gmail access: send, draft, reply, list, read, search,
|
|
26
|
+
label, and manage attachments
|
|
27
|
+
- **Calendar** — Google Calendar events: list calendars,
|
|
28
|
+
create/read/update/delete events, create Google Meet links
|
|
15
29
|
- **Drive** — list, read, upload, update, delete, and share files
|
|
16
30
|
- **Contacts** — list, search, and create contacts
|
|
17
31
|
- **Tasks** — list task lists, create/complete/delete tasks
|
|
@@ -20,10 +34,11 @@ create documents and spreadsheets, and more — using your real Google data.
|
|
|
20
34
|
- **Slides** — create presentations, add/delete slides, find-and-replace text
|
|
21
35
|
- **YouTube** — search videos, manage uploads/playlists/subscriptions
|
|
22
36
|
- **Forms** — create forms, add questions, read responses
|
|
23
|
-
- **Multi-account** — connect several Google accounts, set a default, or pass
|
|
37
|
+
- **Multi-account** — connect several Google accounts, set a default, or pass
|
|
38
|
+
an `account` argument to any tool
|
|
24
39
|
- **OAuth 2.0** — one-time browser authorization; tokens are stored locally and refreshed automatically
|
|
25
40
|
|
|
26
|
-
> **
|
|
41
|
+
> **134 tools** across 11 services, all prefixed `google_`. Full reference:
|
|
27
42
|
> [docs/TOOLS.md](docs/TOOLS.md).
|
|
28
43
|
|
|
29
44
|
## Requirements
|
|
@@ -71,7 +86,8 @@ everywhere below.
|
|
|
71
86
|
|
|
72
87
|
### Release channels
|
|
73
88
|
|
|
74
|
-
- `latest` — stable releases, published automatically
|
|
89
|
+
- `latest` — stable releases, published automatically when a merge to `main`
|
|
90
|
+
changes something the package ships
|
|
75
91
|
- `beta` — staging builds, published manually from `main`
|
|
76
92
|
(e.g. `0.x.x-beta.0`)
|
|
77
93
|
|
|
@@ -194,14 +210,14 @@ Open the [Google Cloud Console](https://console.cloud.google.com/), choose
|
|
|
194
210
|
Set these environment variables (or put them in your MCP client config as
|
|
195
211
|
above):
|
|
196
212
|
|
|
197
|
-
```
|
|
213
|
+
```text
|
|
198
214
|
GOOGLE_MCP_CLIENT_ID=<your-oauth-client-id>
|
|
199
215
|
GOOGLE_MCP_CLIENT_SECRET=<your-oauth-client-secret>
|
|
200
216
|
```
|
|
201
217
|
|
|
202
218
|
Optional:
|
|
203
219
|
|
|
204
|
-
```
|
|
220
|
+
```text
|
|
205
221
|
GOOGLE_MCP_DIR=~/.google-services-mcp # where config and tokens live (default ~/.google-services-mcp)
|
|
206
222
|
GOOGLE_MCP_REDIRECT_PORT=8787 # local loopback port for OAuth (default 8787)
|
|
207
223
|
# Full redirect URI override. Takes precedence over REDIRECT_PORT and must
|
|
@@ -221,7 +237,7 @@ different name (e.g. `work`) to connect more accounts.
|
|
|
221
237
|
|
|
222
238
|
## CLI reference
|
|
223
239
|
|
|
224
|
-
```
|
|
240
|
+
```bash
|
|
225
241
|
npx -y google-services-mcp # run the MCP server over stdio
|
|
226
242
|
npx -y google-services-mcp add <name> # add a Google account (opens browser)
|
|
227
243
|
npx -y google-services-mcp list # list connected accounts
|
|
@@ -254,12 +270,12 @@ npx -y google-services-mcp --help # show help
|
|
|
254
270
|
## Troubleshooting
|
|
255
271
|
|
|
256
272
|
| Symptom | Cause / fix |
|
|
257
|
-
|
|
273
|
+
| --- | --- |
|
|
258
274
|
| `access blocked` on consent | Account not in **Test users** (setup step 2.3) — add it and retry |
|
|
259
|
-
| `redirect_uri_mismatch` |
|
|
260
|
-
| Tokens stop
|
|
261
|
-
| `npx
|
|
262
|
-
| `Google hasn't verified this app` | Normal
|
|
275
|
+
| `redirect_uri_mismatch` | Exactly `http://localhost:8787` (no trailing slash), per OAuth client |
|
|
276
|
+
| Tokens stop after ~7 days | App in **Testing** mode — re-run `add` or **Publish app** |
|
|
277
|
+
| `npx` not found | GUI clients may lack PATH — use `/usr/local/bin/npx` or global install |
|
|
278
|
+
| `Google hasn't verified this app` | Normal — click **Advanced → Continue** for personal use |
|
|
263
279
|
|
|
264
280
|
## Local development
|
|
265
281
|
|
|
@@ -268,7 +284,7 @@ git clone https://github.com/nabheet/google-services-mcp.git
|
|
|
268
284
|
cd google-services-mcp
|
|
269
285
|
npm install
|
|
270
286
|
npm run build # compile to dist/
|
|
271
|
-
npm test # vitest, TDD suites
|
|
287
|
+
npm test # vitest, TDD suites (incl. hermetic E2E in test/e2e/)
|
|
272
288
|
npm run typecheck # tsc --noEmit
|
|
273
289
|
npm run dev # run from source with tsx
|
|
274
290
|
```
|
|
@@ -279,7 +295,8 @@ See [AGENTS.md](AGENTS.md) for architecture and conventions.
|
|
|
279
295
|
|
|
280
296
|
All publishing happens from GitHub Actions — no local npm login needed:
|
|
281
297
|
|
|
282
|
-
1. **Stable** —
|
|
298
|
+
1. **Stable** — a merge to `main` that changes shipping files auto-publishes the
|
|
299
|
+
next patch version
|
|
283
300
|
to `latest` with provenance, then creates a `vX.Y.Z` tag and GitHub
|
|
284
301
|
release. No manual steps. The next version is derived from the last
|
|
285
302
|
published `latest` on npm, so repeated merges never collide; an
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AAEH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,wFAAwF;AACxF,eAAO,MAAM,cAAc,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAKA;;;;;;;;;GASG;AAEH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C,wFAAwF;AACxF,eAAO,MAAM,cAAc,EAAE,MAAM,EA0BlC,CAAC;AAEF,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,mGAAmG;IACnG,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,+DAA+D;IAC/D,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAKhD;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,CAwBlD;AAED,wBAAsB,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAa9D;AAED,wBAAsB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKjG;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAEtD;AAED,+DAA+D;AAC/D,wBAAgB,cAAc,IAAI,MAAM,CAEvC"}
|
package/dist/auth/config.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
1
2
|
import os from "node:os";
|
|
2
3
|
import path from "node:path";
|
|
3
|
-
import fs from "node:fs/promises";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
/**
|
|
6
6
|
* Configuration for the OAuth client and server defaults.
|
|
@@ -33,6 +33,9 @@ export const DEFAULT_SCOPES = [
|
|
|
33
33
|
"https://www.googleapis.com/auth/presentations",
|
|
34
34
|
// YouTube: read/write the user's channel data and playlists
|
|
35
35
|
"https://www.googleapis.com/auth/youtube",
|
|
36
|
+
// YouTube comments: commentThreads.list, comments.insert and moderation
|
|
37
|
+
// require force-ssl (the plain youtube scope does not cover comments)
|
|
38
|
+
"https://www.googleapis.com/auth/youtube.force-ssl",
|
|
36
39
|
// Forms: read/write forms and responses
|
|
37
40
|
"https://www.googleapis.com/auth/forms",
|
|
38
41
|
// Identity: lets fetchUserInfo return the signed-in email for account display
|
|
@@ -61,7 +64,10 @@ export function isValidName(name) {
|
|
|
61
64
|
return /^[a-zA-Z0-9_-]+$/.test(name);
|
|
62
65
|
}
|
|
63
66
|
export async function ensureDirs() {
|
|
64
|
-
await fs.mkdir(getAccountsDir(), { recursive: true });
|
|
67
|
+
await fs.mkdir(getAccountsDir(), { recursive: true, mode: 0o700 });
|
|
68
|
+
// mkdir's mode only applies to newly-created dirs; harden pre-existing ones.
|
|
69
|
+
await fs.chmod(getAccountsDir(), 0o700).catch(() => { });
|
|
70
|
+
await fs.chmod(getDataDir(), 0o700).catch(() => { });
|
|
65
71
|
}
|
|
66
72
|
export async function loadConfig() {
|
|
67
73
|
await ensureDirs();
|
|
@@ -90,7 +96,8 @@ export async function loadConfig() {
|
|
|
90
96
|
export async function saveConfig(config) {
|
|
91
97
|
await ensureDirs();
|
|
92
98
|
const { clientId, clientSecret, redirectPort, redirectUri, defaultAccount, scopes } = config;
|
|
93
|
-
await fs.writeFile(getConfigPath(), JSON.stringify({ clientId, clientSecret, redirectPort, redirectUri, defaultAccount, scopes }, null, 2), "utf8");
|
|
99
|
+
await fs.writeFile(getConfigPath(), JSON.stringify({ clientId, clientSecret, redirectPort, redirectUri, defaultAccount, scopes }, null, 2), { encoding: "utf8", mode: 0o600 });
|
|
100
|
+
await fs.chmod(getConfigPath(), 0o600).catch(() => { });
|
|
94
101
|
}
|
|
95
102
|
export async function saveClientCredentials(clientId, clientSecret) {
|
|
96
103
|
const config = await loadConfig();
|
package/dist/auth/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/auth/config.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/manager.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/auth/manager.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/auth/manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAU,MAAM,YAAY,CAAC;AAC/C,OAAO,EACL,KAAK,MAAM,EAOZ,MAAM,aAAa,CAAC;AAYrB,OAAO,EAIL,KAAK,aAAa,EAEnB,MAAM,YAAY,CAAC;AAoBpB,MAAM,WAAW,iBAAiB;IAChC,2DAA2D;IAC3D,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,qFAAqF;IACrF,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,qBAAqB,EAAE,OAAO,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,aAAa,EAAE,CAAC;CAC3B;AAED;;;GAGG;AACH,cAAM,WAAW;IACT,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAEjC;IAEK,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAE7C;IAED;;;OAGG;IACG,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA+B1D;IAED,iFAAiF;IAC3E,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAsBzD;IAED;;;;OAIG;IACG,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,OAAO,CAAC,aAAa,CAAC,CA+CtF;IAEK,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAiBlD;IAEK,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAWnD;IAEK,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE3E;IAEK,SAAS,IAAI,OAAO,CAAC,YAAY,CAAC,CAevC;CACF;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
package/dist/auth/manager.js
CHANGED
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
import { google } from "googleapis";
|
|
2
|
-
import { loadConfig,
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { getDataDir, hasCredentials, loadConfig, sanitizeName, saveClientCredentials, saveConfig, } from "./config.js";
|
|
3
|
+
import { buildAuthUrl, DEFAULT_AUTH_TIMEOUT_MS, exchangeCode, fetchUserInfo, generatePkce, generateState, openBrowser, refreshAccessToken, waitForOAuthCallback, } from "./oauth.js";
|
|
4
|
+
import { deleteAccount, loadAccount, loadAllAccounts, saveAccount, } from "./store.js";
|
|
5
|
+
/** Sanitized key for a legacy or user-supplied name, falling back to the raw string. */
|
|
6
|
+
function normalizeKey(name) {
|
|
7
|
+
try {
|
|
8
|
+
return sanitizeName(name);
|
|
9
|
+
}
|
|
10
|
+
catch {
|
|
11
|
+
return name;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
function canSanitize(name) {
|
|
15
|
+
try {
|
|
16
|
+
sanitizeName(name);
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
return false;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
5
23
|
/**
|
|
6
24
|
* Coordinates credentials, per-account token storage, the interactive OAuth
|
|
7
25
|
* flow, and refresh. All service modules resolve auth through here.
|
|
@@ -20,10 +38,13 @@ class AuthManager {
|
|
|
20
38
|
async resolveAccount(name) {
|
|
21
39
|
const accounts = await loadAllAccounts();
|
|
22
40
|
if (name) {
|
|
23
|
-
|
|
41
|
+
// Account names are stored sanitized (lowercased, non-alphanumerics
|
|
42
|
+
// replaced), so match the caller's spelling against the same form.
|
|
43
|
+
const key = sanitizeName(name);
|
|
44
|
+
const found = accounts.find((a) => a.name === key);
|
|
24
45
|
if (!found) {
|
|
25
46
|
const available = accounts.length ? accounts.map((a) => a.name).join(", ") : "none";
|
|
26
|
-
throw new Error(`Account "${
|
|
47
|
+
throw new Error(`Account "${key}" not found. Available accounts: ${available}`);
|
|
27
48
|
}
|
|
28
49
|
return found;
|
|
29
50
|
}
|
|
@@ -31,8 +52,12 @@ class AuthManager {
|
|
|
31
52
|
throw new Error("No Google accounts configured. Add one with the account_add tool or run: google-services-mcp add <name>");
|
|
32
53
|
}
|
|
33
54
|
const config = await this.getConfig();
|
|
34
|
-
|
|
35
|
-
|
|
55
|
+
const storedDefault = config.defaultAccount;
|
|
56
|
+
if (storedDefault) {
|
|
57
|
+
// Configs written before names were normalized can hold a raw value
|
|
58
|
+
// ("Work Account"); normalize on read so they keep resolving.
|
|
59
|
+
const key = normalizeKey(storedDefault);
|
|
60
|
+
const found = accounts.find((a) => a.name === key);
|
|
36
61
|
if (found)
|
|
37
62
|
return found;
|
|
38
63
|
}
|
|
@@ -68,13 +93,17 @@ class AuthManager {
|
|
|
68
93
|
* the account alongside the signed-in email.
|
|
69
94
|
*/
|
|
70
95
|
async addAccount(name, options = {}) {
|
|
96
|
+
// Normalize before the OAuth flow: the record and the file are both keyed
|
|
97
|
+
// by the sanitized name, and a bad name should fail before a browser opens.
|
|
98
|
+
const key = sanitizeName(name);
|
|
71
99
|
const config = await this.getConfig();
|
|
72
100
|
if (!hasCredentials(config)) {
|
|
73
101
|
throw new Error("Google OAuth credentials are not configured. Set GOOGLE_MCP_CLIENT_ID and " +
|
|
74
102
|
"GOOGLE_MCP_CLIENT_SECRET (or add them to config.json) first.");
|
|
75
103
|
}
|
|
76
104
|
const state = generateState();
|
|
77
|
-
const
|
|
105
|
+
const { codeVerifier, codeChallenge } = generatePkce();
|
|
106
|
+
const authUrl = buildAuthUrl(config, state, codeChallenge);
|
|
78
107
|
const timeoutMs = options.timeoutMs ?? DEFAULT_AUTH_TIMEOUT_MS;
|
|
79
108
|
// The callback owns its timeout so an aborted flow always closes the
|
|
80
109
|
// loopback listener (no stale port left behind).
|
|
@@ -85,14 +114,14 @@ class AuthManager {
|
|
|
85
114
|
}
|
|
86
115
|
catch {
|
|
87
116
|
// Browser unavailable (headless server) — the error message carries the URL.
|
|
88
|
-
throw new Error(`Could not open a browser. Open this URL manually to authorize "${
|
|
117
|
+
throw new Error(`Could not open a browser. Open this URL manually to authorize "${key}": ${authUrl}`);
|
|
89
118
|
}
|
|
90
119
|
}
|
|
91
120
|
const callback = await callbackPromise;
|
|
92
|
-
const tokens = await exchangeCode(config, callback.code);
|
|
121
|
+
const tokens = await exchangeCode(config, callback.code, codeVerifier);
|
|
93
122
|
const user = await fetchUserInfo(tokens.accessToken);
|
|
94
123
|
const account = {
|
|
95
|
-
name,
|
|
124
|
+
name: key,
|
|
96
125
|
email: user.email,
|
|
97
126
|
accessToken: tokens.accessToken,
|
|
98
127
|
refreshToken: tokens.refreshToken ?? "",
|
|
@@ -104,16 +133,35 @@ class AuthManager {
|
|
|
104
133
|
return account;
|
|
105
134
|
}
|
|
106
135
|
async removeAccount(name) {
|
|
107
|
-
|
|
136
|
+
// Keep the old contract: a name that cannot be an account is simply absent,
|
|
137
|
+
// not an error (callers and the CLI treat false as "nothing to remove").
|
|
138
|
+
if (!canSanitize(name))
|
|
139
|
+
return false;
|
|
140
|
+
const key = sanitizeName(name);
|
|
141
|
+
const removed = await deleteAccount(key);
|
|
142
|
+
// A default pointing at a deleted account makes every subsequent call fail
|
|
143
|
+
// with "multiple accounts but no default" while `status` still shows one.
|
|
144
|
+
if (removed) {
|
|
145
|
+
const config = await this.getConfig();
|
|
146
|
+
const current = config.defaultAccount;
|
|
147
|
+
if (current && normalizeKey(current) === key) {
|
|
148
|
+
config.defaultAccount = undefined;
|
|
149
|
+
await saveConfig(config);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
return removed;
|
|
108
153
|
}
|
|
109
154
|
async setDefaultAccount(name) {
|
|
110
155
|
const config = await this.getConfig();
|
|
111
|
-
|
|
112
|
-
|
|
156
|
+
// An empty name clears the default; anything else is stored in the same
|
|
157
|
+
// sanitized form the account record uses, or resolveAccount cannot match it.
|
|
158
|
+
const key = name ? sanitizeName(name) : "";
|
|
159
|
+
if (key) {
|
|
160
|
+
const exists = await loadAccount(key);
|
|
113
161
|
if (!exists)
|
|
114
|
-
throw new Error(`Cannot set default: account "${
|
|
162
|
+
throw new Error(`Cannot set default: account "${key}" does not exist.`);
|
|
115
163
|
}
|
|
116
|
-
config.defaultAccount =
|
|
164
|
+
config.defaultAccount = key || undefined;
|
|
117
165
|
await saveConfig(config);
|
|
118
166
|
}
|
|
119
167
|
async saveCredentials(clientId, clientSecret) {
|
package/dist/auth/manager.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/auth/manager.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/auth/manager.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/oauth.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export declare const DEFAULT_AUTH_TIMEOUT_MS: number;
|
|
|
15
15
|
*/
|
|
16
16
|
export declare function resolveRedirectUri(config: Config): string;
|
|
17
17
|
/** Build the Google consent-screen URL. */
|
|
18
|
-
export declare function buildAuthUrl(config: Config, state: string): string;
|
|
18
|
+
export declare function buildAuthUrl(config: Config, state: string, codeChallenge: string): string;
|
|
19
19
|
/** Open a URL in the default browser on the current platform. */
|
|
20
20
|
export declare function openBrowser(url: string): Promise<void>;
|
|
21
21
|
export interface AuthCallback {
|
|
@@ -36,7 +36,7 @@ export declare function waitForOAuthCallback(config: Config, expectedState: stri
|
|
|
36
36
|
timeoutMs?: number;
|
|
37
37
|
}): Promise<AuthCallback>;
|
|
38
38
|
/** Exchange an authorization code for tokens. */
|
|
39
|
-
export declare function exchangeCode(config: Config, code: string): Promise<TokenSet>;
|
|
39
|
+
export declare function exchangeCode(config: Config, code: string, codeVerifier: string): Promise<TokenSet>;
|
|
40
40
|
/** Refresh an expired access token. Keeps the existing refresh token if the provider does not rotate it. */
|
|
41
41
|
export declare function refreshAccessToken(config: Config, refreshToken: string): Promise<TokenSet>;
|
|
42
42
|
/** Best-effort fetch of the signed-in user's profile (email/name). Never throws. */
|
|
@@ -46,4 +46,12 @@ export declare function fetchUserInfo(accessToken: string): Promise<{
|
|
|
46
46
|
}>;
|
|
47
47
|
/** Generate a random state value for CSRF protection. */
|
|
48
48
|
export declare function generateState(): string;
|
|
49
|
+
export interface PkcePair {
|
|
50
|
+
/** High-entropy secret kept client-side; sent at token exchange. */
|
|
51
|
+
codeVerifier: string;
|
|
52
|
+
/** S256 hash of the verifier; sent in the authorization URL. */
|
|
53
|
+
codeChallenge: string;
|
|
54
|
+
}
|
|
55
|
+
/** Generate a PKCE (RFC 7636) verifier/challenge pair with S256. */
|
|
56
|
+
export declare function generatePkce(): PkcePair;
|
|
49
57
|
//# sourceMappingURL=oauth.d.ts.map
|
package/dist/auth/oauth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAIA,OAAO,
|
|
1
|
+
{"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,MAAM,EAAyC,MAAM,aAAa,CAAC;AAIjF,MAAM,WAAW,QAAQ;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4DAA4D;IAC5D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAMD,yEAAyE;AACzE,eAAO,MAAM,uBAAuB,QAAgB,CAAC;AAErD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAIzD;AAoBD,2CAA2C;AAC3C,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAczF;AAED,iEAAiE;AACjE,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ5D;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAO,GACnC,OAAO,CAAC,YAAY,CAAC,CA0FvB;AA+BD,iDAAiD;AACjD,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,QAAQ,CAAC,CAOnB;AAED,4GAA4G;AAC5G,wBAAsB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,CAAC,CAKhG;AAED,oFAAoF;AACpF,wBAAsB,aAAa,CACjC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC;IAAE,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAa5C;AAED,yDAAyD;AACzD,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED,MAAM,WAAW,QAAQ;IACvB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;IACrB,gEAAgE;IAChE,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,oEAAoE;AACpE,wBAAgB,YAAY,IAAI,QAAQ,CAOvC"}
|
package/dist/auth/oauth.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { randomBytes } from "node:crypto";
|
|
2
|
-
import { createServer } from "node:http";
|
|
3
1
|
import { execFile } from "node:child_process";
|
|
2
|
+
import { createHash, randomBytes } from "node:crypto";
|
|
3
|
+
import { createServer } from "node:http";
|
|
4
4
|
import { promisify } from "node:util";
|
|
5
5
|
import { DEFAULT_REDIRECT_PORT, DEFAULT_SCOPES } from "./config.js";
|
|
6
6
|
const execFileAsync = promisify(execFile);
|
|
@@ -31,7 +31,7 @@ function parseCallbackTarget(config) {
|
|
|
31
31
|
return { host, port, paths: new Set([configuredPath, "/", "/oauth2callback"]) };
|
|
32
32
|
}
|
|
33
33
|
/** Build the Google consent-screen URL. */
|
|
34
|
-
export function buildAuthUrl(config, state) {
|
|
34
|
+
export function buildAuthUrl(config, state, codeChallenge) {
|
|
35
35
|
const scopes = config.scopes?.length ? config.scopes : DEFAULT_SCOPES;
|
|
36
36
|
const url = new URL(AUTH_ENDPOINT);
|
|
37
37
|
url.searchParams.set("client_id", config.clientId);
|
|
@@ -41,6 +41,8 @@ export function buildAuthUrl(config, state) {
|
|
|
41
41
|
url.searchParams.set("access_type", "offline");
|
|
42
42
|
url.searchParams.set("prompt", "consent");
|
|
43
43
|
url.searchParams.set("state", state);
|
|
44
|
+
url.searchParams.set("code_challenge", codeChallenge);
|
|
45
|
+
url.searchParams.set("code_challenge_method", "S256");
|
|
44
46
|
url.searchParams.set("include_granted_scopes", "true");
|
|
45
47
|
return url.toString();
|
|
46
48
|
}
|
|
@@ -174,9 +176,10 @@ async function postTokenRequest(config, body) {
|
|
|
174
176
|
};
|
|
175
177
|
}
|
|
176
178
|
/** Exchange an authorization code for tokens. */
|
|
177
|
-
export async function exchangeCode(config, code) {
|
|
179
|
+
export async function exchangeCode(config, code, codeVerifier) {
|
|
178
180
|
return postTokenRequest(config, {
|
|
179
181
|
code,
|
|
182
|
+
code_verifier: codeVerifier,
|
|
180
183
|
redirect_uri: resolveRedirectUri(config),
|
|
181
184
|
grant_type: "authorization_code",
|
|
182
185
|
});
|
|
@@ -208,4 +211,13 @@ export async function fetchUserInfo(accessToken) {
|
|
|
208
211
|
export function generateState() {
|
|
209
212
|
return randomBytes(16).toString("hex");
|
|
210
213
|
}
|
|
214
|
+
/** Generate a PKCE (RFC 7636) verifier/challenge pair with S256. */
|
|
215
|
+
export function generatePkce() {
|
|
216
|
+
const codeVerifier = randomBytes(32)
|
|
217
|
+
.toString("base64url")
|
|
218
|
+
.replace(/[^A-Za-z0-9\-._~]/g, "")
|
|
219
|
+
.slice(0, 128);
|
|
220
|
+
const codeChallenge = createHash("sha256").update(codeVerifier).digest("base64url");
|
|
221
|
+
return { codeVerifier, codeChallenge };
|
|
222
|
+
}
|
|
211
223
|
//# sourceMappingURL=oauth.js.map
|
package/dist/auth/oauth.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"oauth.js","sourceRoot":"","sources":["../../src/auth/oauth.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/store.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"AAIA,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"AAIA,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC5B,kEAAkE;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAUvE;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC,CAO7E;AAED,wBAAsB,eAAe,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAchE;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOlE"}
|
package/dist/auth/store.js
CHANGED
|
@@ -5,7 +5,12 @@ export async function saveAccount(account) {
|
|
|
5
5
|
await ensureDirs();
|
|
6
6
|
const safeName = sanitizeName(account.name);
|
|
7
7
|
const toWrite = { ...account, name: safeName };
|
|
8
|
-
await fs.writeFile(getAccountPath(safeName), JSON.stringify(toWrite, null, 2),
|
|
8
|
+
await fs.writeFile(getAccountPath(safeName), JSON.stringify(toWrite, null, 2), {
|
|
9
|
+
encoding: "utf8",
|
|
10
|
+
mode: 0o600,
|
|
11
|
+
});
|
|
12
|
+
// writeFile's mode only applies on create; harden pre-existing files.
|
|
13
|
+
await fs.chmod(getAccountPath(safeName), 0o600).catch(() => { });
|
|
9
14
|
}
|
|
10
15
|
export async function loadAccount(name) {
|
|
11
16
|
try {
|
package/dist/auth/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgBvF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAsB;IACtD,MAAM,UAAU,EAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAkB,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/auth/store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAgBvF,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,OAAsB;IACtD,MAAM,UAAU,EAAE,CAAC;IACnB,MAAM,QAAQ,GAAG,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5C,MAAM,OAAO,GAAkB,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QAC7E,QAAQ,EAAE,MAAM;QAChB,IAAI,EAAE,KAAK;KACZ,CAAC,CAAC;IACH,sEAAsE;IACtE,MAAM,EAAE,CAAC,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AAClE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY;IAC5C,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;QAC5D,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC;IAC1C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe;IACnC,MAAM,UAAU,EAAE,CAAC;IACnB,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,CAAC;IACjD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IACrC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC;YAAE,SAAS;QACtC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;YACzE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkB,CAAC,CAAC;QAClD,CAAC;QAAC,MAAM,CAAC;YACP,6EAA6E;QAC/E,CAAC;IACH,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAY;IAC9C,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC;QACtC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
package/dist/cli.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAyCD,sEAAsE;AACtE,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,SAAS;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAyCD,sEAAsE;AACtE,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,CA0FxE"}
|
package/dist/cli.js
CHANGED
|
@@ -54,7 +54,10 @@ export async function dispatchCommand(args) {
|
|
|
54
54
|
case "add": {
|
|
55
55
|
const name = rest[0];
|
|
56
56
|
if (!name) {
|
|
57
|
-
return {
|
|
57
|
+
return {
|
|
58
|
+
exitCode: 1,
|
|
59
|
+
output: "Usage: google-services-mcp add <name> [--timeout <seconds>]\n",
|
|
60
|
+
};
|
|
58
61
|
}
|
|
59
62
|
try {
|
|
60
63
|
const timeoutMs = parseTimeout(rest);
|
|
@@ -65,7 +68,10 @@ export async function dispatchCommand(args) {
|
|
|
65
68
|
};
|
|
66
69
|
}
|
|
67
70
|
catch (error) {
|
|
68
|
-
return {
|
|
71
|
+
return {
|
|
72
|
+
exitCode: 1,
|
|
73
|
+
output: `Error: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
74
|
+
};
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
case "list": {
|
|
@@ -97,7 +103,10 @@ export async function dispatchCommand(args) {
|
|
|
97
103
|
return { exitCode: 0, output: `Default account set to "${name}".\n` };
|
|
98
104
|
}
|
|
99
105
|
catch (error) {
|
|
100
|
-
return {
|
|
106
|
+
return {
|
|
107
|
+
exitCode: 1,
|
|
108
|
+
output: `Error: ${error instanceof Error ? error.message : String(error)}\n`,
|
|
109
|
+
};
|
|
101
110
|
}
|
|
102
111
|
}
|
|
103
112
|
case "status": {
|
|
@@ -119,7 +128,7 @@ export async function dispatchCommand(args) {
|
|
|
119
128
|
lines.push(` ${a.name}${email} [token ${health}]`);
|
|
120
129
|
}
|
|
121
130
|
}
|
|
122
|
-
return { exitCode: 0, output: lines.join("\n")
|
|
131
|
+
return { exitCode: 0, output: `${lines.join("\n")}\n` };
|
|
123
132
|
}
|
|
124
133
|
default:
|
|
125
134
|
return { exitCode: 1, output: `Unknown command: ${cmd}\n\n${HELP}` };
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAOhD;;;;;;GAMG;AACH,MAAM,OAAO,GAAG,CAAC,GAAW,EAAE;IAC5B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/main.js
CHANGED
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
3
|
-
import { createServer } from "./server.js";
|
|
4
3
|
import { dispatchCommand } from "./cli.js";
|
|
4
|
+
import { createServer } from "./server.js";
|
|
5
|
+
// A client closing the pipe (EPIPE, common after a large tool result) must not
|
|
6
|
+
// crash the process with an unhandled 'error' event.
|
|
7
|
+
process.stdout.on("error", (error) => {
|
|
8
|
+
process.stderr.write(`stdout error (${error.code ?? "unknown"}); exiting\n`);
|
|
9
|
+
process.exit(error.code === "EPIPE" ? 0 : 1);
|
|
10
|
+
});
|
|
5
11
|
async function main() {
|
|
6
12
|
const args = process.argv.slice(2);
|
|
7
13
|
if (args[0] === undefined || args[0] === "serve") {
|