mcp-google-multi 6.0.0-beta.2 → 6.0.0-beta.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 +5 -5
- package/dist/accounts.d.ts +20 -4
- package/dist/accounts.js +68 -44
- package/dist/api-probe.d.ts +5 -0
- package/dist/api-probe.js +20 -15
- package/dist/arg-normalize.js +19 -38
- package/dist/arg-strict.d.ts +7 -0
- package/dist/arg-strict.js +38 -28
- package/dist/auth.d.ts +5 -4
- package/dist/auth.js +16 -23
- package/dist/boot-gates.d.ts +26 -0
- package/dist/boot-gates.js +36 -0
- package/dist/cimd-cache.d.ts +38 -0
- package/dist/cimd-cache.js +111 -0
- package/dist/client-config.d.ts +2 -2
- package/dist/client-config.js +8 -14
- package/dist/client.d.ts +32 -2
- package/dist/client.js +0 -0
- package/dist/compose.d.ts +18 -0
- package/dist/compose.js +109 -0
- package/dist/config-file.d.ts +13 -0
- package/dist/config-file.js +41 -10
- package/dist/discover.js +7 -10
- package/dist/discovery-client.d.ts +3 -0
- package/dist/discovery-client.js +36 -32
- package/dist/doctor.d.ts +9 -5
- package/dist/doctor.js +119 -29
- package/dist/env-load.js +2 -5
- package/dist/executor.d.ts +3 -0
- package/dist/executor.js +6 -6
- package/dist/fanout.d.ts +9 -1
- package/dist/fanout.js +47 -22
- package/dist/fs-atomic.d.ts +8 -0
- package/dist/fs-atomic.js +216 -29
- package/dist/hint-provider.d.ts +129 -0
- package/dist/hint-provider.js +58 -0
- package/dist/http-config.d.ts +2 -2
- package/dist/http-config.js +3 -7
- package/dist/http-transport.d.ts +67 -9
- package/dist/http-transport.js +318 -52
- package/dist/identity.d.ts +6 -3
- package/dist/identity.js +24 -8
- package/dist/index.js +76 -160
- package/dist/master-key.d.ts +3 -3
- package/dist/master-key.js +16 -19
- package/dist/mcp-token.d.ts +126 -19
- package/dist/mcp-token.js +557 -76
- package/dist/metrics-cli.d.ts +1 -1
- package/dist/metrics-cli.js +1 -1
- package/dist/metrics-tap.js +2 -5
- package/dist/migrate-config.d.ts +1 -2
- package/dist/migrate-config.js +5 -7
- package/dist/net-tuning.js +2 -4
- package/dist/oauth-as.d.ts +104 -4
- package/dist/oauth-as.js +368 -114
- package/dist/oauth-consent.d.ts +10 -0
- package/dist/oauth-consent.js +20 -10
- package/dist/outbound-allowlist.js +9 -11
- package/dist/reauth-hint.d.ts +1 -1
- package/dist/reauth-hint.js +11 -10
- package/dist/registry-transfer.d.ts +5 -0
- package/dist/registry-transfer.js +63 -11
- package/dist/registry.d.ts +13 -4
- package/dist/registry.js +100 -72
- package/dist/scope-catalog.d.ts +16 -0
- package/dist/scope-catalog.js +40 -13
- package/dist/scope-observability.d.ts +10 -9
- package/dist/scope-observability.js +34 -24
- package/dist/services.d.ts +18 -10
- package/dist/services.js +61 -22
- package/dist/ssrf-guard.d.ts +23 -9
- package/dist/ssrf-guard.js +106 -78
- package/dist/tenant-purge.d.ts +26 -0
- package/dist/tenant-purge.js +65 -0
- package/dist/token-store.d.ts +20 -2
- package/dist/token-store.js +0 -0
- package/dist/tools/_coerce.d.ts +4 -4
- package/dist/tools/_errors.d.ts +3 -0
- package/dist/tools/_errors.js +72 -60
- package/dist/tools/_local-files.d.ts +9 -0
- package/dist/tools/_local-files.js +22 -8
- package/dist/tools/account-wizard.d.ts +13 -3
- package/dist/tools/account-wizard.js +107 -56
- package/dist/tools/accounts-tool.d.ts +8 -1
- package/dist/tools/accounts-tool.js +35 -19
- package/dist/tools/admin.d.ts +10 -1
- package/dist/tools/admin.js +14 -11
- package/dist/tools/analytics.d.ts +10 -1
- package/dist/tools/analytics.js +14 -10
- package/dist/tools/calendar.d.ts +2 -1
- package/dist/tools/calendar.js +19 -18
- package/dist/tools/chat.d.ts +10 -1
- package/dist/tools/chat.js +12 -8
- package/dist/tools/contacts.d.ts +2 -1
- package/dist/tools/contacts.js +22 -19
- package/dist/tools/docs.d.ts +2 -1
- package/dist/tools/docs.js +35 -36
- package/dist/tools/drive.d.ts +2 -1
- package/dist/tools/drive.js +80 -74
- package/dist/tools/forms.d.ts +10 -1
- package/dist/tools/forms.js +18 -12
- package/dist/tools/generated/_shared.d.ts +2 -1
- package/dist/tools/generated/_shared.js +7 -3
- package/dist/tools/generated/admin.d.ts +2 -1
- package/dist/tools/generated/admin.js +265 -265
- package/dist/tools/generated/analytics.d.ts +2 -1
- package/dist/tools/generated/analytics.js +125 -125
- package/dist/tools/generated/appsmarket.d.ts +2 -1
- package/dist/tools/generated/appsmarket.js +5 -5
- package/dist/tools/generated/calendar.d.ts +2 -1
- package/dist/tools/generated/calendar.js +55 -55
- package/dist/tools/generated/chat.d.ts +2 -1
- package/dist/tools/generated/chat.js +95 -95
- package/dist/tools/generated/classroom.d.ts +2 -1
- package/dist/tools/generated/classroom.js +209 -209
- package/dist/tools/generated/cloudidentity.d.ts +2 -1
- package/dist/tools/generated/cloudidentity.js +133 -133
- package/dist/tools/generated/cloudsearch.d.ts +2 -1
- package/dist/tools/generated/cloudsearch.js +99 -99
- package/dist/tools/generated/contacts.d.ts +2 -1
- package/dist/tools/generated/contacts.js +29 -29
- package/dist/tools/generated/drive.d.ts +2 -1
- package/dist/tools/generated/drive.js +71 -71
- package/dist/tools/generated/driveactivity.d.ts +2 -1
- package/dist/tools/generated/driveactivity.js +3 -3
- package/dist/tools/generated/drivelabels.d.ts +2 -1
- package/dist/tools/generated/drivelabels.js +53 -53
- package/dist/tools/generated/forms.d.ts +2 -1
- package/dist/tools/generated/forms.js +7 -7
- package/dist/tools/generated/gmail.d.ts +2 -1
- package/dist/tools/generated/gmail.js +117 -117
- package/dist/tools/generated/groupsmigration.d.ts +2 -1
- package/dist/tools/generated/groupsmigration.js +3 -3
- package/dist/tools/generated/groupssettings.d.ts +2 -1
- package/dist/tools/generated/groupssettings.js +7 -7
- package/dist/tools/generated/index.d.ts +2 -1
- package/dist/tools/generated/keep.d.ts +2 -1
- package/dist/tools/generated/keep.js +15 -15
- package/dist/tools/generated/licensing.d.ts +2 -1
- package/dist/tools/generated/licensing.js +15 -15
- package/dist/tools/generated/meet.d.ts +2 -1
- package/dist/tools/generated/meet.js +27 -27
- package/dist/tools/generated/postmaster.d.ts +2 -1
- package/dist/tools/generated/postmaster.js +9 -9
- package/dist/tools/generated/reseller.d.ts +2 -1
- package/dist/tools/generated/reseller.js +35 -35
- package/dist/tools/generated/script.d.ts +2 -1
- package/dist/tools/generated/script.js +33 -33
- package/dist/tools/generated/searchconsole.d.ts +2 -1
- package/dist/tools/generated/searchconsole.js +3 -3
- package/dist/tools/generated/sheets.d.ts +2 -1
- package/dist/tools/generated/sheets.js +15 -15
- package/dist/tools/generated/tasks.d.ts +2 -1
- package/dist/tools/generated/tasks.js +5 -5
- package/dist/tools/generated/vault.d.ts +2 -1
- package/dist/tools/generated/vault.js +67 -67
- package/dist/tools/generated/workspaceevents.d.ts +2 -1
- package/dist/tools/generated/workspaceevents.js +31 -31
- package/dist/tools/gmail-mime.d.ts +1 -1
- package/dist/tools/gmail-mime.js +7 -12
- package/dist/tools/gmail.d.ts +4 -3
- package/dist/tools/gmail.js +67 -69
- package/dist/tools/google-api.d.ts +2 -3
- package/dist/tools/google-api.js +34 -22
- package/dist/tools/meet.d.ts +10 -1
- package/dist/tools/meet.js +12 -9
- package/dist/tools/searchconsole.d.ts +2 -1
- package/dist/tools/searchconsole.js +16 -13
- package/dist/tools/sheets.d.ts +2 -1
- package/dist/tools/sheets.js +35 -32
- package/dist/tools/slides.d.ts +10 -1
- package/dist/tools/slides.js +16 -10
- package/dist/tools/tasks.d.ts +2 -1
- package/dist/tools/tasks.js +18 -15
- package/dist/trim.d.ts +5 -0
- package/dist/trim.js +19 -0
- package/dist/usage-metrics.d.ts +23 -0
- package/dist/usage-metrics.js +67 -56
- package/dist/write-control.d.ts +4 -8
- package/dist/write-control.js +13 -6
- package/package.json +47 -21
package/dist/tools/drive.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ToolRegistry } from '../registry.js';
|
|
2
|
+
import { type CuratedToolDeps } from '../client.js';
|
|
2
3
|
export declare function isTextualMime(mimeType: string): boolean;
|
|
3
4
|
export declare function resolveConvertTarget(convertTo: string | undefined): string | undefined;
|
|
4
5
|
export declare const DRIVE_QUERY_HINT: string;
|
|
@@ -10,7 +11,7 @@ export declare function resolveShareNotification(opts: {
|
|
|
10
11
|
transferOwnership?: boolean;
|
|
11
12
|
sendNotification?: boolean;
|
|
12
13
|
}): boolean | undefined;
|
|
13
|
-
export declare function registerDriveTools(server: ToolRegistry): void;
|
|
14
|
+
export declare function registerDriveTools(server: ToolRegistry, deps?: CuratedToolDeps): void;
|
|
14
15
|
export type TransferPlan = {
|
|
15
16
|
kind: 'binary';
|
|
16
17
|
} | {
|
package/dist/tools/drive.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { coerceArray, coerceBoolean, coerceNumber } from './_coerce.js';
|
|
3
3
|
import { drive as driveClient } from '@googleapis/drive';
|
|
4
|
-
import {
|
|
4
|
+
import { accountArgLive } from '../accounts.js';
|
|
5
5
|
import { getClient } from '../client.js';
|
|
6
6
|
import { handleGoogleApiError, invalidParams, safeMessage, stringifyEnvelope } from './_errors.js';
|
|
7
|
-
import { openLocalReadStream, prepareLocalDest } from './_local-files.js';
|
|
7
|
+
import { hostFilesRefused, openLocalReadStream, prepareLocalDest } from './_local-files.js';
|
|
8
8
|
import { checkOutbound, outboundDeniedEnvelope, resolveOutboundAllowlist } from '../outbound-allowlist.js';
|
|
9
9
|
import { isAllowed, writeDisabledResult } from '../write-control.js';
|
|
10
10
|
import { capText, listResult } from '../trim.js';
|
|
@@ -14,10 +14,8 @@ import * as os from 'os';
|
|
|
14
14
|
import * as crypto from 'crypto';
|
|
15
15
|
import { pipeline } from 'node:stream/promises';
|
|
16
16
|
import mime from 'mime-types';
|
|
17
|
-
const accountEnum = accountAliasSchema.optional();
|
|
18
17
|
// drive_transfer's two-account form is the sanctioned schema exception and
|
|
19
18
|
// stays REQUIRED: omission must fail at the schema, not as a runtime riddle.
|
|
20
|
-
const requiredAccountEnum = accountAliasSchema;
|
|
21
19
|
const MAX_FILE_SIZE = 2 * 1024 * 1024; // 2MB
|
|
22
20
|
const FALLBACK_MAX_BYTES = 1024 * 1024 * 1024; // 1GB
|
|
23
21
|
const GOOGLE_WORKSPACE_TYPES = new Set([
|
|
@@ -26,9 +24,8 @@ const GOOGLE_WORKSPACE_TYPES = new Set([
|
|
|
26
24
|
'application/vnd.google-apps.presentation',
|
|
27
25
|
'application/vnd.google-apps.drawing',
|
|
28
26
|
]);
|
|
29
|
-
// drive_read inlines only textual content
|
|
30
|
-
//
|
|
31
|
-
// in practice — image/svg+xml was the motivating false "binary" refusal.
|
|
27
|
+
// drive_read inlines only textual content; RFC 6839 +json/+xml/... suffixes and
|
|
28
|
+
// a few bare application/* types count too (image/svg+xml was the motivating case).
|
|
32
29
|
const TEXTUAL_EXACT = new Set([
|
|
33
30
|
'application/json',
|
|
34
31
|
'application/xml',
|
|
@@ -83,17 +80,14 @@ export const DRIVE_QUERY_HINT = "Drive search syntax: a plain keyword is treated
|
|
|
83
80
|
"structured query needs an operator, e.g. \"name contains 'report'\", " +
|
|
84
81
|
"\"mimeType = 'application/pdf'\", or \"'me' in owners\". " +
|
|
85
82
|
'Reference: https://developers.google.com/drive/api/guides/search-files';
|
|
86
|
-
// A bare keyword
|
|
87
|
-
//
|
|
88
|
-
// match. A query already carrying a comparison operator or a quoted literal is a
|
|
89
|
-
// structured query and is passed through untouched.
|
|
83
|
+
// A bare keyword isn't valid Drive `q` syntax (400s "Invalid Value"), so wrap it
|
|
84
|
+
// as a full-text match; a query with a comparison operator is passed through untouched.
|
|
90
85
|
export function normalizeDriveQuery(raw) {
|
|
91
86
|
const q = raw.trim();
|
|
92
87
|
if (q === '')
|
|
93
88
|
return q;
|
|
94
|
-
// Structured iff it
|
|
95
|
-
//
|
|
96
|
-
// count (names like O'Brien are keywords, not query syntax).
|
|
89
|
+
// Structured iff it has a comparison operator or the membership form "<value> in
|
|
90
|
+
// (parents|owners|writers|readers)"; a bare apostrophe (e.g. O'Brien) doesn't count.
|
|
97
91
|
const hasComparison = /(\bcontains\b|!=|<=|>=|[=<>])/i.test(q);
|
|
98
92
|
const hasMembership = /\bin\s+(parents|owners|writers|readers)\b/i.test(q);
|
|
99
93
|
if (hasComparison || hasMembership)
|
|
@@ -101,9 +95,8 @@ export function normalizeDriveQuery(raw) {
|
|
|
101
95
|
const escaped = q.replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
102
96
|
return `fullText contains '${escaped}'`;
|
|
103
97
|
}
|
|
104
|
-
// Drive
|
|
105
|
-
//
|
|
106
|
-
// instead of a generic upstream_error.
|
|
98
|
+
// Drive 400s a malformed query with the opaque reason "invalid"/"Invalid Value";
|
|
99
|
+
// detect it so drive_search returns query-syntax help instead of a generic upstream_error.
|
|
107
100
|
export function isDriveInvalidQuery(error) {
|
|
108
101
|
const raw = error?.code ?? error?.status ?? error?.response?.status;
|
|
109
102
|
const status = typeof raw === 'string' ? Number(raw) : raw;
|
|
@@ -123,7 +116,14 @@ export function resolveShareNotification(opts) {
|
|
|
123
116
|
return true;
|
|
124
117
|
return opts.sendNotification ?? true;
|
|
125
118
|
}
|
|
126
|
-
export function registerDriveTools(server) {
|
|
119
|
+
export function registerDriveTools(server, deps = {}) {
|
|
120
|
+
// Per-registry, live account enum + injectable client: the schema follows
|
|
121
|
+
// the registry's account view at parse time, not a process-global default.
|
|
122
|
+
const accountEnum = accountArgLive(() => server.accountAliases()).optional();
|
|
123
|
+
const requiredAccountEnum = accountArgLive(() => server.accountAliases());
|
|
124
|
+
const getClientFn = deps.getClientFn ?? getClient;
|
|
125
|
+
const localFiles = deps.localFiles ?? true;
|
|
126
|
+
const registerHostFileTool = localFiles ? server.registerTool : (() => undefined);
|
|
127
127
|
// ─── Read / search / list ──────────────────────────────────────────────
|
|
128
128
|
server.registerTool('drive_search', {
|
|
129
129
|
description: 'Search files in a Google Drive account. A plain keyword is treated as a full-text search; pass Drive query syntax for a structured search.',
|
|
@@ -138,19 +138,18 @@ export function registerDriveTools(server) {
|
|
|
138
138
|
},
|
|
139
139
|
}, async ({ account, query, maxResults, driveId, pageToken }) => {
|
|
140
140
|
try {
|
|
141
|
-
// normalizeDriveQuery trims to '' and Drive reads that as "everything",
|
|
142
|
-
//
|
|
141
|
+
// normalizeDriveQuery trims to '' and Drive reads that as "everything", so
|
|
142
|
+
// a blank query would list the whole drive as a "search" result.
|
|
143
143
|
if (query.trim() === '') {
|
|
144
144
|
return invalidParams(account, '`query` is empty, and Drive reads an empty query as "match everything".', 'Pass a search term, or a structured Drive query such as "mimeType = \'application/pdf\'". To browse a folder instead, use drive_list.');
|
|
145
145
|
}
|
|
146
|
-
const auth = await
|
|
146
|
+
const auth = await getClientFn(account);
|
|
147
147
|
const drive = driveClient({ version: 'v3', auth });
|
|
148
148
|
const params = {
|
|
149
149
|
q: normalizeDriveQuery(query),
|
|
150
150
|
pageSize: maxResults ?? 10,
|
|
151
|
-
// nextPageToken and incompleteSearch live OUTSIDE files(...): omit
|
|
152
|
-
//
|
|
153
|
-
// indistinguishable from a complete one.
|
|
151
|
+
// nextPageToken and incompleteSearch live OUTSIDE files(...): omit them from
|
|
152
|
+
// the mask and Drive drops them, making a partial result indistinguishable from a complete one.
|
|
154
153
|
fields: 'nextPageToken,incompleteSearch,files(id,name,mimeType,modifiedTime,webViewLink,size,parents,driveId)',
|
|
155
154
|
supportsAllDrives: true,
|
|
156
155
|
includeItemsFromAllDrives: true,
|
|
@@ -176,9 +175,8 @@ export function registerDriveTools(server) {
|
|
|
176
175
|
}
|
|
177
176
|
catch (error) {
|
|
178
177
|
if (isDriveInvalidQuery(error)) {
|
|
179
|
-
//
|
|
180
|
-
//
|
|
181
|
-
// non-JSON response landed here uncapped.
|
|
178
|
+
// Goes through safeMessage/stringifyEnvelope like every other envelope
|
|
179
|
+
// so a non-JSON upstream response can't land here uncapped.
|
|
182
180
|
return {
|
|
183
181
|
content: [{ type: 'text', text: stringifyEnvelope({
|
|
184
182
|
error: 'invalid_query',
|
|
@@ -206,7 +204,7 @@ export function registerDriveTools(server) {
|
|
|
206
204
|
},
|
|
207
205
|
}, async ({ account, fileId, maxChars, offset }) => {
|
|
208
206
|
try {
|
|
209
|
-
const auth = await
|
|
207
|
+
const auth = await getClientFn(account);
|
|
210
208
|
const drive = driveClient({ version: 'v3', auth });
|
|
211
209
|
const meta = await drive.files.get({
|
|
212
210
|
fileId,
|
|
@@ -316,7 +314,7 @@ export function registerDriveTools(server) {
|
|
|
316
314
|
},
|
|
317
315
|
}, async ({ account, folderId, maxResults, pageToken }) => {
|
|
318
316
|
try {
|
|
319
|
-
const auth = await
|
|
317
|
+
const auth = await getClientFn(account);
|
|
320
318
|
const drive = driveClient({ version: 'v3', auth });
|
|
321
319
|
// Escape single quotes per Drive query syntax to prevent breaking out of the literal.
|
|
322
320
|
const parent = (folderId ?? 'root').replace(/\\/g, '\\\\').replace(/'/g, "\\'");
|
|
@@ -339,7 +337,7 @@ export function registerDriveTools(server) {
|
|
|
339
337
|
}
|
|
340
338
|
});
|
|
341
339
|
// ─── Write / upload / download ─────────────────────────────────────────
|
|
342
|
-
|
|
340
|
+
registerHostFileTool('drive_upload', {
|
|
343
341
|
description: 'Upload a local file to Google Drive. Pass `convertTo` to import it as a native, editable Google Doc/Sheet/Slides/Drawing instead of storing the raw bytes.',
|
|
344
342
|
inputSchema: {
|
|
345
343
|
account: accountEnum.describe('Google account alias'),
|
|
@@ -351,7 +349,7 @@ export function registerDriveTools(server) {
|
|
|
351
349
|
},
|
|
352
350
|
}, async ({ account, localPath, filename, mimeType: mimeTypeArg, convertTo, parentFolderId }) => {
|
|
353
351
|
try {
|
|
354
|
-
const auth = await
|
|
352
|
+
const auth = await getClientFn(account);
|
|
355
353
|
const drive = driveClient({ version: 'v3', auth });
|
|
356
354
|
const resolvedMime = mimeTypeArg ?? (mime.lookup(localPath) || 'application/octet-stream');
|
|
357
355
|
const fileStream = await openLocalReadStream(localPath);
|
|
@@ -377,7 +375,7 @@ export function registerDriveTools(server) {
|
|
|
377
375
|
return handleDriveError(error, account);
|
|
378
376
|
}
|
|
379
377
|
});
|
|
380
|
-
|
|
378
|
+
registerHostFileTool('drive_download', {
|
|
381
379
|
description: 'Download a binary file from Drive to local disk. For Google Workspace formats (Docs, Sheets, Slides), use drive_export instead.',
|
|
382
380
|
inputSchema: {
|
|
383
381
|
account: accountEnum.describe('Google account alias'),
|
|
@@ -387,7 +385,7 @@ export function registerDriveTools(server) {
|
|
|
387
385
|
},
|
|
388
386
|
}, async ({ account, fileId, savePath, filename }) => {
|
|
389
387
|
try {
|
|
390
|
-
const auth = await
|
|
388
|
+
const auth = await getClientFn(account);
|
|
391
389
|
const drive = driveClient({ version: 'v3', auth });
|
|
392
390
|
const name = filename
|
|
393
391
|
?? (await drive.files.get({ fileId, fields: 'name', supportsAllDrives: true })).data.name
|
|
@@ -405,7 +403,7 @@ export function registerDriveTools(server) {
|
|
|
405
403
|
return handleDriveError(error, account);
|
|
406
404
|
}
|
|
407
405
|
});
|
|
408
|
-
|
|
406
|
+
registerHostFileTool('drive_export', {
|
|
409
407
|
description: 'Export a Google Workspace document (Doc, Sheet, Slide) to a standard format and save to disk. Supported: PDF, DOCX, XLSX, PPTX, TXT, CSV, Markdown (text/markdown for Docs).',
|
|
410
408
|
inputSchema: {
|
|
411
409
|
account: accountEnum.describe('Google account alias'),
|
|
@@ -416,7 +414,7 @@ export function registerDriveTools(server) {
|
|
|
416
414
|
},
|
|
417
415
|
}, async ({ account, fileId, mimeType: exportMime, savePath, filename }) => {
|
|
418
416
|
try {
|
|
419
|
-
const auth = await
|
|
417
|
+
const auth = await getClientFn(account);
|
|
420
418
|
const drive = driveClient({ version: 'v3', auth });
|
|
421
419
|
let name = filename;
|
|
422
420
|
if (!name) {
|
|
@@ -446,7 +444,7 @@ export function registerDriveTools(server) {
|
|
|
446
444
|
},
|
|
447
445
|
}, async ({ account, name, parentFolderId }) => {
|
|
448
446
|
try {
|
|
449
|
-
const auth = await
|
|
447
|
+
const auth = await getClientFn(account);
|
|
450
448
|
const drive = driveClient({ version: 'v3', auth });
|
|
451
449
|
const res = await drive.files.create({
|
|
452
450
|
requestBody: {
|
|
@@ -472,13 +470,22 @@ export function registerDriveTools(server) {
|
|
|
472
470
|
fileId: z.string().min(1).describe('Google Drive file ID'),
|
|
473
471
|
newName: z.string().optional().describe('New filename'),
|
|
474
472
|
newParentFolderId: z.string().optional().describe('Move to this folder, named newParentFolderId here, not parentFolderId'),
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
473
|
+
...(localFiles
|
|
474
|
+
? {
|
|
475
|
+
localPath: z.string().optional().describe('Replace file content with this local file (path on the machine running the server)'),
|
|
476
|
+
mimeType: z.string().optional().describe('MIME type of the replacement file (required if localPath is provided)'),
|
|
477
|
+
convertTo: z.enum(CONVERT_TO_VALUES).optional().describe('When replacing content via localPath, convert the new content into this native Google Workspace type on import: "document" | "spreadsheet" | "presentation" | "drawing" (full application/vnd.google-apps.* ids also accepted).'),
|
|
478
|
+
}
|
|
479
|
+
: {}),
|
|
478
480
|
},
|
|
479
|
-
}, async (
|
|
481
|
+
}, async (args) => {
|
|
482
|
+
const { account, fileId, newName, newParentFolderId } = args;
|
|
483
|
+
// Declared only when the context may read host files (see the shape).
|
|
484
|
+
const { localPath: localPathArg, mimeType: mimeTypeArg, convertTo } = args;
|
|
485
|
+
if (localPathArg && !localFiles)
|
|
486
|
+
return hostFilesRefused(account, 'localPath');
|
|
480
487
|
try {
|
|
481
|
-
const auth = await
|
|
488
|
+
const auth = await getClientFn(account);
|
|
482
489
|
const drive = driveClient({ version: 'v3', auth });
|
|
483
490
|
const requestBody = {};
|
|
484
491
|
if (newName)
|
|
@@ -520,7 +527,7 @@ export function registerDriveTools(server) {
|
|
|
520
527
|
},
|
|
521
528
|
}, async ({ account, fileId }) => {
|
|
522
529
|
try {
|
|
523
|
-
const auth = await
|
|
530
|
+
const auth = await getClientFn(account);
|
|
524
531
|
const drive = driveClient({ version: 'v3', auth });
|
|
525
532
|
await drive.files.delete({ fileId, supportsAllDrives: true });
|
|
526
533
|
return {
|
|
@@ -539,7 +546,7 @@ export function registerDriveTools(server) {
|
|
|
539
546
|
},
|
|
540
547
|
}, async ({ account, fileId }) => {
|
|
541
548
|
try {
|
|
542
|
-
const auth = await
|
|
549
|
+
const auth = await getClientFn(account);
|
|
543
550
|
const drive = driveClient({ version: 'v3', auth });
|
|
544
551
|
await drive.files.update({
|
|
545
552
|
fileId,
|
|
@@ -562,7 +569,7 @@ export function registerDriveTools(server) {
|
|
|
562
569
|
},
|
|
563
570
|
}, async ({ account, fileId }) => {
|
|
564
571
|
try {
|
|
565
|
-
const auth = await
|
|
572
|
+
const auth = await getClientFn(account);
|
|
566
573
|
const drive = driveClient({ version: 'v3', auth });
|
|
567
574
|
const res = await drive.files.update({
|
|
568
575
|
fileId,
|
|
@@ -585,7 +592,7 @@ export function registerDriveTools(server) {
|
|
|
585
592
|
},
|
|
586
593
|
}, async ({ account }) => {
|
|
587
594
|
try {
|
|
588
|
-
const auth = await
|
|
595
|
+
const auth = await getClientFn(account);
|
|
589
596
|
const drive = driveClient({ version: 'v3', auth });
|
|
590
597
|
await drive.files.emptyTrash({});
|
|
591
598
|
return {
|
|
@@ -607,7 +614,7 @@ export function registerDriveTools(server) {
|
|
|
607
614
|
},
|
|
608
615
|
}, async ({ account, fileId, newName, parentFolderId }) => {
|
|
609
616
|
try {
|
|
610
|
-
const auth = await
|
|
617
|
+
const auth = await getClientFn(account);
|
|
611
618
|
const drive = driveClient({ version: 'v3', auth });
|
|
612
619
|
const res = await drive.files.copy({
|
|
613
620
|
fileId,
|
|
@@ -635,7 +642,7 @@ export function registerDriveTools(server) {
|
|
|
635
642
|
},
|
|
636
643
|
}, async ({ account, fileId, newParentFolderId }) => {
|
|
637
644
|
try {
|
|
638
|
-
const auth = await
|
|
645
|
+
const auth = await getClientFn(account);
|
|
639
646
|
const drive = driveClient({ version: 'v3', auth });
|
|
640
647
|
const current = await drive.files.get({ fileId, fields: 'parents', supportsAllDrives: true });
|
|
641
648
|
const res = await drive.files.update({
|
|
@@ -670,9 +677,8 @@ export function registerDriveTools(server) {
|
|
|
670
677
|
},
|
|
671
678
|
}, async ({ account, fileId, type, role, emailAddress, domain, sendNotification, emailMessage, transferOwnership, expirationTime }) => {
|
|
672
679
|
{
|
|
673
|
-
// Outbound allowlist (off unless GOOGLE_OUTBOUND_ALLOWLIST is set):
|
|
674
|
-
//
|
|
675
|
-
// "@domain" entry; "anyone" (link sharing) is refused while active.
|
|
680
|
+
// Outbound allowlist (off unless GOOGLE_OUTBOUND_ALLOWLIST is set): user/group
|
|
681
|
+
// grantees must match, a domain share needs its exact "@domain" entry, "anyone" is refused while active.
|
|
676
682
|
const list = resolveOutboundAllowlist();
|
|
677
683
|
if (list) {
|
|
678
684
|
if ((type === 'user' || type === 'group') && emailAddress) {
|
|
@@ -689,7 +695,7 @@ export function registerDriveTools(server) {
|
|
|
689
695
|
}
|
|
690
696
|
}
|
|
691
697
|
try {
|
|
692
|
-
const auth = await
|
|
698
|
+
const auth = await getClientFn(account);
|
|
693
699
|
const drive = driveClient({ version: 'v3', auth });
|
|
694
700
|
const requestBody = { type, role, emailAddress, domain };
|
|
695
701
|
if (expirationTime)
|
|
@@ -720,7 +726,7 @@ export function registerDriveTools(server) {
|
|
|
720
726
|
},
|
|
721
727
|
}, async ({ account, fileId }) => {
|
|
722
728
|
try {
|
|
723
|
-
const auth = await
|
|
729
|
+
const auth = await getClientFn(account);
|
|
724
730
|
const drive = driveClient({ version: 'v3', auth });
|
|
725
731
|
const res = await drive.permissions.list({
|
|
726
732
|
fileId,
|
|
@@ -752,7 +758,7 @@ export function registerDriveTools(server) {
|
|
|
752
758
|
},
|
|
753
759
|
}, async ({ account, fileId, permissionId, role, expirationTime, removeExpiration, transferOwnership }) => {
|
|
754
760
|
try {
|
|
755
|
-
const auth = await
|
|
761
|
+
const auth = await getClientFn(account);
|
|
756
762
|
const drive = driveClient({ version: 'v3', auth });
|
|
757
763
|
const requestBody = {};
|
|
758
764
|
if (role)
|
|
@@ -785,7 +791,7 @@ export function registerDriveTools(server) {
|
|
|
785
791
|
},
|
|
786
792
|
}, async ({ account, fileId, permissionId }) => {
|
|
787
793
|
try {
|
|
788
|
-
const auth = await
|
|
794
|
+
const auth = await getClientFn(account);
|
|
789
795
|
const drive = driveClient({ version: 'v3', auth });
|
|
790
796
|
await drive.permissions.delete({ fileId, permissionId, supportsAllDrives: true });
|
|
791
797
|
return {
|
|
@@ -811,7 +817,7 @@ export function registerDriveTools(server) {
|
|
|
811
817
|
},
|
|
812
818
|
}, async ({ account, fileId, content, anchor, quotedFileContent }) => {
|
|
813
819
|
try {
|
|
814
|
-
const auth = await
|
|
820
|
+
const auth = await getClientFn(account);
|
|
815
821
|
const drive = driveClient({ version: 'v3', auth });
|
|
816
822
|
const requestBody = { content };
|
|
817
823
|
if (anchor)
|
|
@@ -843,7 +849,7 @@ export function registerDriveTools(server) {
|
|
|
843
849
|
},
|
|
844
850
|
}, async ({ account, fileId, includeDeleted, pageSize, pageToken, startModifiedTime }) => {
|
|
845
851
|
try {
|
|
846
|
-
const auth = await
|
|
852
|
+
const auth = await getClientFn(account);
|
|
847
853
|
const drive = driveClient({ version: 'v3', auth });
|
|
848
854
|
const res = await drive.comments.list({
|
|
849
855
|
fileId,
|
|
@@ -871,7 +877,7 @@ export function registerDriveTools(server) {
|
|
|
871
877
|
},
|
|
872
878
|
}, async ({ account, fileId, commentId, includeDeleted }) => {
|
|
873
879
|
try {
|
|
874
|
-
const auth = await
|
|
880
|
+
const auth = await getClientFn(account);
|
|
875
881
|
const drive = driveClient({ version: 'v3', auth });
|
|
876
882
|
const res = await drive.comments.get({
|
|
877
883
|
fileId,
|
|
@@ -897,7 +903,7 @@ export function registerDriveTools(server) {
|
|
|
897
903
|
},
|
|
898
904
|
}, async ({ account, fileId, commentId, content }) => {
|
|
899
905
|
try {
|
|
900
|
-
const auth = await
|
|
906
|
+
const auth = await getClientFn(account);
|
|
901
907
|
const drive = driveClient({ version: 'v3', auth });
|
|
902
908
|
const res = await drive.comments.update({
|
|
903
909
|
fileId,
|
|
@@ -922,7 +928,7 @@ export function registerDriveTools(server) {
|
|
|
922
928
|
},
|
|
923
929
|
}, async ({ account, fileId, commentId }) => {
|
|
924
930
|
try {
|
|
925
|
-
const auth = await
|
|
931
|
+
const auth = await getClientFn(account);
|
|
926
932
|
const drive = driveClient({ version: 'v3', auth });
|
|
927
933
|
await drive.comments.delete({ fileId, commentId });
|
|
928
934
|
return {
|
|
@@ -946,7 +952,7 @@ export function registerDriveTools(server) {
|
|
|
946
952
|
},
|
|
947
953
|
}, async ({ account, fileId, commentId, content, action }) => {
|
|
948
954
|
try {
|
|
949
|
-
const auth = await
|
|
955
|
+
const auth = await getClientFn(account);
|
|
950
956
|
const drive = driveClient({ version: 'v3', auth });
|
|
951
957
|
const requestBody = { content };
|
|
952
958
|
if (action)
|
|
@@ -977,7 +983,7 @@ export function registerDriveTools(server) {
|
|
|
977
983
|
},
|
|
978
984
|
}, async ({ account, fileId, commentId, includeDeleted, pageSize, pageToken }) => {
|
|
979
985
|
try {
|
|
980
|
-
const auth = await
|
|
986
|
+
const auth = await getClientFn(account);
|
|
981
987
|
const drive = driveClient({ version: 'v3', auth });
|
|
982
988
|
const res = await drive.replies.list({
|
|
983
989
|
fileId,
|
|
@@ -1006,7 +1012,7 @@ export function registerDriveTools(server) {
|
|
|
1006
1012
|
},
|
|
1007
1013
|
}, async ({ account, fileId, commentId, replyId, content }) => {
|
|
1008
1014
|
try {
|
|
1009
|
-
const auth = await
|
|
1015
|
+
const auth = await getClientFn(account);
|
|
1010
1016
|
const drive = driveClient({ version: 'v3', auth });
|
|
1011
1017
|
const res = await drive.replies.update({
|
|
1012
1018
|
fileId,
|
|
@@ -1033,7 +1039,7 @@ export function registerDriveTools(server) {
|
|
|
1033
1039
|
},
|
|
1034
1040
|
}, async ({ account, fileId, commentId, replyId }) => {
|
|
1035
1041
|
try {
|
|
1036
|
-
const auth = await
|
|
1042
|
+
const auth = await getClientFn(account);
|
|
1037
1043
|
const drive = driveClient({ version: 'v3', auth });
|
|
1038
1044
|
await drive.replies.delete({ fileId, commentId, replyId });
|
|
1039
1045
|
return {
|
|
@@ -1055,7 +1061,7 @@ export function registerDriveTools(server) {
|
|
|
1055
1061
|
},
|
|
1056
1062
|
}, async ({ account, fileId, pageSize, pageToken }) => {
|
|
1057
1063
|
try {
|
|
1058
|
-
const auth = await
|
|
1064
|
+
const auth = await getClientFn(account);
|
|
1059
1065
|
const drive = driveClient({ version: 'v3', auth });
|
|
1060
1066
|
const res = await drive.revisions.list({
|
|
1061
1067
|
fileId,
|
|
@@ -1084,7 +1090,7 @@ export function registerDriveTools(server) {
|
|
|
1084
1090
|
},
|
|
1085
1091
|
}, async ({ account, fileId, revisionId, keepForever, published, publishAuto, publishedOutsideDomain }) => {
|
|
1086
1092
|
try {
|
|
1087
|
-
const auth = await
|
|
1093
|
+
const auth = await getClientFn(account);
|
|
1088
1094
|
const drive = driveClient({ version: 'v3', auth });
|
|
1089
1095
|
const requestBody = {};
|
|
1090
1096
|
if (keepForever !== undefined)
|
|
@@ -1118,7 +1124,7 @@ export function registerDriveTools(server) {
|
|
|
1118
1124
|
},
|
|
1119
1125
|
}, async ({ account, fileId, revisionId }) => {
|
|
1120
1126
|
try {
|
|
1121
|
-
const auth = await
|
|
1127
|
+
const auth = await getClientFn(account);
|
|
1122
1128
|
const drive = driveClient({ version: 'v3', auth });
|
|
1123
1129
|
await drive.revisions.delete({ fileId, revisionId });
|
|
1124
1130
|
return {
|
|
@@ -1140,7 +1146,7 @@ export function registerDriveTools(server) {
|
|
|
1140
1146
|
},
|
|
1141
1147
|
}, async ({ account, fileId, pageSize, pageToken }) => {
|
|
1142
1148
|
try {
|
|
1143
|
-
const auth = await
|
|
1149
|
+
const auth = await getClientFn(account);
|
|
1144
1150
|
const drive = driveClient({ version: 'v3', auth });
|
|
1145
1151
|
const res = await drive.accessproposals.list({
|
|
1146
1152
|
fileId,
|
|
@@ -1170,7 +1176,7 @@ export function registerDriveTools(server) {
|
|
|
1170
1176
|
},
|
|
1171
1177
|
}, async ({ account, fileId, proposalId, action, role, view, sendNotification }) => {
|
|
1172
1178
|
try {
|
|
1173
|
-
const auth = await
|
|
1179
|
+
const auth = await getClientFn(account);
|
|
1174
1180
|
const drive = driveClient({ version: 'v3', auth });
|
|
1175
1181
|
const requestBody = { action };
|
|
1176
1182
|
if (role)
|
|
@@ -1203,7 +1209,7 @@ export function registerDriveTools(server) {
|
|
|
1203
1209
|
},
|
|
1204
1210
|
}, async ({ account, pageSize, pageToken, q }) => {
|
|
1205
1211
|
try {
|
|
1206
|
-
const auth = await
|
|
1212
|
+
const auth = await getClientFn(account);
|
|
1207
1213
|
const drive = driveClient({ version: 'v3', auth });
|
|
1208
1214
|
const res = await drive.drives.list({
|
|
1209
1215
|
pageSize: pageSize ?? 50,
|
|
@@ -1227,7 +1233,7 @@ export function registerDriveTools(server) {
|
|
|
1227
1233
|
},
|
|
1228
1234
|
}, async ({ account, driveId }) => {
|
|
1229
1235
|
try {
|
|
1230
|
-
const auth = await
|
|
1236
|
+
const auth = await getClientFn(account);
|
|
1231
1237
|
const drive = driveClient({ version: 'v3', auth });
|
|
1232
1238
|
const res = await drive.drives.get({
|
|
1233
1239
|
driveId,
|
|
@@ -1278,10 +1284,10 @@ export function registerDriveTools(server) {
|
|
|
1278
1284
|
}
|
|
1279
1285
|
let activeAccount = fromAccount;
|
|
1280
1286
|
try {
|
|
1281
|
-
const sourceAuth = await
|
|
1287
|
+
const sourceAuth = await getClientFn(fromAccount);
|
|
1282
1288
|
const sourceDrive = driveClient({ version: 'v3', auth: sourceAuth });
|
|
1283
1289
|
activeAccount = toAccount;
|
|
1284
|
-
const targetAuth = await
|
|
1290
|
+
const targetAuth = await getClientFn(toAccount);
|
|
1285
1291
|
const targetDrive = driveClient({ version: 'v3', auth: targetAuth });
|
|
1286
1292
|
activeAccount = fromAccount;
|
|
1287
1293
|
const meta = await sourceDrive.files.get({
|
|
@@ -1305,7 +1311,7 @@ export function registerDriveTools(server) {
|
|
|
1305
1311
|
};
|
|
1306
1312
|
}
|
|
1307
1313
|
const intendedName = newName ?? meta.data.name ?? 'transferred-file';
|
|
1308
|
-
const targetEmail =
|
|
1314
|
+
const targetEmail = server.accountSet().configs[toAccount].email;
|
|
1309
1315
|
const finish = async (data, strategy, flags) => {
|
|
1310
1316
|
let moveFailed = false;
|
|
1311
1317
|
let moveSkipped = false;
|
|
@@ -1379,7 +1385,7 @@ export function registerDriveTools(server) {
|
|
|
1379
1385
|
},
|
|
1380
1386
|
}, async ({ account }) => {
|
|
1381
1387
|
try {
|
|
1382
|
-
const auth = await
|
|
1388
|
+
const auth = await getClientFn(account);
|
|
1383
1389
|
const drive = driveClient({ version: 'v3', auth });
|
|
1384
1390
|
const res = await drive.about.get({
|
|
1385
1391
|
fields: 'user,storageQuota',
|
package/dist/tools/forms.d.ts
CHANGED
|
@@ -1,2 +1,11 @@
|
|
|
1
1
|
import type { ToolRegistry } from '../registry.js';
|
|
2
|
-
|
|
2
|
+
import type { Account } from '../accounts.js';
|
|
3
|
+
import { type CuratedToolDeps } from '../client.js';
|
|
4
|
+
export declare function registerFormsTools(server: ToolRegistry, deps?: CuratedToolDeps): void;
|
|
5
|
+
export declare function handleFormsError(error: any, account: Account): {
|
|
6
|
+
content: {
|
|
7
|
+
type: "text";
|
|
8
|
+
text: string;
|
|
9
|
+
}[];
|
|
10
|
+
isError: true;
|
|
11
|
+
};
|
package/dist/tools/forms.js
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
import { forms as formsClient } from '@googleapis/forms';
|
|
3
|
-
import {
|
|
3
|
+
import { accountArgLive } from '../accounts.js';
|
|
4
4
|
import { getClient } from '../client.js';
|
|
5
5
|
import { handleGoogleApiError } from './_errors.js';
|
|
6
6
|
import { coerceArray, coerceBoolean, coerceJson } from './_coerce.js';
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
export function registerFormsTools(server, deps = {}) {
|
|
8
|
+
// Per-registry, live account enum + injectable client: the schema follows
|
|
9
|
+
// the registry's account view at parse time, not a process-global default.
|
|
10
|
+
const accountEnum = accountArgLive(() => server.accountAliases()).optional();
|
|
11
|
+
const getClientFn = deps.getClientFn ?? getClient;
|
|
9
12
|
server.registerTool('forms_get', {
|
|
10
13
|
description: 'Get a Google Form (definition: questions, sections, settings). Requires forms.body scope.',
|
|
11
14
|
inputSchema: {
|
|
@@ -14,7 +17,7 @@ export function registerFormsTools(server) {
|
|
|
14
17
|
},
|
|
15
18
|
}, async ({ account, formId }) => {
|
|
16
19
|
try {
|
|
17
|
-
const auth = await
|
|
20
|
+
const auth = await getClientFn(account);
|
|
18
21
|
const forms = formsClient({ version: 'v1', auth });
|
|
19
22
|
const res = await forms.forms.get({ formId });
|
|
20
23
|
return {
|
|
@@ -36,7 +39,7 @@ export function registerFormsTools(server) {
|
|
|
36
39
|
},
|
|
37
40
|
}, async ({ account, formId, pageSize, pageToken, filter }) => {
|
|
38
41
|
try {
|
|
39
|
-
const auth = await
|
|
42
|
+
const auth = await getClientFn(account);
|
|
40
43
|
const forms = formsClient({ version: 'v1', auth });
|
|
41
44
|
const res = await forms.forms.responses.list({
|
|
42
45
|
formId,
|
|
@@ -61,7 +64,7 @@ export function registerFormsTools(server) {
|
|
|
61
64
|
},
|
|
62
65
|
}, async ({ account, formId, responseId }) => {
|
|
63
66
|
try {
|
|
64
|
-
const auth = await
|
|
67
|
+
const auth = await getClientFn(account);
|
|
65
68
|
const forms = formsClient({ version: 'v1', auth });
|
|
66
69
|
const res = await forms.forms.responses.get({ formId, responseId });
|
|
67
70
|
return {
|
|
@@ -80,7 +83,7 @@ export function registerFormsTools(server) {
|
|
|
80
83
|
},
|
|
81
84
|
}, async ({ account, formId }) => {
|
|
82
85
|
try {
|
|
83
|
-
const auth = await
|
|
86
|
+
const auth = await getClientFn(account);
|
|
84
87
|
const forms = formsClient({ version: 'v1', auth });
|
|
85
88
|
const res = await forms.forms.watches.list({ formId });
|
|
86
89
|
return {
|
|
@@ -100,7 +103,7 @@ export function registerFormsTools(server) {
|
|
|
100
103
|
},
|
|
101
104
|
}, async ({ account, title, documentTitle }) => {
|
|
102
105
|
try {
|
|
103
|
-
const auth = await
|
|
106
|
+
const auth = await getClientFn(account);
|
|
104
107
|
const forms = formsClient({ version: 'v1', auth });
|
|
105
108
|
const res = await forms.forms.create({
|
|
106
109
|
requestBody: { info: { title, documentTitle } },
|
|
@@ -135,7 +138,7 @@ export function registerFormsTools(server) {
|
|
|
135
138
|
},
|
|
136
139
|
}, async ({ account, formId, requests, includeFormInResponse, writeControl }) => {
|
|
137
140
|
try {
|
|
138
|
-
const auth = await
|
|
141
|
+
const auth = await getClientFn(account);
|
|
139
142
|
const forms = formsClient({ version: 'v1', auth });
|
|
140
143
|
const res = await forms.forms.batchUpdate({
|
|
141
144
|
formId,
|
|
@@ -163,7 +166,7 @@ export function registerFormsTools(server) {
|
|
|
163
166
|
},
|
|
164
167
|
}, async ({ account, formId, isPublished, isAcceptingResponses }) => {
|
|
165
168
|
try {
|
|
166
|
-
const auth = await
|
|
169
|
+
const auth = await getClientFn(account);
|
|
167
170
|
const forms = formsClient({ version: 'v1', auth });
|
|
168
171
|
const updateMask = ['publishState.isPublished'];
|
|
169
172
|
if (isAcceptingResponses !== undefined)
|
|
@@ -186,6 +189,9 @@ export function registerFormsTools(server) {
|
|
|
186
189
|
}
|
|
187
190
|
});
|
|
188
191
|
}
|
|
189
|
-
function handleFormsError(error, account) {
|
|
190
|
-
return handleGoogleApiError(error, account,
|
|
192
|
+
export function handleFormsError(error, account) {
|
|
193
|
+
return handleGoogleApiError(error, account, {
|
|
194
|
+
scope: "Forms tools require the optional \"forms\" scope bundle. Add GOOGLE_OPTIONAL_SCOPES=forms (or include \"forms\" in the list) and re-auth.",
|
|
195
|
+
bundle: 'forms',
|
|
196
|
+
});
|
|
191
197
|
}
|
|
@@ -21,5 +21,6 @@ export interface GeneratedToolDef {
|
|
|
21
21
|
}>;
|
|
22
22
|
shape: z.ZodRawShape;
|
|
23
23
|
}
|
|
24
|
-
export declare function accountField(): z.ZodOptional<z.ZodType<string, unknown, z.core.$ZodTypeInternals<string, unknown>>>;
|
|
24
|
+
export declare function accountField(aliases?: readonly string[] | (() => readonly string[])): z.ZodOptional<z.ZodType<string, unknown, z.core.$ZodTypeInternals<string, unknown>>>;
|
|
25
|
+
export type { ExecuteDeps } from '../../executor.js';
|
|
25
26
|
export declare function registerGeneratedTool(registry: ToolRegistry, def: GeneratedToolDef, deps?: ExecuteDeps): void;
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
import { accountAliasSchema } from '../../accounts.js';
|
|
1
|
+
import { accountAliasSchema, accountAliasSchemaFor, accountArgLive } from '../../accounts.js';
|
|
2
2
|
import { executeApiMethod } from '../../executor.js';
|
|
3
|
-
export function accountField() {
|
|
4
|
-
|
|
3
|
+
export function accountField(aliases) {
|
|
4
|
+
// Generated code passes a getter over registry.accountAliases(), so the field
|
|
5
|
+
// validates against the registry's CURRENT set, as curated tools do. An
|
|
6
|
+
// array bakes that set; the no-arg form keeps the global-bound schema.
|
|
7
|
+
const schema = typeof aliases === 'function' ? accountArgLive(aliases) : aliases ? accountAliasSchemaFor(aliases) : accountAliasSchema;
|
|
8
|
+
return schema.optional().describe('Google account alias (omit for the default account)');
|
|
5
9
|
}
|
|
6
10
|
export function registerGeneratedTool(registry, def, deps = {}) {
|
|
7
11
|
// Widened locally: `cud` is a registry extension the SDK config type doesn't
|
|
@@ -1,2 +1,3 @@
|
|
|
1
1
|
import type { ToolRegistry } from '../../registry.js';
|
|
2
|
-
|
|
2
|
+
import { type ExecuteDeps } from './_shared.js';
|
|
3
|
+
export declare function registerAdminGeneratedTools(registry: ToolRegistry, deps?: ExecuteDeps): void;
|