@dereekb/firebase-server 13.12.9 → 13.14.0

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 (38) hide show
  1. package/index.cjs.js +1 -0
  2. package/index.esm.js +1 -0
  3. package/mailgun/package.json +9 -9
  4. package/mcp/index.cjs.js +633 -95
  5. package/mcp/index.esm.js +628 -96
  6. package/mcp/package.json +11 -11
  7. package/mcp/src/lib/service/mcp.manifest.d.ts +13 -0
  8. package/mcp/src/lib/service/mcp.response-formatter.d.ts +10 -6
  9. package/mcp/src/lib/service/mcp.server.factory.d.ts +24 -0
  10. package/mcp/src/lib/service/mcp.tool-generator.d.ts +194 -13
  11. package/model/index.cjs.js +209 -0
  12. package/model/index.esm.js +208 -2
  13. package/model/package.json +9 -9
  14. package/model/src/lib/storagefile/storagefile.action.server.d.ts +61 -1
  15. package/oidc/index.cjs.js +1025 -283
  16. package/oidc/index.esm.js +1016 -285
  17. package/oidc/package.json +10 -10
  18. package/oidc/src/lib/controller/oidc.interaction.controller.d.ts +4 -1
  19. package/oidc/src/lib/controller/oidc.provider.controller.d.ts +17 -0
  20. package/oidc/src/lib/oidc.config.d.ts +60 -0
  21. package/oidc/src/lib/service/analytics/index.d.ts +4 -0
  22. package/oidc/src/lib/service/analytics/oidc.analytics.config.d.ts +46 -0
  23. package/oidc/src/lib/service/analytics/oidc.analytics.handler.d.ts +116 -0
  24. package/oidc/src/lib/service/analytics/oidc.analytics.module.d.ts +35 -0
  25. package/oidc/src/lib/service/analytics/oidc.analytics.service.d.ts +23 -0
  26. package/oidc/src/lib/service/index.d.ts +1 -0
  27. package/oidc/src/lib/service/oidc.account.service.d.ts +15 -0
  28. package/oidc/src/lib/service/oidc.client.service.d.ts +4 -0
  29. package/oidc/src/lib/service/oidc.interaction.service.d.ts +2 -2
  30. package/oidc/src/lib/service/oidc.service.d.ts +23 -1
  31. package/oidc/src/lib/service/oidc.session-ttl.d.ts +114 -0
  32. package/package.json +10 -10
  33. package/src/lib/nest/model/api.details.d.ts +117 -32
  34. package/test/index.cjs.js +11 -3
  35. package/test/index.esm.js +11 -3
  36. package/test/package.json +11 -11
  37. package/twilio/package.json +8 -8
  38. package/zoho/package.json +9 -9
package/mcp/package.json CHANGED
@@ -1,17 +1,17 @@
1
1
  {
2
2
  "name": "@dereekb/firebase-server/mcp",
3
- "version": "13.12.9",
3
+ "version": "13.14.0",
4
4
  "peerDependencies": {
5
- "@dereekb/analytics": "13.12.9",
6
- "@dereekb/date": "13.12.9",
7
- "@dereekb/firebase": "13.12.9",
8
- "@dereekb/firebase-server": "13.12.9",
9
- "@dereekb/firebase-server/oidc": "13.12.9",
10
- "@dereekb/model": "13.12.9",
11
- "@dereekb/nestjs": "13.12.9",
12
- "@dereekb/rxjs": "13.12.9",
13
- "@dereekb/util": "13.12.9",
14
- "@dereekb/zoho": "13.12.9",
5
+ "@dereekb/analytics": "13.14.0",
6
+ "@dereekb/date": "13.14.0",
7
+ "@dereekb/firebase": "13.14.0",
8
+ "@dereekb/firebase-server": "13.14.0",
9
+ "@dereekb/firebase-server/oidc": "13.14.0",
10
+ "@dereekb/model": "13.14.0",
11
+ "@dereekb/nestjs": "13.14.0",
12
+ "@dereekb/rxjs": "13.14.0",
13
+ "@dereekb/util": "13.14.0",
14
+ "@dereekb/zoho": "13.14.0",
15
15
  "@modelcontextprotocol/sdk": "1.29.0",
16
16
  "@nestjs/common": "^11.1.19",
17
17
  "@nestjs/core": "^11.1.19",
@@ -18,6 +18,12 @@ export interface McpManifestToolEntry {
18
18
  readonly description?: string;
19
19
  readonly inputSchema?: object;
20
20
  readonly outputSchema?: object;
21
+ /**
22
+ * Name of the MCP-mapped result interface (from `@dbxModelApiMcpResult`) when the output schema was
23
+ * built from a mapped type. Used at boot to detect a `mapSuccessfulResult` handler whose `.api.ts`
24
+ * leaf was never annotated (the output schema would then describe the raw, un-mapped result).
25
+ */
26
+ readonly mcpResultTypeName?: string;
21
27
  }
22
28
  /**
23
29
  * One persisted field on a {@link McpManifestModelEntry}.
@@ -55,6 +61,13 @@ export interface McpManifestModelEntry {
55
61
  readonly sourcePackage: string;
56
62
  readonly sourceFile: string;
57
63
  readonly fields: readonly McpManifestModelField[];
64
+ /**
65
+ * Per-model override of the model segment used in generated MCP tool names (from
66
+ * `@dbxModelMcpToolNameSegment` on the model interface). When present it replaces the model type
67
+ * in tool names (e.g. the collection prefix), trading readability for shorter names. Absent when
68
+ * the model omits the tag — names then use the model type.
69
+ */
70
+ readonly mcpToolNameSegment?: string;
58
71
  /**
59
72
  * Read posture declared by `@dbxModelRead <level>` on the model interface (`system` /
60
73
  * `owner` / `admin-only` / `permissions`). Absent when the source model omits the tag.
@@ -13,20 +13,24 @@ export declare const DEFAULT_VOID_MCP_SUCCESS_VALUE: {
13
13
  /**
14
14
  * Resolves a dispatch result + handler API details into the MCP `CallToolResult` shape.
15
15
  *
16
+ * When `mcp.mapSuccessfulResult` is set, the raw result is first mapped (async-capable) to the value
17
+ * exposed via MCP; the tiers and the default path then operate on the mapped value. The tier
18
+ * callbacks receive `(value, context)` where `context` carries both the raw + mapped values + params.
19
+ *
16
20
  * Three-tier resolution as documented on {@link OnCallModelFunctionApiDetails.mcp}:
17
21
  *
18
22
  * - **Tier 3** — when `mcp.formatResponse` is set, its return value is used verbatim.
19
23
  * - **Tier 2** — when `mcp.summarizeResponse` is set, the summary string is wrapped into a
20
- * single text content block with the raw `result` exposed as `structuredContent`.
21
- * - **Tier 1** — default: JSON-stringify `result` as a single text content block, also
22
- * exposing the raw value as `structuredContent`.
24
+ * single text content block with the (mapped) value exposed as `structuredContent`.
25
+ * - **Tier 1** — default: JSON-stringify the (mapped) value as a single text content block, also
26
+ * exposing it as `structuredContent`.
23
27
  *
24
- * @param result - The handler's return value.
28
+ * @param result - The handler's raw return value.
25
29
  * @param params - The {@link OnCallTypedModelParams} that were dispatched.
26
- * @param details - The handler-level API details (carries Tier 2/3 formatters).
30
+ * @param details - The handler-level API details (carries the mapper + Tier 2/3 formatters).
27
31
  * @returns The MCP tool response content.
28
32
  */
29
- export declare function formatMcpToolResponse(result: unknown, params: OnCallTypedModelParams, details: OnCallModelFunctionApiDetails | undefined): McpToolResponseContent;
33
+ export declare function formatMcpToolResponse(result: unknown, params: OnCallTypedModelParams, details: OnCallModelFunctionApiDetails | undefined): Promise<McpToolResponseContent>;
30
34
  /**
31
35
  * Converts an error thrown from the dispatch chain into the MCP error response shape.
32
36
  *
@@ -53,6 +53,30 @@ export declare class McpServerFactoryService {
53
53
  * @returns The cached or freshly-generated tool generation result.
54
54
  */
55
55
  private _resolveToolDefinitions;
56
+ /**
57
+ * Builds the per-model tool-name segment overrides from the loaded manifest's `models` catalog.
58
+ *
59
+ * Sourcing the segments from the manifest (rather than runtime config) keeps the runtime in
60
+ * agreement with the build-time manifest validation, which reads the same `mcpToolNameSegment`.
61
+ *
62
+ * @returns Naming options carrying the segment map, or `undefined` when no model declares one.
63
+ */
64
+ private _resolveToolNamingOptions;
65
+ /**
66
+ * Logs one skipped tool at the appropriate level: name-cap and collision skips are errors (they
67
+ * would otherwise break or shadow tools on the wire), the rest are warnings.
68
+ *
69
+ * @param skip - The skipped-tool report to log.
70
+ */
71
+ private _logSkip;
72
+ /**
73
+ * Renders a human-readable boot-time warning for an MCP-result mapping inconsistency between a
74
+ * handler's `mapSuccessfulResult` and the build-time manifest.
75
+ *
76
+ * @param warning - The tool-generation warning to describe.
77
+ * @returns The log line to emit at startup.
78
+ */
79
+ private _describeToolGenerationWarning;
56
80
  /**
57
81
  * Builds the list of statically-registered (non-callModel) MCP tools.
58
82
  *
@@ -1,4 +1,5 @@
1
1
  import { type Maybe } from '@dereekb/util';
2
+ import { type KnownOnCallFunctionType } from '@dereekb/firebase';
2
3
  import { type ModelApiDetailsResult, type OnCallModelFunctionApiDetails, type FirebaseServerAuthData, type McpToolDetailsBuilder } from '@dereekb/firebase-server';
3
4
  import { type Request } from 'express';
4
5
  import { type CallToolResult } from '@modelcontextprotocol/sdk/types.js';
@@ -24,12 +25,14 @@ export interface McpToolDefinition {
24
25
  /**
25
26
  * Tool name advertised on `tools/list`.
26
27
  *
27
- * Format: `<modelType>-<callType>` for default (`_`) specifiers,
28
- * `<modelType>-<callType>-<specifier>` for non-default specifiers.
28
+ * Format: `<modelSegment>-<callType>` for default (`_`) specifiers; named specifiers drop the
29
+ * call-type segment (`<modelSegment>-<specifier>`) to stay short. When two visible tools would
30
+ * resolve to the same name, both are disambiguated with the abbreviated call type
31
+ * (`<modelSegment>-<abbrev>-<specifier>`); see {@link buildDisambiguatedMcpToolName}.
29
32
  *
30
33
  * @example 'guestbook-create'
31
- * @example 'profile-update-username'
32
- * @example 'storageFile-invoke-recomputeChecksums'
34
+ * @example 'profile-username'
35
+ * @example 'profile-u-username'
33
36
  */
34
37
  readonly name: string;
35
38
  /**
@@ -144,8 +147,15 @@ export interface JsonSchemaGenerationOptions {
144
147
  export declare const DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS: JsonSchemaGenerationOptions;
145
148
  /**
146
149
  * Reason a tool was skipped during generation.
150
+ *
151
+ * - `missing_input_type` — the handler has no `inputType` to build a schema from.
152
+ * - `schema_generation_failed` — `toJsonSchema()` threw for the handler's `inputType`.
153
+ * - `name_too_long` — the resolved name exceeds {@link MCP_TOOL_NAME_MAX_LENGTH}; advertising it
154
+ * would make remote clients reject the whole `tools/list` payload, so it is dropped.
155
+ * - `duplicate_name` — another already-registered visible tool resolved to the same name (e.g. two
156
+ * specifiers collide once the call-type segment is dropped); the later tool is dropped.
147
157
  */
148
- export type McpToolGenerationSkipReason = 'missing_input_type' | 'schema_generation_failed';
158
+ export type McpToolGenerationSkipReason = 'missing_input_type' | 'schema_generation_failed' | 'name_too_long' | 'duplicate_name';
149
159
  /**
150
160
  * One tool that was skipped during generation.
151
161
  */
@@ -155,6 +165,35 @@ export interface McpToolGenerationSkip {
155
165
  readonly dispatch: McpToolDispatchTarget;
156
166
  readonly error?: Error;
157
167
  }
168
+ /**
169
+ * Reason a generated tool's handler and build-time manifest disagree about MCP result mapping.
170
+ *
171
+ * - `mapper_without_mapped_manifest` — the handler declares `mcp.mapSuccessfulResult` but the
172
+ * manifest entry was not built from a mapped result type, i.e. the `.api.ts` leaf is missing its
173
+ * `@dbxModelApiMcpResult <TypeName>` annotation, so the advertised output schema describes the raw
174
+ * (un-mapped) result.
175
+ * - `mapped_manifest_without_mapper` — the manifest entry is annotated for a mapped result but the
176
+ * handler no longer declares `mapSuccessfulResult` (stale annotation).
177
+ *
178
+ * Both are runtime↔manifest consistency checks the build-time manifest renderer cannot perform on
179
+ * its own (it has the `.api.ts` annotation but not the handler's wired `mapSuccessfulResult`), so the
180
+ * runtime keeps them. Purely build-time-detectable conditions are deliberately *not* warned here to
181
+ * keep the server boot quiet:
182
+ * - Name length over the soft limit is surfaced by the manifest renderer, not at runtime (the hard
183
+ * cap is still enforced as a `name_too_long` skip).
184
+ * - A preferred name that collided with another visible tool is re-derived with the abbreviated call
185
+ * type ({@link buildDisambiguatedMcpToolName}) **silently** at runtime; the manifest renderer flags it.
186
+ */
187
+ export type McpToolGenerationWarningReason = 'mapper_without_mapped_manifest' | 'mapped_manifest_without_mapper';
188
+ /**
189
+ * One generated tool whose handler / manifest MCP-result mapping is inconsistent. The tool is still
190
+ * generated; the warning is surfaced so the caller can log the drift at startup.
191
+ */
192
+ export interface McpToolGenerationWarning {
193
+ readonly toolName: string;
194
+ readonly reason: McpToolGenerationWarningReason;
195
+ readonly dispatch: McpToolDispatchTarget;
196
+ }
158
197
  /**
159
198
  * Aggregated output of {@link generateMcpToolDefinitions}.
160
199
  */
@@ -174,6 +213,11 @@ export interface McpToolGenerationResult {
174
213
  * Surfaced so the caller can log them at startup.
175
214
  */
176
215
  readonly skipped: ReadonlyArray<McpToolGenerationSkip>;
216
+ /**
217
+ * Generated tools whose handler / manifest MCP-result mapping is inconsistent (only computed when a
218
+ * manifest is supplied). Surfaced so the caller can log the drift at startup.
219
+ */
220
+ readonly warnings: ReadonlyArray<McpToolGenerationWarning>;
177
221
  }
178
222
  interface BuildStaticWireEntryInput {
179
223
  readonly name: string;
@@ -196,17 +240,120 @@ export declare function buildStaticWireEntry(input: BuildStaticWireEntryInput):
196
240
  */
197
241
  export declare const DEFAULT_SPECIFIER_KEY = "_";
198
242
  /**
199
- * Builds the MCP tool name for a (modelType, callType, specifier) triple.
243
+ * Soft limit for an MCP tool name. Names longer than this still register, but the generator
244
+ * surfaces a `name_length_warning` so the drift toward the hard cap is visible at boot / build.
245
+ */
246
+ export declare const MCP_TOOL_NAME_WARN_LENGTH = 55;
247
+ /**
248
+ * Hard limit for an MCP tool name. Remote MCP clients reject a `tools/list` payload that contains
249
+ * any tool whose `name` exceeds this (`FrontendRemoteMcpToolDefinition.name: String should have at
250
+ * most 64 characters`), which fails the whole connection. Names over this are not registered.
251
+ */
252
+ export declare const MCP_TOOL_NAME_MAX_LENGTH = 64;
253
+ /**
254
+ * Severity of a tool name's length relative to {@link MCP_TOOL_NAME_WARN_LENGTH} /
255
+ * {@link MCP_TOOL_NAME_MAX_LENGTH}.
256
+ *
257
+ * - `error` — over the hard cap; the tool must not be advertised.
258
+ * - `warn` — over the soft limit but within the hard cap; advertised, but flagged.
259
+ * - `ok` — within the soft limit.
260
+ */
261
+ export type McpToolNameLengthLevel = 'ok' | 'warn' | 'error';
262
+ /**
263
+ * The outcome of validating a tool name's length.
264
+ */
265
+ export interface McpToolNameValidation {
266
+ readonly name: string;
267
+ readonly length: number;
268
+ readonly level: McpToolNameLengthLevel;
269
+ }
270
+ /**
271
+ * Classifies a tool name's length against the soft/hard MCP name-length limits.
272
+ *
273
+ * Shared by the runtime generator and the build-time manifest renderer so both apply the
274
+ * same thresholds and never drift.
275
+ *
276
+ * @param name - The fully-resolved tool name (including any per-handler override).
277
+ * @returns The length classification — `error` over {@link MCP_TOOL_NAME_MAX_LENGTH}, `warn` over
278
+ * {@link MCP_TOOL_NAME_WARN_LENGTH}, otherwise `ok`.
279
+ *
280
+ * @example
281
+ * ```ts
282
+ * validateMcpToolName('worker-create'); // { name: 'worker-create', length: 13, level: 'ok' }
283
+ * ```
284
+ */
285
+ export declare function validateMcpToolName(name: string): McpToolNameValidation;
286
+ /**
287
+ * Builds the MCP tool name for a (modelSegment, callType, specifier) triple.
200
288
  *
201
- * Apps can override the auto-generated name by setting
202
- * {@link OnCallModelFunctionApiDetails.mcp.name} on the handler.
289
+ * The call-type segment is only emitted for the default (`_`) specifier, where it carries the
290
+ * meaning (`worker-create`, `worker-update`). Named specifiers drop it — the specifier already
291
+ * disambiguates (`worker-syncCheckHqEmployee`), which keeps names short and within the MCP
292
+ * 64-character cap. Apps can override the whole name per handler via
293
+ * {@link OnCallModelFunctionApiDetails.mcp.name}.
203
294
  *
204
- * @param modelType - The Firestore model type (e.g., `storageFile`).
295
+ * This is the preferred (short) form. When two visible tools collide on it — two call types share a
296
+ * specifier once the call-type segment is dropped — the generator re-derives both names with
297
+ * {@link buildDisambiguatedMcpToolName} instead.
298
+ *
299
+ * @param modelSegment - The model segment of the name. Defaults to the model type, but may be a
300
+ * shorter per-model override (e.g. the collection prefix) resolved by the caller.
205
301
  * @param callType - The call type (e.g., `invoke`).
206
302
  * @param specifier - The specifier key, or `_` / undefined for the default entry.
207
303
  * @returns The hyphen-joined tool name advertised on `tools/list`.
304
+ *
305
+ * @example
306
+ * ```ts
307
+ * buildMcpToolName('worker', 'create'); // 'worker-create'
308
+ * buildMcpToolName('worker', 'update', 'syncCheckHqEmployee'); // 'worker-syncCheckHqEmployee'
309
+ * ```
310
+ */
311
+ export declare function buildMcpToolName(modelSegment: string, callType: string, specifier?: Maybe<string>): string;
312
+ /**
313
+ * Single-character abbreviations for the standard CRUDQ + invoke call types, used to disambiguate
314
+ * colliding tool names without re-introducing the full call-type segment everywhere.
315
+ *
316
+ * @example
317
+ * ```ts
318
+ * MCP_CALL_TYPE_ABBREVIATIONS.update; // 'u'
319
+ * ```
320
+ */
321
+ export declare const MCP_CALL_TYPE_ABBREVIATIONS: Readonly<Record<KnownOnCallFunctionType, string>>;
322
+ /**
323
+ * Abbreviates a call type for use in a disambiguated tool name. Known CRUDQ + invoke types collapse
324
+ * to a single character; a custom call type is returned unchanged so the name stays unambiguous.
325
+ *
326
+ * @param callType - The call type / verb.
327
+ * @returns The single-character abbreviation, or the original string for a custom call type.
328
+ *
329
+ * @example
330
+ * ```ts
331
+ * abbreviateMcpCallType('update'); // 'u'
332
+ * abbreviateMcpCallType('recompute'); // 'recompute'
333
+ * ```
334
+ */
335
+ export declare function abbreviateMcpCallType(callType: string): string;
336
+ /**
337
+ * Builds the disambiguated MCP tool name for a (modelSegment, callType, specifier) triple — the form
338
+ * used only when the preferred {@link buildMcpToolName} output collides with another visible tool.
339
+ *
340
+ * Named specifiers re-insert the call type, abbreviated, between the segment and specifier
341
+ * (`worker-u-syncCheckHqEmployee`); since the two colliding tools differ only by call type, their
342
+ * abbreviations differ and the names no longer clash. Default (`_`) specifiers already carry the
343
+ * full call type, so they are returned in their {@link buildMcpToolName} form unchanged.
344
+ *
345
+ * @param modelSegment - The model segment of the name (model type, or a per-model override).
346
+ * @param callType - The call type / verb.
347
+ * @param specifier - The specifier key, or `_` / undefined for the default entry.
348
+ * @returns The hyphen-joined disambiguated tool name.
349
+ *
350
+ * @example
351
+ * ```ts
352
+ * buildDisambiguatedMcpToolName('worker', 'update', 'syncCheckHqEmployee'); // 'worker-u-syncCheckHqEmployee'
353
+ * buildDisambiguatedMcpToolName('worker', 'create'); // 'worker-create'
354
+ * ```
208
355
  */
209
- export declare function buildMcpToolName(modelType: string, callType: string, specifier?: Maybe<string>): string;
356
+ export declare function buildDisambiguatedMcpToolName(modelSegment: string, callType: string, specifier?: Maybe<string>): string;
210
357
  /**
211
358
  * Builds the default description used when no build-time MCP manifest
212
359
  * entry is available for the (modelType, callType, specifier) tuple.
@@ -217,6 +364,32 @@ export declare function buildMcpToolName(modelType: string, callType: string, sp
217
364
  * @returns A human-readable fallback description for the tool.
218
365
  */
219
366
  export declare function buildDefaultMcpToolDescription(modelType: string, callType: string, specifier?: Maybe<string>): string;
367
+ /**
368
+ * Optional naming inputs for {@link generateMcpToolDefinitions}.
369
+ */
370
+ export interface McpToolGenerationNamingOptions {
371
+ /**
372
+ * Per-model override of the tool-name model segment, keyed by model type. When a model type is
373
+ * present, its segment (e.g. the collection prefix) replaces the model type in generated names;
374
+ * otherwise the model type is used.
375
+ */
376
+ readonly modelSegments?: ReadonlyMap<string, string>;
377
+ }
378
+ /**
379
+ * Optional build-time context for {@link generateMcpToolDefinitions}. Grouped into one object so the
380
+ * function stays at three parameters and new build-time inputs extend it rather than the arg list.
381
+ */
382
+ export interface GenerateMcpToolDefinitionsContext {
383
+ /**
384
+ * Build-time manifest map supplying overrides for descriptions and input/output schemas, keyed by
385
+ * {@link mcpManifestKey}.
386
+ */
387
+ readonly manifest?: ReadonlyMap<string, McpManifestToolEntry>;
388
+ /**
389
+ * Per-model name segment overrides (e.g. collection prefixes).
390
+ */
391
+ readonly naming?: McpToolGenerationNamingOptions;
392
+ }
220
393
  /**
221
394
  * Generates MCP tool definitions from a model-first API details tree.
222
395
  *
@@ -224,12 +397,20 @@ export declare function buildDefaultMcpToolDescription(modelType: string, callTy
224
397
  * `inputType.toJsonSchema(options)` for the schema, and applies any handler-level
225
398
  * MCP `name` override. Descriptions and input/output schemas are pulled from the
226
399
  * build-time manifest when supplied. Tools without an `inputType` are skipped and
227
- * reported so callers can log the gap at startup.
400
+ * reported so callers can log the gap at startup. Tools whose resolved name exceeds
401
+ * {@link MCP_TOOL_NAME_MAX_LENGTH} are skipped so the advertised `tools/list` stays valid.
402
+ *
403
+ * Generation runs in two passes so a name clash is known before any name is finalized: the first
404
+ * pass plans every candidate and counts how many visible auto-named tools share each preferred name;
405
+ * the second builds each tool, re-deriving the colliding ones with the abbreviated call type
406
+ * ({@link buildDisambiguatedMcpToolName}) so both survive instead of one shadowing the other. A
407
+ * residual collision that disambiguation cannot resolve (e.g. an `mcp.name` override matching an auto
408
+ * name) drops the later tool so the dispatch map stays unambiguous.
228
409
  *
229
410
  * @param apiDetails - The model-first API details tree returned by `getModelApiDetails(callModelFn)`.
230
411
  * @param options - Optional schema generation options forwarded to `toJsonSchema()`. Defaults to {@link DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS}.
231
- * @param manifest - Optional build-time manifest map; supplies overrides for descriptions and input/output schemas keyed by {@link mcpManifestKey}.
412
+ * @param context - Optional build-time context (manifest overrides + per-model name segments).
232
413
  * @returns The list of generated tool definitions plus any skip reports.
233
414
  */
234
- export declare function generateMcpToolDefinitions(apiDetails: ModelApiDetailsResult, options?: JsonSchemaGenerationOptions, manifest?: ReadonlyMap<string, McpManifestToolEntry>): McpToolGenerationResult;
415
+ export declare function generateMcpToolDefinitions(apiDetails: ModelApiDetailsResult, options?: JsonSchemaGenerationOptions, context?: GenerateMcpToolDefinitionsContext): McpToolGenerationResult;
235
416
  export {};
@@ -9425,6 +9425,8 @@ function _ts_generator$4(thisArg, body) {
9425
9425
  deleteStorageFile: deleteStorageFileFactory(context),
9426
9426
  downloadStorageFile: downloadStorageFileFactory(context),
9427
9427
  downloadMultipleStorageFiles: downloadMultipleStorageFilesFactory(context),
9428
+ readStorageFileMetadata: readStorageFileMetadataFactory(context),
9429
+ readMultipleStorageFilesMetadata: readMultipleStorageFilesMetadataFactory(context),
9428
9430
  createStorageFileGroup: createStorageFileGroupFactory(context),
9429
9431
  updateStorageFileGroup: updateStorageFileGroupFactory(context),
9430
9432
  syncStorageFileWithGroups: syncStorageFileWithGroupsFactory(context),
@@ -11027,6 +11029,210 @@ function _resolveSignedUploadUrlFilenameOrThrow(policy, filename) {
11027
11029
  })();
11028
11030
  });
11029
11031
  }
11032
+ /**
11033
+ * Default maximum number of concurrent metadata read operations when batch-reading StorageFile metadata.
11034
+ */ var DEFAULT_READ_MULTIPLE_STORAGE_FILES_METADATA_MAX_PARALLEL_TASKS = 5;
11035
+ /**
11036
+ * Internal factory that reads the underlying Cloud Storage object metadata for one or more StorageFiles.
11037
+ *
11038
+ * Uses {@link performAsyncTasks} with concurrency limiting to avoid overwhelming Cloud Storage.
11039
+ * When the underlying object does not exist, the item resolves with `exists: false` rather than failing.
11040
+ * When `throwOnFirstError` is true, the first failure throws immediately (single-read behavior).
11041
+ * When false, failures are collected in the errors array (batch behavior).
11042
+ *
11043
+ * @param context - The storage file server actions context.
11044
+ * @returns An async function that processes a {@link ReadMultipleStorageFilesMetadataFactoryInput} and returns a {@link ReadMultipleStorageFilesMetadataResult}
11045
+ */ function _readMultipleStorageFilesMetadataFactory(context) {
11046
+ var storageService = context.storageService, storageFileCollection = context.storageFileCollection;
11047
+ return function(input) {
11048
+ return _async_to_generator$4(function() {
11049
+ var items, throwOnFirstError, inputMaxParallelTasks, taskResult, success, errors;
11050
+ return _ts_generator$4(this, function(_state) {
11051
+ switch(_state.label){
11052
+ case 0:
11053
+ items = input.items, throwOnFirstError = input.throwOnFirstError, inputMaxParallelTasks = input.maxParallelTasks;
11054
+ return [
11055
+ 4,
11056
+ util.performAsyncTasks(items, function(item) {
11057
+ return _async_to_generator$4(function() {
11058
+ var _item_storageFileDocument, storageFileDocument, storageFile, fileAccessor, exists, result, metadata;
11059
+ return _ts_generator$4(this, function(_state) {
11060
+ switch(_state.label){
11061
+ case 0:
11062
+ // Load document from key if not provided
11063
+ storageFileDocument = (_item_storageFileDocument = item.storageFileDocument) !== null && _item_storageFileDocument !== void 0 ? _item_storageFileDocument : storageFileCollection.documentAccessor().loadDocumentForKey(item.key);
11064
+ return [
11065
+ 4,
11066
+ firebaseServer.assertSnapshotData(storageFileDocument)
11067
+ ];
11068
+ case 1:
11069
+ storageFile = _state.sent();
11070
+ fileAccessor = storageService.file(storageFile);
11071
+ return [
11072
+ 4,
11073
+ fileAccessor.exists()
11074
+ ];
11075
+ case 2:
11076
+ exists = _state.sent();
11077
+ if (!exists) return [
11078
+ 3,
11079
+ 4
11080
+ ];
11081
+ return [
11082
+ 4,
11083
+ fileAccessor.getMetadata()
11084
+ ];
11085
+ case 3:
11086
+ metadata = _state.sent();
11087
+ result = {
11088
+ key: item.key,
11089
+ exists: true,
11090
+ metadata: metadata
11091
+ };
11092
+ return [
11093
+ 3,
11094
+ 5
11095
+ ];
11096
+ case 4:
11097
+ result = {
11098
+ key: item.key,
11099
+ exists: false
11100
+ };
11101
+ _state.label = 5;
11102
+ case 5:
11103
+ return [
11104
+ 2,
11105
+ result
11106
+ ];
11107
+ }
11108
+ });
11109
+ })();
11110
+ }, {
11111
+ throwError: throwOnFirstError !== null && throwOnFirstError !== void 0 ? throwOnFirstError : false,
11112
+ maxParallelTasks: inputMaxParallelTasks !== null && inputMaxParallelTasks !== void 0 ? inputMaxParallelTasks : DEFAULT_READ_MULTIPLE_STORAGE_FILES_METADATA_MAX_PARALLEL_TASKS
11113
+ })
11114
+ ];
11115
+ case 1:
11116
+ taskResult = _state.sent();
11117
+ success = taskResult.results.map(function(param) {
11118
+ var _param = _sliced_to_array(param, 2), result = _param[1];
11119
+ return result;
11120
+ });
11121
+ errors = taskResult.errors.map(function(param) {
11122
+ var _param = _sliced_to_array(param, 2), item = _param[0], error = _param[1];
11123
+ return {
11124
+ key: item.key,
11125
+ error: _instanceof(error, Error) ? error.message : 'Metadata read failed'
11126
+ };
11127
+ });
11128
+ return [
11129
+ 2,
11130
+ {
11131
+ success: success,
11132
+ errors: errors
11133
+ }
11134
+ ];
11135
+ }
11136
+ });
11137
+ })();
11138
+ };
11139
+ }
11140
+ /**
11141
+ * Factory for the `readStorageFileMetadata` action.
11142
+ *
11143
+ * Reads the underlying Cloud Storage object metadata for a single {@link StorageFile}.
11144
+ * Delegates to {@link _readMultipleStorageFilesMetadataFactory} with a single item and `throwOnFirstError: true`.
11145
+ *
11146
+ * @param context - The storage file server actions context.
11147
+ * @returns An async transform-and-validate function that reads a StorageFile's Cloud Storage metadata.
11148
+ */ function readStorageFileMetadataFactory(context) {
11149
+ var firebaseServerActionTransformFunctionFactory = context.firebaseServerActionTransformFunctionFactory;
11150
+ var readMultipleStorageFilesMetadata = _readMultipleStorageFilesMetadataFactory(context);
11151
+ return firebaseServerActionTransformFunctionFactory(firebase.readStorageFileMetadataParamsType, function(params) {
11152
+ return _async_to_generator$4(function() {
11153
+ var key;
11154
+ return _ts_generator$4(this, function(_state) {
11155
+ key = params.key;
11156
+ return [
11157
+ 2,
11158
+ function(storageFileDocument) {
11159
+ return _async_to_generator$4(function() {
11160
+ var result;
11161
+ return _ts_generator$4(this, function(_state) {
11162
+ switch(_state.label){
11163
+ case 0:
11164
+ return [
11165
+ 4,
11166
+ readMultipleStorageFilesMetadata({
11167
+ items: [
11168
+ {
11169
+ key: key,
11170
+ storageFileDocument: storageFileDocument
11171
+ }
11172
+ ],
11173
+ throwOnFirstError: true
11174
+ })
11175
+ ];
11176
+ case 1:
11177
+ result = _state.sent();
11178
+ // success item structurally satisfies ReadStorageFileMetadataResult (extra `key` is ignored)
11179
+ return [
11180
+ 2,
11181
+ result.success[0]
11182
+ ];
11183
+ }
11184
+ });
11185
+ })();
11186
+ }
11187
+ ];
11188
+ });
11189
+ })();
11190
+ });
11191
+ }
11192
+ /**
11193
+ * Factory for the `readMultipleStorageFilesMetadata` action.
11194
+ *
11195
+ * Reads the underlying Cloud Storage object metadata for multiple {@link StorageFile} documents in a single call.
11196
+ * By default, individual failures are collected in the errors array rather than failing the entire batch.
11197
+ * Set `throwOnFirstError` in params to throw on the first failure instead.
11198
+ *
11199
+ * @param context - The storage file server actions context.
11200
+ * @returns An async transform-and-validate function that reads Cloud Storage metadata for multiple files.
11201
+ */ function readMultipleStorageFilesMetadataFactory(context) {
11202
+ var firebaseServerActionTransformFunctionFactory = context.firebaseServerActionTransformFunctionFactory;
11203
+ var readMultipleStorageFilesMetadata = _readMultipleStorageFilesMetadataFactory(context);
11204
+ return firebaseServerActionTransformFunctionFactory(firebase.readMultipleStorageFilesMetadataParamsType, function(params) {
11205
+ return _async_to_generator$4(function() {
11206
+ var files, throwOnFirstError;
11207
+ return _ts_generator$4(this, function(_state) {
11208
+ files = params.files, throwOnFirstError = params.throwOnFirstError;
11209
+ return [
11210
+ 2,
11211
+ function(storageFileDocuments) {
11212
+ return _async_to_generator$4(function() {
11213
+ var items;
11214
+ return _ts_generator$4(this, function(_state) {
11215
+ items = files.map(function(file, i) {
11216
+ return {
11217
+ key: file.key,
11218
+ storageFileDocument: storageFileDocuments === null || storageFileDocuments === void 0 ? void 0 : storageFileDocuments[i]
11219
+ };
11220
+ });
11221
+ return [
11222
+ 2,
11223
+ readMultipleStorageFilesMetadata({
11224
+ items: items,
11225
+ throwOnFirstError: throwOnFirstError !== null && throwOnFirstError !== void 0 ? throwOnFirstError : false
11226
+ })
11227
+ ];
11228
+ });
11229
+ })();
11230
+ }
11231
+ ];
11232
+ });
11233
+ })();
11234
+ });
11235
+ }
11030
11236
  /**
11031
11237
  * Internal factory that creates a function for creating a {@link StorageFileGroup} document
11032
11238
  * within a Firestore transaction.
@@ -14050,6 +14256,7 @@ exports.DEFAULT_COMPRESS_PDF_IMAGE_QUALITY = DEFAULT_COMPRESS_PDF_IMAGE_QUALITY;
14050
14256
  exports.DEFAULT_COMPRESS_PDF_IMAGE_SIZE_THRESHOLD_BYTES = DEFAULT_COMPRESS_PDF_IMAGE_SIZE_THRESHOLD_BYTES;
14051
14257
  exports.DEFAULT_DOWNLOAD_MULTIPLE_STORAGE_FILES_MAX_PARALLEL_TASKS = DEFAULT_DOWNLOAD_MULTIPLE_STORAGE_FILES_MAX_PARALLEL_TASKS;
14052
14258
  exports.DEFAULT_MAILGUN_NOTIFICATION_EMAIL_SEND_SERVICE_MAX_BATCH_SIZE_PER_REQUEST = DEFAULT_MAILGUN_NOTIFICATION_EMAIL_SEND_SERVICE_MAX_BATCH_SIZE_PER_REQUEST;
14259
+ exports.DEFAULT_READ_MULTIPLE_STORAGE_FILES_METADATA_MAX_PARALLEL_TASKS = DEFAULT_READ_MULTIPLE_STORAGE_FILES_METADATA_MAX_PARALLEL_TASKS;
14053
14260
  exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS = KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_DELETE_AFTER_RETRY_ATTEMPTS;
14054
14261
  exports.KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY = KNOWN_BUT_UNCONFIGURED_NOTIFICATION_TEMPLATE_TYPE_HOURS_DELAY;
14055
14262
  exports.MAKE_TEMPLATE_FOR_NOTIFICATION_RELATED_MODEL_INITIALIZATION_FUNCTION_DELETE_RESPONSE = MAKE_TEMPLATE_FOR_NOTIFICATION_RELATED_MODEL_INITIALIZATION_FUNCTION_DELETE_RESPONSE;
@@ -14149,6 +14356,8 @@ exports.processAllQueuedStorageFilesFactory = processAllQueuedStorageFilesFactor
14149
14356
  exports.processStorageFileFactory = processStorageFileFactory;
14150
14357
  exports.provideMutableNotificationExpediteService = provideMutableNotificationExpediteService;
14151
14358
  exports.queryAndFlagStorageFilesForDelete = queryAndFlagStorageFilesForDelete;
14359
+ exports.readMultipleStorageFilesMetadataFactory = readMultipleStorageFilesMetadataFactory;
14360
+ exports.readStorageFileMetadataFactory = readStorageFileMetadataFactory;
14152
14361
  exports.regenerateAllFlaggedStorageFileGroupsContentFactory = regenerateAllFlaggedStorageFileGroupsContentFactory;
14153
14362
  exports.regenerateStorageFileGroupContentFactory = regenerateStorageFileGroupContentFactory;
14154
14363
  exports.resyncAllNotificationUsersFactory = resyncAllNotificationUsersFactory;