mcp-google-multi 5.2.0-alpha.3 → 5.2.0-alpha.4

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
@@ -9,7 +9,7 @@ A **local** [MCP](https://modelcontextprotocol.io) server that gives Claude Code
9
9
  - 🔑 **Multi-account** — drive any number of your Google accounts from one server, each by a short alias.
10
10
  - 🔒 **Secure by default** — refresh tokens **encrypted at rest** (AES-256-GCM); **writes are deny-by-default**; no telemetry — it talks only to Google.
11
11
  - 📦 **npm-first** — install and run with `npx`; everything configured through env vars.
12
- - 🧰 **~175 tools** across 13 services → full list in **[COVERAGE.md](./COVERAGE.md)**.
12
+ - 🧰 **Exhaustive coverage** — every OAuth-reachable Workspace API method is a named tool: **871 tools across 28 services** (182 hand-curated + 689 generated from Google's API Discovery), plus an escape hatch for anything else → full list in **[COVERAGE.md](./COVERAGE.md)**.
13
13
 
14
14
  > v5 is **local + user-OAuth only**. Service accounts and hosting (and the APIs they unlock) are on the [roadmap](https://github.com/bakissation/mcp-google-multi/milestones). **Upgrading from v4?** Jump to [Upgrading](#upgrading-from-v4).
15
15
 
@@ -126,7 +126,7 @@ Reads are never gated. **Every create/update/delete is off until you opt in**
126
126
 
127
127
  ## What's covered
128
128
 
129
- ~175 tools across Gmail, Drive, Calendar, Sheets, Docs, Contacts, Search Console, Tasks, Meet, and (optional) Slides, Forms, Chat, Workspace Admin. **Full per-tool list → [COVERAGE.md](./COVERAGE.md).** Every tool takes an `account` argument matching one of your aliases.
129
+ Every OAuth-reachable Workspace API method is a named tool — 871 across 28 services. Core services (Gmail, Drive, Calendar, Sheets, Docs, Contacts, Search Console, Tasks, Meet) are on by default; Slides, Forms, Chat, Classroom, Vault, Keep, Apps Script, Cloud Search, Drive Labels and more enable via `GOOGLE_OPTIONAL_SCOPES` bundles, and Workspace Admin APIs via `GOOGLE_ADMIN_ACCOUNTS`. Curated tools give shaped, token-lean responses for everyday operations; generated tools (from Google's API Discovery documents) cover the long tail with the same write-control and account fan-out. **Full per-tool list → [COVERAGE.md](./COVERAGE.md).** Every tool takes an `account` argument matching one of your aliases.
130
130
 
131
131
  ## Google Cloud setup
132
132
 
package/dist/index.js CHANGED
@@ -5,21 +5,8 @@ import { fileURLToPath } from 'node:url';
5
5
  import path from 'node:path';
6
6
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
7
7
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
- import { registerGmailTools } from './tools/gmail.js';
9
- import { registerDriveTools } from './tools/drive.js';
10
- import { registerCalendarTools } from './tools/calendar.js';
11
- import { registerSheetsTools } from './tools/sheets.js';
12
- import { registerDocsTools } from './tools/docs.js';
13
- import { registerContactsTools } from './tools/contacts.js';
14
- import { registerSearchConsoleTools } from './tools/searchconsole.js';
15
- import { registerTasksTools } from './tools/tasks.js';
16
- import { registerMeetTools } from './tools/meet.js';
17
- import { registerSlidesTools } from './tools/slides.js';
18
- import { registerFormsTools } from './tools/forms.js';
19
- import { registerChatTools } from './tools/chat.js';
20
- import { registerAdminTools } from './tools/admin.js';
21
- import { getOptionalBundles, getAdminAccounts } from './auth.js';
22
8
  import { GENERATED_SERVICES } from './tools/generated/index.js';
9
+ import { GENERATED_GATES, SERVICES } from './services.js';
23
10
  import { ToolRegistry } from './registry.js';
24
11
  import { registerDiscoverTools } from './discover.js';
25
12
  import { registerEscapeTools } from './tools/google-api.js';
@@ -28,45 +15,6 @@ import { getToolsets, toolsetEnabled } from './toolsets.js';
28
15
  import { resolvePolicy, isAllowed, describePolicy } from './write-control.js';
29
16
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
30
17
  const pkg = JSON.parse(readFileSync(path.resolve(__dirname, '..', 'package.json'), 'utf-8'));
31
- const SERVICES = [
32
- { name: 'gmail', register: registerGmailTools },
33
- { name: 'drive', register: registerDriveTools },
34
- { name: 'calendar', register: registerCalendarTools },
35
- { name: 'sheets', register: registerSheetsTools },
36
- { name: 'docs', register: registerDocsTools },
37
- { name: 'contacts', register: registerContactsTools },
38
- { name: 'searchconsole', register: registerSearchConsoleTools },
39
- { name: 'tasks', register: registerTasksTools },
40
- { name: 'meet', register: registerMeetTools },
41
- { name: 'slides', register: registerSlidesTools, enabled: () => new Set(getOptionalBundles()).has('slides') },
42
- { name: 'forms', register: registerFormsTools, enabled: () => new Set(getOptionalBundles()).has('forms') },
43
- { name: 'chat', register: registerChatTools, enabled: () => new Set(getOptionalBundles()).has('chat') },
44
- { name: 'admin', register: registerAdminTools, enabled: () => getAdminAccounts().length > 0 },
45
- ];
46
- // Opt-in gates for generated-only services whose scopes are not granted by
47
- // default; shared services (admin, forms, chat) reuse their curated gate below.
48
- // workspaceevents has no dedicated scope (subscriptions use the underlying
49
- // resource scopes), so it registers ungated.
50
- const bundleGate = (name) => ({
51
- enabled: () => new Set(getOptionalBundles()).has(name),
52
- hint: `add "${name}" to GOOGLE_OPTIONAL_SCOPES`,
53
- });
54
- const GENERATED_GATES = {
55
- appsmarket: bundleGate('appsmarket'),
56
- classroom: bundleGate('classroom'),
57
- cloudidentity: bundleGate('cloudidentity'),
58
- cloudsearch: bundleGate('cloudsearch'),
59
- driveactivity: bundleGate('driveactivity'),
60
- drivelabels: bundleGate('drivelabels'),
61
- groupsmigration: bundleGate('groupsmigration'),
62
- groupssettings: bundleGate('groupssettings'),
63
- keep: bundleGate('keep'),
64
- licensing: bundleGate('licensing'),
65
- postmaster: bundleGate('postmaster'),
66
- reseller: bundleGate('reseller'),
67
- script: bundleGate('script'),
68
- vault: bundleGate('vault'),
69
- };
70
18
  function buildRegistry(server, policy) {
71
19
  const registry = new ToolRegistry(server, policy);
72
20
  const toolsets = getToolsets();
@@ -0,0 +1,11 @@
1
+ import type { ToolRegistry } from './registry.js';
2
+ export interface ServiceEntry {
3
+ name: string;
4
+ register: (registry: ToolRegistry) => void;
5
+ enabled?: () => boolean;
6
+ }
7
+ export declare const SERVICES: ServiceEntry[];
8
+ export declare const GENERATED_GATES: Record<string, {
9
+ enabled: () => boolean;
10
+ hint: string;
11
+ }>;
@@ -0,0 +1,53 @@
1
+ import { registerGmailTools } from './tools/gmail.js';
2
+ import { registerDriveTools } from './tools/drive.js';
3
+ import { registerCalendarTools } from './tools/calendar.js';
4
+ import { registerSheetsTools } from './tools/sheets.js';
5
+ import { registerDocsTools } from './tools/docs.js';
6
+ import { registerContactsTools } from './tools/contacts.js';
7
+ import { registerSearchConsoleTools } from './tools/searchconsole.js';
8
+ import { registerTasksTools } from './tools/tasks.js';
9
+ import { registerMeetTools } from './tools/meet.js';
10
+ import { registerSlidesTools } from './tools/slides.js';
11
+ import { registerFormsTools } from './tools/forms.js';
12
+ import { registerChatTools } from './tools/chat.js';
13
+ import { registerAdminTools } from './tools/admin.js';
14
+ import { getOptionalBundles, getAdminAccounts } from './auth.js';
15
+ export const SERVICES = [
16
+ { name: 'gmail', register: registerGmailTools },
17
+ { name: 'drive', register: registerDriveTools },
18
+ { name: 'calendar', register: registerCalendarTools },
19
+ { name: 'sheets', register: registerSheetsTools },
20
+ { name: 'docs', register: registerDocsTools },
21
+ { name: 'contacts', register: registerContactsTools },
22
+ { name: 'searchconsole', register: registerSearchConsoleTools },
23
+ { name: 'tasks', register: registerTasksTools },
24
+ { name: 'meet', register: registerMeetTools },
25
+ { name: 'slides', register: registerSlidesTools, enabled: () => new Set(getOptionalBundles()).has('slides') },
26
+ { name: 'forms', register: registerFormsTools, enabled: () => new Set(getOptionalBundles()).has('forms') },
27
+ { name: 'chat', register: registerChatTools, enabled: () => new Set(getOptionalBundles()).has('chat') },
28
+ { name: 'admin', register: registerAdminTools, enabled: () => getAdminAccounts().length > 0 },
29
+ ];
30
+ // Opt-in gates for generated-only services whose scopes are not granted by
31
+ // default; shared services (admin, forms, chat) reuse their curated gate in
32
+ // buildRegistry. workspaceevents has no dedicated scope (subscriptions use the
33
+ // underlying resource scopes), so it registers ungated.
34
+ const bundleGate = (name) => ({
35
+ enabled: () => new Set(getOptionalBundles()).has(name),
36
+ hint: `add "${name}" to GOOGLE_OPTIONAL_SCOPES`,
37
+ });
38
+ export const GENERATED_GATES = {
39
+ appsmarket: bundleGate('appsmarket'),
40
+ classroom: bundleGate('classroom'),
41
+ cloudidentity: bundleGate('cloudidentity'),
42
+ cloudsearch: bundleGate('cloudsearch'),
43
+ driveactivity: bundleGate('driveactivity'),
44
+ drivelabels: bundleGate('drivelabels'),
45
+ groupsmigration: bundleGate('groupsmigration'),
46
+ groupssettings: bundleGate('groupssettings'),
47
+ keep: bundleGate('keep'),
48
+ licensing: bundleGate('licensing'),
49
+ postmaster: bundleGate('postmaster'),
50
+ reseller: bundleGate('reseller'),
51
+ script: bundleGate('script'),
52
+ vault: bundleGate('vault'),
53
+ };
@@ -1775,7 +1775,7 @@ export function registerAdminGeneratedTools(registry) {
1775
1775
  },
1776
1776
  });
1777
1777
  registerGeneratedTool(registry, {
1778
- name: "admin_users_update",
1778
+ name: "admin_users_replace",
1779
1779
  cud: "update",
1780
1780
  description: "Updates a user. This method supports patch semantics, meaning that you only need to include the fields you wish to update. Fields that are not present in the re",
1781
1781
  method: { id: "directory.users.update", httpMethod: "PUT", path: "admin/directory/v1/users/{userKey}", baseUrl: "https://admin.googleapis.com/", requiredParams: ["userKey"] },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-google-multi",
3
- "version": "5.2.0-alpha.3",
3
+ "version": "5.2.0-alpha.4",
4
4
  "description": "Local MCP server for Google Workspace (Gmail, Drive, Calendar, Sheets, Docs, Contacts, Tasks, Meet, Search Console, +Forms/Chat/Admin) across multiple accounts — OAuth-only, encrypted token storage, deny-by-default writes.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -56,7 +56,8 @@
56
56
  "test": "vitest run",
57
57
  "test:watch": "vitest",
58
58
  "gen:discovery": "tsx scripts/fetch-discovery.ts",
59
- "gen:tools": "tsx scripts/gen-tools.ts"
59
+ "gen:tools": "tsx scripts/gen-tools.ts",
60
+ "gen:coverage": "tsx scripts/gen-coverage.ts"
60
61
  },
61
62
  "dependencies": {
62
63
  "@modelcontextprotocol/sdk": "^1.29.0",