mcp-google-multi 6.0.0-alpha.23 → 6.0.0-alpha.24

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.
@@ -1,4 +1,8 @@
1
1
  import { z } from 'zod';
2
2
  export declare function coerceArray<T extends z.ZodTypeAny>(element: T): z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodArray<T>>;
3
3
  export declare function coerceJson<T extends z.ZodTypeAny>(schema: T): z.ZodPipe<z.ZodTransform<unknown, unknown>, T>;
4
+ /** Numeric args arrive string-encoded from some clients; over stdio the SDK
5
+ * validates the schema directly (the HTTP transport's arg-normalization layer
6
+ * never runs), so the coercion must live in the schema itself. */
7
+ export declare function coerceNumber<T extends z.ZodTypeAny>(schema: T): z.ZodPipe<z.ZodTransform<unknown, unknown>, T>;
4
8
  export declare const coerceBoolean: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodBoolean>;
@@ -22,6 +22,16 @@ export function coerceArray(element) {
22
22
  export function coerceJson(schema) {
23
23
  return z.preprocess((val) => (typeof val === 'string' ? parseJsonLoose(val) : val), schema);
24
24
  }
25
+ /** Numeric args arrive string-encoded from some clients; over stdio the SDK
26
+ * validates the schema directly (the HTTP transport's arg-normalization layer
27
+ * never runs), so the coercion must live in the schema itself. */
28
+ export function coerceNumber(schema) {
29
+ return z.preprocess((val) => {
30
+ if (typeof val === 'string' && val.trim() !== '' && !Number.isNaN(Number(val)))
31
+ return Number(val);
32
+ return val;
33
+ }, schema);
34
+ }
25
35
  export const coerceBoolean = z.preprocess((val) => {
26
36
  if (typeof val === 'boolean')
27
37
  return val;
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { coerceArray, coerceBoolean } from './_coerce.js';
2
+ import { coerceArray, coerceBoolean, coerceNumber } from './_coerce.js';
3
3
  import { drive as driveClient } from '@googleapis/drive';
4
4
  import { accountAliasSchema, getAccountSet } from '../accounts.js';
5
5
  import { getClient } from '../client.js';
@@ -129,7 +129,7 @@ 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(10).optional()
132
+ maxResults: coerceNumber(z.number().min(1).max(100)).optional()
133
133
  .describe('Max results to return (default: 10, max: 100)'),
134
134
  driveId: z.string().optional().describe('Optional shared drive ID'),
135
135
  },
@@ -1,5 +1,5 @@
1
1
  import { z } from 'zod';
2
- import { coerceArray, coerceBoolean, coerceJson } from './_coerce.js';
2
+ import { coerceArray, coerceBoolean, coerceJson, coerceNumber } from './_coerce.js';
3
3
  import { gmail as gmailClient } from '@googleapis/gmail';
4
4
  import { accountAliasSchema } from '../accounts.js';
5
5
  import { getClient } from '../client.js';
@@ -442,7 +442,7 @@ export function registerGmailTools(server) {
442
442
  inputSchema: {
443
443
  account: accountEnum.describe('Google account alias'),
444
444
  query: z.string().describe('Gmail search syntax, e.g. "from:monaam is:unread"'),
445
- maxResults: z.number().min(1).max(100).default(20).optional()
445
+ maxResults: coerceNumber(z.number().min(1).max(100)).optional()
446
446
  .describe('Max results to return (default: 20, max: 100)'),
447
447
  full: coerceBoolean.optional().describe('Return the full row shape instead of the compact default'),
448
448
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mcp-google-multi",
3
- "version": "6.0.0-alpha.23",
3
+ "version": "6.0.0-alpha.24",
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",
@@ -58,6 +58,7 @@
58
58
  "gen:discovery": "tsx scripts/fetch-discovery.ts",
59
59
  "gen:tools": "tsx scripts/gen-tools.ts",
60
60
  "gen:coverage": "tsx scripts/gen-coverage.ts",
61
+ "eval:contract": "npx --yes promptfoo@0.123.1 eval -c eval/contract/promptfooconfig.yaml --no-progress-bar",
61
62
  "measure:lazy": "node scripts/measure-tools.mjs",
62
63
  "pack:mcpb": "mcpb pack . mcp-google-multi.mcpb",
63
64
  "bundle": "esbuild dist/index.js --bundle --platform=node --format=esm --outfile=bundle/index.js --external:@napi-rs/keyring --banner:js=\"import{createRequire as __dockerCR}from'node:module';var require=__dockerCR(import.meta.url);\" --log-level=warning"