@dereekb/firebase-server 13.17.0 → 13.18.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.
package/mcp/index.esm.js CHANGED
@@ -15,7 +15,7 @@ function _class_call_check$5(instance, Constructor) {
15
15
  throw new TypeError("Cannot call a class as a function");
16
16
  }
17
17
  }
18
- function _define_property$8(obj, key, value) {
18
+ function _define_property$9(obj, key, value) {
19
19
  if (key in obj) {
20
20
  Object.defineProperty(obj, key, {
21
21
  value: value,
@@ -45,6 +45,23 @@ function _define_property$8(obj, key, value) {
45
45
  * Default `instructions` string advertised by the MCP server on the JSON-RPC `initialize`
46
46
  * handshake. Apps may override this via {@link McpModuleConfig.serverInstructions}.
47
47
  */ var DEFAULT_MCP_SERVER_INSTRUCTIONS = 'A set of call-model tools generated automatically.';
48
+ /**
49
+ * Default name of the auto-injected reason parameter added to every advertised MCP tool's input
50
+ * schema. See {@link McpReasonParameterConfig.parameterName}.
51
+ */ var DEFAULT_MCP_REASON_PARAMETER_NAME = 'reason';
52
+ /**
53
+ * Default maximum length (in characters) of the auto-injected reason parameter. Values longer than
54
+ * this are clamped server-side before being forwarded to analytics. See
55
+ * {@link McpReasonParameterConfig.maxLength}.
56
+ */ var DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH = 250;
57
+ /**
58
+ * Default required-ness of the auto-injected reason parameter. See
59
+ * {@link McpReasonParameterConfig.required}.
60
+ */ var DEFAULT_MCP_REASON_PARAMETER_REQUIRED = true;
61
+ /**
62
+ * Default description advertised for the auto-injected reason parameter on every tool's input schema.
63
+ * See {@link McpReasonParameterConfig.description}.
64
+ */ var DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION = 'A brief human-readable reason (≤250 chars) explaining why this tool is being called. Recorded for analytics/audit only; not part of the operation.';
48
65
  /**
49
66
  * Configuration for the firebase-server/mcp module.
50
67
  *
@@ -69,7 +86,7 @@ function _define_property$8(obj, key, value) {
69
86
  * discovery document. Claude custom-connector reads this to discover the OIDC issuer.
70
87
  *
71
88
  * @example 'https://api.example.com/oidc'
72
- */ _define_property$8(this, "oidcIssuer", void 0);
89
+ */ _define_property$9(this, "oidcIssuer", void 0);
73
90
  /**
74
91
  * The canonical resource URL of the MCP endpoint.
75
92
  *
@@ -77,19 +94,19 @@ function _define_property$8(obj, key, value) {
77
94
  * and used as the audience the access token's `aud` claim should match.
78
95
  *
79
96
  * @example 'https://api.example.com/mcp'
80
- */ _define_property$8(this, "mcpUrl", void 0);
97
+ */ _define_property$9(this, "mcpUrl", void 0);
81
98
  /**
82
99
  * Optional name advertised on the MCP `initialize` handshake. Defaults to
83
100
  * {@link DEFAULT_MCP_SERVER_NAME}.
84
- */ _define_property$8(this, "serverName", void 0);
101
+ */ _define_property$9(this, "serverName", void 0);
85
102
  /**
86
103
  * Optional version advertised on the MCP `initialize` handshake.
87
- */ _define_property$8(this, "serverVersion", void 0);
104
+ */ _define_property$9(this, "serverVersion", void 0);
88
105
  /**
89
106
  * Optional override for the `instructions` string passed to `new McpServer(...)` and
90
107
  * advertised on the JSON-RPC `initialize` handshake. Defaults to
91
108
  * {@link DEFAULT_MCP_SERVER_INSTRUCTIONS}.
92
- */ _define_property$8(this, "serverInstructions", void 0);
109
+ */ _define_property$9(this, "serverInstructions", void 0);
93
110
  /**
94
111
  * Absolute path to a pre-rendered MCP manifest JSON file produced by
95
112
  * `dbx-cli-generate-mcp-manifest`. When set, the runtime reads it once at
@@ -99,7 +116,7 @@ function _define_property$8(obj, key, value) {
99
116
  * Optional. When unset or the file is missing, the runtime falls back to
100
117
  * today's behavior (auto-generated descriptions, ArkType-derived input
101
118
  * schemas, no output schemas) and emits a single boot warning.
102
- */ _define_property$8(this, "mcpManifestPath", void 0);
119
+ */ _define_property$9(this, "mcpManifestPath", void 0);
103
120
  /**
104
121
  * Absolute path to a pre-rendered route manifest JSON file produced by
105
122
  * `dbx-cli-generate-route-manifest`. When set, the runtime reads it once at
@@ -109,7 +126,7 @@ function _define_property$8(obj, key, value) {
109
126
  * Optional. When unset or the file is missing, the runtime skips registering
110
127
  * `url-models` and emits a single boot warning when the path was set but
111
128
  * unreadable.
112
- */ _define_property$8(this, "mcpRouteManifestPath", void 0);
129
+ */ _define_property$9(this, "mcpRouteManifestPath", void 0);
113
130
  /**
114
131
  * When `true`, the MCP server only advertises tools whose effective read-only classification is `true`.
115
132
  *
@@ -119,19 +136,29 @@ function _define_property$8(obj, key, value) {
119
136
  *
120
137
  * The advertised `serverName` on the JSON-RPC `initialize` handshake is suffixed with
121
138
  * ` (read-only)` so the client surface reflects the mode.
122
- */ _define_property$8(this, "readOnly", void 0);
139
+ */ _define_property$9(this, "readOnly", void 0);
140
+ /**
141
+ * Controls the auto-injected `reason` parameter added to every advertised tool's input schema.
142
+ *
143
+ * Enabled by default (unset / `true` = defaults on). Pass a {@link McpReasonParameterConfig} object
144
+ * to tune `required`, `maxLength`, `description`, or `parameterName`, or `false` to disable it.
145
+ *
146
+ * When enabled, every advertised tool's `inputSchema` carries a required `reason` string the model
147
+ * fills with a short justification for the call. The value is forwarded to analytics and stripped
148
+ * from the dispatched handler body. See {@link McpReasonParameterConfig}.
149
+ */ _define_property$9(this, "reasonParameter", void 0);
123
150
  };
124
151
  /**
125
152
  * NestJS injection token for the optional {@link McpAuthRoleReader} provider.
126
153
  */ var MCP_AUTH_ROLE_READER = 'MCP_AUTH_ROLE_READER';
127
154
 
128
- function _type_of$4(obj) {
155
+ function _type_of$5(obj) {
129
156
  "@swc/helpers - typeof";
130
157
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
131
158
  }
132
159
  function __decorate(decorators, target, key, desc) {
133
160
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
134
- if ((typeof Reflect === "undefined" ? "undefined" : _type_of$4(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
161
+ if ((typeof Reflect === "undefined" ? "undefined" : _type_of$5(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
135
162
  else for(var i = decorators.length - 1; i >= 0; i--)if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
136
163
  return c > 3 && r && Object.defineProperty(target, key, r), r;
137
164
  }
@@ -145,6 +172,206 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
145
172
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
146
173
  };
147
174
 
175
+ function _array_like_to_array$a(arr, len) {
176
+ if (len == null || len > arr.length) len = arr.length;
177
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
178
+ return arr2;
179
+ }
180
+ function _array_without_holes$7(arr) {
181
+ if (Array.isArray(arr)) return _array_like_to_array$a(arr);
182
+ }
183
+ function _define_property$8(obj, key, value) {
184
+ if (key in obj) {
185
+ Object.defineProperty(obj, key, {
186
+ value: value,
187
+ enumerable: true,
188
+ configurable: true,
189
+ writable: true
190
+ });
191
+ } else {
192
+ obj[key] = value;
193
+ }
194
+ return obj;
195
+ }
196
+ function _iterable_to_array$7(iter) {
197
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
198
+ }
199
+ function _non_iterable_spread$7() {
200
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
201
+ }
202
+ function _object_spread$5(target) {
203
+ for(var i = 1; i < arguments.length; i++){
204
+ var source = arguments[i] != null ? arguments[i] : {};
205
+ var ownKeys = Object.keys(source);
206
+ if (typeof Object.getOwnPropertySymbols === "function") {
207
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
208
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
209
+ }));
210
+ }
211
+ ownKeys.forEach(function(key) {
212
+ _define_property$8(target, key, source[key]);
213
+ });
214
+ }
215
+ return target;
216
+ }
217
+ function ownKeys$3(object, enumerableOnly) {
218
+ var keys = Object.keys(object);
219
+ if (Object.getOwnPropertySymbols) {
220
+ var symbols = Object.getOwnPropertySymbols(object);
221
+ keys.push.apply(keys, symbols);
222
+ }
223
+ return keys;
224
+ }
225
+ function _object_spread_props$3(target, source) {
226
+ source = source != null ? source : {};
227
+ if (Object.getOwnPropertyDescriptors) {
228
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
229
+ } else {
230
+ ownKeys$3(Object(source)).forEach(function(key) {
231
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
232
+ });
233
+ }
234
+ return target;
235
+ }
236
+ function _to_consumable_array$7(arr) {
237
+ return _array_without_holes$7(arr) || _iterable_to_array$7(arr) || _unsupported_iterable_to_array$a(arr) || _non_iterable_spread$7();
238
+ }
239
+ function _type_of$4(obj) {
240
+ "@swc/helpers - typeof";
241
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
242
+ }
243
+ function _unsupported_iterable_to_array$a(o, minLen) {
244
+ if (!o) return;
245
+ if (typeof o === "string") return _array_like_to_array$a(o, minLen);
246
+ var n = Object.prototype.toString.call(o).slice(8, -1);
247
+ if (n === "Object" && o.constructor) n = o.constructor.name;
248
+ if (n === "Map" || n === "Set") return Array.from(n);
249
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$a(o, minLen);
250
+ }
251
+ /**
252
+ * Normalizes the app-supplied {@link McpModuleConfig.reasonParameter} value (object / boolean /
253
+ * undefined) into a fully-resolved {@link ResolvedMcpReasonParameterConfig} with the package defaults
254
+ * applied.
255
+ *
256
+ * - `undefined` / `true` → defaults, enabled.
257
+ * - `false` → defaults, but `enabled: false`.
258
+ * - object → per-field overrides on top of the defaults (`enabled` defaults to `true`).
259
+ *
260
+ * @param config - The raw config from {@link McpModuleConfig.reasonParameter}.
261
+ * @returns The resolved config with all defaults applied.
262
+ */ function resolveMcpReasonParameterConfig(config) {
263
+ var result;
264
+ if (config === false) {
265
+ result = {
266
+ enabled: false,
267
+ required: DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
268
+ maxLength: DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
269
+ description: DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
270
+ parameterName: DEFAULT_MCP_REASON_PARAMETER_NAME
271
+ };
272
+ } else if (config == null || config === true) {
273
+ result = {
274
+ enabled: true,
275
+ required: DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
276
+ maxLength: DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
277
+ description: DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
278
+ parameterName: DEFAULT_MCP_REASON_PARAMETER_NAME
279
+ };
280
+ } else {
281
+ var _config_enabled, _config_required, _config_maxLength, _config_description, _config_parameterName;
282
+ result = {
283
+ enabled: (_config_enabled = config.enabled) !== null && _config_enabled !== void 0 ? _config_enabled : true,
284
+ required: (_config_required = config.required) !== null && _config_required !== void 0 ? _config_required : DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
285
+ maxLength: (_config_maxLength = config.maxLength) !== null && _config_maxLength !== void 0 ? _config_maxLength : DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
286
+ description: (_config_description = config.description) !== null && _config_description !== void 0 ? _config_description : DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
287
+ parameterName: (_config_parameterName = config.parameterName) !== null && _config_parameterName !== void 0 ? _config_parameterName : DEFAULT_MCP_REASON_PARAMETER_NAME
288
+ };
289
+ }
290
+ return result;
291
+ }
292
+ /**
293
+ * Returns `true` when the JSON schema already declares a property named `name` under `properties`.
294
+ *
295
+ * Used as the collision guard so a handler that legitimately consumes its own field of the same name
296
+ * is never double-declared (schema injection) or stripped (arg extraction).
297
+ *
298
+ * @param schema - The candidate JSON schema object (may be `undefined`).
299
+ * @param name - The property name to look for.
300
+ * @returns Whether the schema's `properties` already contains `name`.
301
+ */ function mcpSchemaDeclaresProperty(schema, name) {
302
+ var properties = schema === null || schema === void 0 ? void 0 : schema.properties;
303
+ return properties != null && (typeof properties === "undefined" ? "undefined" : _type_of$4(properties)) === 'object' && Object.prototype.hasOwnProperty.call(properties, name);
304
+ }
305
+ /**
306
+ * Returns a NEW JSON schema object with the reason parameter property merged into `properties` (and
307
+ * appended to `required` when configured). Never mutates the input — the static wire schemas are
308
+ * shared module-level constants reused across requests.
309
+ *
310
+ * Self-skips (returns the input schema unchanged) when the config is disabled or the schema already
311
+ * declares the parameter name. Defensive against a non-object / missing-`properties` input.
312
+ *
313
+ * @param inputSchema - The tool's resolved input schema.
314
+ * @param resolved - The resolved reason-parameter config.
315
+ * @returns A new schema carrying the reason property, or the original schema when skipped.
316
+ */ function applyMcpReasonParameterToSchema(inputSchema, resolved) {
317
+ var result = inputSchema;
318
+ if (resolved.enabled && !mcpSchemaDeclaresProperty(inputSchema, resolved.parameterName)) {
319
+ var _base_type;
320
+ var base = (typeof inputSchema === "undefined" ? "undefined" : _type_of$4(inputSchema)) === 'object' && inputSchema != null ? inputSchema : {};
321
+ var existingProperties = _type_of$4(base.properties) === 'object' && base.properties != null ? base.properties : {};
322
+ var next = _object_spread_props$3(_object_spread$5({}, base), {
323
+ type: (_base_type = base.type) !== null && _base_type !== void 0 ? _base_type : 'object',
324
+ properties: _object_spread_props$3(_object_spread$5({}, existingProperties), _define_property$8({}, resolved.parameterName, {
325
+ type: 'string',
326
+ maxLength: resolved.maxLength,
327
+ description: resolved.description
328
+ }))
329
+ });
330
+ if (resolved.required) {
331
+ var existingRequired = Array.isArray(base.required) ? base.required : [];
332
+ next.required = existingRequired.includes(resolved.parameterName) ? _to_consumable_array$7(existingRequired) : _to_consumable_array$7(existingRequired).concat([
333
+ resolved.parameterName
334
+ ]);
335
+ }
336
+ result = next;
337
+ }
338
+ return result;
339
+ }
340
+ /**
341
+ * Splits the auto-injected reason value out of a tool call's raw arguments.
342
+ *
343
+ * When enabled and the tool did NOT declare its own field of the same name: shallow-copies the args,
344
+ * deletes the parameter key, and coerces + clamps the value to `maxLength` (the client is not trusted).
345
+ * An empty / absent value yields `reason: undefined`.
346
+ *
347
+ * Otherwise (disabled, or the handler legitimately owns the field) returns the args unchanged so a
348
+ * field the handler actually consumes is never stripped.
349
+ *
350
+ * @param args - The raw `tools/call` arguments.
351
+ * @param resolved - The resolved reason-parameter config.
352
+ * @param toolDeclaresOwnReason - Whether the tool's own input schema already declares the parameter.
353
+ * @returns The extracted reason plus the (possibly stripped) args to dispatch.
354
+ */ function extractMcpReasonFromArgs(args, resolved, toolDeclaresOwnReason) {
355
+ var result;
356
+ if (resolved.enabled && !toolDeclaresOwnReason && Object.prototype.hasOwnProperty.call(args, resolved.parameterName)) {
357
+ var rawValue = args[resolved.parameterName];
358
+ var nextArgs = _object_spread$5({}, args);
359
+ delete nextArgs[resolved.parameterName];
360
+ var stringValue = rawValue == null ? '' : String(rawValue);
361
+ var clamped = stringValue.length > resolved.maxLength ? stringValue.slice(0, resolved.maxLength) : stringValue;
362
+ result = {
363
+ reason: clamped.length > 0 ? clamped : undefined,
364
+ args: nextArgs
365
+ };
366
+ } else {
367
+ result = {
368
+ reason: undefined,
369
+ args: args
370
+ };
371
+ }
372
+ return result;
373
+ }
374
+
148
375
  function _class_call_check$4(instance, Constructor) {
149
376
  if (!(instance instanceof Constructor)) {
150
377
  throw new TypeError("Cannot call a class as a function");
@@ -947,6 +1174,46 @@ function _unsupported_iterable_to_array$8(o, minLen) {
947
1174
  */ function applyWriteMarker(description, annotations) {
948
1175
  return annotations.readOnlyHint === false ? "".concat(MCP_WRITE_TOOL_DESCRIPTION_PREFIX).concat(description) : description;
949
1176
  }
1177
+ /**
1178
+ * Assembles a statically-registered {@link McpToolDefinition} with consistent MCP annotations.
1179
+ *
1180
+ * Built-in tools (e.g. `whoami`, `model-get`, `batch-execute`) don't flow through
1181
+ * {@link buildToolFromCandidate}, so this is their analogous single source of truth: it derives the
1182
+ * read/write annotations from {@link BuildStaticToolDefinitionInput.effectiveReadOnly} via
1183
+ * {@link resolveMcpToolAnnotations}, applies the {@link MCP_WRITE_TOOL_DESCRIPTION_PREFIX} write
1184
+ * marker to the description, then mirrors the annotations onto both the definition's `annotations`
1185
+ * field and the frozen {@link McpToolDefinition.staticWireEntry}. Centralizing this guarantees no
1186
+ * built-in tool reaches `tools/list` un-annotated (which would surface as an uncategorized "other"
1187
+ * tool in clients that bucket by `readOnlyHint`).
1188
+ *
1189
+ * @param input - The tool identity, schemas, dispatch target, static handler, and read-only classification.
1190
+ * @returns A statically-registered {@link McpToolDefinition} to append to the MCP server factory's tool registry.
1191
+ */ function buildStaticToolDefinition(input) {
1192
+ var name = input.name, inputSchema = input.inputSchema, outputSchema = input.outputSchema, dispatch = input.dispatch, staticHandler = input.staticHandler, effectiveReadOnly = input.effectiveReadOnly, rule = input.rule;
1193
+ var annotations = resolveMcpToolAnnotations(effectiveReadOnly);
1194
+ var description = applyWriteMarker(input.description, annotations);
1195
+ return {
1196
+ name: name,
1197
+ description: description,
1198
+ inputSchema: inputSchema,
1199
+ outputSchema: outputSchema,
1200
+ annotations: annotations,
1201
+ dispatch: dispatch,
1202
+ staticHandler: staticHandler,
1203
+ filterMetadata: {
1204
+ visibilityKind: 'declarative',
1205
+ rule: rule !== null && rule !== void 0 ? rule : {},
1206
+ effectiveReadOnly: effectiveReadOnly
1207
+ },
1208
+ staticWireEntry: buildStaticWireEntry({
1209
+ name: name,
1210
+ description: description,
1211
+ inputSchema: inputSchema,
1212
+ outputSchema: outputSchema,
1213
+ annotations: annotations
1214
+ })
1215
+ };
1216
+ }
950
1217
  // MARK: Naming
951
1218
  /**
952
1219
  * The default specifier key used when a handler is not behind a specifier router.
@@ -1644,7 +1911,7 @@ function _ts_generator$5(thisArg, body) {
1644
1911
  };
1645
1912
  var name = MODEL_GET_TOOL_NAME;
1646
1913
  var description = 'Fetch one or more Firestore model documents by key or bare id. Values containing `/` are treated as full keys; bare ids are auto-promoted to `<collectionName>/<id>` for root models. Subcollection models require full keys.';
1647
- return {
1914
+ return buildStaticToolDefinition({
1648
1915
  name: name,
1649
1916
  description: description,
1650
1917
  inputSchema: MODEL_GET_INPUT_SCHEMA,
@@ -1654,20 +1921,11 @@ function _ts_generator$5(thisArg, body) {
1654
1921
  modelType: MODEL_GET_DISPATCH_MODEL_TYPE
1655
1922
  },
1656
1923
  staticHandler: handler,
1657
- filterMetadata: {
1658
- visibilityKind: 'declarative',
1659
- rule: {
1660
- requireAuthenticated: true
1661
- },
1662
- effectiveReadOnly: true
1663
- },
1664
- staticWireEntry: buildStaticWireEntry({
1665
- name: name,
1666
- description: description,
1667
- inputSchema: MODEL_GET_INPUT_SCHEMA,
1668
- outputSchema: MODEL_GET_OUTPUT_SCHEMA
1669
- })
1670
- };
1924
+ effectiveReadOnly: true,
1925
+ rule: {
1926
+ requireAuthenticated: true
1927
+ }
1928
+ });
1671
1929
  }
1672
1930
  // MARK: Handler
1673
1931
  function modelGetToolHandler(args, ctx, deps) {
@@ -1938,7 +2196,7 @@ function _object_spread$4(target) {
1938
2196
  }
1939
2197
  return target;
1940
2198
  }
1941
- function ownKeys$1(object, enumerableOnly) {
2199
+ function ownKeys$2(object, enumerableOnly) {
1942
2200
  var keys = Object.keys(object);
1943
2201
  if (Object.getOwnPropertySymbols) {
1944
2202
  var symbols = Object.getOwnPropertySymbols(object);
@@ -1946,12 +2204,12 @@ function ownKeys$1(object, enumerableOnly) {
1946
2204
  }
1947
2205
  return keys;
1948
2206
  }
1949
- function _object_spread_props$1(target, source) {
2207
+ function _object_spread_props$2(target, source) {
1950
2208
  source = source != null ? source : {};
1951
2209
  if (Object.getOwnPropertyDescriptors) {
1952
2210
  Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
1953
2211
  } else {
1954
- ownKeys$1(Object(source)).forEach(function(key) {
2212
+ ownKeys$2(Object(source)).forEach(function(key) {
1955
2213
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
1956
2214
  });
1957
2215
  }
@@ -2015,7 +2273,7 @@ function _unsupported_iterable_to_array$6(o, minLen) {
2015
2273
  var name = MODEL_INFO_TOOL_NAME;
2016
2274
  var count = deps.manifest.length;
2017
2275
  var description = "Browse the Firestore model catalog (".concat(count, " model").concat(count === 1 ? '' : 's', "). No args returns model groups + counts (start here). ") + '`model` (a modelType/identityConst/collectionPrefix string, or an array of them) returns full detail per match — misses are reported in `notFound`. ' + '`modelGroup` returns the summary list for that group. `all:true` returns the full catalog summary. ' + '`fields` (boolean) forces or suppresses persisted-field detail in list/multiple modes.';
2018
- return {
2276
+ return buildStaticToolDefinition({
2019
2277
  name: name,
2020
2278
  description: description,
2021
2279
  inputSchema: MODEL_INFO_INPUT_SCHEMA,
@@ -2025,20 +2283,11 @@ function _unsupported_iterable_to_array$6(o, minLen) {
2025
2283
  modelType: MODEL_INFO_DISPATCH_MODEL_TYPE
2026
2284
  },
2027
2285
  staticHandler: handler,
2028
- filterMetadata: {
2029
- visibilityKind: 'declarative',
2030
- rule: {
2031
- requireAuthenticated: true
2032
- },
2033
- effectiveReadOnly: true
2034
- },
2035
- staticWireEntry: buildStaticWireEntry({
2036
- name: name,
2037
- description: description,
2038
- inputSchema: MODEL_INFO_INPUT_SCHEMA,
2039
- outputSchema: MODEL_INFO_OUTPUT_SCHEMA
2040
- })
2041
- };
2286
+ effectiveReadOnly: true,
2287
+ rule: {
2288
+ requireAuthenticated: true
2289
+ }
2290
+ });
2042
2291
  }
2043
2292
  // MARK: Handler
2044
2293
  function modelInfoToolHandler(args, _ctx, deps) {
@@ -2142,7 +2391,7 @@ function resolveModelInfoOutput(input, manifest) {
2142
2391
  }
2143
2392
  }
2144
2393
  if (tables.length > 0) {
2145
- result = _object_spread_props$1(_object_spread$4({}, output), {
2394
+ result = _object_spread_props$2(_object_spread$4({}, output), {
2146
2395
  enums: tables
2147
2396
  });
2148
2397
  }
@@ -2196,7 +2445,7 @@ function parseModelInfoInput(args) {
2196
2445
  var modelGroup = parseModelGroupArg(args['modelGroup']);
2197
2446
  var all = parseBooleanArg(args['all'], 'all');
2198
2447
  var fields = parseBooleanArg(args['fields'], 'fields');
2199
- return _object_spread$4(_object_spread_props$1(_object_spread$4(_object_spread_props$1(_object_spread$4({}, modelQueries == null ? {} : {
2448
+ return _object_spread$4(_object_spread_props$2(_object_spread$4(_object_spread_props$2(_object_spread$4({}, modelQueries == null ? {} : {
2200
2449
  modelQueries: modelQueries
2201
2450
  }), {
2202
2451
  modelIsArray: Array.isArray(args['model'])
@@ -2694,7 +2943,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
2694
2943
  type: 'string',
2695
2944
  description: 'Present when `mode` is `"list"` from a `modelGroup` filter. The canonical group name.'
2696
2945
  },
2697
- model: _object_spread_props$1(_object_spread$4({}, MODEL_ROW_SCHEMA), {
2946
+ model: _object_spread_props$2(_object_spread$4({}, MODEL_ROW_SCHEMA), {
2698
2947
  description: 'Present when `mode` is `"single"`. The matched model entry (full detail unless `fields:false`).'
2699
2948
  }),
2700
2949
  notFound: {
@@ -2829,7 +3078,7 @@ function _object_spread$3(target) {
2829
3078
  };
2830
3079
  var name = MODEL_DECODE_TOOL_NAME;
2831
3080
  var description = 'Decode a Firestore model key ("prefix/id", or subcollection path "parentPrefix/parentId/childPrefix/childId") into { leaf, ancestors, unresolvedPrefixes } using the registered manifest ('.concat(deps.manifest.length, " model").concat(deps.manifest.length === 1 ? '' : 's', ").");
2832
- return {
3081
+ return buildStaticToolDefinition({
2833
3082
  name: name,
2834
3083
  description: description,
2835
3084
  inputSchema: MODEL_DECODE_INPUT_SCHEMA,
@@ -2839,20 +3088,11 @@ function _object_spread$3(target) {
2839
3088
  modelType: MODEL_DECODE_DISPATCH_MODEL_TYPE
2840
3089
  },
2841
3090
  staticHandler: handler,
2842
- filterMetadata: {
2843
- visibilityKind: 'declarative',
2844
- rule: {
2845
- requireAuthenticated: true
2846
- },
2847
- effectiveReadOnly: true
2848
- },
2849
- staticWireEntry: buildStaticWireEntry({
2850
- name: name,
2851
- description: description,
2852
- inputSchema: MODEL_DECODE_INPUT_SCHEMA,
2853
- outputSchema: MODEL_DECODE_OUTPUT_SCHEMA
2854
- })
2855
- };
3091
+ effectiveReadOnly: true,
3092
+ rule: {
3093
+ requireAuthenticated: true
3094
+ }
3095
+ });
2856
3096
  }
2857
3097
  // MARK: Handler
2858
3098
  function modelDecodeToolHandler(args, _ctx, deps) {
@@ -3059,7 +3299,7 @@ var MODEL_DECODE_OUTPUT_SCHEMA = {
3059
3299
  var name = ENUM_INFO_TOOL_NAME;
3060
3300
  var count = Object.keys(deps.enums).length;
3061
3301
  var description = "Look up enum value→label tables by name (".concat(count, " enum").concat(count === 1 ? '' : 's', ' registered). Pass `enum` (a string or array of enum declaration names, e.g. "JobWorkerTimesheetState") to decode the raw persisted integer/string values a model field stores. Misses are reported in `notFound`.');
3062
- return {
3302
+ return buildStaticToolDefinition({
3063
3303
  name: name,
3064
3304
  description: description,
3065
3305
  inputSchema: ENUM_INFO_INPUT_SCHEMA,
@@ -3069,20 +3309,11 @@ var MODEL_DECODE_OUTPUT_SCHEMA = {
3069
3309
  modelType: ENUM_INFO_DISPATCH_MODEL_TYPE
3070
3310
  },
3071
3311
  staticHandler: handler,
3072
- filterMetadata: {
3073
- visibilityKind: 'declarative',
3074
- rule: {
3075
- requireAuthenticated: true
3076
- },
3077
- effectiveReadOnly: true
3078
- },
3079
- staticWireEntry: buildStaticWireEntry({
3080
- name: name,
3081
- description: description,
3082
- inputSchema: ENUM_INFO_INPUT_SCHEMA,
3083
- outputSchema: ENUM_INFO_OUTPUT_SCHEMA
3084
- })
3085
- };
3312
+ effectiveReadOnly: true,
3313
+ rule: {
3314
+ requireAuthenticated: true
3315
+ }
3316
+ });
3086
3317
  }
3087
3318
  // MARK: Handler
3088
3319
  function enumInfoToolHandler(args, _ctx, deps) {
@@ -3345,7 +3576,7 @@ function _unsupported_iterable_to_array$5(o, minLen) {
3345
3576
  var name = WHOAMI_TOOL_NAME;
3346
3577
  var appLabel = (_ref = (_deps_auth_app = deps.auth.app) === null || _deps_auth_app === void 0 ? void 0 : _deps_auth_app.app) !== null && _ref !== void 0 ? _ref : 'this server';
3347
3578
  var description = "Reports the authenticated caller's uid, raw custom claims, and decoded role set for `".concat(appLabel, "`. Returns `authenticated: false` for anonymous callers. Claim descriptions are drawn from the build-time auth manifest; only keys actually present on the live token are detailed.");
3348
- return {
3579
+ return buildStaticToolDefinition({
3349
3580
  name: name,
3350
3581
  description: description,
3351
3582
  inputSchema: WHOAMI_INPUT_SCHEMA,
@@ -3355,18 +3586,9 @@ function _unsupported_iterable_to_array$5(o, minLen) {
3355
3586
  modelType: WHOAMI_DISPATCH_MODEL_TYPE
3356
3587
  },
3357
3588
  staticHandler: handler,
3358
- filterMetadata: {
3359
- visibilityKind: 'declarative',
3360
- rule: {},
3361
- effectiveReadOnly: true
3362
- },
3363
- staticWireEntry: buildStaticWireEntry({
3364
- name: name,
3365
- description: description,
3366
- inputSchema: WHOAMI_INPUT_SCHEMA,
3367
- outputSchema: WHOAMI_OUTPUT_SCHEMA
3368
- })
3369
- };
3589
+ effectiveReadOnly: true,
3590
+ rule: {}
3591
+ });
3370
3592
  }
3371
3593
  // MARK: Handler
3372
3594
  function whoamiToolHandler(ctx, deps) {
@@ -3762,7 +3984,7 @@ function _object_spread$1(target) {
3762
3984
  }
3763
3985
  return target;
3764
3986
  }
3765
- function ownKeys(object, enumerableOnly) {
3987
+ function ownKeys$1(object, enumerableOnly) {
3766
3988
  var keys = Object.keys(object);
3767
3989
  if (Object.getOwnPropertySymbols) {
3768
3990
  var symbols = Object.getOwnPropertySymbols(object);
@@ -3770,12 +3992,12 @@ function ownKeys(object, enumerableOnly) {
3770
3992
  }
3771
3993
  return keys;
3772
3994
  }
3773
- function _object_spread_props(target, source) {
3995
+ function _object_spread_props$1(target, source) {
3774
3996
  source = source != null ? source : {};
3775
3997
  if (Object.getOwnPropertyDescriptors) {
3776
3998
  Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
3777
3999
  } else {
3778
- ownKeys(Object(source)).forEach(function(key) {
4000
+ ownKeys$1(Object(source)).forEach(function(key) {
3779
4001
  Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
3780
4002
  });
3781
4003
  }
@@ -3929,7 +4151,7 @@ function _ts_generator$4(thisArg, body) {
3929
4151
  };
3930
4152
  var name = URL_MODELS_TOOL_NAME;
3931
4153
  var description = 'Decode an app URL (or path) into the Firestore models its page renders. Pass a URL like `https://app.example.co/worker/abc/timesheets/list`; the tool matches it against the build-time route manifest and returns each model type plus the concrete key (route params + `{authUid}` substituted). Use `models` to filter to specific types, `keysOnly` for just the resolved keys, or `load: true` to fetch the documents via the same permission-checked path as `model-get` (cannot combine `load` with `keysOnly`).';
3932
- return {
4154
+ return buildStaticToolDefinition({
3933
4155
  name: name,
3934
4156
  description: description,
3935
4157
  inputSchema: URL_MODELS_INPUT_SCHEMA,
@@ -3939,20 +4161,11 @@ function _ts_generator$4(thisArg, body) {
3939
4161
  modelType: URL_MODELS_DISPATCH_MODEL_TYPE
3940
4162
  },
3941
4163
  staticHandler: handler,
3942
- filterMetadata: {
3943
- visibilityKind: 'declarative',
3944
- rule: {
3945
- requireAuthenticated: true
3946
- },
3947
- effectiveReadOnly: true
3948
- },
3949
- staticWireEntry: buildStaticWireEntry({
3950
- name: name,
3951
- description: description,
3952
- inputSchema: URL_MODELS_INPUT_SCHEMA,
3953
- outputSchema: URL_MODELS_OUTPUT_SCHEMA
3954
- })
3955
- };
4164
+ effectiveReadOnly: true,
4165
+ rule: {
4166
+ requireAuthenticated: true
4167
+ }
4168
+ });
3956
4169
  }
3957
4170
  // MARK: Handler
3958
4171
  function urlModelsToolHandler(args, ctx, deps) {
@@ -4029,7 +4242,7 @@ function parseUrlModelsInput(args) {
4029
4242
  }
4030
4243
  currentUserUid = args.currentUserUid;
4031
4244
  }
4032
- return _object_spread$1(_object_spread_props(_object_spread$1({
4245
+ return _object_spread$1(_object_spread_props$1(_object_spread$1({
4033
4246
  url: url
4034
4247
  }, models === undefined ? {} : {
4035
4248
  models: models
@@ -4809,7 +5022,7 @@ function _ts_generator$3(thisArg, body) {
4809
5022
  };
4810
5023
  var name = BATCH_EXECUTE_TOOL_NAME;
4811
5024
  var description = 'Execute a batch of MCP operations server-side from an uploaded JSON/NDJSON file, returning a success/failure summary. Each line/element is an operation `{ call, modelType, specifier?, data }` matching any other write tool you could call individually. Generate the file with a script and upload it instead of invoking a per-record tool many times. Every operation is authorized against your visible tools before any run; a forbidden or malformed operation aborts the whole batch with nothing executed.';
4812
- return {
5025
+ return buildStaticToolDefinition({
4813
5026
  name: name,
4814
5027
  description: description,
4815
5028
  inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
@@ -4819,20 +5032,11 @@ function _ts_generator$3(thisArg, body) {
4819
5032
  modelType: BATCH_EXECUTE_DISPATCH_MODEL_TYPE
4820
5033
  },
4821
5034
  staticHandler: handler,
4822
- filterMetadata: {
4823
- visibilityKind: 'declarative',
4824
- rule: {
4825
- requireAuthenticated: true
4826
- },
4827
- effectiveReadOnly: false
4828
- },
4829
- staticWireEntry: buildStaticWireEntry({
4830
- name: name,
4831
- description: description,
4832
- inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
4833
- outputSchema: BATCH_EXECUTE_OUTPUT_SCHEMA
4834
- })
4835
- };
5035
+ effectiveReadOnly: false,
5036
+ rule: {
5037
+ requireAuthenticated: true
5038
+ }
5039
+ });
4836
5040
  }
4837
5041
  // MARK: Handler
4838
5042
  function batchExecuteToolHandler(args, ctx, deps) {
@@ -5536,6 +5740,25 @@ function _object_spread(target) {
5536
5740
  }
5537
5741
  return target;
5538
5742
  }
5743
+ function ownKeys(object, enumerableOnly) {
5744
+ var keys = Object.keys(object);
5745
+ if (Object.getOwnPropertySymbols) {
5746
+ var symbols = Object.getOwnPropertySymbols(object);
5747
+ keys.push.apply(keys, symbols);
5748
+ }
5749
+ return keys;
5750
+ }
5751
+ function _object_spread_props(target, source) {
5752
+ source = source != null ? source : {};
5753
+ if (Object.getOwnPropertyDescriptors) {
5754
+ Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
5755
+ } else {
5756
+ ownKeys(Object(source)).forEach(function(key) {
5757
+ Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
5758
+ });
5759
+ }
5760
+ return target;
5761
+ }
5539
5762
  function _sliced_to_array(arr, i) {
5540
5763
  return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest();
5541
5764
  }
@@ -5681,6 +5904,7 @@ var McpServerFactoryService_1;
5681
5904
  _define_property$3(this, "_manifestLoaded", false);
5682
5905
  _define_property$3(this, "_loggedSkips", false);
5683
5906
  _define_property$3(this, "_warnedMissingRoleReader", false);
5907
+ _define_property$3(this, "_resolvedReasonConfig", void 0);
5684
5908
  _define_property$3(this, "_analyticsService", void 0);
5685
5909
  this.mcpConfig = mcpConfig;
5686
5910
  this.dispatchService = dispatchService;
@@ -6383,11 +6607,32 @@ var McpServerFactoryService_1;
6383
6607
  },
6384
6608
  {
6385
6609
  /**
6610
+ * Resolves the app's reason-parameter config once and caches it for the process lifetime.
6611
+ *
6612
+ * The underlying {@link McpModuleConfig.reasonParameter} value is fixed at boot, so the normalized
6613
+ * form is safe to memoize and reuse across every `tools/list` and `tools/call`.
6614
+ *
6615
+ * @returns The resolved reason-parameter config (defaults applied).
6616
+ */ key: "_resolveReasonConfig",
6617
+ value: function _resolveReasonConfig() {
6618
+ var result = this._resolvedReasonConfig;
6619
+ if (result == null) {
6620
+ result = resolveMcpReasonParameterConfig(this.mcpConfig.reasonParameter);
6621
+ this._resolvedReasonConfig = result;
6622
+ }
6623
+ return result;
6624
+ }
6625
+ },
6626
+ {
6627
+ /**
6386
6628
  * Resolves the wire-shape `tools/list` entry for a single tool.
6387
6629
  *
6388
6630
  * Hot-path short-circuit: tools without a `toolDetailsBuilder` reuse the precomputed,
6389
6631
  * frozen {@link McpToolDefinition.staticWireEntry} verbatim — zero allocations per
6390
- * request for the common case.
6632
+ * request for the common case. When the auto-injected reason parameter is enabled (the
6633
+ * default), the entry is no longer returned frozen-verbatim: its `inputSchema` is wrapped
6634
+ * with the reason property per request (`tools/list` is low-frequency, so the allocation is
6635
+ * acceptable). Tools that already declare the parameter name are still reused verbatim.
6391
6636
  *
6392
6637
  * Tools that opted in to {@link McpToolDetailsBuilder} get a fresh wire entry built
6393
6638
  * from the builder's overrides. If the builder throws, the framework falls back to
@@ -6399,9 +6644,20 @@ var McpServerFactoryService_1;
6399
6644
  * @returns The wire-shape entry to emit for this tool on `tools/list`.
6400
6645
  */ key: "_buildToolListEntry",
6401
6646
  value: function _buildToolListEntry(tool, ctx, scopes) {
6647
+ var reasonConfig = this._resolveReasonConfig();
6402
6648
  var result;
6403
6649
  if (tool.toolDetailsBuilder == null) {
6404
6650
  result = tool.staticWireEntry;
6651
+ if (reasonConfig.enabled) {
6652
+ var reasoned = applyMcpReasonParameterToSchema(tool.staticWireEntry.inputSchema, reasonConfig);
6653
+ // applyMcpReasonParameterToSchema self-skips (returns the same reference) on collision, so the
6654
+ // frozen-verbatim hot path still holds for tools that already declare the parameter name.
6655
+ if (reasoned !== tool.staticWireEntry.inputSchema) {
6656
+ result = _object_spread_props(_object_spread({}, tool.staticWireEntry), {
6657
+ inputSchema: reasoned
6658
+ });
6659
+ }
6660
+ }
6405
6661
  } else {
6406
6662
  var description = tool.description;
6407
6663
  var inputSchema = tool.inputSchema;
@@ -6422,12 +6678,16 @@ var McpServerFactoryService_1;
6422
6678
  } catch (error) {
6423
6679
  this._logger.warn("MCP tool ".concat(tool.name, " toolDetails builder threw; falling back to defaults: ").concat(error.message));
6424
6680
  }
6681
+ var resolvedInputSchema = inputSchema !== null && inputSchema !== void 0 ? inputSchema : {
6682
+ type: 'object'
6683
+ };
6684
+ if (reasonConfig.enabled) {
6685
+ resolvedInputSchema = applyMcpReasonParameterToSchema(resolvedInputSchema, reasonConfig);
6686
+ }
6425
6687
  var wire = {
6426
6688
  name: tool.name,
6427
6689
  description: description,
6428
- inputSchema: inputSchema !== null && inputSchema !== void 0 ? inputSchema : {
6429
- type: 'object'
6430
- }
6690
+ inputSchema: resolvedInputSchema
6431
6691
  };
6432
6692
  if (tool.outputSchema != null) {
6433
6693
  wire.outputSchema = tool.outputSchema;
@@ -6457,14 +6717,20 @@ var McpServerFactoryService_1;
6457
6717
  * @returns The MCP tool response.
6458
6718
  */ function _handleToolCall(request, definitionsByName, ctx) {
6459
6719
  return _async_to_generator$2(function() {
6460
- var _request_params_arguments, _ctx_auth, toolName, definition, args, startedAt, outcome, isSuccessful, toolKind;
6720
+ var _request_params_arguments, _ctx_auth, toolName, definition, rawArgs, startedAt, reasonConfig, declaresOwn, _extractMcpReasonFromArgs, reason, args, outcome, isSuccessful, toolKind;
6461
6721
  return _ts_generator$2(this, function(_state) {
6462
6722
  switch(_state.label){
6463
6723
  case 0:
6464
6724
  toolName = request.params.name;
6465
6725
  definition = definitionsByName.get(toolName);
6466
- args = (_request_params_arguments = request.params.arguments) !== null && _request_params_arguments !== void 0 ? _request_params_arguments : {};
6726
+ rawArgs = (_request_params_arguments = request.params.arguments) !== null && _request_params_arguments !== void 0 ? _request_params_arguments : {};
6467
6727
  startedAt = Date.now();
6728
+ // Split the auto-injected reason out of the args: forward it to analytics, but never let it reach
6729
+ // the underlying handler. Tools that declare their own field of the same name keep it (driven by
6730
+ // the tool's own resolved inputSchema, not the reason-augmented wire schema).
6731
+ reasonConfig = this._resolveReasonConfig();
6732
+ declaresOwn = mcpSchemaDeclaresProperty(definition === null || definition === void 0 ? void 0 : definition.inputSchema, reasonConfig.parameterName);
6733
+ _extractMcpReasonFromArgs = extractMcpReasonFromArgs(rawArgs, reasonConfig, declaresOwn), reason = _extractMcpReasonFromArgs.reason, args = _extractMcpReasonFromArgs.args;
6468
6734
  if (!(definition == null)) return [
6469
6735
  3,
6470
6736
  1
@@ -6514,6 +6780,7 @@ var McpServerFactoryService_1;
6514
6780
  auth: ctx.auth,
6515
6781
  readOnly: this.mcpConfig.readOnly === true,
6516
6782
  args: args,
6783
+ reason: reason,
6517
6784
  isSuccessful: isSuccessful,
6518
6785
  error: outcome.error,
6519
6786
  durationMs: Date.now() - startedAt
@@ -7355,18 +7622,20 @@ var FirebaseServerMcpAnalyticsService_1;
7355
7622
  if (this._logEvents) {
7356
7623
  var uidSuffix = event.uid ? " uid=".concat(event.uid) : '';
7357
7624
  var durationSuffix = event.durationMs == null ? '' : " (".concat(event.durationMs, "ms)");
7625
+ var reasonSuffix = event.reason ? ' reason="'.concat(event.reason, '"') : '';
7358
7626
  var outcome = event.isSuccessful ? 'Succeeded' : 'Failed';
7359
- this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix));
7627
+ this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix).concat(reasonSuffix));
7360
7628
  }
7361
7629
  if (this.analyticsService != null) {
7362
- var _event_call, _event_modelType, _event_specifier;
7630
+ var _event_call, _event_modelType, _event_specifier, _event_reason;
7363
7631
  this.analyticsService.sendEventData(event.uid, this._eventName, {
7364
7632
  tool: event.toolName,
7365
7633
  toolKind: event.toolKind,
7366
7634
  call: (_event_call = event.call) !== null && _event_call !== void 0 ? _event_call : '',
7367
7635
  modelType: (_event_modelType = event.modelType) !== null && _event_modelType !== void 0 ? _event_modelType : '',
7368
7636
  specifier: (_event_specifier = event.specifier) !== null && _event_specifier !== void 0 ? _event_specifier : '',
7369
- success: event.isSuccessful
7637
+ success: event.isSuccessful,
7638
+ reason: (_event_reason = event.reason) !== null && _event_reason !== void 0 ? _event_reason : ''
7370
7639
  });
7371
7640
  }
7372
7641
  }
@@ -7453,4 +7722,4 @@ function _unsupported_iterable_to_array(o, minLen) {
7453
7722
  };
7454
7723
  }
7455
7724
 
7456
- export { BATCH_EXECUTE_DISPATCH_CALL, BATCH_EXECUTE_DISPATCH_MODEL_TYPE, BATCH_EXECUTE_TOOL_NAME, DEFAULT_BATCH_EXECUTE_MAX_PARALLEL, DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS, DEFAULT_MCP_ANALYTICS_EVENT_NAME, DEFAULT_MCP_PATH, DEFAULT_MCP_SERVER_INSTRUCTIONS, DEFAULT_MCP_SERVER_NAME, DEFAULT_SPECIFIER_KEY, DEFAULT_VOID_MCP_SUCCESS_VALUE, ENUM_INFO_DISPATCH_CALL, ENUM_INFO_DISPATCH_MODEL_TYPE, ENUM_INFO_TOOL_NAME, ENUM_TABLE_SCHEMA, FIREBASE_SERVER_MCP_ANALYTICS_CONFIG, FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerMcpAnalyticsService, MAX_BATCH_EXECUTE_FILE_BYTES, MAX_BATCH_EXECUTE_OPERATIONS, MCP_ANALYTICS_SERVICE, MCP_AUTH_ROLE_READER, MCP_CALL_TYPE_ABBREVIATIONS, MCP_MANIFEST_VERSION, MCP_MODEL_GET_BATCH_SIZE, MCP_TOOL_NAME_MAX_LENGTH, MCP_TOOL_NAME_WARN_LENGTH, MCP_WRITE_TOOL_DESCRIPTION_PREFIX, MODEL_DECODE_DISPATCH_CALL, MODEL_DECODE_DISPATCH_MODEL_TYPE, MODEL_DECODE_TOOL_NAME, MODEL_GET_DISPATCH_CALL, MODEL_GET_DISPATCH_MODEL_TYPE, MODEL_GET_TOOL_NAME, MODEL_INFO_DISPATCH_CALL, MODEL_INFO_DISPATCH_MODEL_TYPE, MODEL_INFO_GROUPS_HINT, MODEL_INFO_TOOL_NAME, MODEL_INFO_UNGROUPED_LABEL, McpAnalyticsService, McpController, McpModuleConfig, McpServerFactoryService, McpWellKnownController, ROUTE_MANIFEST_VERSION, URL_MODELS_DISPATCH_CALL, URL_MODELS_DISPATCH_MODEL_TYPE, URL_MODELS_TOOL_NAME, abbreviateMcpCallType, appMcpAnalyticsModuleMetadata, applyWriteMarker, batchOperationCoordKey, buildDefaultMcpToolDescription, buildDisambiguatedMcpToolName, buildMcpToolName, buildStaticWireEntry, classifyVisibility, createBatchExecuteTool, createEnumInfoTool, createModelDecodeTool, createModelGetTool, createModelInfoTool, createUrlModelsTool, decodeFirestoreModelKey, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, matchRouteManifestUrl, mcpManifestKey, mcpModuleMetadata, noopMcpAnalyticsService, parseUrlModelsPathname, resolveEffectiveReadOnly, resolveEnumInfoOutput, resolveMcpToolAnnotations, resolveRequiredScope, validateMcpToolName };
7725
+ export { BATCH_EXECUTE_DISPATCH_CALL, BATCH_EXECUTE_DISPATCH_MODEL_TYPE, BATCH_EXECUTE_TOOL_NAME, DEFAULT_BATCH_EXECUTE_MAX_PARALLEL, DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS, DEFAULT_MCP_ANALYTICS_EVENT_NAME, DEFAULT_MCP_PATH, DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION, DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH, DEFAULT_MCP_REASON_PARAMETER_NAME, DEFAULT_MCP_REASON_PARAMETER_REQUIRED, DEFAULT_MCP_SERVER_INSTRUCTIONS, DEFAULT_MCP_SERVER_NAME, DEFAULT_SPECIFIER_KEY, DEFAULT_VOID_MCP_SUCCESS_VALUE, ENUM_INFO_DISPATCH_CALL, ENUM_INFO_DISPATCH_MODEL_TYPE, ENUM_INFO_TOOL_NAME, ENUM_TABLE_SCHEMA, FIREBASE_SERVER_MCP_ANALYTICS_CONFIG, FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE, FirebaseServerMcpAnalyticsService, MAX_BATCH_EXECUTE_FILE_BYTES, MAX_BATCH_EXECUTE_OPERATIONS, MCP_ANALYTICS_SERVICE, MCP_AUTH_ROLE_READER, MCP_CALL_TYPE_ABBREVIATIONS, MCP_MANIFEST_VERSION, MCP_MODEL_GET_BATCH_SIZE, MCP_TOOL_NAME_MAX_LENGTH, MCP_TOOL_NAME_WARN_LENGTH, MCP_WRITE_TOOL_DESCRIPTION_PREFIX, MODEL_DECODE_DISPATCH_CALL, MODEL_DECODE_DISPATCH_MODEL_TYPE, MODEL_DECODE_TOOL_NAME, MODEL_GET_DISPATCH_CALL, MODEL_GET_DISPATCH_MODEL_TYPE, MODEL_GET_TOOL_NAME, MODEL_INFO_DISPATCH_CALL, MODEL_INFO_DISPATCH_MODEL_TYPE, MODEL_INFO_GROUPS_HINT, MODEL_INFO_TOOL_NAME, MODEL_INFO_UNGROUPED_LABEL, McpAnalyticsService, McpController, McpModuleConfig, McpServerFactoryService, McpWellKnownController, ROUTE_MANIFEST_VERSION, URL_MODELS_DISPATCH_CALL, URL_MODELS_DISPATCH_MODEL_TYPE, URL_MODELS_TOOL_NAME, abbreviateMcpCallType, appMcpAnalyticsModuleMetadata, applyMcpReasonParameterToSchema, applyWriteMarker, batchOperationCoordKey, buildDefaultMcpToolDescription, buildDisambiguatedMcpToolName, buildMcpToolName, buildStaticToolDefinition, buildStaticWireEntry, classifyVisibility, createBatchExecuteTool, createEnumInfoTool, createModelDecodeTool, createModelGetTool, createModelInfoTool, createUrlModelsTool, decodeFirestoreModelKey, extractMcpReasonFromArgs, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, matchRouteManifestUrl, mcpManifestKey, mcpModuleMetadata, mcpSchemaDeclaresProperty, noopMcpAnalyticsService, parseUrlModelsPathname, resolveEffectiveReadOnly, resolveEnumInfoOutput, resolveMcpReasonParameterConfig, resolveMcpToolAnnotations, resolveRequiredScope, validateMcpToolName };