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.
Files changed (181) hide show
  1. package/README.md +5 -5
  2. package/dist/accounts.d.ts +20 -4
  3. package/dist/accounts.js +68 -44
  4. package/dist/api-probe.d.ts +5 -0
  5. package/dist/api-probe.js +20 -15
  6. package/dist/arg-normalize.js +19 -38
  7. package/dist/arg-strict.d.ts +7 -0
  8. package/dist/arg-strict.js +38 -28
  9. package/dist/auth.d.ts +5 -4
  10. package/dist/auth.js +16 -23
  11. package/dist/boot-gates.d.ts +26 -0
  12. package/dist/boot-gates.js +36 -0
  13. package/dist/cimd-cache.d.ts +38 -0
  14. package/dist/cimd-cache.js +111 -0
  15. package/dist/client-config.d.ts +2 -2
  16. package/dist/client-config.js +8 -14
  17. package/dist/client.d.ts +32 -2
  18. package/dist/client.js +0 -0
  19. package/dist/compose.d.ts +18 -0
  20. package/dist/compose.js +109 -0
  21. package/dist/config-file.d.ts +13 -0
  22. package/dist/config-file.js +41 -10
  23. package/dist/discover.js +7 -10
  24. package/dist/discovery-client.d.ts +3 -0
  25. package/dist/discovery-client.js +36 -32
  26. package/dist/doctor.d.ts +9 -5
  27. package/dist/doctor.js +119 -29
  28. package/dist/env-load.js +2 -5
  29. package/dist/executor.d.ts +3 -0
  30. package/dist/executor.js +6 -6
  31. package/dist/fanout.d.ts +9 -1
  32. package/dist/fanout.js +47 -22
  33. package/dist/fs-atomic.d.ts +8 -0
  34. package/dist/fs-atomic.js +216 -29
  35. package/dist/hint-provider.d.ts +129 -0
  36. package/dist/hint-provider.js +58 -0
  37. package/dist/http-config.d.ts +2 -2
  38. package/dist/http-config.js +3 -7
  39. package/dist/http-transport.d.ts +67 -9
  40. package/dist/http-transport.js +318 -52
  41. package/dist/identity.d.ts +6 -3
  42. package/dist/identity.js +24 -8
  43. package/dist/index.js +76 -160
  44. package/dist/master-key.d.ts +3 -3
  45. package/dist/master-key.js +16 -19
  46. package/dist/mcp-token.d.ts +126 -19
  47. package/dist/mcp-token.js +557 -76
  48. package/dist/metrics-cli.d.ts +1 -1
  49. package/dist/metrics-cli.js +1 -1
  50. package/dist/metrics-tap.js +2 -5
  51. package/dist/migrate-config.d.ts +1 -2
  52. package/dist/migrate-config.js +5 -7
  53. package/dist/net-tuning.js +2 -4
  54. package/dist/oauth-as.d.ts +104 -4
  55. package/dist/oauth-as.js +368 -114
  56. package/dist/oauth-consent.d.ts +10 -0
  57. package/dist/oauth-consent.js +20 -10
  58. package/dist/outbound-allowlist.js +9 -11
  59. package/dist/reauth-hint.d.ts +1 -1
  60. package/dist/reauth-hint.js +11 -10
  61. package/dist/registry-transfer.d.ts +5 -0
  62. package/dist/registry-transfer.js +63 -11
  63. package/dist/registry.d.ts +13 -4
  64. package/dist/registry.js +100 -72
  65. package/dist/scope-catalog.d.ts +16 -0
  66. package/dist/scope-catalog.js +40 -13
  67. package/dist/scope-observability.d.ts +10 -9
  68. package/dist/scope-observability.js +34 -24
  69. package/dist/services.d.ts +18 -10
  70. package/dist/services.js +61 -22
  71. package/dist/ssrf-guard.d.ts +23 -9
  72. package/dist/ssrf-guard.js +106 -78
  73. package/dist/tenant-purge.d.ts +26 -0
  74. package/dist/tenant-purge.js +65 -0
  75. package/dist/token-store.d.ts +20 -2
  76. package/dist/token-store.js +0 -0
  77. package/dist/tools/_coerce.d.ts +4 -4
  78. package/dist/tools/_errors.d.ts +3 -0
  79. package/dist/tools/_errors.js +72 -60
  80. package/dist/tools/_local-files.d.ts +9 -0
  81. package/dist/tools/_local-files.js +22 -8
  82. package/dist/tools/account-wizard.d.ts +13 -3
  83. package/dist/tools/account-wizard.js +107 -56
  84. package/dist/tools/accounts-tool.d.ts +8 -1
  85. package/dist/tools/accounts-tool.js +35 -19
  86. package/dist/tools/admin.d.ts +10 -1
  87. package/dist/tools/admin.js +14 -11
  88. package/dist/tools/analytics.d.ts +10 -1
  89. package/dist/tools/analytics.js +14 -10
  90. package/dist/tools/calendar.d.ts +2 -1
  91. package/dist/tools/calendar.js +19 -18
  92. package/dist/tools/chat.d.ts +10 -1
  93. package/dist/tools/chat.js +12 -8
  94. package/dist/tools/contacts.d.ts +2 -1
  95. package/dist/tools/contacts.js +22 -19
  96. package/dist/tools/docs.d.ts +2 -1
  97. package/dist/tools/docs.js +35 -36
  98. package/dist/tools/drive.d.ts +2 -1
  99. package/dist/tools/drive.js +80 -74
  100. package/dist/tools/forms.d.ts +10 -1
  101. package/dist/tools/forms.js +18 -12
  102. package/dist/tools/generated/_shared.d.ts +2 -1
  103. package/dist/tools/generated/_shared.js +7 -3
  104. package/dist/tools/generated/admin.d.ts +2 -1
  105. package/dist/tools/generated/admin.js +265 -265
  106. package/dist/tools/generated/analytics.d.ts +2 -1
  107. package/dist/tools/generated/analytics.js +125 -125
  108. package/dist/tools/generated/appsmarket.d.ts +2 -1
  109. package/dist/tools/generated/appsmarket.js +5 -5
  110. package/dist/tools/generated/calendar.d.ts +2 -1
  111. package/dist/tools/generated/calendar.js +55 -55
  112. package/dist/tools/generated/chat.d.ts +2 -1
  113. package/dist/tools/generated/chat.js +95 -95
  114. package/dist/tools/generated/classroom.d.ts +2 -1
  115. package/dist/tools/generated/classroom.js +209 -209
  116. package/dist/tools/generated/cloudidentity.d.ts +2 -1
  117. package/dist/tools/generated/cloudidentity.js +133 -133
  118. package/dist/tools/generated/cloudsearch.d.ts +2 -1
  119. package/dist/tools/generated/cloudsearch.js +99 -99
  120. package/dist/tools/generated/contacts.d.ts +2 -1
  121. package/dist/tools/generated/contacts.js +29 -29
  122. package/dist/tools/generated/drive.d.ts +2 -1
  123. package/dist/tools/generated/drive.js +71 -71
  124. package/dist/tools/generated/driveactivity.d.ts +2 -1
  125. package/dist/tools/generated/driveactivity.js +3 -3
  126. package/dist/tools/generated/drivelabels.d.ts +2 -1
  127. package/dist/tools/generated/drivelabels.js +53 -53
  128. package/dist/tools/generated/forms.d.ts +2 -1
  129. package/dist/tools/generated/forms.js +7 -7
  130. package/dist/tools/generated/gmail.d.ts +2 -1
  131. package/dist/tools/generated/gmail.js +117 -117
  132. package/dist/tools/generated/groupsmigration.d.ts +2 -1
  133. package/dist/tools/generated/groupsmigration.js +3 -3
  134. package/dist/tools/generated/groupssettings.d.ts +2 -1
  135. package/dist/tools/generated/groupssettings.js +7 -7
  136. package/dist/tools/generated/index.d.ts +2 -1
  137. package/dist/tools/generated/keep.d.ts +2 -1
  138. package/dist/tools/generated/keep.js +15 -15
  139. package/dist/tools/generated/licensing.d.ts +2 -1
  140. package/dist/tools/generated/licensing.js +15 -15
  141. package/dist/tools/generated/meet.d.ts +2 -1
  142. package/dist/tools/generated/meet.js +27 -27
  143. package/dist/tools/generated/postmaster.d.ts +2 -1
  144. package/dist/tools/generated/postmaster.js +9 -9
  145. package/dist/tools/generated/reseller.d.ts +2 -1
  146. package/dist/tools/generated/reseller.js +35 -35
  147. package/dist/tools/generated/script.d.ts +2 -1
  148. package/dist/tools/generated/script.js +33 -33
  149. package/dist/tools/generated/searchconsole.d.ts +2 -1
  150. package/dist/tools/generated/searchconsole.js +3 -3
  151. package/dist/tools/generated/sheets.d.ts +2 -1
  152. package/dist/tools/generated/sheets.js +15 -15
  153. package/dist/tools/generated/tasks.d.ts +2 -1
  154. package/dist/tools/generated/tasks.js +5 -5
  155. package/dist/tools/generated/vault.d.ts +2 -1
  156. package/dist/tools/generated/vault.js +67 -67
  157. package/dist/tools/generated/workspaceevents.d.ts +2 -1
  158. package/dist/tools/generated/workspaceevents.js +31 -31
  159. package/dist/tools/gmail-mime.d.ts +1 -1
  160. package/dist/tools/gmail-mime.js +7 -12
  161. package/dist/tools/gmail.d.ts +4 -3
  162. package/dist/tools/gmail.js +67 -69
  163. package/dist/tools/google-api.d.ts +2 -3
  164. package/dist/tools/google-api.js +34 -22
  165. package/dist/tools/meet.d.ts +10 -1
  166. package/dist/tools/meet.js +12 -9
  167. package/dist/tools/searchconsole.d.ts +2 -1
  168. package/dist/tools/searchconsole.js +16 -13
  169. package/dist/tools/sheets.d.ts +2 -1
  170. package/dist/tools/sheets.js +35 -32
  171. package/dist/tools/slides.d.ts +10 -1
  172. package/dist/tools/slides.js +16 -10
  173. package/dist/tools/tasks.d.ts +2 -1
  174. package/dist/tools/tasks.js +18 -15
  175. package/dist/trim.d.ts +5 -0
  176. package/dist/trim.js +19 -0
  177. package/dist/usage-metrics.d.ts +23 -0
  178. package/dist/usage-metrics.js +67 -56
  179. package/dist/write-control.d.ts +4 -8
  180. package/dist/write-control.js +13 -6
  181. package/package.json +47 -21
@@ -2,11 +2,14 @@ import { z } from 'zod';
2
2
  import { coerceArray, coerceJson } from './_coerce.js';
3
3
  import { searchconsole as searchconsoleClient } from '@googleapis/searchconsole';
4
4
  import { webmasters as webmastersClient } from '@googleapis/webmasters';
5
- import { accountAliasSchema } from '../accounts.js';
5
+ import { accountArgLive } from '../accounts.js';
6
6
  import { getClient } from '../client.js';
7
7
  import { handleGoogleApiError } from './_errors.js';
8
- const accountEnum = accountAliasSchema.optional();
9
- export function registerSearchConsoleTools(server) {
8
+ export function registerSearchConsoleTools(server, deps = {}) {
9
+ // Per-registry, live account enum + injectable client: the schema follows
10
+ // the registry's account view at parse time, not a process-global default.
11
+ const accountEnum = accountArgLive(() => server.accountAliases()).optional();
12
+ const getClientFn = deps.getClientFn ?? getClient;
10
13
  // ─── Sites ───────────────────────────────────────────────
11
14
  server.registerTool('searchconsole_sites_list', {
12
15
  description: 'List all sites (properties) the account has access to in Google Search Console',
@@ -15,7 +18,7 @@ export function registerSearchConsoleTools(server) {
15
18
  },
16
19
  }, async ({ account }) => {
17
20
  try {
18
- const auth = await getClient(account);
21
+ const auth = await getClientFn(account);
19
22
  const wm = webmastersClient({ version: 'v3', auth });
20
23
  const res = await wm.sites.list();
21
24
  return {
@@ -34,7 +37,7 @@ export function registerSearchConsoleTools(server) {
34
37
  },
35
38
  }, async ({ account, siteUrl }) => {
36
39
  try {
37
- const auth = await getClient(account);
40
+ const auth = await getClientFn(account);
38
41
  const wm = webmastersClient({ version: 'v3', auth });
39
42
  const res = await wm.sites.get({ siteUrl });
40
43
  return {
@@ -53,7 +56,7 @@ export function registerSearchConsoleTools(server) {
53
56
  },
54
57
  }, async ({ account, siteUrl }) => {
55
58
  try {
56
- const auth = await getClient(account);
59
+ const auth = await getClientFn(account);
57
60
  const wm = webmastersClient({ version: 'v3', auth });
58
61
  await wm.sites.add({ siteUrl });
59
62
  return {
@@ -72,7 +75,7 @@ export function registerSearchConsoleTools(server) {
72
75
  },
73
76
  }, async ({ account, siteUrl }) => {
74
77
  try {
75
- const auth = await getClient(account);
78
+ const auth = await getClientFn(account);
76
79
  const wm = webmastersClient({ version: 'v3', auth });
77
80
  await wm.sites.delete({ siteUrl });
78
81
  return {
@@ -92,7 +95,7 @@ export function registerSearchConsoleTools(server) {
92
95
  },
93
96
  }, async ({ account, siteUrl }) => {
94
97
  try {
95
- const auth = await getClient(account);
98
+ const auth = await getClientFn(account);
96
99
  const wm = webmastersClient({ version: 'v3', auth });
97
100
  const res = await wm.sitemaps.list({ siteUrl });
98
101
  return {
@@ -112,7 +115,7 @@ export function registerSearchConsoleTools(server) {
112
115
  },
113
116
  }, async ({ account, siteUrl, feedpath }) => {
114
117
  try {
115
- const auth = await getClient(account);
118
+ const auth = await getClientFn(account);
116
119
  const wm = webmastersClient({ version: 'v3', auth });
117
120
  const res = await wm.sitemaps.get({ siteUrl, feedpath });
118
121
  return {
@@ -132,7 +135,7 @@ export function registerSearchConsoleTools(server) {
132
135
  },
133
136
  }, async ({ account, siteUrl, feedpath }) => {
134
137
  try {
135
- const auth = await getClient(account);
138
+ const auth = await getClientFn(account);
136
139
  const wm = webmastersClient({ version: 'v3', auth });
137
140
  await wm.sitemaps.submit({ siteUrl, feedpath });
138
141
  return {
@@ -152,7 +155,7 @@ export function registerSearchConsoleTools(server) {
152
155
  },
153
156
  }, async ({ account, siteUrl, feedpath }) => {
154
157
  try {
155
- const auth = await getClient(account);
158
+ const auth = await getClientFn(account);
156
159
  const wm = webmastersClient({ version: 'v3', auth });
157
160
  await wm.sitemaps.delete({ siteUrl, feedpath });
158
161
  return {
@@ -195,7 +198,7 @@ export function registerSearchConsoleTools(server) {
195
198
  },
196
199
  }, async ({ account, siteUrl, startDate, endDate, dimensions, type, dimensionFilterGroups, rowLimit, startRow, aggregationType, dataState }) => {
197
200
  try {
198
- const auth = await getClient(account);
201
+ const auth = await getClientFn(account);
199
202
  const wm = webmastersClient({ version: 'v3', auth });
200
203
  const requestBody = { startDate, endDate };
201
204
  if (dimensions)
@@ -237,7 +240,7 @@ export function registerSearchConsoleTools(server) {
237
240
  },
238
241
  }, async ({ account, siteUrl, inspectionUrl, languageCode }) => {
239
242
  try {
240
- const auth = await getClient(account);
243
+ const auth = await getClientFn(account);
241
244
  const searchconsole = searchconsoleClient({ version: 'v1', auth });
242
245
  const res = await searchconsole.urlInspection.index.inspect({
243
246
  requestBody: {
@@ -1,5 +1,6 @@
1
1
  import type { ToolRegistry } from '../registry.js';
2
- export declare function registerSheetsTools(server: ToolRegistry): void;
2
+ import { type CuratedToolDeps } from '../client.js';
3
+ export declare function registerSheetsTools(server: ToolRegistry, deps?: CuratedToolDeps): void;
3
4
  export declare function buildCellFormat(input: {
4
5
  backgroundColor?: {
5
6
  red?: number;
@@ -1,11 +1,14 @@
1
1
  import { z } from 'zod';
2
2
  import { coerceArray, coerceBoolean, coerceJson } from './_coerce.js';
3
3
  import { sheets as sheetsClient } from '@googleapis/sheets';
4
- import { accountAliasSchema } from '../accounts.js';
4
+ import { accountArgLive } from '../accounts.js';
5
5
  import { getClient } from '../client.js';
6
6
  import { handleGoogleApiError, invalidParams } from './_errors.js';
7
- const accountEnum = accountAliasSchema.optional();
8
- export function registerSheetsTools(server) {
7
+ export function registerSheetsTools(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('sheets_create', {
10
13
  description: 'Create a new Google Sheets spreadsheet',
11
14
  inputSchema: {
@@ -16,7 +19,7 @@ export function registerSheetsTools(server) {
16
19
  },
17
20
  }, async ({ account, title, sheetTitles }) => {
18
21
  try {
19
- const auth = await getClient(account);
22
+ const auth = await getClientFn(account);
20
23
  const sheets = sheetsClient({ version: 'v4', auth });
21
24
  const requestBody = {
22
25
  properties: { title },
@@ -48,7 +51,7 @@ export function registerSheetsTools(server) {
48
51
  },
49
52
  }, async ({ account, spreadsheetId }) => {
50
53
  try {
51
- const auth = await getClient(account);
54
+ const auth = await getClientFn(account);
52
55
  const sheets = sheetsClient({ version: 'v4', auth });
53
56
  const res = await sheets.spreadsheets.get({
54
57
  spreadsheetId,
@@ -85,7 +88,7 @@ export function registerSheetsTools(server) {
85
88
  },
86
89
  }, async ({ account, spreadsheetId, range, valueRenderOption }) => {
87
90
  try {
88
- const auth = await getClient(account);
91
+ const auth = await getClientFn(account);
89
92
  const sheets = sheetsClient({ version: 'v4', auth });
90
93
  const res = await sheets.spreadsheets.values.get({
91
94
  spreadsheetId,
@@ -115,7 +118,7 @@ export function registerSheetsTools(server) {
115
118
  },
116
119
  }, async ({ account, spreadsheetId, range, values, valueInputOption }) => {
117
120
  try {
118
- const auth = await getClient(account);
121
+ const auth = await getClientFn(account);
119
122
  const sheets = sheetsClient({ version: 'v4', auth });
120
123
  const res = await sheets.spreadsheets.values.update({
121
124
  spreadsheetId,
@@ -148,7 +151,7 @@ export function registerSheetsTools(server) {
148
151
  },
149
152
  }, async ({ account, spreadsheetId, range, values, valueInputOption }) => {
150
153
  try {
151
- const auth = await getClient(account);
154
+ const auth = await getClientFn(account);
152
155
  const sheets = sheetsClient({ version: 'v4', auth });
153
156
  const res = await sheets.spreadsheets.values.append({
154
157
  spreadsheetId,
@@ -179,7 +182,7 @@ export function registerSheetsTools(server) {
179
182
  },
180
183
  }, async ({ account, spreadsheetId, range }) => {
181
184
  try {
182
- const auth = await getClient(account);
185
+ const auth = await getClientFn(account);
183
186
  const sheets = sheetsClient({ version: 'v4', auth });
184
187
  const res = await sheets.spreadsheets.values.clear({
185
188
  spreadsheetId,
@@ -208,7 +211,7 @@ export function registerSheetsTools(server) {
208
211
  },
209
212
  }, async ({ account, spreadsheetId, ranges, valueRenderOption }) => {
210
213
  try {
211
- const auth = await getClient(account);
214
+ const auth = await getClientFn(account);
212
215
  const sheets = sheetsClient({ version: 'v4', auth });
213
216
  const res = await sheets.spreadsheets.values.batchGet({
214
217
  spreadsheetId,
@@ -241,7 +244,7 @@ export function registerSheetsTools(server) {
241
244
  },
242
245
  }, async ({ account, spreadsheetId, data, valueInputOption }) => {
243
246
  try {
244
- const auth = await getClient(account);
247
+ const auth = await getClientFn(account);
245
248
  const sheets = sheetsClient({ version: 'v4', auth });
246
249
  const res = await sheets.spreadsheets.values.batchUpdate({
247
250
  spreadsheetId,
@@ -277,7 +280,7 @@ export function registerSheetsTools(server) {
277
280
  },
278
281
  }, async ({ account, spreadsheetId, title, rowCount, columnCount }) => {
279
282
  try {
280
- const auth = await getClient(account);
283
+ const auth = await getClientFn(account);
281
284
  const sheets = sheetsClient({ version: 'v4', auth });
282
285
  const res = await sheets.spreadsheets.batchUpdate({
283
286
  spreadsheetId,
@@ -318,7 +321,7 @@ export function registerSheetsTools(server) {
318
321
  },
319
322
  }, async ({ account, spreadsheetId, sheetId }) => {
320
323
  try {
321
- const auth = await getClient(account);
324
+ const auth = await getClientFn(account);
322
325
  const sheets = sheetsClient({ version: 'v4', auth });
323
326
  await sheets.spreadsheets.batchUpdate({
324
327
  spreadsheetId,
@@ -343,7 +346,7 @@ export function registerSheetsTools(server) {
343
346
  },
344
347
  }, async ({ account, spreadsheetId, sourceSheetId, newSheetName, insertSheetIndex }) => {
345
348
  try {
346
- const auth = await getClient(account);
349
+ const auth = await getClientFn(account);
347
350
  const sheets = sheetsClient({ version: 'v4', auth });
348
351
  const res = await sheets.spreadsheets.batchUpdate({
349
352
  spreadsheetId,
@@ -383,7 +386,7 @@ export function registerSheetsTools(server) {
383
386
  },
384
387
  }, async ({ account, spreadsheetId, sheetId, title, index, hidden, tabColor, frozenRowCount, frozenColumnCount, rowCount, columnCount }) => {
385
388
  try {
386
- const auth = await getClient(account);
389
+ const auth = await getClientFn(account);
387
390
  const sheets = sheetsClient({ version: 'v4', auth });
388
391
  const properties = { sheetId };
389
392
  const fields = [];
@@ -475,7 +478,7 @@ export function registerSheetsTools(server) {
475
478
  },
476
479
  }, async ({ account, spreadsheetId, range, ...format }) => {
477
480
  try {
478
- const auth = await getClient(account);
481
+ const auth = await getClientFn(account);
479
482
  const sheets = sheetsClient({ version: 'v4', auth });
480
483
  const built = buildCellFormat(format);
481
484
  if (built.fields.length === 0) {
@@ -516,7 +519,7 @@ export function registerSheetsTools(server) {
516
519
  },
517
520
  }, async ({ account, spreadsheetId, range, top, bottom, left, right, innerHorizontal, innerVertical }) => {
518
521
  try {
519
- const auth = await getClient(account);
522
+ const auth = await getClientFn(account);
520
523
  const sheets = sheetsClient({ version: 'v4', auth });
521
524
  const borders = { range };
522
525
  if (top)
@@ -556,7 +559,7 @@ export function registerSheetsTools(server) {
556
559
  },
557
560
  }, async ({ account, spreadsheetId, range, mergeType }) => {
558
561
  try {
559
- const auth = await getClient(account);
562
+ const auth = await getClientFn(account);
560
563
  const sheets = sheetsClient({ version: 'v4', auth });
561
564
  await sheets.spreadsheets.batchUpdate({
562
565
  spreadsheetId,
@@ -581,7 +584,7 @@ export function registerSheetsTools(server) {
581
584
  },
582
585
  }, async ({ account, spreadsheetId, range }) => {
583
586
  try {
584
- const auth = await getClient(account);
587
+ const auth = await getClientFn(account);
585
588
  const sheets = sheetsClient({ version: 'v4', auth });
586
589
  await sheets.spreadsheets.batchUpdate({
587
590
  spreadsheetId,
@@ -628,7 +631,7 @@ export function registerSheetsTools(server) {
628
631
  if (!booleanRule && !gradientRule) {
629
632
  return invalidParams(account, 'A conditional format rule needs a rule body: neither booleanRule nor gradientRule was supplied.', 'Pass booleanRule for a condition-based rule, or gradientRule for a color scale.');
630
633
  }
631
- const auth = await getClient(account);
634
+ const auth = await getClientFn(account);
632
635
  const sheets = sheetsClient({ version: 'v4', auth });
633
636
  const rule = { ranges };
634
637
  if (booleanRule) {
@@ -692,7 +695,7 @@ export function registerSheetsTools(server) {
692
695
  },
693
696
  }, async ({ account, spreadsheetId, range, sortSpecs }) => {
694
697
  try {
695
- const auth = await getClient(account);
698
+ const auth = await getClientFn(account);
696
699
  const sheets = sheetsClient({ version: 'v4', auth });
697
700
  await sheets.spreadsheets.batchUpdate({
698
701
  spreadsheetId,
@@ -724,7 +727,7 @@ export function registerSheetsTools(server) {
724
727
  },
725
728
  }, async ({ account, spreadsheetId, range, sortSpecs, filterSpecs }) => {
726
729
  try {
727
- const auth = await getClient(account);
730
+ const auth = await getClientFn(account);
728
731
  const sheets = sheetsClient({ version: 'v4', auth });
729
732
  const filter = { range };
730
733
  if (sortSpecs)
@@ -766,7 +769,7 @@ export function registerSheetsTools(server) {
766
769
  },
767
770
  }, async ({ account, spreadsheetId, sheetId }) => {
768
771
  try {
769
- const auth = await getClient(account);
772
+ const auth = await getClientFn(account);
770
773
  const sheets = sheetsClient({ version: 'v4', auth });
771
774
  await sheets.spreadsheets.batchUpdate({
772
775
  spreadsheetId,
@@ -799,7 +802,7 @@ export function registerSheetsTools(server) {
799
802
  },
800
803
  }, async ({ account, spreadsheetId, find, replacement, scope, sheetId, range, matchCase, matchEntireCell, searchByRegex, includeFormulas }) => {
801
804
  try {
802
- const auth = await getClient(account);
805
+ const auth = await getClientFn(account);
803
806
  const sheets = sheetsClient({ version: 'v4', auth });
804
807
  const findReplace = {
805
808
  find,
@@ -855,7 +858,7 @@ export function registerSheetsTools(server) {
855
858
  },
856
859
  }, async ({ account, spreadsheetId, sheetId, dimension, startIndex, endIndex }) => {
857
860
  try {
858
- const auth = await getClient(account);
861
+ const auth = await getClientFn(account);
859
862
  const sheets = sheetsClient({ version: 'v4', auth });
860
863
  const dimensions = { sheetId, dimension };
861
864
  if (startIndex !== undefined)
@@ -887,7 +890,7 @@ export function registerSheetsTools(server) {
887
890
  },
888
891
  }, async ({ account, spreadsheetId, sheetId, dimension, startIndex, endIndex, inheritFromBefore }) => {
889
892
  try {
890
- const auth = await getClient(account);
893
+ const auth = await getClientFn(account);
891
894
  const sheets = sheetsClient({ version: 'v4', auth });
892
895
  await sheets.spreadsheets.batchUpdate({
893
896
  spreadsheetId,
@@ -920,7 +923,7 @@ export function registerSheetsTools(server) {
920
923
  },
921
924
  }, async ({ account, spreadsheetId, sheetId, dimension, startIndex, endIndex }) => {
922
925
  try {
923
- const auth = await getClient(account);
926
+ const auth = await getClientFn(account);
924
927
  const sheets = sheetsClient({ version: 'v4', auth });
925
928
  await sheets.spreadsheets.batchUpdate({
926
929
  spreadsheetId,
@@ -955,7 +958,7 @@ export function registerSheetsTools(server) {
955
958
  },
956
959
  }, async ({ account, spreadsheetId, range, conditionType, conditionValues, inputMessage, strict, showCustomUi }) => {
957
960
  try {
958
- const auth = await getClient(account);
961
+ const auth = await getClientFn(account);
959
962
  const sheets = sheetsClient({ version: 'v4', auth });
960
963
  const rule = {
961
964
  condition: {
@@ -993,7 +996,7 @@ export function registerSheetsTools(server) {
993
996
  },
994
997
  }, async ({ account, spreadsheetId, name, range }) => {
995
998
  try {
996
- const auth = await getClient(account);
999
+ const auth = await getClientFn(account);
997
1000
  const sheets = sheetsClient({ version: 'v4', auth });
998
1001
  const res = await sheets.spreadsheets.batchUpdate({
999
1002
  spreadsheetId,
@@ -1019,7 +1022,7 @@ export function registerSheetsTools(server) {
1019
1022
  },
1020
1023
  }, async ({ account, spreadsheetId, namedRangeId }) => {
1021
1024
  try {
1022
- const auth = await getClient(account);
1025
+ const auth = await getClientFn(account);
1023
1026
  const sheets = sheetsClient({ version: 'v4', auth });
1024
1027
  await sheets.spreadsheets.batchUpdate({
1025
1028
  spreadsheetId,
@@ -1043,7 +1046,7 @@ export function registerSheetsTools(server) {
1043
1046
  },
1044
1047
  }, async ({ account, spreadsheetId, ranges }) => {
1045
1048
  try {
1046
- const auth = await getClient(account);
1049
+ const auth = await getClientFn(account);
1047
1050
  const sheets = sheetsClient({ version: 'v4', auth });
1048
1051
  const res = await sheets.spreadsheets.values.batchClear({
1049
1052
  spreadsheetId,
@@ -1073,7 +1076,7 @@ export function registerSheetsTools(server) {
1073
1076
  },
1074
1077
  }, async ({ account, spreadsheetId, requests, includeSpreadsheetInResponse, responseRanges, responseIncludeGridData }) => {
1075
1078
  try {
1076
- const auth = await getClient(account);
1079
+ const auth = await getClientFn(account);
1077
1080
  const sheets = sheetsClient({ version: 'v4', auth });
1078
1081
  const res = await sheets.spreadsheets.batchUpdate({
1079
1082
  spreadsheetId,
@@ -1,4 +1,13 @@
1
1
  import type { ToolRegistry } from '../registry.js';
2
- export declare function registerSlidesTools(server: ToolRegistry): void;
2
+ import type { Account } from '../accounts.js';
3
+ import { type CuratedToolDeps } from '../client.js';
4
+ export declare function registerSlidesTools(server: ToolRegistry, deps?: CuratedToolDeps): void;
3
5
  export declare function extractPageText(elements: Array<Record<string, any>> | undefined): string;
4
6
  export declare function summarizePresentation(p: Record<string, any>): Record<string, unknown>;
7
+ export declare function handleSlidesError(error: any, account: Account): {
8
+ content: {
9
+ type: "text";
10
+ text: string;
11
+ }[];
12
+ isError: true;
13
+ };
@@ -1,13 +1,16 @@
1
1
  import { z } from 'zod';
2
2
  import { slides as slidesClient } from '@googleapis/slides';
3
- import { accountAliasSchema } from '../accounts.js';
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
7
  import { sliceClean } from '../trim.js';
8
- const accountEnum = accountAliasSchema.optional();
9
8
  const SLIDE_TEXT_DIGEST_CHARS = 200;
10
- export function registerSlidesTools(server) {
9
+ export function registerSlidesTools(server, deps = {}) {
10
+ // Per-registry, live account enum + injectable client: the schema follows
11
+ // the registry's account view at parse time, not a process-global default.
12
+ const accountEnum = accountArgLive(() => server.accountAliases()).optional();
13
+ const getClientFn = deps.getClientFn ?? getClient;
11
14
  server.registerTool('slides_create', {
12
15
  description: 'Create a new Google Slides presentation (starts with one blank slide)',
13
16
  inputSchema: {
@@ -16,7 +19,7 @@ export function registerSlidesTools(server) {
16
19
  },
17
20
  }, async ({ account, title }) => {
18
21
  try {
19
- const auth = await getClient(account);
22
+ const auth = await getClientFn(account);
20
23
  const slides = slidesClient({ version: 'v1', auth });
21
24
  const res = await slides.presentations.create({ requestBody: { title } });
22
25
  return {
@@ -41,7 +44,7 @@ export function registerSlidesTools(server) {
41
44
  },
42
45
  }, async ({ account, presentationId, full }) => {
43
46
  try {
44
- const auth = await getClient(account);
47
+ const auth = await getClientFn(account);
45
48
  const slides = slidesClient({ version: 'v1', auth });
46
49
  const res = await slides.presentations.get({ presentationId });
47
50
  const payload = full ? res.data : summarizePresentation(res.data);
@@ -62,7 +65,7 @@ export function registerSlidesTools(server) {
62
65
  },
63
66
  }, async ({ account, presentationId, pageObjectId }) => {
64
67
  try {
65
- const auth = await getClient(account);
68
+ const auth = await getClientFn(account);
66
69
  const slides = slidesClient({ version: 'v1', auth });
67
70
  const res = await slides.presentations.pages.get({ presentationId, pageObjectId });
68
71
  return {
@@ -85,7 +88,7 @@ export function registerSlidesTools(server) {
85
88
  },
86
89
  }, async ({ account, presentationId, pageObjectId, mimeType, thumbnailSize }) => {
87
90
  try {
88
- const auth = await getClient(account);
91
+ const auth = await getClientFn(account);
89
92
  const slides = slidesClient({ version: 'v1', auth });
90
93
  const res = await slides.presentations.pages.getThumbnail({
91
94
  presentationId,
@@ -116,7 +119,7 @@ export function registerSlidesTools(server) {
116
119
  },
117
120
  }, async ({ account, presentationId, requests, writeControl }) => {
118
121
  try {
119
- const auth = await getClient(account);
122
+ const auth = await getClientFn(account);
120
123
  const slides = slidesClient({ version: 'v1', auth });
121
124
  const res = await slides.presentations.batchUpdate({
122
125
  presentationId,
@@ -180,6 +183,9 @@ export function summarizePresentation(p) {
180
183
  hint: 'Pass full:true for the raw Presentation JSON, or slides_page_get for one slide.',
181
184
  };
182
185
  }
183
- function handleSlidesError(error, account) {
184
- return handleGoogleApiError(error, account, "Slides tools require the optional \"slides\" scope bundle. Add GOOGLE_OPTIONAL_SCOPES=slides (or include \"slides\" in the list) and re-auth.");
186
+ export function handleSlidesError(error, account) {
187
+ return handleGoogleApiError(error, account, {
188
+ scope: "Slides tools require the optional \"slides\" scope bundle. Add GOOGLE_OPTIONAL_SCOPES=slides (or include \"slides\" in the list) and re-auth.",
189
+ bundle: 'slides',
190
+ });
185
191
  }
@@ -1,2 +1,3 @@
1
1
  import type { ToolRegistry } from '../registry.js';
2
- export declare function registerTasksTools(server: ToolRegistry): void;
2
+ import { type CuratedToolDeps } from '../client.js';
3
+ export declare function registerTasksTools(server: ToolRegistry, deps?: CuratedToolDeps): void;
@@ -1,11 +1,14 @@
1
1
  import { z } from 'zod';
2
2
  import { coerceBoolean } from './_coerce.js';
3
3
  import { tasks as tasksClient } from '@googleapis/tasks';
4
- import { accountAliasSchema } from '../accounts.js';
4
+ import { accountArgLive } from '../accounts.js';
5
5
  import { getClient } from '../client.js';
6
6
  import { handleGoogleApiError, invalidParams } from './_errors.js';
7
- const accountEnum = accountAliasSchema.optional();
8
- export function registerTasksTools(server) {
7
+ export function registerTasksTools(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
  // ─── Tasklists ─────────────────────────────────────────────────────────
10
13
  server.registerTool('tasks_lists_list', {
11
14
  description: 'List all tasklists (the user\'s top-level task containers)',
@@ -16,7 +19,7 @@ export function registerTasksTools(server) {
16
19
  },
17
20
  }, async ({ account, maxResults, pageToken }) => {
18
21
  try {
19
- const auth = await getClient(account);
22
+ const auth = await getClientFn(account);
20
23
  const tasks = tasksClient({ version: 'v1', auth });
21
24
  const res = await tasks.tasklists.list({
22
25
  maxResults: maxResults ?? 100,
@@ -38,7 +41,7 @@ export function registerTasksTools(server) {
38
41
  },
39
42
  }, async ({ account, tasklistId }) => {
40
43
  try {
41
- const auth = await getClient(account);
44
+ const auth = await getClientFn(account);
42
45
  const tasks = tasksClient({ version: 'v1', auth });
43
46
  const res = await tasks.tasklists.get({ tasklist: tasklistId });
44
47
  return {
@@ -57,7 +60,7 @@ export function registerTasksTools(server) {
57
60
  },
58
61
  }, async ({ account, title }) => {
59
62
  try {
60
- const auth = await getClient(account);
63
+ const auth = await getClientFn(account);
61
64
  const tasks = tasksClient({ version: 'v1', auth });
62
65
  const res = await tasks.tasklists.insert({
63
66
  requestBody: { title },
@@ -79,7 +82,7 @@ export function registerTasksTools(server) {
79
82
  },
80
83
  }, async ({ account, tasklistId, title }) => {
81
84
  try {
82
- const auth = await getClient(account);
85
+ const auth = await getClientFn(account);
83
86
  const tasks = tasksClient({ version: 'v1', auth });
84
87
  const res = await tasks.tasklists.patch({
85
88
  tasklist: tasklistId,
@@ -101,7 +104,7 @@ export function registerTasksTools(server) {
101
104
  },
102
105
  }, async ({ account, tasklistId }) => {
103
106
  try {
104
- const auth = await getClient(account);
107
+ const auth = await getClientFn(account);
105
108
  const tasks = tasksClient({ version: 'v1', auth });
106
109
  await tasks.tasklists.delete({ tasklist: tasklistId });
107
110
  return {
@@ -132,7 +135,7 @@ export function registerTasksTools(server) {
132
135
  },
133
136
  }, async ({ account, tasklistId, ...params }) => {
134
137
  try {
135
- const auth = await getClient(account);
138
+ const auth = await getClientFn(account);
136
139
  const tasks = tasksClient({ version: 'v1', auth });
137
140
  const res = await tasks.tasks.list({
138
141
  tasklist: tasklistId,
@@ -155,7 +158,7 @@ export function registerTasksTools(server) {
155
158
  },
156
159
  }, async ({ account, tasklistId, taskId }) => {
157
160
  try {
158
- const auth = await getClient(account);
161
+ const auth = await getClientFn(account);
159
162
  const tasks = tasksClient({ version: 'v1', auth });
160
163
  const res = await tasks.tasks.get({ tasklist: tasklistId, task: taskId });
161
164
  return {
@@ -180,7 +183,7 @@ export function registerTasksTools(server) {
180
183
  },
181
184
  }, async ({ account, tasklistId, title, notes, due, status, parent, previous }) => {
182
185
  try {
183
- const auth = await getClient(account);
186
+ const auth = await getClientFn(account);
184
187
  const tasks = tasksClient({ version: 'v1', auth });
185
188
  const requestBody = { title };
186
189
  if (notes !== undefined)
@@ -216,7 +219,7 @@ export function registerTasksTools(server) {
216
219
  },
217
220
  }, async ({ account, tasklistId, taskId, title, notes, due, status }) => {
218
221
  try {
219
- const auth = await getClient(account);
222
+ const auth = await getClientFn(account);
220
223
  const tasks = tasksClient({ version: 'v1', auth });
221
224
  const requestBody = {};
222
225
  if (title !== undefined)
@@ -252,7 +255,7 @@ export function registerTasksTools(server) {
252
255
  },
253
256
  }, async ({ account, tasklistId, taskId }) => {
254
257
  try {
255
- const auth = await getClient(account);
258
+ const auth = await getClientFn(account);
256
259
  const tasks = tasksClient({ version: 'v1', auth });
257
260
  await tasks.tasks.delete({ tasklist: tasklistId, task: taskId });
258
261
  return {
@@ -275,7 +278,7 @@ export function registerTasksTools(server) {
275
278
  },
276
279
  }, async ({ account, tasklistId, taskId, parent, previous, destinationTasklist }) => {
277
280
  try {
278
- const auth = await getClient(account);
281
+ const auth = await getClientFn(account);
279
282
  const tasks = tasksClient({ version: 'v1', auth });
280
283
  const res = await tasks.tasks.move({
281
284
  tasklist: tasklistId,
@@ -300,7 +303,7 @@ export function registerTasksTools(server) {
300
303
  },
301
304
  }, async ({ account, tasklistId }) => {
302
305
  try {
303
- const auth = await getClient(account);
306
+ const auth = await getClientFn(account);
304
307
  const tasks = tasksClient({ version: 'v1', auth });
305
308
  await tasks.tasks.clear({ tasklist: tasklistId });
306
309
  return {
package/dist/trim.d.ts CHANGED
@@ -6,6 +6,11 @@ export interface CappedText {
6
6
  }
7
7
  export declare function capText(text: string, maxChars: number, offset?: number): CappedText;
8
8
  export declare function sliceClean(text: string, max: number): string;
9
+ /** An untrusted value made fit for one log line: never throws, at most `max`
10
+ * characters of it (then `...(len=N)`), each unsafe character as a literal
11
+ * `\uXXXX`. Backslash stays as is, so a value already through here comes back
12
+ * unchanged and a clean short value keeps its exact text. */
13
+ export declare function logSafe(value: unknown, max: number): string;
9
14
  /** Largest prefix whose JSON encoding (the wrapping quotes included) fits
10
15
  * `maxEncoded`. Slicing raw characters overshoots whenever the text contains
11
16
  * quotes or backslashes, which JSON.stringify doubles: the escape hatch's
package/dist/trim.js CHANGED
@@ -11,6 +11,25 @@ export function sliceClean(text, max) {
11
11
  const sliced = text.slice(0, max);
12
12
  return /[\uD800-\uDBFF]$/.test(sliced) ? sliced.slice(0, -1) : sliced;
13
13
  }
14
+ // C0/C1/DEL can end a line or drive a terminal; bidi/invisible format
15
+ // controls make a line read differently from its bytes.
16
+ const LOG_UNSAFE = /[\p{Cc}\u061c\u200e\u200f\u202a-\u202e\u2028\u2029\u2066-\u2069]/gu;
17
+ /** An untrusted value made fit for one log line: never throws, at most `max`
18
+ * characters of it (then `...(len=N)`), each unsafe character as a literal
19
+ * `\uXXXX`. Backslash stays as is, so a value already through here comes back
20
+ * unchanged and a clean short value keeps its exact text. */
21
+ export function logSafe(value, max) {
22
+ let text;
23
+ try {
24
+ text = String(value);
25
+ }
26
+ catch {
27
+ return '<unprintable>';
28
+ }
29
+ const cut = text.length > max ? sliceClean(text, max) : text;
30
+ const escaped = cut.replace(LOG_UNSAFE, (c) => `\\u${c.charCodeAt(0).toString(16).padStart(4, '0')}`);
31
+ return cut === text ? escaped : `${escaped}...(len=${text.length})`;
32
+ }
14
33
  /** Largest prefix whose JSON encoding (the wrapping quotes included) fits
15
34
  * `maxEncoded`. Slicing raw characters overshoots whenever the text contains
16
35
  * quotes or backslashes, which JSON.stringify doubles: the escape hatch's