mcp-google-multi 6.0.0-alpha.21 → 6.0.0-alpha.22

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.
@@ -129,8 +129,8 @@ export function registerDriveTools(server) {
129
129
  inputSchema: {
130
130
  account: accountEnum.describe('Google account alias'),
131
131
  query: z.string().describe('A plain keyword (full-text search) or Drive query syntax, e.g. "name contains \'MoU\'"'),
132
- maxResults: z.number().min(1).max(100).default(20).optional()
133
- .describe('Max results to return (default: 20)'),
132
+ maxResults: z.number().min(1).max(100).default(10).optional()
133
+ .describe('Max results to return (default: 10, max: 100)'),
134
134
  driveId: z.string().optional().describe('Optional shared drive ID'),
135
135
  },
136
136
  }, async ({ account, query, maxResults, driveId }) => {
@@ -139,7 +139,7 @@ export function registerDriveTools(server) {
139
139
  const drive = driveClient({ version: 'v3', auth });
140
140
  const params = {
141
141
  q: normalizeDriveQuery(query),
142
- pageSize: maxResults ?? 20,
142
+ pageSize: maxResults ?? 10,
143
143
  fields: 'files(id,name,mimeType,modifiedTime,webViewLink,size,parents,driveId)',
144
144
  supportsAllDrives: true,
145
145
  includeItemsFromAllDrives: true,
@@ -1,7 +1,7 @@
1
1
  import type { ToolRegistry } from '../registry.js';
2
2
  import type { Account } from '../accounts.js';
3
3
  import { type ComposeAttachment } from './gmail-mime.js';
4
- import type { GmailMessageFull } from '../types.js';
4
+ import type { GmailMessageHeader, GmailMessageFull } from '../types.js';
5
5
  /** Re: prefix unless the subject already carries one (case-insensitive, after
6
6
  * trimming); never double-prefix. */
7
7
  export declare function deriveReplySubject(sourceSubject: string): string;
@@ -33,5 +33,14 @@ export declare function parseMessage(msg: any, bodyCap?: number, opts?: {
33
33
  * ordered per-id entries followed by a trailing counts summary.
34
34
  */
35
35
  export declare function readBatch(gmail: any, account: Account, ids: string[], full: boolean, rawHtml: boolean): Promise<any[]>;
36
+ /** Compact gmail_search row: just the pick-one-message selection signal, with
37
+ * the snippet flattened to one bounded line. Pure. */
38
+ export declare function compactMessageRow(m: GmailMessageHeader): {
39
+ id: string;
40
+ from: string;
41
+ subject: string;
42
+ date: string;
43
+ snippet: string;
44
+ };
36
45
  export declare function registerGmailTools(server: ToolRegistry): void;
37
46
  export {};
@@ -423,16 +423,30 @@ export async function readBatch(gmail, account, ids, full, rawHtml) {
423
423
  const summary = { counts: { ok, failed }, ...(truncatedAny ? { truncated: true } : {}) };
424
424
  return [...entries, summary];
425
425
  }
426
+ /** Compact gmail_search row: just the pick-one-message selection signal, with
427
+ * the snippet flattened to one bounded line. Pure. */
428
+ export function compactMessageRow(m) {
429
+ const snippet = m.snippet.replace(/\s+/g, ' ').trim();
430
+ return {
431
+ id: m.id,
432
+ from: m.from,
433
+ subject: m.subject,
434
+ date: m.date,
435
+ snippet: snippet.length > 120 ? `${snippet.slice(0, 119)}…` : snippet,
436
+ };
437
+ }
426
438
  export function registerGmailTools(server) {
427
439
  server.registerTool('gmail_search', {
428
- description: 'Search messages in a Gmail account',
440
+ description: 'Search messages in a Gmail account. Returns compact rows (id, from, subject, date, snippet); ' +
441
+ 'pass full=true for threadId, to, labelIds and the untruncated snippet.',
429
442
  inputSchema: {
430
443
  account: accountEnum.describe('Google account alias'),
431
444
  query: z.string().describe('Gmail search syntax, e.g. "from:monaam is:unread"'),
432
445
  maxResults: z.number().min(1).max(100).default(20).optional()
433
446
  .describe('Max results to return (default: 20, max: 100)'),
447
+ full: coerceBoolean.optional().describe('Return the full row shape instead of the compact default'),
434
448
  },
435
- }, async ({ account, query, maxResults }) => {
449
+ }, async ({ account, query, maxResults, full }) => {
436
450
  try {
437
451
  const auth = await getClient(account);
438
452
  const gmail = gmailClient({ version: 'v1', auth });
@@ -466,8 +480,12 @@ export function registerGmailTools(server) {
466
480
  });
467
481
  }
468
482
  }
483
+ // Search is a pick-one-message step ~always followed by gmail_read;
484
+ // the compact row is the selection signal, the rest was measured burn
485
+ // (p90 14.4k chars per call). full=true restores the pre-6.0 shape.
486
+ const rows = full === true ? results : results.map(compactMessageRow);
469
487
  return {
470
- content: [{ type: 'text', text: JSON.stringify(results, null, 2) }],
488
+ content: [{ type: 'text', text: JSON.stringify(rows, null, 2) }],
471
489
  };
472
490
  }
473
491
  catch (error) {
@@ -117,7 +117,8 @@ export function registerEscapeTools(registry, policy, deps = {}) {
117
117
  registry.registerMeta('google_api_call', {
118
118
  description: 'Invoke any Google Workspace REST method by Discovery id (escape hatch for operations without a ' +
119
119
  'dedicated tool). Find methods with google_api_search first. Subject to the same write-control ' +
120
- 'policy as named tools. Returns JSON only for binary/file content (media downloads, ' +
120
+ 'policy as named tools. On reads, pass a `fields` query param (Google partial response) to keep ' +
121
+ 'the payload small. Returns JSON only — for binary/file content (media downloads, ' +
121
122
  'drive.files.export) use drive_download / drive_export instead.',
122
123
  inputSchema: {
123
124
  account: accountEnum.describe('Google account alias (omit for the default account)'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-google-multi",
3
- "version": "6.0.0-alpha.21",
3
+ "version": "6.0.0-alpha.22",
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",