@dereekb/firebase-server 13.16.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/index.cjs.js +24 -1
- package/index.esm.js +24 -1
- package/mailgun/package.json +9 -9
- package/mcp/index.cjs.js +2314 -333
- package/mcp/index.esm.js +2290 -334
- package/mcp/package.json +11 -11
- package/mcp/src/lib/mcp.config.d.ts +82 -0
- package/mcp/src/lib/service/analytics/mcp.analytics.handler.d.ts +8 -1
- package/mcp/src/lib/service/index.d.ts +4 -0
- package/mcp/src/lib/service/mcp.manifest.d.ts +29 -0
- package/mcp/src/lib/service/mcp.reason.d.ts +80 -0
- package/mcp/src/lib/service/mcp.route-manifest.d.ts +120 -0
- package/mcp/src/lib/service/mcp.server.factory.d.ts +28 -1
- package/mcp/src/lib/service/mcp.tool-generator.d.ts +65 -2
- package/mcp/src/lib/service/mcp.visibility.d.ts +17 -0
- package/mcp/src/lib/service/tools/mcp.tool.enum-info.d.ts +70 -0
- package/mcp/src/lib/service/tools/mcp.tool.model-info.d.ts +51 -2
- package/mcp/src/lib/service/tools/mcp.tool.url-models.d.ts +101 -0
- package/model/package.json +9 -9
- package/oidc/package.json +10 -10
- package/package.json +10 -10
- package/src/lib/nest/controller/model/model.api.get.service.d.ts +5 -0
- package/test/package.json +11 -11
- package/twilio/package.json +8 -8
- package/zoho/package.json +9 -9
package/mcp/index.cjs.js
CHANGED
|
@@ -17,7 +17,7 @@ function _class_call_check$5(instance, Constructor) {
|
|
|
17
17
|
throw new TypeError("Cannot call a class as a function");
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
function _define_property$
|
|
20
|
+
function _define_property$9(obj, key, value) {
|
|
21
21
|
if (key in obj) {
|
|
22
22
|
Object.defineProperty(obj, key, {
|
|
23
23
|
value: value,
|
|
@@ -47,6 +47,23 @@ function _define_property$7(obj, key, value) {
|
|
|
47
47
|
* Default `instructions` string advertised by the MCP server on the JSON-RPC `initialize`
|
|
48
48
|
* handshake. Apps may override this via {@link McpModuleConfig.serverInstructions}.
|
|
49
49
|
*/ var DEFAULT_MCP_SERVER_INSTRUCTIONS = 'A set of call-model tools generated automatically.';
|
|
50
|
+
/**
|
|
51
|
+
* Default name of the auto-injected reason parameter added to every advertised MCP tool's input
|
|
52
|
+
* schema. See {@link McpReasonParameterConfig.parameterName}.
|
|
53
|
+
*/ var DEFAULT_MCP_REASON_PARAMETER_NAME = 'reason';
|
|
54
|
+
/**
|
|
55
|
+
* Default maximum length (in characters) of the auto-injected reason parameter. Values longer than
|
|
56
|
+
* this are clamped server-side before being forwarded to analytics. See
|
|
57
|
+
* {@link McpReasonParameterConfig.maxLength}.
|
|
58
|
+
*/ var DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH = 250;
|
|
59
|
+
/**
|
|
60
|
+
* Default required-ness of the auto-injected reason parameter. See
|
|
61
|
+
* {@link McpReasonParameterConfig.required}.
|
|
62
|
+
*/ var DEFAULT_MCP_REASON_PARAMETER_REQUIRED = true;
|
|
63
|
+
/**
|
|
64
|
+
* Default description advertised for the auto-injected reason parameter on every tool's input schema.
|
|
65
|
+
* See {@link McpReasonParameterConfig.description}.
|
|
66
|
+
*/ 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.';
|
|
50
67
|
/**
|
|
51
68
|
* Configuration for the firebase-server/mcp module.
|
|
52
69
|
*
|
|
@@ -71,7 +88,7 @@ function _define_property$7(obj, key, value) {
|
|
|
71
88
|
* discovery document. Claude custom-connector reads this to discover the OIDC issuer.
|
|
72
89
|
*
|
|
73
90
|
* @example 'https://api.example.com/oidc'
|
|
74
|
-
*/ _define_property$
|
|
91
|
+
*/ _define_property$9(this, "oidcIssuer", void 0);
|
|
75
92
|
/**
|
|
76
93
|
* The canonical resource URL of the MCP endpoint.
|
|
77
94
|
*
|
|
@@ -79,19 +96,19 @@ function _define_property$7(obj, key, value) {
|
|
|
79
96
|
* and used as the audience the access token's `aud` claim should match.
|
|
80
97
|
*
|
|
81
98
|
* @example 'https://api.example.com/mcp'
|
|
82
|
-
*/ _define_property$
|
|
99
|
+
*/ _define_property$9(this, "mcpUrl", void 0);
|
|
83
100
|
/**
|
|
84
101
|
* Optional name advertised on the MCP `initialize` handshake. Defaults to
|
|
85
102
|
* {@link DEFAULT_MCP_SERVER_NAME}.
|
|
86
|
-
*/ _define_property$
|
|
103
|
+
*/ _define_property$9(this, "serverName", void 0);
|
|
87
104
|
/**
|
|
88
105
|
* Optional version advertised on the MCP `initialize` handshake.
|
|
89
|
-
*/ _define_property$
|
|
106
|
+
*/ _define_property$9(this, "serverVersion", void 0);
|
|
90
107
|
/**
|
|
91
108
|
* Optional override for the `instructions` string passed to `new McpServer(...)` and
|
|
92
109
|
* advertised on the JSON-RPC `initialize` handshake. Defaults to
|
|
93
110
|
* {@link DEFAULT_MCP_SERVER_INSTRUCTIONS}.
|
|
94
|
-
*/ _define_property$
|
|
111
|
+
*/ _define_property$9(this, "serverInstructions", void 0);
|
|
95
112
|
/**
|
|
96
113
|
* Absolute path to a pre-rendered MCP manifest JSON file produced by
|
|
97
114
|
* `dbx-cli-generate-mcp-manifest`. When set, the runtime reads it once at
|
|
@@ -101,7 +118,17 @@ function _define_property$7(obj, key, value) {
|
|
|
101
118
|
* Optional. When unset or the file is missing, the runtime falls back to
|
|
102
119
|
* today's behavior (auto-generated descriptions, ArkType-derived input
|
|
103
120
|
* schemas, no output schemas) and emits a single boot warning.
|
|
104
|
-
*/ _define_property$
|
|
121
|
+
*/ _define_property$9(this, "mcpManifestPath", void 0);
|
|
122
|
+
/**
|
|
123
|
+
* Absolute path to a pre-rendered route manifest JSON file produced by
|
|
124
|
+
* `dbx-cli-generate-route-manifest`. When set, the runtime reads it once at
|
|
125
|
+
* boot and registers the built-in `url-models` tool, which decodes an app URL
|
|
126
|
+
* into the Firestore models its page renders.
|
|
127
|
+
*
|
|
128
|
+
* Optional. When unset or the file is missing, the runtime skips registering
|
|
129
|
+
* `url-models` and emits a single boot warning when the path was set but
|
|
130
|
+
* unreadable.
|
|
131
|
+
*/ _define_property$9(this, "mcpRouteManifestPath", void 0);
|
|
105
132
|
/**
|
|
106
133
|
* When `true`, the MCP server only advertises tools whose effective read-only classification is `true`.
|
|
107
134
|
*
|
|
@@ -111,19 +138,29 @@ function _define_property$7(obj, key, value) {
|
|
|
111
138
|
*
|
|
112
139
|
* The advertised `serverName` on the JSON-RPC `initialize` handshake is suffixed with
|
|
113
140
|
* ` (read-only)` so the client surface reflects the mode.
|
|
114
|
-
*/ _define_property$
|
|
141
|
+
*/ _define_property$9(this, "readOnly", void 0);
|
|
142
|
+
/**
|
|
143
|
+
* Controls the auto-injected `reason` parameter added to every advertised tool's input schema.
|
|
144
|
+
*
|
|
145
|
+
* Enabled by default (unset / `true` = defaults on). Pass a {@link McpReasonParameterConfig} object
|
|
146
|
+
* to tune `required`, `maxLength`, `description`, or `parameterName`, or `false` to disable it.
|
|
147
|
+
*
|
|
148
|
+
* When enabled, every advertised tool's `inputSchema` carries a required `reason` string the model
|
|
149
|
+
* fills with a short justification for the call. The value is forwarded to analytics and stripped
|
|
150
|
+
* from the dispatched handler body. See {@link McpReasonParameterConfig}.
|
|
151
|
+
*/ _define_property$9(this, "reasonParameter", void 0);
|
|
115
152
|
};
|
|
116
153
|
/**
|
|
117
154
|
* NestJS injection token for the optional {@link McpAuthRoleReader} provider.
|
|
118
155
|
*/ var MCP_AUTH_ROLE_READER = 'MCP_AUTH_ROLE_READER';
|
|
119
156
|
|
|
120
|
-
function _type_of$
|
|
157
|
+
function _type_of$5(obj) {
|
|
121
158
|
"@swc/helpers - typeof";
|
|
122
159
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
123
160
|
}
|
|
124
161
|
function __decorate(decorators, target, key, desc) {
|
|
125
162
|
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
126
|
-
if ((typeof Reflect === "undefined" ? "undefined" : _type_of$
|
|
163
|
+
if ((typeof Reflect === "undefined" ? "undefined" : _type_of$5(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
127
164
|
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;
|
|
128
165
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
129
166
|
}
|
|
@@ -137,6 +174,206 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
|
|
|
137
174
|
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
138
175
|
};
|
|
139
176
|
|
|
177
|
+
function _array_like_to_array$a(arr, len) {
|
|
178
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
179
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
180
|
+
return arr2;
|
|
181
|
+
}
|
|
182
|
+
function _array_without_holes$7(arr) {
|
|
183
|
+
if (Array.isArray(arr)) return _array_like_to_array$a(arr);
|
|
184
|
+
}
|
|
185
|
+
function _define_property$8(obj, key, value) {
|
|
186
|
+
if (key in obj) {
|
|
187
|
+
Object.defineProperty(obj, key, {
|
|
188
|
+
value: value,
|
|
189
|
+
enumerable: true,
|
|
190
|
+
configurable: true,
|
|
191
|
+
writable: true
|
|
192
|
+
});
|
|
193
|
+
} else {
|
|
194
|
+
obj[key] = value;
|
|
195
|
+
}
|
|
196
|
+
return obj;
|
|
197
|
+
}
|
|
198
|
+
function _iterable_to_array$7(iter) {
|
|
199
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
200
|
+
}
|
|
201
|
+
function _non_iterable_spread$7() {
|
|
202
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
203
|
+
}
|
|
204
|
+
function _object_spread$5(target) {
|
|
205
|
+
for(var i = 1; i < arguments.length; i++){
|
|
206
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
207
|
+
var ownKeys = Object.keys(source);
|
|
208
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
209
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
210
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
211
|
+
}));
|
|
212
|
+
}
|
|
213
|
+
ownKeys.forEach(function(key) {
|
|
214
|
+
_define_property$8(target, key, source[key]);
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
return target;
|
|
218
|
+
}
|
|
219
|
+
function ownKeys$3(object, enumerableOnly) {
|
|
220
|
+
var keys = Object.keys(object);
|
|
221
|
+
if (Object.getOwnPropertySymbols) {
|
|
222
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
223
|
+
keys.push.apply(keys, symbols);
|
|
224
|
+
}
|
|
225
|
+
return keys;
|
|
226
|
+
}
|
|
227
|
+
function _object_spread_props$3(target, source) {
|
|
228
|
+
source = source != null ? source : {};
|
|
229
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
230
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
231
|
+
} else {
|
|
232
|
+
ownKeys$3(Object(source)).forEach(function(key) {
|
|
233
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
236
|
+
return target;
|
|
237
|
+
}
|
|
238
|
+
function _to_consumable_array$7(arr) {
|
|
239
|
+
return _array_without_holes$7(arr) || _iterable_to_array$7(arr) || _unsupported_iterable_to_array$a(arr) || _non_iterable_spread$7();
|
|
240
|
+
}
|
|
241
|
+
function _type_of$4(obj) {
|
|
242
|
+
"@swc/helpers - typeof";
|
|
243
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
244
|
+
}
|
|
245
|
+
function _unsupported_iterable_to_array$a(o, minLen) {
|
|
246
|
+
if (!o) return;
|
|
247
|
+
if (typeof o === "string") return _array_like_to_array$a(o, minLen);
|
|
248
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
249
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
250
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
251
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$a(o, minLen);
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Normalizes the app-supplied {@link McpModuleConfig.reasonParameter} value (object / boolean /
|
|
255
|
+
* undefined) into a fully-resolved {@link ResolvedMcpReasonParameterConfig} with the package defaults
|
|
256
|
+
* applied.
|
|
257
|
+
*
|
|
258
|
+
* - `undefined` / `true` → defaults, enabled.
|
|
259
|
+
* - `false` → defaults, but `enabled: false`.
|
|
260
|
+
* - object → per-field overrides on top of the defaults (`enabled` defaults to `true`).
|
|
261
|
+
*
|
|
262
|
+
* @param config - The raw config from {@link McpModuleConfig.reasonParameter}.
|
|
263
|
+
* @returns The resolved config with all defaults applied.
|
|
264
|
+
*/ function resolveMcpReasonParameterConfig(config) {
|
|
265
|
+
var result;
|
|
266
|
+
if (config === false) {
|
|
267
|
+
result = {
|
|
268
|
+
enabled: false,
|
|
269
|
+
required: DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
|
|
270
|
+
maxLength: DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
|
|
271
|
+
description: DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
|
|
272
|
+
parameterName: DEFAULT_MCP_REASON_PARAMETER_NAME
|
|
273
|
+
};
|
|
274
|
+
} else if (config == null || config === true) {
|
|
275
|
+
result = {
|
|
276
|
+
enabled: true,
|
|
277
|
+
required: DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
|
|
278
|
+
maxLength: DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
|
|
279
|
+
description: DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
|
|
280
|
+
parameterName: DEFAULT_MCP_REASON_PARAMETER_NAME
|
|
281
|
+
};
|
|
282
|
+
} else {
|
|
283
|
+
var _config_enabled, _config_required, _config_maxLength, _config_description, _config_parameterName;
|
|
284
|
+
result = {
|
|
285
|
+
enabled: (_config_enabled = config.enabled) !== null && _config_enabled !== void 0 ? _config_enabled : true,
|
|
286
|
+
required: (_config_required = config.required) !== null && _config_required !== void 0 ? _config_required : DEFAULT_MCP_REASON_PARAMETER_REQUIRED,
|
|
287
|
+
maxLength: (_config_maxLength = config.maxLength) !== null && _config_maxLength !== void 0 ? _config_maxLength : DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH,
|
|
288
|
+
description: (_config_description = config.description) !== null && _config_description !== void 0 ? _config_description : DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION,
|
|
289
|
+
parameterName: (_config_parameterName = config.parameterName) !== null && _config_parameterName !== void 0 ? _config_parameterName : DEFAULT_MCP_REASON_PARAMETER_NAME
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* Returns `true` when the JSON schema already declares a property named `name` under `properties`.
|
|
296
|
+
*
|
|
297
|
+
* Used as the collision guard so a handler that legitimately consumes its own field of the same name
|
|
298
|
+
* is never double-declared (schema injection) or stripped (arg extraction).
|
|
299
|
+
*
|
|
300
|
+
* @param schema - The candidate JSON schema object (may be `undefined`).
|
|
301
|
+
* @param name - The property name to look for.
|
|
302
|
+
* @returns Whether the schema's `properties` already contains `name`.
|
|
303
|
+
*/ function mcpSchemaDeclaresProperty(schema, name) {
|
|
304
|
+
var properties = schema === null || schema === void 0 ? void 0 : schema.properties;
|
|
305
|
+
return properties != null && (typeof properties === "undefined" ? "undefined" : _type_of$4(properties)) === 'object' && Object.prototype.hasOwnProperty.call(properties, name);
|
|
306
|
+
}
|
|
307
|
+
/**
|
|
308
|
+
* Returns a NEW JSON schema object with the reason parameter property merged into `properties` (and
|
|
309
|
+
* appended to `required` when configured). Never mutates the input — the static wire schemas are
|
|
310
|
+
* shared module-level constants reused across requests.
|
|
311
|
+
*
|
|
312
|
+
* Self-skips (returns the input schema unchanged) when the config is disabled or the schema already
|
|
313
|
+
* declares the parameter name. Defensive against a non-object / missing-`properties` input.
|
|
314
|
+
*
|
|
315
|
+
* @param inputSchema - The tool's resolved input schema.
|
|
316
|
+
* @param resolved - The resolved reason-parameter config.
|
|
317
|
+
* @returns A new schema carrying the reason property, or the original schema when skipped.
|
|
318
|
+
*/ function applyMcpReasonParameterToSchema(inputSchema, resolved) {
|
|
319
|
+
var result = inputSchema;
|
|
320
|
+
if (resolved.enabled && !mcpSchemaDeclaresProperty(inputSchema, resolved.parameterName)) {
|
|
321
|
+
var _base_type;
|
|
322
|
+
var base = (typeof inputSchema === "undefined" ? "undefined" : _type_of$4(inputSchema)) === 'object' && inputSchema != null ? inputSchema : {};
|
|
323
|
+
var existingProperties = _type_of$4(base.properties) === 'object' && base.properties != null ? base.properties : {};
|
|
324
|
+
var next = _object_spread_props$3(_object_spread$5({}, base), {
|
|
325
|
+
type: (_base_type = base.type) !== null && _base_type !== void 0 ? _base_type : 'object',
|
|
326
|
+
properties: _object_spread_props$3(_object_spread$5({}, existingProperties), _define_property$8({}, resolved.parameterName, {
|
|
327
|
+
type: 'string',
|
|
328
|
+
maxLength: resolved.maxLength,
|
|
329
|
+
description: resolved.description
|
|
330
|
+
}))
|
|
331
|
+
});
|
|
332
|
+
if (resolved.required) {
|
|
333
|
+
var existingRequired = Array.isArray(base.required) ? base.required : [];
|
|
334
|
+
next.required = existingRequired.includes(resolved.parameterName) ? _to_consumable_array$7(existingRequired) : _to_consumable_array$7(existingRequired).concat([
|
|
335
|
+
resolved.parameterName
|
|
336
|
+
]);
|
|
337
|
+
}
|
|
338
|
+
result = next;
|
|
339
|
+
}
|
|
340
|
+
return result;
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Splits the auto-injected reason value out of a tool call's raw arguments.
|
|
344
|
+
*
|
|
345
|
+
* When enabled and the tool did NOT declare its own field of the same name: shallow-copies the args,
|
|
346
|
+
* deletes the parameter key, and coerces + clamps the value to `maxLength` (the client is not trusted).
|
|
347
|
+
* An empty / absent value yields `reason: undefined`.
|
|
348
|
+
*
|
|
349
|
+
* Otherwise (disabled, or the handler legitimately owns the field) returns the args unchanged so a
|
|
350
|
+
* field the handler actually consumes is never stripped.
|
|
351
|
+
*
|
|
352
|
+
* @param args - The raw `tools/call` arguments.
|
|
353
|
+
* @param resolved - The resolved reason-parameter config.
|
|
354
|
+
* @param toolDeclaresOwnReason - Whether the tool's own input schema already declares the parameter.
|
|
355
|
+
* @returns The extracted reason plus the (possibly stripped) args to dispatch.
|
|
356
|
+
*/ function extractMcpReasonFromArgs(args, resolved, toolDeclaresOwnReason) {
|
|
357
|
+
var result;
|
|
358
|
+
if (resolved.enabled && !toolDeclaresOwnReason && Object.prototype.hasOwnProperty.call(args, resolved.parameterName)) {
|
|
359
|
+
var rawValue = args[resolved.parameterName];
|
|
360
|
+
var nextArgs = _object_spread$5({}, args);
|
|
361
|
+
delete nextArgs[resolved.parameterName];
|
|
362
|
+
var stringValue = rawValue == null ? '' : String(rawValue);
|
|
363
|
+
var clamped = stringValue.length > resolved.maxLength ? stringValue.slice(0, resolved.maxLength) : stringValue;
|
|
364
|
+
result = {
|
|
365
|
+
reason: clamped.length > 0 ? clamped : undefined,
|
|
366
|
+
args: nextArgs
|
|
367
|
+
};
|
|
368
|
+
} else {
|
|
369
|
+
result = {
|
|
370
|
+
reason: undefined,
|
|
371
|
+
args: args
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
return result;
|
|
375
|
+
}
|
|
376
|
+
|
|
140
377
|
function _class_call_check$4(instance, Constructor) {
|
|
141
378
|
if (!(instance instanceof Constructor)) {
|
|
142
379
|
throw new TypeError("Cannot call a class as a function");
|
|
@@ -192,73 +429,356 @@ function _class_call_check$4(instance, Constructor) {
|
|
|
192
429
|
return isDefault ? "".concat(modelType, ".").concat(call, "._") : "".concat(modelType, ".").concat(call, ".").concat(specifier);
|
|
193
430
|
}
|
|
194
431
|
|
|
195
|
-
function
|
|
432
|
+
function _array_like_to_array$9(arr, len) {
|
|
433
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
434
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
435
|
+
return arr2;
|
|
436
|
+
}
|
|
437
|
+
function _array_with_holes$5(arr) {
|
|
438
|
+
if (Array.isArray(arr)) return arr;
|
|
439
|
+
}
|
|
440
|
+
function _iterable_to_array_limit$5(arr, i) {
|
|
441
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
442
|
+
if (_i == null) return;
|
|
443
|
+
var _arr = [];
|
|
444
|
+
var _n = true;
|
|
445
|
+
var _d = false;
|
|
446
|
+
var _s, _e;
|
|
196
447
|
try {
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
448
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
449
|
+
_arr.push(_s.value);
|
|
450
|
+
if (i && _arr.length === i) break;
|
|
451
|
+
}
|
|
452
|
+
} catch (err) {
|
|
453
|
+
_d = true;
|
|
454
|
+
_e = err;
|
|
455
|
+
} finally{
|
|
456
|
+
try {
|
|
457
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
458
|
+
} finally{
|
|
459
|
+
if (_d) throw _e;
|
|
460
|
+
}
|
|
202
461
|
}
|
|
203
|
-
|
|
204
|
-
|
|
462
|
+
return _arr;
|
|
463
|
+
}
|
|
464
|
+
function _non_iterable_rest$5() {
|
|
465
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
466
|
+
}
|
|
467
|
+
function _sliced_to_array$5(arr, i) {
|
|
468
|
+
return _array_with_holes$5(arr) || _iterable_to_array_limit$5(arr, i) || _unsupported_iterable_to_array$9(arr, i) || _non_iterable_rest$5();
|
|
469
|
+
}
|
|
470
|
+
function _unsupported_iterable_to_array$9(o, minLen) {
|
|
471
|
+
if (!o) return;
|
|
472
|
+
if (typeof o === "string") return _array_like_to_array$9(o, minLen);
|
|
473
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
474
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
475
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
476
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$9(o, minLen);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* Runtime mirror of the build-time route manifest schema + a ported URL matcher.
|
|
480
|
+
*
|
|
481
|
+
* Structural mirror of `@dereekb/dbx-cli`'s `route-manifest.ts` types and the
|
|
482
|
+
* pure `url-match.ts` matcher, so the firebase-server/mcp runtime can consume
|
|
483
|
+
* the generated `route.manifest.json` without taking a runtime dependency on
|
|
484
|
+
* the build-time CLI package. Both sides bump {@link ROUTE_MANIFEST_VERSION}
|
|
485
|
+
* together when the manifest shape changes.
|
|
486
|
+
*/ /**
|
|
487
|
+
* Version stamp embedded in `route.manifest.json`. Runtime loaders refuse
|
|
488
|
+
* manifests whose `version` does not match. Mirror in `@dereekb/dbx-cli`'s
|
|
489
|
+
* `ROUTE_MANIFEST_VERSION` — bump both together.
|
|
490
|
+
*/ var ROUTE_MANIFEST_VERSION = 1;
|
|
491
|
+
/**
|
|
492
|
+
* Extracts the normalized pathname from a full URL or a bare path. Strips the
|
|
493
|
+
* scheme/host/port, query string, and hash; collapses an empty path to `/` and
|
|
494
|
+
* trims a single trailing slash.
|
|
495
|
+
*
|
|
496
|
+
* @param url - A full URL (`https://app.example.co/worker/x/timesheets/list`) or bare path.
|
|
497
|
+
* @returns The normalized pathname.
|
|
498
|
+
*
|
|
499
|
+
* @example
|
|
500
|
+
* ```ts
|
|
501
|
+
* parseUrlModelsPathname('https://app.hellosubs.co/worker/abc/timesheets/list/'); // => '/worker/abc/timesheets/list'
|
|
502
|
+
* ```
|
|
503
|
+
*/ function parseUrlModelsPathname(url) {
|
|
504
|
+
var trimmed = url.trim();
|
|
505
|
+
var pathname;
|
|
506
|
+
if (RegExp("^[a-z][a-z0-9+.-]*:\\/\\/", "iu").test(trimmed)) {
|
|
507
|
+
pathname = new URL(trimmed).pathname;
|
|
205
508
|
} else {
|
|
206
|
-
|
|
509
|
+
var hashStripped = trimmed.split('#', 1)[0];
|
|
510
|
+
var pathPart = hashStripped.split('?', 1)[0];
|
|
511
|
+
pathname = pathPart.startsWith('/') ? pathPart : "/".concat(pathPart);
|
|
207
512
|
}
|
|
513
|
+
return normalizePathname(pathname);
|
|
208
514
|
}
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
515
|
+
/**
|
|
516
|
+
* Matches a URL against the manifest's states, preferring a literal match over
|
|
517
|
+
* a parameterised one. A tie at either tier collapses to `ambiguous`; otherwise
|
|
518
|
+
* the closest near-misses are scored and returned in a `none` result.
|
|
519
|
+
*
|
|
520
|
+
* @param input - The manifest and the URL (or pathname) to resolve.
|
|
521
|
+
* @returns A discriminated match / ambiguous / none result.
|
|
522
|
+
*/ function matchRouteManifestUrl(input) {
|
|
523
|
+
var pathname = parseUrlModelsPathname(input.url);
|
|
524
|
+
var states = input.manifest.states;
|
|
525
|
+
var literal = states.filter(function(s) {
|
|
526
|
+
return s.fullUrl !== undefined && normalizePathname(s.fullUrl) === pathname;
|
|
527
|
+
});
|
|
528
|
+
var result;
|
|
529
|
+
if (literal.length === 1) {
|
|
530
|
+
result = {
|
|
531
|
+
kind: 'match',
|
|
532
|
+
via: 'literal',
|
|
533
|
+
state: literal[0],
|
|
534
|
+
params: {},
|
|
535
|
+
pathname: pathname
|
|
536
|
+
};
|
|
537
|
+
} else if (literal.length > 1) {
|
|
538
|
+
result = {
|
|
539
|
+
kind: 'ambiguous',
|
|
540
|
+
states: literal,
|
|
541
|
+
pathname: pathname
|
|
542
|
+
};
|
|
543
|
+
} else {
|
|
544
|
+
result = matchParamOrNone(states, pathname);
|
|
545
|
+
}
|
|
546
|
+
return result;
|
|
547
|
+
}
|
|
548
|
+
function matchParamOrNone(states, pathname) {
|
|
549
|
+
var inputSegments = splitSegments(pathname);
|
|
550
|
+
var hits = [];
|
|
551
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
552
|
+
try {
|
|
553
|
+
for(var _iterator = states[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
554
|
+
var state = _step.value;
|
|
555
|
+
if (state.fullUrl === undefined || !hasParamSegment(state.fullUrl)) {
|
|
556
|
+
continue;
|
|
216
557
|
}
|
|
217
|
-
|
|
218
|
-
|
|
558
|
+
var params = tryMatchSegments(splitSegments(state.fullUrl), inputSegments);
|
|
559
|
+
if (params) {
|
|
560
|
+
hits.push({
|
|
561
|
+
state: state,
|
|
562
|
+
params: params
|
|
563
|
+
});
|
|
219
564
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
565
|
+
}
|
|
566
|
+
} catch (err) {
|
|
567
|
+
_didIteratorError = true;
|
|
568
|
+
_iteratorError = err;
|
|
569
|
+
} finally{
|
|
570
|
+
try {
|
|
571
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
572
|
+
_iterator.return();
|
|
573
|
+
}
|
|
574
|
+
} finally{
|
|
575
|
+
if (_didIteratorError) {
|
|
576
|
+
throw _iteratorError;
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
var result;
|
|
581
|
+
if (hits.length === 1) {
|
|
582
|
+
result = {
|
|
583
|
+
kind: 'match',
|
|
584
|
+
via: 'param',
|
|
585
|
+
state: hits[0].state,
|
|
586
|
+
params: hits[0].params,
|
|
587
|
+
pathname: pathname
|
|
588
|
+
};
|
|
589
|
+
} else if (hits.length > 1) {
|
|
590
|
+
result = {
|
|
591
|
+
kind: 'ambiguous',
|
|
592
|
+
states: hits.map(function(h) {
|
|
593
|
+
return h.state;
|
|
594
|
+
}),
|
|
595
|
+
pathname: pathname
|
|
596
|
+
};
|
|
597
|
+
} else {
|
|
598
|
+
result = {
|
|
599
|
+
kind: 'none',
|
|
600
|
+
candidates: scoreCandidates(states, pathname),
|
|
601
|
+
pathname: pathname
|
|
602
|
+
};
|
|
603
|
+
}
|
|
604
|
+
return result;
|
|
223
605
|
}
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
606
|
+
// MARK: Pure URL helpers (mirror of @dereekb/dbx-cli url-match.ts)
|
|
607
|
+
function normalizePathname(pathname) {
|
|
608
|
+
var result;
|
|
609
|
+
if (pathname.length === 0) {
|
|
610
|
+
result = '/';
|
|
611
|
+
} else if (pathname.length > 1 && pathname.endsWith('/')) {
|
|
612
|
+
result = pathname.slice(0, -1);
|
|
228
613
|
} else {
|
|
229
|
-
|
|
614
|
+
result = pathname;
|
|
230
615
|
}
|
|
616
|
+
return result;
|
|
231
617
|
}
|
|
232
|
-
function
|
|
233
|
-
var
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
return d(g, "next", {
|
|
243
|
-
value: verb(0)
|
|
244
|
-
}), d(g, "throw", {
|
|
245
|
-
value: verb(1)
|
|
246
|
-
}), d(g, "return", {
|
|
247
|
-
value: verb(2)
|
|
248
|
-
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
249
|
-
value: function() {
|
|
250
|
-
return this;
|
|
251
|
-
}
|
|
252
|
-
}), g;
|
|
253
|
-
function verb(n) {
|
|
254
|
-
return function(v) {
|
|
255
|
-
return step([
|
|
256
|
-
n,
|
|
257
|
-
v
|
|
258
|
-
]);
|
|
259
|
-
};
|
|
618
|
+
function splitSegments(path) {
|
|
619
|
+
var normalized = path.startsWith('/') ? path.slice(1) : path;
|
|
620
|
+
return normalized.length === 0 ? [] : normalized.split('/');
|
|
621
|
+
}
|
|
622
|
+
function hasParamSegment(path) {
|
|
623
|
+
return path.includes(':') || path.includes('{');
|
|
624
|
+
}
|
|
625
|
+
function tryMatchSegments(route, input) {
|
|
626
|
+
if (route.length !== input.length) {
|
|
627
|
+
return undefined;
|
|
260
628
|
}
|
|
261
|
-
|
|
629
|
+
var params = {};
|
|
630
|
+
var result = params;
|
|
631
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
632
|
+
try {
|
|
633
|
+
for(var _iterator = route.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
634
|
+
var _step_value = _sliced_to_array$5(_step.value, 2), i = _step_value[0], r = _step_value[1];
|
|
635
|
+
var v = input[i];
|
|
636
|
+
if (r.startsWith(':')) {
|
|
637
|
+
params[r.slice(1)] = decodeURIComponent(v);
|
|
638
|
+
} else if (r.startsWith('{') && r.endsWith('}')) {
|
|
639
|
+
var inner = r.slice(1, -1);
|
|
640
|
+
var colonIdx = inner.indexOf(':');
|
|
641
|
+
var key = colonIdx >= 0 ? inner.slice(0, colonIdx) : inner;
|
|
642
|
+
params[key] = decodeURIComponent(v);
|
|
643
|
+
} else if (r !== v) {
|
|
644
|
+
result = undefined;
|
|
645
|
+
break;
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
} catch (err) {
|
|
649
|
+
_didIteratorError = true;
|
|
650
|
+
_iteratorError = err;
|
|
651
|
+
} finally{
|
|
652
|
+
try {
|
|
653
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
654
|
+
_iterator.return();
|
|
655
|
+
}
|
|
656
|
+
} finally{
|
|
657
|
+
if (_didIteratorError) {
|
|
658
|
+
throw _iteratorError;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
return result;
|
|
663
|
+
}
|
|
664
|
+
function scoreCandidates(states, pathname) {
|
|
665
|
+
var segments = splitSegments(pathname);
|
|
666
|
+
var scored = [];
|
|
667
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
668
|
+
try {
|
|
669
|
+
for(var _iterator = states[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
670
|
+
var state = _step.value;
|
|
671
|
+
if (state.fullUrl === undefined) {
|
|
672
|
+
continue;
|
|
673
|
+
}
|
|
674
|
+
var candidateSegments = splitSegments(state.fullUrl);
|
|
675
|
+
var score = 0;
|
|
676
|
+
var maxIndex = Math.min(segments.length, candidateSegments.length);
|
|
677
|
+
for(var i = 0; i < maxIndex; i += 1){
|
|
678
|
+
if (segments[i] === candidateSegments[i]) {
|
|
679
|
+
score += 2;
|
|
680
|
+
} else if (candidateSegments[i].startsWith(':') || candidateSegments[i].startsWith('{')) {
|
|
681
|
+
score += 1;
|
|
682
|
+
} else {
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
if (score > 0) {
|
|
687
|
+
scored.push({
|
|
688
|
+
state: state,
|
|
689
|
+
score: score
|
|
690
|
+
});
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
} catch (err) {
|
|
694
|
+
_didIteratorError = true;
|
|
695
|
+
_iteratorError = err;
|
|
696
|
+
} finally{
|
|
697
|
+
try {
|
|
698
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
699
|
+
_iterator.return();
|
|
700
|
+
}
|
|
701
|
+
} finally{
|
|
702
|
+
if (_didIteratorError) {
|
|
703
|
+
throw _iteratorError;
|
|
704
|
+
}
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
scored.sort(function(a, b) {
|
|
708
|
+
return b.score - a.score;
|
|
709
|
+
});
|
|
710
|
+
return scored.slice(0, 5).map(function(s) {
|
|
711
|
+
return s.state;
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
function asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, key, arg) {
|
|
716
|
+
try {
|
|
717
|
+
var info = gen[key](arg);
|
|
718
|
+
var value = info.value;
|
|
719
|
+
} catch (error) {
|
|
720
|
+
reject(error);
|
|
721
|
+
return;
|
|
722
|
+
}
|
|
723
|
+
if (info.done) {
|
|
724
|
+
resolve(value);
|
|
725
|
+
} else {
|
|
726
|
+
Promise.resolve(value).then(_next, _throw);
|
|
727
|
+
}
|
|
728
|
+
}
|
|
729
|
+
function _async_to_generator$6(fn) {
|
|
730
|
+
return function() {
|
|
731
|
+
var self = this, args = arguments;
|
|
732
|
+
return new Promise(function(resolve, reject) {
|
|
733
|
+
var gen = fn.apply(self, args);
|
|
734
|
+
function _next(value) {
|
|
735
|
+
asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "next", value);
|
|
736
|
+
}
|
|
737
|
+
function _throw(err) {
|
|
738
|
+
asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "throw", err);
|
|
739
|
+
}
|
|
740
|
+
_next(undefined);
|
|
741
|
+
});
|
|
742
|
+
};
|
|
743
|
+
}
|
|
744
|
+
function _instanceof$1(left, right) {
|
|
745
|
+
"@swc/helpers - instanceof";
|
|
746
|
+
if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
|
|
747
|
+
return !!right[Symbol.hasInstance](left);
|
|
748
|
+
} else {
|
|
749
|
+
return left instanceof right;
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
function _ts_generator$6(thisArg, body) {
|
|
753
|
+
var f, y, t, _ = {
|
|
754
|
+
label: 0,
|
|
755
|
+
sent: function() {
|
|
756
|
+
if (t[0] & 1) throw t[1];
|
|
757
|
+
return t[1];
|
|
758
|
+
},
|
|
759
|
+
trys: [],
|
|
760
|
+
ops: []
|
|
761
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
762
|
+
return d(g, "next", {
|
|
763
|
+
value: verb(0)
|
|
764
|
+
}), d(g, "throw", {
|
|
765
|
+
value: verb(1)
|
|
766
|
+
}), d(g, "return", {
|
|
767
|
+
value: verb(2)
|
|
768
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
769
|
+
value: function() {
|
|
770
|
+
return this;
|
|
771
|
+
}
|
|
772
|
+
}), g;
|
|
773
|
+
function verb(n) {
|
|
774
|
+
return function(v) {
|
|
775
|
+
return step([
|
|
776
|
+
n,
|
|
777
|
+
v
|
|
778
|
+
]);
|
|
779
|
+
};
|
|
780
|
+
}
|
|
781
|
+
function step(op) {
|
|
262
782
|
if (f) throw new TypeError("Generator is already executing.");
|
|
263
783
|
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
264
784
|
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
@@ -357,9 +877,9 @@ function _ts_generator$5(thisArg, body) {
|
|
|
357
877
|
* @param details - The handler-level API details (carries the mapper + Tier 2/3 formatters).
|
|
358
878
|
* @returns The MCP tool response content.
|
|
359
879
|
*/ function formatMcpToolResponse(result, params, details) {
|
|
360
|
-
return _async_to_generator$
|
|
880
|
+
return _async_to_generator$6(function() {
|
|
361
881
|
var mcp, value, _tmp, context, response, summary;
|
|
362
|
-
return _ts_generator$
|
|
882
|
+
return _ts_generator$6(this, function(_state) {
|
|
363
883
|
switch(_state.label){
|
|
364
884
|
case 0:
|
|
365
885
|
mcp = details === null || details === void 0 ? void 0 : details.mcp;
|
|
@@ -512,6 +1032,28 @@ function stringifyResult(result) {
|
|
|
512
1032
|
}
|
|
513
1033
|
return READ_ONLY_BY_CALL_TYPE[callType];
|
|
514
1034
|
}
|
|
1035
|
+
/**
|
|
1036
|
+
* Maps an effective read-only classification to the standard MCP {@link ToolAnnotations} hints
|
|
1037
|
+
* advertised on `tools/list`.
|
|
1038
|
+
*
|
|
1039
|
+
* A definitively read-only tool advertises `{ readOnlyHint: true }`. Everything else — a known
|
|
1040
|
+
* write (`false`) or an unclassified verb (`undefined`, e.g. `invoke`/custom) — fails safe to
|
|
1041
|
+
* `{ readOnlyHint: false, destructiveHint: true }` so a client never mistakes an ambiguous tool
|
|
1042
|
+
* for a safe read. `idempotentHint` / `openWorldHint` are intentionally left unset.
|
|
1043
|
+
*
|
|
1044
|
+
* Co-located with {@link resolveEffectiveReadOnly} / {@link READ_ONLY_BY_CALL_TYPE} so the
|
|
1045
|
+
* read/write classification rules stay in one file.
|
|
1046
|
+
*
|
|
1047
|
+
* @param effectiveReadOnly - The resolved read-only classification from {@link resolveEffectiveReadOnly}.
|
|
1048
|
+
* @returns The MCP annotations describing the tool's read/write behaviour.
|
|
1049
|
+
*/ function resolveMcpToolAnnotations(effectiveReadOnly) {
|
|
1050
|
+
return effectiveReadOnly === true ? {
|
|
1051
|
+
readOnlyHint: true
|
|
1052
|
+
} : {
|
|
1053
|
+
readOnlyHint: false,
|
|
1054
|
+
destructiveHint: true
|
|
1055
|
+
};
|
|
1056
|
+
}
|
|
515
1057
|
/**
|
|
516
1058
|
* Resolves the OIDC scope required to invoke a given call type, or `undefined` for
|
|
517
1059
|
* non-CRUD calls. Thin re-export so the tool generator doesn't need to reach into
|
|
@@ -523,15 +1065,15 @@ function stringifyResult(result) {
|
|
|
523
1065
|
return firebase.callModelOidcScopeForCallType(callType);
|
|
524
1066
|
}
|
|
525
1067
|
|
|
526
|
-
function _array_like_to_array$
|
|
1068
|
+
function _array_like_to_array$8(arr, len) {
|
|
527
1069
|
if (len == null || len > arr.length) len = arr.length;
|
|
528
1070
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
529
1071
|
return arr2;
|
|
530
1072
|
}
|
|
531
|
-
function _array_with_holes$
|
|
1073
|
+
function _array_with_holes$4(arr) {
|
|
532
1074
|
if (Array.isArray(arr)) return arr;
|
|
533
1075
|
}
|
|
534
|
-
function _iterable_to_array_limit$
|
|
1076
|
+
function _iterable_to_array_limit$4(arr, i) {
|
|
535
1077
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
536
1078
|
if (_i == null) return;
|
|
537
1079
|
var _arr = [];
|
|
@@ -555,23 +1097,23 @@ function _iterable_to_array_limit$3(arr, i) {
|
|
|
555
1097
|
}
|
|
556
1098
|
return _arr;
|
|
557
1099
|
}
|
|
558
|
-
function _non_iterable_rest$
|
|
1100
|
+
function _non_iterable_rest$4() {
|
|
559
1101
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
560
1102
|
}
|
|
561
|
-
function _sliced_to_array$
|
|
562
|
-
return _array_with_holes$
|
|
1103
|
+
function _sliced_to_array$4(arr, i) {
|
|
1104
|
+
return _array_with_holes$4(arr) || _iterable_to_array_limit$4(arr, i) || _unsupported_iterable_to_array$8(arr, i) || _non_iterable_rest$4();
|
|
563
1105
|
}
|
|
564
|
-
function _type_of$
|
|
1106
|
+
function _type_of$3(obj) {
|
|
565
1107
|
"@swc/helpers - typeof";
|
|
566
1108
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
567
1109
|
}
|
|
568
|
-
function _unsupported_iterable_to_array$
|
|
1110
|
+
function _unsupported_iterable_to_array$8(o, minLen) {
|
|
569
1111
|
if (!o) return;
|
|
570
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
1112
|
+
if (typeof o === "string") return _array_like_to_array$8(o, minLen);
|
|
571
1113
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
572
1114
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
573
1115
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
574
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
1116
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$8(o, minLen);
|
|
575
1117
|
}
|
|
576
1118
|
/**
|
|
577
1119
|
* Default `toJsonSchema()` options.
|
|
@@ -607,18 +1149,73 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
607
1149
|
var inputSchema = (_input_inputSchema = input.inputSchema) !== null && _input_inputSchema !== void 0 ? _input_inputSchema : {
|
|
608
1150
|
type: 'object'
|
|
609
1151
|
};
|
|
610
|
-
var entry =
|
|
1152
|
+
var entry = {
|
|
611
1153
|
name: input.name,
|
|
612
1154
|
description: input.description,
|
|
613
1155
|
inputSchema: inputSchema
|
|
614
|
-
} : {
|
|
615
|
-
name: input.name,
|
|
616
|
-
description: input.description,
|
|
617
|
-
inputSchema: inputSchema,
|
|
618
|
-
outputSchema: input.outputSchema
|
|
619
1156
|
};
|
|
1157
|
+
if (input.outputSchema != null) {
|
|
1158
|
+
entry.outputSchema = input.outputSchema;
|
|
1159
|
+
}
|
|
1160
|
+
if (input.annotations != null) {
|
|
1161
|
+
entry.annotations = input.annotations;
|
|
1162
|
+
}
|
|
620
1163
|
return Object.freeze(entry);
|
|
621
1164
|
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Description prefix prepended to a mutating tool's description so MCP clients that don't render
|
|
1167
|
+
* {@link ToolAnnotations} still surface the write signal in plain text.
|
|
1168
|
+
*/ var MCP_WRITE_TOOL_DESCRIPTION_PREFIX = '[WRITE] ';
|
|
1169
|
+
/**
|
|
1170
|
+
* Prepends {@link MCP_WRITE_TOOL_DESCRIPTION_PREFIX} to a description when its annotations mark the
|
|
1171
|
+
* tool as a write (`readOnlyHint === false`). Read-only tools are returned unchanged.
|
|
1172
|
+
*
|
|
1173
|
+
* @param description - The base tool description.
|
|
1174
|
+
* @param annotations - The resolved MCP annotations for the tool.
|
|
1175
|
+
* @returns The description, prefixed with the write marker when the tool mutates.
|
|
1176
|
+
*/ function applyWriteMarker(description, annotations) {
|
|
1177
|
+
return annotations.readOnlyHint === false ? "".concat(MCP_WRITE_TOOL_DESCRIPTION_PREFIX).concat(description) : description;
|
|
1178
|
+
}
|
|
1179
|
+
/**
|
|
1180
|
+
* Assembles a statically-registered {@link McpToolDefinition} with consistent MCP annotations.
|
|
1181
|
+
*
|
|
1182
|
+
* Built-in tools (e.g. `whoami`, `model-get`, `batch-execute`) don't flow through
|
|
1183
|
+
* {@link buildToolFromCandidate}, so this is their analogous single source of truth: it derives the
|
|
1184
|
+
* read/write annotations from {@link BuildStaticToolDefinitionInput.effectiveReadOnly} via
|
|
1185
|
+
* {@link resolveMcpToolAnnotations}, applies the {@link MCP_WRITE_TOOL_DESCRIPTION_PREFIX} write
|
|
1186
|
+
* marker to the description, then mirrors the annotations onto both the definition's `annotations`
|
|
1187
|
+
* field and the frozen {@link McpToolDefinition.staticWireEntry}. Centralizing this guarantees no
|
|
1188
|
+
* built-in tool reaches `tools/list` un-annotated (which would surface as an uncategorized "other"
|
|
1189
|
+
* tool in clients that bucket by `readOnlyHint`).
|
|
1190
|
+
*
|
|
1191
|
+
* @param input - The tool identity, schemas, dispatch target, static handler, and read-only classification.
|
|
1192
|
+
* @returns A statically-registered {@link McpToolDefinition} to append to the MCP server factory's tool registry.
|
|
1193
|
+
*/ function buildStaticToolDefinition(input) {
|
|
1194
|
+
var name = input.name, inputSchema = input.inputSchema, outputSchema = input.outputSchema, dispatch = input.dispatch, staticHandler = input.staticHandler, effectiveReadOnly = input.effectiveReadOnly, rule = input.rule;
|
|
1195
|
+
var annotations = resolveMcpToolAnnotations(effectiveReadOnly);
|
|
1196
|
+
var description = applyWriteMarker(input.description, annotations);
|
|
1197
|
+
return {
|
|
1198
|
+
name: name,
|
|
1199
|
+
description: description,
|
|
1200
|
+
inputSchema: inputSchema,
|
|
1201
|
+
outputSchema: outputSchema,
|
|
1202
|
+
annotations: annotations,
|
|
1203
|
+
dispatch: dispatch,
|
|
1204
|
+
staticHandler: staticHandler,
|
|
1205
|
+
filterMetadata: {
|
|
1206
|
+
visibilityKind: 'declarative',
|
|
1207
|
+
rule: rule !== null && rule !== void 0 ? rule : {},
|
|
1208
|
+
effectiveReadOnly: effectiveReadOnly
|
|
1209
|
+
},
|
|
1210
|
+
staticWireEntry: buildStaticWireEntry({
|
|
1211
|
+
name: name,
|
|
1212
|
+
description: description,
|
|
1213
|
+
inputSchema: inputSchema,
|
|
1214
|
+
outputSchema: outputSchema,
|
|
1215
|
+
annotations: annotations
|
|
1216
|
+
})
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
622
1219
|
// MARK: Naming
|
|
623
1220
|
/**
|
|
624
1221
|
* The default specifier key used when a handler is not behind a specifier router.
|
|
@@ -837,18 +1434,18 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
837
1434
|
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
838
1435
|
try {
|
|
839
1436
|
for(var _iterator = Object.entries(apiDetails.models)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
840
|
-
var _step_value = _sliced_to_array$
|
|
1437
|
+
var _step_value = _sliced_to_array$4(_step.value, 2), modelType = _step_value[0], modelEntry = _step_value[1];
|
|
841
1438
|
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
842
1439
|
try {
|
|
843
1440
|
for(var _iterator1 = Object.entries(modelEntry.calls)[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
844
|
-
var _step_value1 = _sliced_to_array$
|
|
1441
|
+
var _step_value1 = _sliced_to_array$4(_step1.value, 2), callType = _step_value1[0], callDetails = _step_value1[1];
|
|
845
1442
|
if (callDetails == null) {
|
|
846
1443
|
continue;
|
|
847
1444
|
}
|
|
848
1445
|
var _iteratorNormalCompletion2 = true, _didIteratorError2 = false, _iteratorError2 = undefined;
|
|
849
1446
|
try {
|
|
850
1447
|
for(var _iterator2 = Object.entries(callDetails.specifiers)[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true){
|
|
851
|
-
var _step_value2 = _sliced_to_array$
|
|
1448
|
+
var _step_value2 = _sliced_to_array$4(_step2.value, 2), specifierKey = _step_value2[0], handlerDetails = _step_value2[1];
|
|
852
1449
|
var _ref;
|
|
853
1450
|
var _naming_modelSegments, _handlerDetails_mcp, _handlerDetails_mcp1;
|
|
854
1451
|
if (handlerDetails == null) {
|
|
@@ -985,7 +1582,7 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
985
1582
|
return;
|
|
986
1583
|
}
|
|
987
1584
|
var manifestEntry = manifest === null || manifest === void 0 ? void 0 : manifest.get(mcpManifestKey(modelType, callType, specifier));
|
|
988
|
-
var
|
|
1585
|
+
var baseDescription = (_ref = manifestEntry === null || manifestEntry === void 0 ? void 0 : manifestEntry.description) !== null && _ref !== void 0 ? _ref : buildDefaultMcpToolDescription(modelType, callType, specifier);
|
|
989
1586
|
var inputSchema = resolveInputSchema({
|
|
990
1587
|
handlerDetails: handlerDetails,
|
|
991
1588
|
manifestEntry: manifestEntry,
|
|
@@ -1019,6 +1616,8 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
1019
1616
|
}
|
|
1020
1617
|
var requiredScope = (_resolveRequiredScope = resolveRequiredScope(callType)) !== null && _resolveRequiredScope !== void 0 ? _resolveRequiredScope : undefined;
|
|
1021
1618
|
var effectiveReadOnly = resolveEffectiveReadOnly((_handlerDetails_mcp = handlerDetails.mcp) === null || _handlerDetails_mcp === void 0 ? void 0 : _handlerDetails_mcp.readOnly, callType);
|
|
1619
|
+
var annotations = resolveMcpToolAnnotations(effectiveReadOnly);
|
|
1620
|
+
var description = applyWriteMarker(baseDescription, annotations);
|
|
1022
1621
|
var filterMetadata;
|
|
1023
1622
|
if (classified.visibilityKind === 'declarative') {
|
|
1024
1623
|
filterMetadata = {
|
|
@@ -1061,13 +1660,15 @@ function _unsupported_iterable_to_array$7(o, minLen) {
|
|
|
1061
1660
|
name: name,
|
|
1062
1661
|
description: description,
|
|
1063
1662
|
inputSchema: inputSchema,
|
|
1064
|
-
outputSchema: outputSchema
|
|
1663
|
+
outputSchema: outputSchema,
|
|
1664
|
+
annotations: annotations
|
|
1065
1665
|
});
|
|
1066
1666
|
var definition = {
|
|
1067
1667
|
name: name,
|
|
1068
1668
|
description: description,
|
|
1069
1669
|
inputSchema: inputSchema,
|
|
1070
1670
|
outputSchema: outputSchema,
|
|
1671
|
+
annotations: annotations,
|
|
1071
1672
|
details: handlerDetails,
|
|
1072
1673
|
dispatch: dispatch,
|
|
1073
1674
|
filterMetadata: filterMetadata,
|
|
@@ -1096,7 +1697,7 @@ function resolveInputSchema(context) {
|
|
|
1096
1697
|
var result;
|
|
1097
1698
|
try {
|
|
1098
1699
|
var exported = model.arktypeToJsonSchemaForExport(handlerDetails.inputType);
|
|
1099
|
-
if (exported && (typeof exported === "undefined" ? "undefined" : _type_of$
|
|
1700
|
+
if (exported && (typeof exported === "undefined" ? "undefined" : _type_of$3(exported)) === 'object') {
|
|
1100
1701
|
result = exported;
|
|
1101
1702
|
} else {
|
|
1102
1703
|
// arktypeToJsonSchemaForExport returned a non-object (shouldn't happen for object schemas).
|
|
@@ -1115,15 +1716,15 @@ function resolveInputSchema(context) {
|
|
|
1115
1716
|
return result;
|
|
1116
1717
|
}
|
|
1117
1718
|
|
|
1118
|
-
function _array_like_to_array$
|
|
1719
|
+
function _array_like_to_array$7(arr, len) {
|
|
1119
1720
|
if (len == null || len > arr.length) len = arr.length;
|
|
1120
1721
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1121
1722
|
return arr2;
|
|
1122
1723
|
}
|
|
1123
|
-
function _array_without_holes$
|
|
1124
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
1724
|
+
function _array_without_holes$6(arr) {
|
|
1725
|
+
if (Array.isArray(arr)) return _array_like_to_array$7(arr);
|
|
1125
1726
|
}
|
|
1126
|
-
function asyncGeneratorStep$
|
|
1727
|
+
function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
|
|
1127
1728
|
try {
|
|
1128
1729
|
var info = gen[key](arg);
|
|
1129
1730
|
var value = info.value;
|
|
@@ -1137,39 +1738,39 @@ function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
|
|
|
1137
1738
|
Promise.resolve(value).then(_next, _throw);
|
|
1138
1739
|
}
|
|
1139
1740
|
}
|
|
1140
|
-
function _async_to_generator$
|
|
1741
|
+
function _async_to_generator$5(fn) {
|
|
1141
1742
|
return function() {
|
|
1142
1743
|
var self = this, args = arguments;
|
|
1143
1744
|
return new Promise(function(resolve, reject) {
|
|
1144
1745
|
var gen = fn.apply(self, args);
|
|
1145
1746
|
function _next(value) {
|
|
1146
|
-
asyncGeneratorStep$
|
|
1747
|
+
asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "next", value);
|
|
1147
1748
|
}
|
|
1148
1749
|
function _throw(err) {
|
|
1149
|
-
asyncGeneratorStep$
|
|
1750
|
+
asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "throw", err);
|
|
1150
1751
|
}
|
|
1151
1752
|
_next(undefined);
|
|
1152
1753
|
});
|
|
1153
1754
|
};
|
|
1154
1755
|
}
|
|
1155
|
-
function _iterable_to_array$
|
|
1756
|
+
function _iterable_to_array$6(iter) {
|
|
1156
1757
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
1157
1758
|
}
|
|
1158
|
-
function _non_iterable_spread$
|
|
1759
|
+
function _non_iterable_spread$6() {
|
|
1159
1760
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1160
1761
|
}
|
|
1161
|
-
function _to_consumable_array$
|
|
1162
|
-
return _array_without_holes$
|
|
1762
|
+
function _to_consumable_array$6(arr) {
|
|
1763
|
+
return _array_without_holes$6(arr) || _iterable_to_array$6(arr) || _unsupported_iterable_to_array$7(arr) || _non_iterable_spread$6();
|
|
1163
1764
|
}
|
|
1164
|
-
function _unsupported_iterable_to_array$
|
|
1765
|
+
function _unsupported_iterable_to_array$7(o, minLen) {
|
|
1165
1766
|
if (!o) return;
|
|
1166
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
1767
|
+
if (typeof o === "string") return _array_like_to_array$7(o, minLen);
|
|
1167
1768
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1168
1769
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1169
1770
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1170
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
1771
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$7(o, minLen);
|
|
1171
1772
|
}
|
|
1172
|
-
function _ts_generator$
|
|
1773
|
+
function _ts_generator$5(thisArg, body) {
|
|
1173
1774
|
var f, y, t, _ = {
|
|
1174
1775
|
label: 0,
|
|
1175
1776
|
sent: function() {
|
|
@@ -1312,7 +1913,7 @@ function _ts_generator$4(thisArg, body) {
|
|
|
1312
1913
|
};
|
|
1313
1914
|
var name = MODEL_GET_TOOL_NAME;
|
|
1314
1915
|
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.';
|
|
1315
|
-
return {
|
|
1916
|
+
return buildStaticToolDefinition({
|
|
1316
1917
|
name: name,
|
|
1317
1918
|
description: description,
|
|
1318
1919
|
inputSchema: MODEL_GET_INPUT_SCHEMA,
|
|
@@ -1322,26 +1923,17 @@ function _ts_generator$4(thisArg, body) {
|
|
|
1322
1923
|
modelType: MODEL_GET_DISPATCH_MODEL_TYPE
|
|
1323
1924
|
},
|
|
1324
1925
|
staticHandler: handler,
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
effectiveReadOnly: true
|
|
1331
|
-
},
|
|
1332
|
-
staticWireEntry: buildStaticWireEntry({
|
|
1333
|
-
name: name,
|
|
1334
|
-
description: description,
|
|
1335
|
-
inputSchema: MODEL_GET_INPUT_SCHEMA,
|
|
1336
|
-
outputSchema: MODEL_GET_OUTPUT_SCHEMA
|
|
1337
|
-
})
|
|
1338
|
-
};
|
|
1926
|
+
effectiveReadOnly: true,
|
|
1927
|
+
rule: {
|
|
1928
|
+
requireAuthenticated: true
|
|
1929
|
+
}
|
|
1930
|
+
});
|
|
1339
1931
|
}
|
|
1340
1932
|
// MARK: Handler
|
|
1341
1933
|
function modelGetToolHandler(args, ctx, deps) {
|
|
1342
|
-
return _async_to_generator$
|
|
1934
|
+
return _async_to_generator$5(function() {
|
|
1343
1935
|
var result, input, identity, resolvedKeys, merged, error;
|
|
1344
|
-
return _ts_generator$
|
|
1936
|
+
return _ts_generator$5(this, function(_state) {
|
|
1345
1937
|
switch(_state.label){
|
|
1346
1938
|
case 0:
|
|
1347
1939
|
_state.trys.push([
|
|
@@ -1358,7 +1950,7 @@ function modelGetToolHandler(args, ctx, deps) {
|
|
|
1358
1950
|
resolvedKeys = resolveKeys(input.keys, identity);
|
|
1359
1951
|
return [
|
|
1360
1952
|
4,
|
|
1361
|
-
readInChunks({
|
|
1953
|
+
readInChunks$1({
|
|
1362
1954
|
modelType: input.modelType,
|
|
1363
1955
|
keys: resolvedKeys,
|
|
1364
1956
|
auth: ctx.auth,
|
|
@@ -1447,10 +2039,10 @@ function resolveKeys(keys, identity) {
|
|
|
1447
2039
|
}
|
|
1448
2040
|
return resolved;
|
|
1449
2041
|
}
|
|
1450
|
-
function readInChunks(input) {
|
|
1451
|
-
return _async_to_generator$
|
|
2042
|
+
function readInChunks$1(input) {
|
|
2043
|
+
return _async_to_generator$5(function() {
|
|
1452
2044
|
var modelType, keys, auth, readDocuments, merged, offset, _merged_results, _merged_errors, batch, partial;
|
|
1453
|
-
return _ts_generator$
|
|
2045
|
+
return _ts_generator$5(this, function(_state) {
|
|
1454
2046
|
switch(_state.label){
|
|
1455
2047
|
case 0:
|
|
1456
2048
|
modelType = input.modelType, keys = input.keys, auth = input.auth, readDocuments = input.readDocuments;
|
|
@@ -1472,8 +2064,8 @@ function readInChunks(input) {
|
|
|
1472
2064
|
];
|
|
1473
2065
|
case 2:
|
|
1474
2066
|
partial = _state.sent();
|
|
1475
|
-
(_merged_results = merged.results).push.apply(_merged_results, _to_consumable_array$
|
|
1476
|
-
(_merged_errors = merged.errors).push.apply(_merged_errors, _to_consumable_array$
|
|
2067
|
+
(_merged_results = merged.results).push.apply(_merged_results, _to_consumable_array$6(partial.results));
|
|
2068
|
+
(_merged_errors = merged.errors).push.apply(_merged_errors, _to_consumable_array$6(partial.errors));
|
|
1477
2069
|
_state.label = 3;
|
|
1478
2070
|
case 3:
|
|
1479
2071
|
offset += MCP_MODEL_GET_BATCH_SIZE;
|
|
@@ -1564,15 +2156,15 @@ var MODEL_GET_OUTPUT_SCHEMA = {
|
|
|
1564
2156
|
}
|
|
1565
2157
|
};
|
|
1566
2158
|
|
|
1567
|
-
function _array_like_to_array$
|
|
2159
|
+
function _array_like_to_array$6(arr, len) {
|
|
1568
2160
|
if (len == null || len > arr.length) len = arr.length;
|
|
1569
2161
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
1570
2162
|
return arr2;
|
|
1571
2163
|
}
|
|
1572
|
-
function _array_without_holes$
|
|
1573
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
2164
|
+
function _array_without_holes$5(arr) {
|
|
2165
|
+
if (Array.isArray(arr)) return _array_like_to_array$6(arr);
|
|
1574
2166
|
}
|
|
1575
|
-
function _define_property$
|
|
2167
|
+
function _define_property$7(obj, key, value) {
|
|
1576
2168
|
if (key in obj) {
|
|
1577
2169
|
Object.defineProperty(obj, key, {
|
|
1578
2170
|
value: value,
|
|
@@ -1585,13 +2177,13 @@ function _define_property$6(obj, key, value) {
|
|
|
1585
2177
|
}
|
|
1586
2178
|
return obj;
|
|
1587
2179
|
}
|
|
1588
|
-
function _iterable_to_array$
|
|
2180
|
+
function _iterable_to_array$5(iter) {
|
|
1589
2181
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
1590
2182
|
}
|
|
1591
|
-
function _non_iterable_spread$
|
|
2183
|
+
function _non_iterable_spread$5() {
|
|
1592
2184
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
1593
2185
|
}
|
|
1594
|
-
function _object_spread$
|
|
2186
|
+
function _object_spread$4(target) {
|
|
1595
2187
|
for(var i = 1; i < arguments.length; i++){
|
|
1596
2188
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
1597
2189
|
var ownKeys = Object.keys(source);
|
|
@@ -1601,12 +2193,12 @@ function _object_spread$2(target) {
|
|
|
1601
2193
|
}));
|
|
1602
2194
|
}
|
|
1603
2195
|
ownKeys.forEach(function(key) {
|
|
1604
|
-
_define_property$
|
|
2196
|
+
_define_property$7(target, key, source[key]);
|
|
1605
2197
|
});
|
|
1606
2198
|
}
|
|
1607
2199
|
return target;
|
|
1608
2200
|
}
|
|
1609
|
-
function ownKeys(object, enumerableOnly) {
|
|
2201
|
+
function ownKeys$2(object, enumerableOnly) {
|
|
1610
2202
|
var keys = Object.keys(object);
|
|
1611
2203
|
if (Object.getOwnPropertySymbols) {
|
|
1612
2204
|
var symbols = Object.getOwnPropertySymbols(object);
|
|
@@ -1614,27 +2206,27 @@ function ownKeys(object, enumerableOnly) {
|
|
|
1614
2206
|
}
|
|
1615
2207
|
return keys;
|
|
1616
2208
|
}
|
|
1617
|
-
function _object_spread_props(target, source) {
|
|
2209
|
+
function _object_spread_props$2(target, source) {
|
|
1618
2210
|
source = source != null ? source : {};
|
|
1619
2211
|
if (Object.getOwnPropertyDescriptors) {
|
|
1620
2212
|
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
1621
2213
|
} else {
|
|
1622
|
-
ownKeys(Object(source)).forEach(function(key) {
|
|
2214
|
+
ownKeys$2(Object(source)).forEach(function(key) {
|
|
1623
2215
|
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
1624
2216
|
});
|
|
1625
2217
|
}
|
|
1626
2218
|
return target;
|
|
1627
2219
|
}
|
|
1628
|
-
function _to_consumable_array$
|
|
1629
|
-
return _array_without_holes$
|
|
2220
|
+
function _to_consumable_array$5(arr) {
|
|
2221
|
+
return _array_without_holes$5(arr) || _iterable_to_array$5(arr) || _unsupported_iterable_to_array$6(arr) || _non_iterable_spread$5();
|
|
1630
2222
|
}
|
|
1631
|
-
function _unsupported_iterable_to_array$
|
|
2223
|
+
function _unsupported_iterable_to_array$6(o, minLen) {
|
|
1632
2224
|
if (!o) return;
|
|
1633
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
2225
|
+
if (typeof o === "string") return _array_like_to_array$6(o, minLen);
|
|
1634
2226
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
1635
2227
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
1636
2228
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
1637
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
2229
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$6(o, minLen);
|
|
1638
2230
|
}
|
|
1639
2231
|
// MARK: Constants
|
|
1640
2232
|
/**
|
|
@@ -1683,7 +2275,7 @@ function _unsupported_iterable_to_array$5(o, minLen) {
|
|
|
1683
2275
|
var name = MODEL_INFO_TOOL_NAME;
|
|
1684
2276
|
var count = deps.manifest.length;
|
|
1685
2277
|
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.';
|
|
1686
|
-
return {
|
|
2278
|
+
return buildStaticToolDefinition({
|
|
1687
2279
|
name: name,
|
|
1688
2280
|
description: description,
|
|
1689
2281
|
inputSchema: MODEL_INFO_INPUT_SCHEMA,
|
|
@@ -1693,27 +2285,19 @@ function _unsupported_iterable_to_array$5(o, minLen) {
|
|
|
1693
2285
|
modelType: MODEL_INFO_DISPATCH_MODEL_TYPE
|
|
1694
2286
|
},
|
|
1695
2287
|
staticHandler: handler,
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
effectiveReadOnly: true
|
|
1702
|
-
},
|
|
1703
|
-
staticWireEntry: buildStaticWireEntry({
|
|
1704
|
-
name: name,
|
|
1705
|
-
description: description,
|
|
1706
|
-
inputSchema: MODEL_INFO_INPUT_SCHEMA,
|
|
1707
|
-
outputSchema: MODEL_INFO_OUTPUT_SCHEMA
|
|
1708
|
-
})
|
|
1709
|
-
};
|
|
2288
|
+
effectiveReadOnly: true,
|
|
2289
|
+
rule: {
|
|
2290
|
+
requireAuthenticated: true
|
|
2291
|
+
}
|
|
2292
|
+
});
|
|
1710
2293
|
}
|
|
1711
2294
|
// MARK: Handler
|
|
1712
2295
|
function modelInfoToolHandler(args, _ctx, deps) {
|
|
1713
2296
|
var result;
|
|
1714
2297
|
try {
|
|
1715
2298
|
var input = parseModelInfoInput(args);
|
|
1716
|
-
var
|
|
2299
|
+
var resolved = resolveModelInfoOutput(input, deps.manifest);
|
|
2300
|
+
var output = attachReferencedEnums(resolved, deps.enums);
|
|
1717
2301
|
result = {
|
|
1718
2302
|
content: [
|
|
1719
2303
|
{
|
|
@@ -1750,16 +2334,123 @@ function resolveModelInfoOutput(input, manifest) {
|
|
|
1750
2334
|
}
|
|
1751
2335
|
return output;
|
|
1752
2336
|
}
|
|
1753
|
-
// MARK:
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1762
|
-
|
|
2337
|
+
// MARK: Enum attachment
|
|
2338
|
+
/**
|
|
2339
|
+
* Attaches the value→label tables for every enum referenced (by `enumRef`) on the returned models'
|
|
2340
|
+
* fields — recursively through `nestedFields` — as a top-level `enums` section.
|
|
2341
|
+
*
|
|
2342
|
+
* Gated behind full field detail: only `single` / `multiple` rows and `list` rows that opted into
|
|
2343
|
+
* `fields:true` carry the persisted `fields` array, so the compact default modes are untouched.
|
|
2344
|
+
* Returns the input unchanged when no enum map is wired or no referenced enum resolves.
|
|
2345
|
+
*
|
|
2346
|
+
* @param output - The resolved model-info output.
|
|
2347
|
+
* @param enums - The optional enum value tables keyed by name.
|
|
2348
|
+
* @returns The output, with an `enums` section attached when detailed rows reference known enums.
|
|
2349
|
+
*/ function attachReferencedEnums(output, enums) {
|
|
2350
|
+
var result = output;
|
|
2351
|
+
if (enums != null) {
|
|
2352
|
+
var referenced = new Set();
|
|
2353
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2354
|
+
try {
|
|
2355
|
+
for(var _iterator = collectDetailedEntries(output)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
2356
|
+
var entry = _step.value;
|
|
2357
|
+
collectFieldEnumRefs(entry.fields, referenced);
|
|
2358
|
+
}
|
|
2359
|
+
} catch (err) {
|
|
2360
|
+
_didIteratorError = true;
|
|
2361
|
+
_iteratorError = err;
|
|
2362
|
+
} finally{
|
|
2363
|
+
try {
|
|
2364
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2365
|
+
_iterator.return();
|
|
2366
|
+
}
|
|
2367
|
+
} finally{
|
|
2368
|
+
if (_didIteratorError) {
|
|
2369
|
+
throw _iteratorError;
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
}
|
|
2373
|
+
var tables = [];
|
|
2374
|
+
var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
2375
|
+
try {
|
|
2376
|
+
for(var _iterator1 = referenced[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
|
|
2377
|
+
var name = _step1.value;
|
|
2378
|
+
var table = enums[name];
|
|
2379
|
+
if (table != null) tables.push(table);
|
|
2380
|
+
}
|
|
2381
|
+
} catch (err) {
|
|
2382
|
+
_didIteratorError1 = true;
|
|
2383
|
+
_iteratorError1 = err;
|
|
2384
|
+
} finally{
|
|
2385
|
+
try {
|
|
2386
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
2387
|
+
_iterator1.return();
|
|
2388
|
+
}
|
|
2389
|
+
} finally{
|
|
2390
|
+
if (_didIteratorError1) {
|
|
2391
|
+
throw _iteratorError1;
|
|
2392
|
+
}
|
|
2393
|
+
}
|
|
2394
|
+
}
|
|
2395
|
+
if (tables.length > 0) {
|
|
2396
|
+
result = _object_spread_props$2(_object_spread$4({}, output), {
|
|
2397
|
+
enums: tables
|
|
2398
|
+
});
|
|
2399
|
+
}
|
|
2400
|
+
}
|
|
2401
|
+
return result;
|
|
2402
|
+
}
|
|
2403
|
+
/**
|
|
2404
|
+
* Collects the full {@link McpManifestModelEntry} rows (those carrying a persisted `fields` array)
|
|
2405
|
+
* from a model-info output. Summary rows (which expose `fieldCount`, not `fields`) are skipped.
|
|
2406
|
+
*
|
|
2407
|
+
* @param output - The resolved model-info output.
|
|
2408
|
+
* @returns The detailed model entries present in the output.
|
|
2409
|
+
*/ function collectDetailedEntries(output) {
|
|
2410
|
+
var rows = [];
|
|
2411
|
+
if (output.mode === 'single') {
|
|
2412
|
+
rows.push(output.model);
|
|
2413
|
+
} else if (output.mode === 'list' || output.mode === 'multiple') {
|
|
2414
|
+
var _rows;
|
|
2415
|
+
(_rows = rows).push.apply(_rows, _to_consumable_array$5(output.models));
|
|
2416
|
+
}
|
|
2417
|
+
return rows.filter(function(row) {
|
|
2418
|
+
return Array.isArray(row.fields);
|
|
2419
|
+
});
|
|
2420
|
+
}
|
|
2421
|
+
function collectFieldEnumRefs(fields, into) {
|
|
2422
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
2423
|
+
try {
|
|
2424
|
+
for(var _iterator = fields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
2425
|
+
var field = _step.value;
|
|
2426
|
+
if (field.enumRef) into.add(field.enumRef);
|
|
2427
|
+
if (field.nestedFields) collectFieldEnumRefs(field.nestedFields, into);
|
|
2428
|
+
}
|
|
2429
|
+
} catch (err) {
|
|
2430
|
+
_didIteratorError = true;
|
|
2431
|
+
_iteratorError = err;
|
|
2432
|
+
} finally{
|
|
2433
|
+
try {
|
|
2434
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2435
|
+
_iterator.return();
|
|
2436
|
+
}
|
|
2437
|
+
} finally{
|
|
2438
|
+
if (_didIteratorError) {
|
|
2439
|
+
throw _iteratorError;
|
|
2440
|
+
}
|
|
2441
|
+
}
|
|
2442
|
+
}
|
|
2443
|
+
}
|
|
2444
|
+
// MARK: Input parsing
|
|
2445
|
+
function parseModelInfoInput(args) {
|
|
2446
|
+
var modelQueries = parseModelArg(args['model']);
|
|
2447
|
+
var modelGroup = parseModelGroupArg(args['modelGroup']);
|
|
2448
|
+
var all = parseBooleanArg(args['all'], 'all');
|
|
2449
|
+
var fields = parseBooleanArg(args['fields'], 'fields');
|
|
2450
|
+
return _object_spread$4(_object_spread_props$2(_object_spread$4(_object_spread_props$2(_object_spread$4({}, modelQueries == null ? {} : {
|
|
2451
|
+
modelQueries: modelQueries
|
|
2452
|
+
}), {
|
|
2453
|
+
modelIsArray: Array.isArray(args['model'])
|
|
1763
2454
|
}), modelGroup == null ? {} : {
|
|
1764
2455
|
modelGroup: modelGroup
|
|
1765
2456
|
}), {
|
|
@@ -1774,14 +2465,14 @@ function parseModelArg(raw) {
|
|
|
1774
2465
|
result = undefined;
|
|
1775
2466
|
} else if (typeof raw === 'string') {
|
|
1776
2467
|
result = [
|
|
1777
|
-
requireNonEmptyString(raw, 'model')
|
|
2468
|
+
requireNonEmptyString$1(raw, 'model')
|
|
1778
2469
|
];
|
|
1779
2470
|
} else if (Array.isArray(raw)) {
|
|
1780
2471
|
if (raw.length === 0) {
|
|
1781
2472
|
throw new Error('model-info: "model" array must contain at least one entry.');
|
|
1782
2473
|
}
|
|
1783
2474
|
result = raw.map(function(value, index) {
|
|
1784
|
-
return requireNonEmptyString(value, "model[".concat(index, "]"));
|
|
2475
|
+
return requireNonEmptyString$1(value, "model[".concat(index, "]"));
|
|
1785
2476
|
});
|
|
1786
2477
|
} else {
|
|
1787
2478
|
throw new TypeError('model-info: "model" must be a string or an array of strings when provided.');
|
|
@@ -1793,7 +2484,7 @@ function parseModelGroupArg(raw) {
|
|
|
1793
2484
|
if (raw == null) {
|
|
1794
2485
|
result = undefined;
|
|
1795
2486
|
} else if (typeof raw === 'string') {
|
|
1796
|
-
result = requireNonEmptyString(raw, 'modelGroup');
|
|
2487
|
+
result = requireNonEmptyString$1(raw, 'modelGroup');
|
|
1797
2488
|
} else {
|
|
1798
2489
|
throw new TypeError('model-info: "modelGroup" must be a string when provided.');
|
|
1799
2490
|
}
|
|
@@ -1810,7 +2501,7 @@ function parseBooleanArg(raw, label) {
|
|
|
1810
2501
|
}
|
|
1811
2502
|
return result;
|
|
1812
2503
|
}
|
|
1813
|
-
function requireNonEmptyString(value, label) {
|
|
2504
|
+
function requireNonEmptyString$1(value, label) {
|
|
1814
2505
|
if (typeof value !== 'string') {
|
|
1815
2506
|
throw new TypeError('model-info: "'.concat(label, '" must be a string.'));
|
|
1816
2507
|
}
|
|
@@ -1919,7 +2610,7 @@ function toModelRow(entry, detailed) {
|
|
|
1919
2610
|
return detailed ? entry : toSummaryRow(entry);
|
|
1920
2611
|
}
|
|
1921
2612
|
function toSummaryRow(entry) {
|
|
1922
|
-
return _object_spread$
|
|
2613
|
+
return _object_spread$4({
|
|
1923
2614
|
modelType: entry.modelType,
|
|
1924
2615
|
modelName: entry.modelName,
|
|
1925
2616
|
identityConst: entry.identityConst,
|
|
@@ -1947,7 +2638,7 @@ function toSummaryRow(entry) {
|
|
|
1947
2638
|
*
|
|
1948
2639
|
* @__NO_SIDE_EFFECTS__
|
|
1949
2640
|
*/ function computeGroupCounts(manifest) {
|
|
1950
|
-
var grouped = util.makeValuesGroupMap(_to_consumable_array$
|
|
2641
|
+
var grouped = util.makeValuesGroupMap(_to_consumable_array$5(manifest), function(entry) {
|
|
1951
2642
|
var _entry_modelGroup;
|
|
1952
2643
|
return (_entry_modelGroup = entry.modelGroup) !== null && _entry_modelGroup !== void 0 ? _entry_modelGroup : MODEL_INFO_UNGROUPED_LABEL;
|
|
1953
2644
|
});
|
|
@@ -2157,6 +2848,48 @@ var MODEL_ROW_SCHEMA = {
|
|
|
2157
2848
|
}
|
|
2158
2849
|
}
|
|
2159
2850
|
};
|
|
2851
|
+
/**
|
|
2852
|
+
* JSON-schema for one enum value→label table. Shared with the `enum-info` tool so both advertise the
|
|
2853
|
+
* identical enum shape.
|
|
2854
|
+
*/ var ENUM_TABLE_SCHEMA = {
|
|
2855
|
+
type: 'object',
|
|
2856
|
+
required: [
|
|
2857
|
+
'name',
|
|
2858
|
+
'values'
|
|
2859
|
+
],
|
|
2860
|
+
properties: {
|
|
2861
|
+
name: {
|
|
2862
|
+
type: 'string'
|
|
2863
|
+
},
|
|
2864
|
+
description: {
|
|
2865
|
+
type: 'string'
|
|
2866
|
+
},
|
|
2867
|
+
values: {
|
|
2868
|
+
type: 'array',
|
|
2869
|
+
items: {
|
|
2870
|
+
type: 'object',
|
|
2871
|
+
required: [
|
|
2872
|
+
'name',
|
|
2873
|
+
'value'
|
|
2874
|
+
],
|
|
2875
|
+
properties: {
|
|
2876
|
+
name: {
|
|
2877
|
+
type: 'string'
|
|
2878
|
+
},
|
|
2879
|
+
value: {
|
|
2880
|
+
type: [
|
|
2881
|
+
'string',
|
|
2882
|
+
'number'
|
|
2883
|
+
]
|
|
2884
|
+
},
|
|
2885
|
+
description: {
|
|
2886
|
+
type: 'string'
|
|
2887
|
+
}
|
|
2888
|
+
}
|
|
2889
|
+
}
|
|
2890
|
+
}
|
|
2891
|
+
}
|
|
2892
|
+
};
|
|
2160
2893
|
// MCP's `tools/list` validator requires `outputSchema.type === 'object'` at the root
|
|
2161
2894
|
// (see @modelcontextprotocol/sdk Zod schema), so the variants are expressed via a top-level
|
|
2162
2895
|
// object whose nested `oneOf` discriminates by the `mode` literal.
|
|
@@ -2212,7 +2945,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
|
|
|
2212
2945
|
type: 'string',
|
|
2213
2946
|
description: 'Present when `mode` is `"list"` from a `modelGroup` filter. The canonical group name.'
|
|
2214
2947
|
},
|
|
2215
|
-
model: _object_spread_props(_object_spread$
|
|
2948
|
+
model: _object_spread_props$2(_object_spread$4({}, MODEL_ROW_SCHEMA), {
|
|
2216
2949
|
description: 'Present when `mode` is `"single"`. The matched model entry (full detail unless `fields:false`).'
|
|
2217
2950
|
}),
|
|
2218
2951
|
notFound: {
|
|
@@ -2233,6 +2966,11 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
|
|
|
2233
2966
|
}
|
|
2234
2967
|
}
|
|
2235
2968
|
}
|
|
2969
|
+
},
|
|
2970
|
+
enums: {
|
|
2971
|
+
type: 'array',
|
|
2972
|
+
description: 'Value→label tables for the enums referenced by the returned models’ fields. Present only when full field detail is returned (single/multiple modes, or list/all with `fields:true`) and at least one referenced enum is registered.',
|
|
2973
|
+
items: ENUM_TABLE_SCHEMA
|
|
2236
2974
|
}
|
|
2237
2975
|
},
|
|
2238
2976
|
oneOf: [
|
|
@@ -2280,7 +3018,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
|
|
|
2280
3018
|
]
|
|
2281
3019
|
};
|
|
2282
3020
|
|
|
2283
|
-
function _define_property$
|
|
3021
|
+
function _define_property$6(obj, key, value) {
|
|
2284
3022
|
if (key in obj) {
|
|
2285
3023
|
Object.defineProperty(obj, key, {
|
|
2286
3024
|
value: value,
|
|
@@ -2293,7 +3031,7 @@ function _define_property$5(obj, key, value) {
|
|
|
2293
3031
|
}
|
|
2294
3032
|
return obj;
|
|
2295
3033
|
}
|
|
2296
|
-
function _object_spread$
|
|
3034
|
+
function _object_spread$3(target) {
|
|
2297
3035
|
for(var i = 1; i < arguments.length; i++){
|
|
2298
3036
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
2299
3037
|
var ownKeys = Object.keys(source);
|
|
@@ -2303,7 +3041,7 @@ function _object_spread$1(target) {
|
|
|
2303
3041
|
}));
|
|
2304
3042
|
}
|
|
2305
3043
|
ownKeys.forEach(function(key) {
|
|
2306
|
-
_define_property$
|
|
3044
|
+
_define_property$6(target, key, source[key]);
|
|
2307
3045
|
});
|
|
2308
3046
|
}
|
|
2309
3047
|
return target;
|
|
@@ -2342,7 +3080,7 @@ function _object_spread$1(target) {
|
|
|
2342
3080
|
};
|
|
2343
3081
|
var name = MODEL_DECODE_TOOL_NAME;
|
|
2344
3082
|
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', ").");
|
|
2345
|
-
return {
|
|
3083
|
+
return buildStaticToolDefinition({
|
|
2346
3084
|
name: name,
|
|
2347
3085
|
description: description,
|
|
2348
3086
|
inputSchema: MODEL_DECODE_INPUT_SCHEMA,
|
|
@@ -2352,20 +3090,11 @@ function _object_spread$1(target) {
|
|
|
2352
3090
|
modelType: MODEL_DECODE_DISPATCH_MODEL_TYPE
|
|
2353
3091
|
},
|
|
2354
3092
|
staticHandler: handler,
|
|
2355
|
-
|
|
2356
|
-
|
|
2357
|
-
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
effectiveReadOnly: true
|
|
2361
|
-
},
|
|
2362
|
-
staticWireEntry: buildStaticWireEntry({
|
|
2363
|
-
name: name,
|
|
2364
|
-
description: description,
|
|
2365
|
-
inputSchema: MODEL_DECODE_INPUT_SCHEMA,
|
|
2366
|
-
outputSchema: MODEL_DECODE_OUTPUT_SCHEMA
|
|
2367
|
-
})
|
|
2368
|
-
};
|
|
3093
|
+
effectiveReadOnly: true,
|
|
3094
|
+
rule: {
|
|
3095
|
+
requireAuthenticated: true
|
|
3096
|
+
}
|
|
3097
|
+
});
|
|
2369
3098
|
}
|
|
2370
3099
|
// MARK: Handler
|
|
2371
3100
|
function modelDecodeToolHandler(args, _ctx, deps) {
|
|
@@ -2441,7 +3170,7 @@ function parseModelDecodeInput(args) {
|
|
|
2441
3170
|
};
|
|
2442
3171
|
}
|
|
2443
3172
|
function toSegment(prefix, id, entry) {
|
|
2444
|
-
var segment = entry ? _object_spread$
|
|
3173
|
+
var segment = entry ? _object_spread$3({
|
|
2445
3174
|
prefix: prefix,
|
|
2446
3175
|
id: id,
|
|
2447
3176
|
modelType: entry.modelType,
|
|
@@ -2539,18 +3268,210 @@ var MODEL_DECODE_OUTPUT_SCHEMA = {
|
|
|
2539
3268
|
}
|
|
2540
3269
|
};
|
|
2541
3270
|
|
|
2542
|
-
|
|
3271
|
+
// MARK: Constants
|
|
3272
|
+
/**
|
|
3273
|
+
* Reserved tool name for the built-in `enum-info` static tool.
|
|
3274
|
+
*/ var ENUM_INFO_TOOL_NAME = 'enum-info';
|
|
3275
|
+
/**
|
|
3276
|
+
* Synthetic call type used in the tool's dispatch identity. Mirrors the `info` call shared with
|
|
3277
|
+
* `model-info`.
|
|
3278
|
+
*/ var ENUM_INFO_DISPATCH_CALL = 'info';
|
|
3279
|
+
/**
|
|
3280
|
+
* Synthetic model type used in the tool's dispatch identity. Apps avoiding collisions should not
|
|
3281
|
+
* register a real model literally named "enum".
|
|
3282
|
+
*/ var ENUM_INFO_DISPATCH_MODEL_TYPE = 'enum';
|
|
3283
|
+
// MARK: Factory
|
|
3284
|
+
/**
|
|
3285
|
+
* Builds the built-in `enum-info` MCP tool definition — the symmetric counterpart to `model-info`
|
|
3286
|
+
* for raw enum decoding.
|
|
3287
|
+
*
|
|
3288
|
+
* Resolves each requested enum name against the manifest's `enums` block and returns the matching
|
|
3289
|
+
* value→label tables; misses land in `notFound`. A bare string is treated as a one-element array.
|
|
3290
|
+
*
|
|
3291
|
+
* Output is delivered as both stringified JSON in `content[0].text` and `structuredContent` so MCP
|
|
3292
|
+
* clients can consume either form.
|
|
3293
|
+
*
|
|
3294
|
+
* @param deps - The frozen enum value tables loaded at boot from the MCP manifest JSON.
|
|
3295
|
+
* @returns A statically-registered {@link McpToolDefinition} ready to be appended to the MCP server
|
|
3296
|
+
* factory's tool registry.
|
|
3297
|
+
*/ function createEnumInfoTool(deps) {
|
|
3298
|
+
var handler = function handler(args, ctx) {
|
|
3299
|
+
return Promise.resolve(enumInfoToolHandler(args, ctx, deps));
|
|
3300
|
+
};
|
|
3301
|
+
var name = ENUM_INFO_TOOL_NAME;
|
|
3302
|
+
var count = Object.keys(deps.enums).length;
|
|
3303
|
+
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`.');
|
|
3304
|
+
return buildStaticToolDefinition({
|
|
3305
|
+
name: name,
|
|
3306
|
+
description: description,
|
|
3307
|
+
inputSchema: ENUM_INFO_INPUT_SCHEMA,
|
|
3308
|
+
outputSchema: ENUM_INFO_OUTPUT_SCHEMA,
|
|
3309
|
+
dispatch: {
|
|
3310
|
+
call: ENUM_INFO_DISPATCH_CALL,
|
|
3311
|
+
modelType: ENUM_INFO_DISPATCH_MODEL_TYPE
|
|
3312
|
+
},
|
|
3313
|
+
staticHandler: handler,
|
|
3314
|
+
effectiveReadOnly: true,
|
|
3315
|
+
rule: {
|
|
3316
|
+
requireAuthenticated: true
|
|
3317
|
+
}
|
|
3318
|
+
});
|
|
3319
|
+
}
|
|
3320
|
+
// MARK: Handler
|
|
3321
|
+
function enumInfoToolHandler(args, _ctx, deps) {
|
|
3322
|
+
var result;
|
|
3323
|
+
try {
|
|
3324
|
+
var names = parseEnumInfoInput(args);
|
|
3325
|
+
var output = resolveEnumInfoOutput(names, deps.enums);
|
|
3326
|
+
result = {
|
|
3327
|
+
content: [
|
|
3328
|
+
{
|
|
3329
|
+
type: 'text',
|
|
3330
|
+
text: JSON.stringify(output)
|
|
3331
|
+
}
|
|
3332
|
+
],
|
|
3333
|
+
structuredContent: output
|
|
3334
|
+
};
|
|
3335
|
+
} catch (error) {
|
|
3336
|
+
result = formatMcpToolErrorResponse(error);
|
|
3337
|
+
}
|
|
3338
|
+
return result;
|
|
3339
|
+
}
|
|
3340
|
+
/**
|
|
3341
|
+
* Resolves each requested enum name against the registered value tables.
|
|
3342
|
+
*
|
|
3343
|
+
* @param names - The requested enum declaration names.
|
|
3344
|
+
* @param enums - The registered enum value tables keyed by name.
|
|
3345
|
+
* @returns The matched tables, with any unmatched names in `notFound`.
|
|
3346
|
+
*
|
|
3347
|
+
* @__NO_SIDE_EFFECTS__
|
|
3348
|
+
*/ function resolveEnumInfoOutput(names, enums) {
|
|
3349
|
+
var found = [];
|
|
3350
|
+
var notFound = [];
|
|
3351
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
3352
|
+
try {
|
|
3353
|
+
for(var _iterator = names[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
3354
|
+
var name = _step.value;
|
|
3355
|
+
var table = enums[name];
|
|
3356
|
+
if (table == null) {
|
|
3357
|
+
notFound.push(name);
|
|
3358
|
+
} else {
|
|
3359
|
+
found.push(table);
|
|
3360
|
+
}
|
|
3361
|
+
}
|
|
3362
|
+
} catch (err) {
|
|
3363
|
+
_didIteratorError = true;
|
|
3364
|
+
_iteratorError = err;
|
|
3365
|
+
} finally{
|
|
3366
|
+
try {
|
|
3367
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
3368
|
+
_iterator.return();
|
|
3369
|
+
}
|
|
3370
|
+
} finally{
|
|
3371
|
+
if (_didIteratorError) {
|
|
3372
|
+
throw _iteratorError;
|
|
3373
|
+
}
|
|
3374
|
+
}
|
|
3375
|
+
}
|
|
3376
|
+
return notFound.length > 0 ? {
|
|
3377
|
+
enums: found,
|
|
3378
|
+
notFound: notFound
|
|
3379
|
+
} : {
|
|
3380
|
+
enums: found
|
|
3381
|
+
};
|
|
3382
|
+
}
|
|
3383
|
+
// MARK: Input parsing
|
|
3384
|
+
function parseEnumInfoInput(args) {
|
|
3385
|
+
var raw = args['enum'];
|
|
3386
|
+
var result;
|
|
3387
|
+
if (raw == null) {
|
|
3388
|
+
throw new Error('enum-info: "enum" is required and must be a string or an array of strings.');
|
|
3389
|
+
} else if (typeof raw === 'string') {
|
|
3390
|
+
result = [
|
|
3391
|
+
requireNonEmptyString(raw, 'enum')
|
|
3392
|
+
];
|
|
3393
|
+
} else if (Array.isArray(raw)) {
|
|
3394
|
+
if (raw.length === 0) {
|
|
3395
|
+
throw new Error('enum-info: "enum" array must contain at least one entry.');
|
|
3396
|
+
}
|
|
3397
|
+
result = raw.map(function(value, index) {
|
|
3398
|
+
return requireNonEmptyString(value, "enum[".concat(index, "]"));
|
|
3399
|
+
});
|
|
3400
|
+
} else {
|
|
3401
|
+
throw new TypeError('enum-info: "enum" must be a string or an array of strings.');
|
|
3402
|
+
}
|
|
3403
|
+
return result;
|
|
3404
|
+
}
|
|
3405
|
+
function requireNonEmptyString(value, label) {
|
|
3406
|
+
if (typeof value !== 'string') {
|
|
3407
|
+
throw new TypeError('enum-info: "'.concat(label, '" must be a string.'));
|
|
3408
|
+
}
|
|
3409
|
+
var trimmed = value.trim();
|
|
3410
|
+
if (trimmed.length === 0) {
|
|
3411
|
+
throw new Error('enum-info: "'.concat(label, '" must be a non-empty string.'));
|
|
3412
|
+
}
|
|
3413
|
+
return trimmed;
|
|
3414
|
+
}
|
|
3415
|
+
// MARK: Schemas
|
|
3416
|
+
var ENUM_INFO_INPUT_SCHEMA = {
|
|
3417
|
+
type: 'object',
|
|
3418
|
+
required: [
|
|
3419
|
+
'enum'
|
|
3420
|
+
],
|
|
3421
|
+
properties: {
|
|
3422
|
+
enum: {
|
|
3423
|
+
description: 'One enum name (string) or many (string array), each matched exactly by declaration name (e.g. "JobWorkerTimesheetState"). Misses are reported in `notFound`.',
|
|
3424
|
+
oneOf: [
|
|
3425
|
+
{
|
|
3426
|
+
type: 'string',
|
|
3427
|
+
minLength: 1
|
|
3428
|
+
},
|
|
3429
|
+
{
|
|
3430
|
+
type: 'array',
|
|
3431
|
+
minItems: 1,
|
|
3432
|
+
items: {
|
|
3433
|
+
type: 'string',
|
|
3434
|
+
minLength: 1
|
|
3435
|
+
}
|
|
3436
|
+
}
|
|
3437
|
+
]
|
|
3438
|
+
}
|
|
3439
|
+
},
|
|
3440
|
+
additionalProperties: false
|
|
3441
|
+
};
|
|
3442
|
+
var ENUM_INFO_OUTPUT_SCHEMA = {
|
|
3443
|
+
type: 'object',
|
|
3444
|
+
required: [
|
|
3445
|
+
'enums'
|
|
3446
|
+
],
|
|
3447
|
+
properties: {
|
|
3448
|
+
enums: {
|
|
3449
|
+
type: 'array',
|
|
3450
|
+
description: 'The resolved enum value→label tables, in request order.',
|
|
3451
|
+
items: ENUM_TABLE_SCHEMA
|
|
3452
|
+
},
|
|
3453
|
+
notFound: {
|
|
3454
|
+
type: 'array',
|
|
3455
|
+
description: 'Requested enum names that matched no registered enum.',
|
|
3456
|
+
items: {
|
|
3457
|
+
type: 'string'
|
|
3458
|
+
}
|
|
3459
|
+
}
|
|
3460
|
+
}
|
|
3461
|
+
};
|
|
3462
|
+
|
|
3463
|
+
function _array_like_to_array$5(arr, len) {
|
|
2543
3464
|
if (len == null || len > arr.length) len = arr.length;
|
|
2544
3465
|
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
2545
3466
|
return arr2;
|
|
2546
3467
|
}
|
|
2547
|
-
function _array_with_holes$
|
|
3468
|
+
function _array_with_holes$3(arr) {
|
|
2548
3469
|
if (Array.isArray(arr)) return arr;
|
|
2549
3470
|
}
|
|
2550
|
-
function _array_without_holes$
|
|
2551
|
-
if (Array.isArray(arr)) return _array_like_to_array$
|
|
3471
|
+
function _array_without_holes$4(arr) {
|
|
3472
|
+
if (Array.isArray(arr)) return _array_like_to_array$5(arr);
|
|
2552
3473
|
}
|
|
2553
|
-
function _define_property$
|
|
3474
|
+
function _define_property$5(obj, key, value) {
|
|
2554
3475
|
if (key in obj) {
|
|
2555
3476
|
Object.defineProperty(obj, key, {
|
|
2556
3477
|
value: value,
|
|
@@ -2563,10 +3484,10 @@ function _define_property$4(obj, key, value) {
|
|
|
2563
3484
|
}
|
|
2564
3485
|
return obj;
|
|
2565
3486
|
}
|
|
2566
|
-
function _iterable_to_array$
|
|
3487
|
+
function _iterable_to_array$4(iter) {
|
|
2567
3488
|
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
2568
3489
|
}
|
|
2569
|
-
function _iterable_to_array_limit$
|
|
3490
|
+
function _iterable_to_array_limit$3(arr, i) {
|
|
2570
3491
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
2571
3492
|
if (_i == null) return;
|
|
2572
3493
|
var _arr = [];
|
|
@@ -2590,13 +3511,13 @@ function _iterable_to_array_limit$2(arr, i) {
|
|
|
2590
3511
|
}
|
|
2591
3512
|
return _arr;
|
|
2592
3513
|
}
|
|
2593
|
-
function _non_iterable_rest$
|
|
3514
|
+
function _non_iterable_rest$3() {
|
|
2594
3515
|
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
2595
3516
|
}
|
|
2596
|
-
function _non_iterable_spread$
|
|
3517
|
+
function _non_iterable_spread$4() {
|
|
2597
3518
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
2598
3519
|
}
|
|
2599
|
-
function _object_spread(target) {
|
|
3520
|
+
function _object_spread$2(target) {
|
|
2600
3521
|
for(var i = 1; i < arguments.length; i++){
|
|
2601
3522
|
var source = arguments[i] != null ? arguments[i] : {};
|
|
2602
3523
|
var ownKeys = Object.keys(source);
|
|
@@ -2606,24 +3527,24 @@ function _object_spread(target) {
|
|
|
2606
3527
|
}));
|
|
2607
3528
|
}
|
|
2608
3529
|
ownKeys.forEach(function(key) {
|
|
2609
|
-
_define_property$
|
|
3530
|
+
_define_property$5(target, key, source[key]);
|
|
2610
3531
|
});
|
|
2611
3532
|
}
|
|
2612
3533
|
return target;
|
|
2613
3534
|
}
|
|
2614
|
-
function _sliced_to_array$
|
|
2615
|
-
return _array_with_holes$
|
|
3535
|
+
function _sliced_to_array$3(arr, i) {
|
|
3536
|
+
return _array_with_holes$3(arr) || _iterable_to_array_limit$3(arr, i) || _unsupported_iterable_to_array$5(arr, i) || _non_iterable_rest$3();
|
|
2616
3537
|
}
|
|
2617
|
-
function _to_consumable_array$
|
|
2618
|
-
return _array_without_holes$
|
|
3538
|
+
function _to_consumable_array$4(arr) {
|
|
3539
|
+
return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$5(arr) || _non_iterable_spread$4();
|
|
2619
3540
|
}
|
|
2620
|
-
function _unsupported_iterable_to_array$
|
|
3541
|
+
function _unsupported_iterable_to_array$5(o, minLen) {
|
|
2621
3542
|
if (!o) return;
|
|
2622
|
-
if (typeof o === "string") return _array_like_to_array$
|
|
3543
|
+
if (typeof o === "string") return _array_like_to_array$5(o, minLen);
|
|
2623
3544
|
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
2624
3545
|
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
2625
3546
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
2626
|
-
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$
|
|
3547
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
|
|
2627
3548
|
}
|
|
2628
3549
|
// MARK: Constants
|
|
2629
3550
|
/**
|
|
@@ -2657,7 +3578,7 @@ function _unsupported_iterable_to_array$4(o, minLen) {
|
|
|
2657
3578
|
var name = WHOAMI_TOOL_NAME;
|
|
2658
3579
|
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';
|
|
2659
3580
|
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.");
|
|
2660
|
-
return {
|
|
3581
|
+
return buildStaticToolDefinition({
|
|
2661
3582
|
name: name,
|
|
2662
3583
|
description: description,
|
|
2663
3584
|
inputSchema: WHOAMI_INPUT_SCHEMA,
|
|
@@ -2667,18 +3588,9 @@ function _unsupported_iterable_to_array$4(o, minLen) {
|
|
|
2667
3588
|
modelType: WHOAMI_DISPATCH_MODEL_TYPE
|
|
2668
3589
|
},
|
|
2669
3590
|
staticHandler: handler,
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
effectiveReadOnly: true
|
|
2674
|
-
},
|
|
2675
|
-
staticWireEntry: buildStaticWireEntry({
|
|
2676
|
-
name: name,
|
|
2677
|
-
description: description,
|
|
2678
|
-
inputSchema: WHOAMI_INPUT_SCHEMA,
|
|
2679
|
-
outputSchema: WHOAMI_OUTPUT_SCHEMA
|
|
2680
|
-
})
|
|
2681
|
-
};
|
|
3591
|
+
effectiveReadOnly: true,
|
|
3592
|
+
rule: {}
|
|
3593
|
+
});
|
|
2682
3594
|
}
|
|
2683
3595
|
// MARK: Handler
|
|
2684
3596
|
function whoamiToolHandler(ctx, deps) {
|
|
@@ -2697,14 +3609,14 @@ function whoamiToolHandler(ctx, deps) {
|
|
|
2697
3609
|
}
|
|
2698
3610
|
var token = (_auth_token = auth.token) !== null && _auth_token !== void 0 ? _auth_token : {};
|
|
2699
3611
|
var presentKeys = Object.entries(token).filter(function(param) {
|
|
2700
|
-
var _param = _sliced_to_array$
|
|
3612
|
+
var _param = _sliced_to_array$3(param, 2), value = _param[1];
|
|
2701
3613
|
return value !== undefined;
|
|
2702
3614
|
}).map(function(param) {
|
|
2703
|
-
var _param = _sliced_to_array$
|
|
3615
|
+
var _param = _sliced_to_array$3(param, 1), key = _param[0];
|
|
2704
3616
|
return key;
|
|
2705
3617
|
});
|
|
2706
3618
|
var roleSet = deps.roleReader == null ? new Set() : deps.roleReader(token);
|
|
2707
|
-
var roles = _to_consumable_array$
|
|
3619
|
+
var roles = _to_consumable_array$4(roleSet).sort(function(a, b) {
|
|
2708
3620
|
return a.localeCompare(b);
|
|
2709
3621
|
});
|
|
2710
3622
|
var claimsByKey = new Map();
|
|
@@ -2741,7 +3653,7 @@ function whoamiToolHandler(ctx, deps) {
|
|
|
2741
3653
|
if (claim1 == null) {
|
|
2742
3654
|
unknownClaimKeys.push(key);
|
|
2743
3655
|
} else {
|
|
2744
|
-
claimDetails.push(_object_spread({
|
|
3656
|
+
claimDetails.push(_object_spread$2({
|
|
2745
3657
|
key: claim1.key,
|
|
2746
3658
|
description: claim1.description,
|
|
2747
3659
|
grantedRoles: claim1.mapping.roles,
|
|
@@ -2766,10 +3678,10 @@ function whoamiToolHandler(ctx, deps) {
|
|
|
2766
3678
|
}
|
|
2767
3679
|
}
|
|
2768
3680
|
}
|
|
2769
|
-
var output1 = _object_spread({
|
|
3681
|
+
var output1 = _object_spread$2({
|
|
2770
3682
|
authenticated: true,
|
|
2771
3683
|
uid: auth.uid,
|
|
2772
|
-
claims: _object_spread({}, token),
|
|
3684
|
+
claims: _object_spread$2({}, token),
|
|
2773
3685
|
roles: roles,
|
|
2774
3686
|
claimDetails: claimDetails,
|
|
2775
3687
|
unknownClaimKeys: unknownClaimKeys
|
|
@@ -2876,99 +3788,989 @@ function appendUnknownClaimLines(lines, unknownClaimKeys) {
|
|
|
2876
3788
|
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
2877
3789
|
_iterator.return();
|
|
2878
3790
|
}
|
|
2879
|
-
} finally{
|
|
2880
|
-
if (_didIteratorError) {
|
|
2881
|
-
throw _iteratorError;
|
|
3791
|
+
} finally{
|
|
3792
|
+
if (_didIteratorError) {
|
|
3793
|
+
throw _iteratorError;
|
|
3794
|
+
}
|
|
3795
|
+
}
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
// MARK: Schemas
|
|
3799
|
+
var WHOAMI_INPUT_SCHEMA = {
|
|
3800
|
+
type: 'object',
|
|
3801
|
+
properties: {},
|
|
3802
|
+
additionalProperties: false
|
|
3803
|
+
};
|
|
3804
|
+
var WHOAMI_OUTPUT_SCHEMA = {
|
|
3805
|
+
type: 'object',
|
|
3806
|
+
required: [
|
|
3807
|
+
'authenticated',
|
|
3808
|
+
'claims',
|
|
3809
|
+
'roles',
|
|
3810
|
+
'claimDetails',
|
|
3811
|
+
'unknownClaimKeys'
|
|
3812
|
+
],
|
|
3813
|
+
description: 'Caller identity, raw token claims, decoded role set, and per-claim descriptions for every key present on the live token.',
|
|
3814
|
+
properties: {
|
|
3815
|
+
authenticated: {
|
|
3816
|
+
type: 'boolean'
|
|
3817
|
+
},
|
|
3818
|
+
uid: {
|
|
3819
|
+
type: 'string'
|
|
3820
|
+
},
|
|
3821
|
+
email: {
|
|
3822
|
+
type: 'string'
|
|
3823
|
+
},
|
|
3824
|
+
emailVerified: {
|
|
3825
|
+
type: 'boolean'
|
|
3826
|
+
},
|
|
3827
|
+
app: {
|
|
3828
|
+
type: 'string'
|
|
3829
|
+
},
|
|
3830
|
+
claims: {
|
|
3831
|
+
type: 'object',
|
|
3832
|
+
additionalProperties: true
|
|
3833
|
+
},
|
|
3834
|
+
roles: {
|
|
3835
|
+
type: 'array',
|
|
3836
|
+
items: {
|
|
3837
|
+
type: 'string'
|
|
3838
|
+
}
|
|
3839
|
+
},
|
|
3840
|
+
claimDetails: {
|
|
3841
|
+
type: 'array',
|
|
3842
|
+
items: {
|
|
3843
|
+
type: 'object',
|
|
3844
|
+
required: [
|
|
3845
|
+
'key',
|
|
3846
|
+
'description',
|
|
3847
|
+
'grantedRoles',
|
|
3848
|
+
'inverse',
|
|
3849
|
+
'tags'
|
|
3850
|
+
],
|
|
3851
|
+
properties: {
|
|
3852
|
+
key: {
|
|
3853
|
+
type: 'string'
|
|
3854
|
+
},
|
|
3855
|
+
interfaceName: {
|
|
3856
|
+
type: 'string'
|
|
3857
|
+
},
|
|
3858
|
+
description: {
|
|
3859
|
+
type: 'string'
|
|
3860
|
+
},
|
|
3861
|
+
grantedRoles: {
|
|
3862
|
+
type: 'array',
|
|
3863
|
+
items: {
|
|
3864
|
+
type: 'string'
|
|
3865
|
+
}
|
|
3866
|
+
},
|
|
3867
|
+
inverse: {
|
|
3868
|
+
type: 'boolean'
|
|
3869
|
+
},
|
|
3870
|
+
tags: {
|
|
3871
|
+
type: 'array',
|
|
3872
|
+
items: {
|
|
3873
|
+
type: 'string'
|
|
3874
|
+
}
|
|
3875
|
+
}
|
|
3876
|
+
}
|
|
3877
|
+
}
|
|
3878
|
+
},
|
|
3879
|
+
unknownClaimKeys: {
|
|
3880
|
+
type: 'array',
|
|
3881
|
+
items: {
|
|
3882
|
+
type: 'string'
|
|
3883
|
+
}
|
|
3884
|
+
}
|
|
3885
|
+
}
|
|
3886
|
+
};
|
|
3887
|
+
|
|
3888
|
+
function _array_like_to_array$4(arr, len) {
|
|
3889
|
+
if (len == null || len > arr.length) len = arr.length;
|
|
3890
|
+
for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
|
|
3891
|
+
return arr2;
|
|
3892
|
+
}
|
|
3893
|
+
function _array_with_holes$2(arr) {
|
|
3894
|
+
if (Array.isArray(arr)) return arr;
|
|
3895
|
+
}
|
|
3896
|
+
function _array_without_holes$3(arr) {
|
|
3897
|
+
if (Array.isArray(arr)) return _array_like_to_array$4(arr);
|
|
3898
|
+
}
|
|
3899
|
+
function asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, key, arg) {
|
|
3900
|
+
try {
|
|
3901
|
+
var info = gen[key](arg);
|
|
3902
|
+
var value = info.value;
|
|
3903
|
+
} catch (error) {
|
|
3904
|
+
reject(error);
|
|
3905
|
+
return;
|
|
3906
|
+
}
|
|
3907
|
+
if (info.done) {
|
|
3908
|
+
resolve(value);
|
|
3909
|
+
} else {
|
|
3910
|
+
Promise.resolve(value).then(_next, _throw);
|
|
3911
|
+
}
|
|
3912
|
+
}
|
|
3913
|
+
function _async_to_generator$4(fn) {
|
|
3914
|
+
return function() {
|
|
3915
|
+
var self = this, args = arguments;
|
|
3916
|
+
return new Promise(function(resolve, reject) {
|
|
3917
|
+
var gen = fn.apply(self, args);
|
|
3918
|
+
function _next(value) {
|
|
3919
|
+
asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "next", value);
|
|
3920
|
+
}
|
|
3921
|
+
function _throw(err) {
|
|
3922
|
+
asyncGeneratorStep$4(gen, resolve, reject, _next, _throw, "throw", err);
|
|
3923
|
+
}
|
|
3924
|
+
_next(undefined);
|
|
3925
|
+
});
|
|
3926
|
+
};
|
|
3927
|
+
}
|
|
3928
|
+
function _define_property$4(obj, key, value) {
|
|
3929
|
+
if (key in obj) {
|
|
3930
|
+
Object.defineProperty(obj, key, {
|
|
3931
|
+
value: value,
|
|
3932
|
+
enumerable: true,
|
|
3933
|
+
configurable: true,
|
|
3934
|
+
writable: true
|
|
3935
|
+
});
|
|
3936
|
+
} else {
|
|
3937
|
+
obj[key] = value;
|
|
3938
|
+
}
|
|
3939
|
+
return obj;
|
|
3940
|
+
}
|
|
3941
|
+
function _iterable_to_array$3(iter) {
|
|
3942
|
+
if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
|
|
3943
|
+
}
|
|
3944
|
+
function _iterable_to_array_limit$2(arr, i) {
|
|
3945
|
+
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
3946
|
+
if (_i == null) return;
|
|
3947
|
+
var _arr = [];
|
|
3948
|
+
var _n = true;
|
|
3949
|
+
var _d = false;
|
|
3950
|
+
var _s, _e;
|
|
3951
|
+
try {
|
|
3952
|
+
for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
|
|
3953
|
+
_arr.push(_s.value);
|
|
3954
|
+
if (i && _arr.length === i) break;
|
|
3955
|
+
}
|
|
3956
|
+
} catch (err) {
|
|
3957
|
+
_d = true;
|
|
3958
|
+
_e = err;
|
|
3959
|
+
} finally{
|
|
3960
|
+
try {
|
|
3961
|
+
if (!_n && _i["return"] != null) _i["return"]();
|
|
3962
|
+
} finally{
|
|
3963
|
+
if (_d) throw _e;
|
|
3964
|
+
}
|
|
3965
|
+
}
|
|
3966
|
+
return _arr;
|
|
3967
|
+
}
|
|
3968
|
+
function _non_iterable_rest$2() {
|
|
3969
|
+
throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3970
|
+
}
|
|
3971
|
+
function _non_iterable_spread$3() {
|
|
3972
|
+
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3973
|
+
}
|
|
3974
|
+
function _object_spread$1(target) {
|
|
3975
|
+
for(var i = 1; i < arguments.length; i++){
|
|
3976
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
3977
|
+
var ownKeys = Object.keys(source);
|
|
3978
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
3979
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
3980
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
3981
|
+
}));
|
|
3982
|
+
}
|
|
3983
|
+
ownKeys.forEach(function(key) {
|
|
3984
|
+
_define_property$4(target, key, source[key]);
|
|
3985
|
+
});
|
|
3986
|
+
}
|
|
3987
|
+
return target;
|
|
3988
|
+
}
|
|
3989
|
+
function ownKeys$1(object, enumerableOnly) {
|
|
3990
|
+
var keys = Object.keys(object);
|
|
3991
|
+
if (Object.getOwnPropertySymbols) {
|
|
3992
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
3993
|
+
keys.push.apply(keys, symbols);
|
|
3994
|
+
}
|
|
3995
|
+
return keys;
|
|
3996
|
+
}
|
|
3997
|
+
function _object_spread_props$1(target, source) {
|
|
3998
|
+
source = source != null ? source : {};
|
|
3999
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
4000
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
4001
|
+
} else {
|
|
4002
|
+
ownKeys$1(Object(source)).forEach(function(key) {
|
|
4003
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
4004
|
+
});
|
|
4005
|
+
}
|
|
4006
|
+
return target;
|
|
4007
|
+
}
|
|
4008
|
+
function _sliced_to_array$2(arr, i) {
|
|
4009
|
+
return _array_with_holes$2(arr) || _iterable_to_array_limit$2(arr, i) || _unsupported_iterable_to_array$4(arr, i) || _non_iterable_rest$2();
|
|
4010
|
+
}
|
|
4011
|
+
function _to_consumable_array$3(arr) {
|
|
4012
|
+
return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$3();
|
|
4013
|
+
}
|
|
4014
|
+
function _unsupported_iterable_to_array$4(o, minLen) {
|
|
4015
|
+
if (!o) return;
|
|
4016
|
+
if (typeof o === "string") return _array_like_to_array$4(o, minLen);
|
|
4017
|
+
var n = Object.prototype.toString.call(o).slice(8, -1);
|
|
4018
|
+
if (n === "Object" && o.constructor) n = o.constructor.name;
|
|
4019
|
+
if (n === "Map" || n === "Set") return Array.from(n);
|
|
4020
|
+
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
|
|
4021
|
+
}
|
|
4022
|
+
function _ts_generator$4(thisArg, body) {
|
|
4023
|
+
var f, y, t, _ = {
|
|
4024
|
+
label: 0,
|
|
4025
|
+
sent: function() {
|
|
4026
|
+
if (t[0] & 1) throw t[1];
|
|
4027
|
+
return t[1];
|
|
4028
|
+
},
|
|
4029
|
+
trys: [],
|
|
4030
|
+
ops: []
|
|
4031
|
+
}, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
|
|
4032
|
+
return d(g, "next", {
|
|
4033
|
+
value: verb(0)
|
|
4034
|
+
}), d(g, "throw", {
|
|
4035
|
+
value: verb(1)
|
|
4036
|
+
}), d(g, "return", {
|
|
4037
|
+
value: verb(2)
|
|
4038
|
+
}), typeof Symbol === "function" && d(g, Symbol.iterator, {
|
|
4039
|
+
value: function() {
|
|
4040
|
+
return this;
|
|
4041
|
+
}
|
|
4042
|
+
}), g;
|
|
4043
|
+
function verb(n) {
|
|
4044
|
+
return function(v) {
|
|
4045
|
+
return step([
|
|
4046
|
+
n,
|
|
4047
|
+
v
|
|
4048
|
+
]);
|
|
4049
|
+
};
|
|
4050
|
+
}
|
|
4051
|
+
function step(op) {
|
|
4052
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
4053
|
+
while(g && (g = 0, op[0] && (_ = 0)), _)try {
|
|
4054
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
4055
|
+
if (y = 0, t) op = [
|
|
4056
|
+
op[0] & 2,
|
|
4057
|
+
t.value
|
|
4058
|
+
];
|
|
4059
|
+
switch(op[0]){
|
|
4060
|
+
case 0:
|
|
4061
|
+
case 1:
|
|
4062
|
+
t = op;
|
|
4063
|
+
break;
|
|
4064
|
+
case 4:
|
|
4065
|
+
_.label++;
|
|
4066
|
+
return {
|
|
4067
|
+
value: op[1],
|
|
4068
|
+
done: false
|
|
4069
|
+
};
|
|
4070
|
+
case 5:
|
|
4071
|
+
_.label++;
|
|
4072
|
+
y = op[1];
|
|
4073
|
+
op = [
|
|
4074
|
+
0
|
|
4075
|
+
];
|
|
4076
|
+
continue;
|
|
4077
|
+
case 7:
|
|
4078
|
+
op = _.ops.pop();
|
|
4079
|
+
_.trys.pop();
|
|
4080
|
+
continue;
|
|
4081
|
+
default:
|
|
4082
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
|
|
4083
|
+
_ = 0;
|
|
4084
|
+
continue;
|
|
4085
|
+
}
|
|
4086
|
+
if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
|
|
4087
|
+
_.label = op[1];
|
|
4088
|
+
break;
|
|
4089
|
+
}
|
|
4090
|
+
if (op[0] === 6 && _.label < t[1]) {
|
|
4091
|
+
_.label = t[1];
|
|
4092
|
+
t = op;
|
|
4093
|
+
break;
|
|
4094
|
+
}
|
|
4095
|
+
if (t && _.label < t[2]) {
|
|
4096
|
+
_.label = t[2];
|
|
4097
|
+
_.ops.push(op);
|
|
4098
|
+
break;
|
|
4099
|
+
}
|
|
4100
|
+
if (t[2]) _.ops.pop();
|
|
4101
|
+
_.trys.pop();
|
|
4102
|
+
continue;
|
|
4103
|
+
}
|
|
4104
|
+
op = body.call(thisArg, _);
|
|
4105
|
+
} catch (e) {
|
|
4106
|
+
op = [
|
|
4107
|
+
6,
|
|
4108
|
+
e
|
|
4109
|
+
];
|
|
4110
|
+
y = 0;
|
|
4111
|
+
} finally{
|
|
4112
|
+
f = t = 0;
|
|
4113
|
+
}
|
|
4114
|
+
if (op[0] & 5) throw op[1];
|
|
4115
|
+
return {
|
|
4116
|
+
value: op[0] ? op[1] : void 0,
|
|
4117
|
+
done: true
|
|
4118
|
+
};
|
|
4119
|
+
}
|
|
4120
|
+
}
|
|
4121
|
+
// MARK: Constants
|
|
4122
|
+
/**
|
|
4123
|
+
* Reserved tool name for the built-in `url-models` static tool.
|
|
4124
|
+
*/ var URL_MODELS_TOOL_NAME = 'url-models';
|
|
4125
|
+
/**
|
|
4126
|
+
* Synthetic call type used in the tool's dispatch identity.
|
|
4127
|
+
*/ var URL_MODELS_DISPATCH_CALL = 'url-models';
|
|
4128
|
+
/**
|
|
4129
|
+
* Synthetic model type used in the tool's dispatch identity. The tool isn't
|
|
4130
|
+
* bound to a real model (the `url` is its input), so we use the literal "route".
|
|
4131
|
+
*/ var URL_MODELS_DISPATCH_MODEL_TYPE = 'route';
|
|
4132
|
+
/**
|
|
4133
|
+
* Placeholder segment standing for the caller's authenticated uid.
|
|
4134
|
+
*/ var AUTH_UID_PLACEHOLDER = '{authUid}';
|
|
4135
|
+
// MARK: Factory
|
|
4136
|
+
/**
|
|
4137
|
+
* Builds the built-in `url-models` MCP tool definition.
|
|
4138
|
+
*
|
|
4139
|
+
* Matches a pasted app URL against the build-time route manifest and returns the
|
|
4140
|
+
* Firestore models the page renders — model types plus concrete keys with the
|
|
4141
|
+
* route params and `{authUid}` substituted. Optionally filtered to specific
|
|
4142
|
+
* `models`, reduced to keys-only, or loaded via the same permission-checked read
|
|
4143
|
+
* path as `model-get`.
|
|
4144
|
+
*
|
|
4145
|
+
* A URL that matches no state returns a structured `{ matched: null, candidates }`
|
|
4146
|
+
* (not an error) so the caller can suggest near-misses.
|
|
4147
|
+
*
|
|
4148
|
+
* @param deps - The route manifest plus the shared read-documents / identity callbacks.
|
|
4149
|
+
* @returns A statically-registered {@link McpToolDefinition}.
|
|
4150
|
+
*/ function createUrlModelsTool(deps) {
|
|
4151
|
+
var handler = function handler(args, ctx) {
|
|
4152
|
+
return urlModelsToolHandler(args, ctx, deps);
|
|
4153
|
+
};
|
|
4154
|
+
var name = URL_MODELS_TOOL_NAME;
|
|
4155
|
+
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`).';
|
|
4156
|
+
return buildStaticToolDefinition({
|
|
4157
|
+
name: name,
|
|
4158
|
+
description: description,
|
|
4159
|
+
inputSchema: URL_MODELS_INPUT_SCHEMA,
|
|
4160
|
+
outputSchema: URL_MODELS_OUTPUT_SCHEMA,
|
|
4161
|
+
dispatch: {
|
|
4162
|
+
call: URL_MODELS_DISPATCH_CALL,
|
|
4163
|
+
modelType: URL_MODELS_DISPATCH_MODEL_TYPE
|
|
4164
|
+
},
|
|
4165
|
+
staticHandler: handler,
|
|
4166
|
+
effectiveReadOnly: true,
|
|
4167
|
+
rule: {
|
|
4168
|
+
requireAuthenticated: true
|
|
4169
|
+
}
|
|
4170
|
+
});
|
|
4171
|
+
}
|
|
4172
|
+
// MARK: Handler
|
|
4173
|
+
function urlModelsToolHandler(args, ctx, deps) {
|
|
4174
|
+
return _async_to_generator$4(function() {
|
|
4175
|
+
var result, input, payload, error;
|
|
4176
|
+
return _ts_generator$4(this, function(_state) {
|
|
4177
|
+
switch(_state.label){
|
|
4178
|
+
case 0:
|
|
4179
|
+
_state.trys.push([
|
|
4180
|
+
0,
|
|
4181
|
+
2,
|
|
4182
|
+
,
|
|
4183
|
+
3
|
|
4184
|
+
]);
|
|
4185
|
+
input = parseUrlModelsInput(args);
|
|
4186
|
+
return [
|
|
4187
|
+
4,
|
|
4188
|
+
resolveUrlModels(input, ctx, deps)
|
|
4189
|
+
];
|
|
4190
|
+
case 1:
|
|
4191
|
+
payload = _state.sent();
|
|
4192
|
+
result = {
|
|
4193
|
+
content: [
|
|
4194
|
+
{
|
|
4195
|
+
type: 'text',
|
|
4196
|
+
text: JSON.stringify(payload)
|
|
4197
|
+
}
|
|
4198
|
+
],
|
|
4199
|
+
structuredContent: payload
|
|
4200
|
+
};
|
|
4201
|
+
return [
|
|
4202
|
+
3,
|
|
4203
|
+
3
|
|
4204
|
+
];
|
|
4205
|
+
case 2:
|
|
4206
|
+
error = _state.sent();
|
|
4207
|
+
result = formatMcpToolErrorResponse(error);
|
|
4208
|
+
return [
|
|
4209
|
+
3,
|
|
4210
|
+
3
|
|
4211
|
+
];
|
|
4212
|
+
case 3:
|
|
4213
|
+
return [
|
|
4214
|
+
2,
|
|
4215
|
+
result
|
|
4216
|
+
];
|
|
4217
|
+
}
|
|
4218
|
+
});
|
|
4219
|
+
})();
|
|
4220
|
+
}
|
|
4221
|
+
function parseUrlModelsInput(args) {
|
|
4222
|
+
var url = args.url;
|
|
4223
|
+
if (typeof url !== 'string' || url.length === 0) {
|
|
4224
|
+
throw new Error('url-models: "url" is required and must be a non-empty string.');
|
|
4225
|
+
}
|
|
4226
|
+
var keysOnly = args.keysOnly === true;
|
|
4227
|
+
var load = args.load === true;
|
|
4228
|
+
if (keysOnly && load) {
|
|
4229
|
+
throw new Error('url-models: "keysOnly" and "load" cannot be combined — "keysOnly" returns keys without loading documents.');
|
|
4230
|
+
}
|
|
4231
|
+
var models;
|
|
4232
|
+
if (args.models !== undefined) {
|
|
4233
|
+
if (!Array.isArray(args.models) || args.models.some(function(m) {
|
|
4234
|
+
return typeof m !== 'string';
|
|
4235
|
+
})) {
|
|
4236
|
+
throw new Error('url-models: "models" must be an array of model-type strings.');
|
|
4237
|
+
}
|
|
4238
|
+
models = args.models;
|
|
4239
|
+
}
|
|
4240
|
+
var currentUserUid;
|
|
4241
|
+
if (args.currentUserUid !== undefined) {
|
|
4242
|
+
if (typeof args.currentUserUid !== 'string' || args.currentUserUid.length === 0) {
|
|
4243
|
+
throw new Error('url-models: "currentUserUid" must be a non-empty string.');
|
|
4244
|
+
}
|
|
4245
|
+
currentUserUid = args.currentUserUid;
|
|
4246
|
+
}
|
|
4247
|
+
return _object_spread$1(_object_spread_props$1(_object_spread$1({
|
|
4248
|
+
url: url
|
|
4249
|
+
}, models === undefined ? {} : {
|
|
4250
|
+
models: models
|
|
4251
|
+
}), {
|
|
4252
|
+
keysOnly: keysOnly,
|
|
4253
|
+
load: load
|
|
4254
|
+
}), currentUserUid === undefined ? {} : {
|
|
4255
|
+
currentUserUid: currentUserUid
|
|
4256
|
+
});
|
|
4257
|
+
}
|
|
4258
|
+
function resolveUrlModels(input, ctx, deps) {
|
|
4259
|
+
return _async_to_generator$4(function() {
|
|
4260
|
+
var matchResult, payload, _tmp;
|
|
4261
|
+
return _ts_generator$4(this, function(_state) {
|
|
4262
|
+
switch(_state.label){
|
|
4263
|
+
case 0:
|
|
4264
|
+
matchResult = matchRouteManifestUrl({
|
|
4265
|
+
manifest: deps.routeManifest,
|
|
4266
|
+
url: input.url
|
|
4267
|
+
});
|
|
4268
|
+
if (!(matchResult.kind === 'none')) return [
|
|
4269
|
+
3,
|
|
4270
|
+
1
|
|
4271
|
+
];
|
|
4272
|
+
payload = {
|
|
4273
|
+
url: input.url,
|
|
4274
|
+
pathname: matchResult.pathname,
|
|
4275
|
+
matched: null,
|
|
4276
|
+
candidates: matchResult.candidates.map(stateSummary)
|
|
4277
|
+
};
|
|
4278
|
+
return [
|
|
4279
|
+
3,
|
|
4280
|
+
4
|
|
4281
|
+
];
|
|
4282
|
+
case 1:
|
|
4283
|
+
if (!(matchResult.kind === 'ambiguous')) return [
|
|
4284
|
+
3,
|
|
4285
|
+
2
|
|
4286
|
+
];
|
|
4287
|
+
payload = {
|
|
4288
|
+
url: input.url,
|
|
4289
|
+
pathname: matchResult.pathname,
|
|
4290
|
+
matched: null,
|
|
4291
|
+
ambiguous: matchResult.states.map(stateSummary)
|
|
4292
|
+
};
|
|
4293
|
+
return [
|
|
4294
|
+
3,
|
|
4295
|
+
4
|
|
4296
|
+
];
|
|
4297
|
+
case 2:
|
|
4298
|
+
_tmp = {
|
|
4299
|
+
url: input.url,
|
|
4300
|
+
pathname: matchResult.pathname
|
|
4301
|
+
};
|
|
4302
|
+
return [
|
|
4303
|
+
4,
|
|
4304
|
+
buildMatchedPayload({
|
|
4305
|
+
match: matchResult,
|
|
4306
|
+
input: input,
|
|
4307
|
+
ctx: ctx,
|
|
4308
|
+
deps: deps
|
|
4309
|
+
})
|
|
4310
|
+
];
|
|
4311
|
+
case 3:
|
|
4312
|
+
payload = (_tmp.matched = _state.sent(), _tmp);
|
|
4313
|
+
_state.label = 4;
|
|
4314
|
+
case 4:
|
|
4315
|
+
return [
|
|
4316
|
+
2,
|
|
4317
|
+
payload
|
|
4318
|
+
];
|
|
4319
|
+
}
|
|
4320
|
+
});
|
|
4321
|
+
})();
|
|
4322
|
+
}
|
|
4323
|
+
function stateSummary(state) {
|
|
4324
|
+
return {
|
|
4325
|
+
name: state.name,
|
|
4326
|
+
fullUrl: state.fullUrl
|
|
4327
|
+
};
|
|
4328
|
+
}
|
|
4329
|
+
function buildMatchedPayload(args) {
|
|
4330
|
+
return _async_to_generator$4(function() {
|
|
4331
|
+
var _input_currentUserUid, _ctx_auth, match, input, ctx, deps, uid, filtered, resolved, loaded, _tmp;
|
|
4332
|
+
return _ts_generator$4(this, function(_state) {
|
|
4333
|
+
switch(_state.label){
|
|
4334
|
+
case 0:
|
|
4335
|
+
match = args.match, input = args.input, ctx = args.ctx, deps = args.deps;
|
|
4336
|
+
// `currentUserUid` (when supplied) overrides the uid used to fill `{authUid}` placeholders so a
|
|
4337
|
+
// caller can preview another user's page-models. The document-load path still uses `ctx.auth`, so
|
|
4338
|
+
// this is a key-substitution preview only — no privilege escalation on the actual reads.
|
|
4339
|
+
uid = (_input_currentUserUid = input.currentUserUid) !== null && _input_currentUserUid !== void 0 ? _input_currentUserUid : (_ctx_auth = ctx.auth) === null || _ctx_auth === void 0 ? void 0 : _ctx_auth.uid;
|
|
4340
|
+
filtered = input.models === undefined ? match.state.models : match.state.models.filter(function(m) {
|
|
4341
|
+
var _input_models;
|
|
4342
|
+
return (_input_models = input.models) === null || _input_models === void 0 ? void 0 : _input_models.includes(m.modelType);
|
|
4343
|
+
});
|
|
4344
|
+
resolved = filtered.map(function(entry) {
|
|
4345
|
+
return resolveModelEntry({
|
|
4346
|
+
entry: entry,
|
|
4347
|
+
params: match.params,
|
|
4348
|
+
uid: uid,
|
|
4349
|
+
keysOnly: input.keysOnly === true,
|
|
4350
|
+
deps: deps,
|
|
4351
|
+
ctx: ctx
|
|
4352
|
+
});
|
|
4353
|
+
});
|
|
4354
|
+
if (!(input.load === true)) return [
|
|
4355
|
+
3,
|
|
4356
|
+
2
|
|
4357
|
+
];
|
|
4358
|
+
return [
|
|
4359
|
+
4,
|
|
4360
|
+
loadResolvedModels(resolved, ctx, deps)
|
|
4361
|
+
];
|
|
4362
|
+
case 1:
|
|
4363
|
+
_tmp = _state.sent();
|
|
4364
|
+
return [
|
|
4365
|
+
3,
|
|
4366
|
+
3
|
|
4367
|
+
];
|
|
4368
|
+
case 2:
|
|
4369
|
+
_tmp = undefined;
|
|
4370
|
+
_state.label = 3;
|
|
4371
|
+
case 3:
|
|
4372
|
+
loaded = _tmp;
|
|
4373
|
+
return [
|
|
4374
|
+
2,
|
|
4375
|
+
_object_spread$1({
|
|
4376
|
+
state: {
|
|
4377
|
+
name: match.state.name,
|
|
4378
|
+
fullUrl: match.state.fullUrl,
|
|
4379
|
+
component: match.state.component,
|
|
4380
|
+
componentFile: match.state.componentFile
|
|
4381
|
+
},
|
|
4382
|
+
via: match.via,
|
|
4383
|
+
params: match.params,
|
|
4384
|
+
models: resolved
|
|
4385
|
+
}, loaded === undefined ? {} : {
|
|
4386
|
+
loaded: loaded
|
|
4387
|
+
})
|
|
4388
|
+
];
|
|
4389
|
+
}
|
|
4390
|
+
});
|
|
4391
|
+
})();
|
|
4392
|
+
}
|
|
4393
|
+
function resolveModelEntry(input) {
|
|
4394
|
+
var entry = input.entry, keysOnly = input.keysOnly;
|
|
4395
|
+
var base = keysOnly ? {
|
|
4396
|
+
modelType: entry.modelType,
|
|
4397
|
+
kind: entry.kind
|
|
4398
|
+
} : _object_spread$1({
|
|
4399
|
+
modelType: entry.modelType,
|
|
4400
|
+
kind: entry.kind
|
|
4401
|
+
}, entry.keyTemplate === undefined ? {} : {
|
|
4402
|
+
keyTemplate: entry.keyTemplate
|
|
4403
|
+
}, entry.description === undefined ? {} : {
|
|
4404
|
+
description: entry.description
|
|
4405
|
+
}, entry.from === undefined ? {} : {
|
|
4406
|
+
from: entry.from
|
|
4407
|
+
});
|
|
4408
|
+
var result;
|
|
4409
|
+
if (entry.kind === 'list') {
|
|
4410
|
+
result = base;
|
|
4411
|
+
} else if (entry.kind === 'id') {
|
|
4412
|
+
result = _object_spread$1({}, base, resolveIdKey(input));
|
|
4413
|
+
} else {
|
|
4414
|
+
result = _object_spread$1({}, base, resolveFullKey(input));
|
|
4415
|
+
}
|
|
4416
|
+
return result;
|
|
4417
|
+
}
|
|
4418
|
+
function resolveIdKey(input) {
|
|
4419
|
+
var _entry_keyTemplate;
|
|
4420
|
+
var entry = input.entry, params = input.params, uid = input.uid, deps = input.deps, ctx = input.ctx;
|
|
4421
|
+
var value = substitutePlaceholder((_entry_keyTemplate = entry.keyTemplate) !== null && _entry_keyTemplate !== void 0 ? _entry_keyTemplate : '', params, uid);
|
|
4422
|
+
var result;
|
|
4423
|
+
if (value.kind === 'unresolved') {
|
|
4424
|
+
result = {
|
|
4425
|
+
unresolved: value.unresolved
|
|
4426
|
+
};
|
|
4427
|
+
} else {
|
|
4428
|
+
var identity = deps.resolveIdentity(entry.modelType, ctx.auth);
|
|
4429
|
+
if (identity == null) {
|
|
4430
|
+
result = {
|
|
4431
|
+
unresolved: {
|
|
4432
|
+
reason: 'unknown-model-type',
|
|
4433
|
+
message: "Unknown model type `".concat(entry.modelType, "`.")
|
|
4434
|
+
}
|
|
4435
|
+
};
|
|
4436
|
+
} else if (identity.type === 'root') {
|
|
4437
|
+
result = {
|
|
4438
|
+
key: "".concat(identity.collectionName, "/").concat(value.value)
|
|
4439
|
+
};
|
|
4440
|
+
} else {
|
|
4441
|
+
result = {
|
|
4442
|
+
unresolved: {
|
|
4443
|
+
reason: 'subcollection-requires-key-template',
|
|
4444
|
+
message: "Model `".concat(entry.modelType, "` is a subcollection; an `id` key template cannot be promoted to a full key. Annotate it with a full `gb/:id/...` key template.")
|
|
4445
|
+
}
|
|
4446
|
+
};
|
|
4447
|
+
}
|
|
4448
|
+
}
|
|
4449
|
+
return result;
|
|
4450
|
+
}
|
|
4451
|
+
function resolveFullKey(input) {
|
|
4452
|
+
var _entry_keyTemplate;
|
|
4453
|
+
var entry = input.entry, params = input.params, uid = input.uid;
|
|
4454
|
+
var segments = ((_entry_keyTemplate = entry.keyTemplate) !== null && _entry_keyTemplate !== void 0 ? _entry_keyTemplate : '').split('/');
|
|
4455
|
+
var parts = [];
|
|
4456
|
+
var unresolved;
|
|
4457
|
+
var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
4458
|
+
try {
|
|
4459
|
+
for(var _iterator = segments[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
4460
|
+
var segment = _step.value;
|
|
4461
|
+
if (segment.startsWith(':') || segment === AUTH_UID_PLACEHOLDER) {
|
|
4462
|
+
var value = substitutePlaceholder(segment, params, uid);
|
|
4463
|
+
if (value.kind === 'unresolved') {
|
|
4464
|
+
unresolved = value.unresolved;
|
|
4465
|
+
break;
|
|
4466
|
+
}
|
|
4467
|
+
parts.push(value.value);
|
|
4468
|
+
} else {
|
|
4469
|
+
parts.push(segment);
|
|
4470
|
+
}
|
|
4471
|
+
}
|
|
4472
|
+
} catch (err) {
|
|
4473
|
+
_didIteratorError = true;
|
|
4474
|
+
_iteratorError = err;
|
|
4475
|
+
} finally{
|
|
4476
|
+
try {
|
|
4477
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
4478
|
+
_iterator.return();
|
|
4479
|
+
}
|
|
4480
|
+
} finally{
|
|
4481
|
+
if (_didIteratorError) {
|
|
4482
|
+
throw _iteratorError;
|
|
4483
|
+
}
|
|
4484
|
+
}
|
|
4485
|
+
}
|
|
4486
|
+
return unresolved === undefined ? {
|
|
4487
|
+
key: parts.join('/')
|
|
4488
|
+
} : {
|
|
4489
|
+
unresolved: unresolved
|
|
4490
|
+
};
|
|
4491
|
+
}
|
|
4492
|
+
function substitutePlaceholder(segment, params, uid) {
|
|
4493
|
+
var result;
|
|
4494
|
+
if (segment === AUTH_UID_PLACEHOLDER) {
|
|
4495
|
+
result = uid == null || uid.length === 0 ? {
|
|
4496
|
+
kind: 'unresolved',
|
|
4497
|
+
unresolved: {
|
|
4498
|
+
reason: 'auth-required',
|
|
4499
|
+
message: 'This page keys a model by the caller uid (`{authUid}`) but the request is not authenticated.'
|
|
4500
|
+
}
|
|
4501
|
+
} : {
|
|
4502
|
+
kind: 'value',
|
|
4503
|
+
value: uid
|
|
4504
|
+
};
|
|
4505
|
+
} else if (segment.startsWith(':')) {
|
|
4506
|
+
var paramName = segment.slice(1);
|
|
4507
|
+
var value = params[paramName];
|
|
4508
|
+
result = value === undefined ? {
|
|
4509
|
+
kind: 'unresolved',
|
|
4510
|
+
unresolved: {
|
|
4511
|
+
reason: 'missing-param',
|
|
4512
|
+
message: "Route param `:".concat(paramName, "` was not captured from the URL.")
|
|
4513
|
+
}
|
|
4514
|
+
} : {
|
|
4515
|
+
kind: 'value',
|
|
4516
|
+
value: value
|
|
4517
|
+
};
|
|
4518
|
+
} else {
|
|
4519
|
+
result = {
|
|
4520
|
+
kind: 'value',
|
|
4521
|
+
value: segment
|
|
4522
|
+
};
|
|
4523
|
+
}
|
|
4524
|
+
return result;
|
|
4525
|
+
}
|
|
4526
|
+
// MARK: Load
|
|
4527
|
+
function loadResolvedModels(resolved, ctx, deps) {
|
|
4528
|
+
return _async_to_generator$4(function() {
|
|
4529
|
+
var keysByType, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, model, existing, out, _iteratorNormalCompletion1, _didIteratorError1, _iteratorError1, _iterator1, _step1, _step_value, modelType, keys, merged, err;
|
|
4530
|
+
return _ts_generator$4(this, function(_state) {
|
|
4531
|
+
switch(_state.label){
|
|
4532
|
+
case 0:
|
|
4533
|
+
keysByType = new Map();
|
|
4534
|
+
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
4535
|
+
try {
|
|
4536
|
+
for(_iterator = resolved[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
4537
|
+
model = _step.value;
|
|
4538
|
+
if (model.key !== undefined) {
|
|
4539
|
+
existing = keysByType.get(model.modelType);
|
|
4540
|
+
if (existing === undefined) {
|
|
4541
|
+
keysByType.set(model.modelType, [
|
|
4542
|
+
model.key
|
|
4543
|
+
]);
|
|
4544
|
+
} else {
|
|
4545
|
+
existing.push(model.key);
|
|
4546
|
+
}
|
|
4547
|
+
}
|
|
4548
|
+
}
|
|
4549
|
+
} catch (err) {
|
|
4550
|
+
_didIteratorError = true;
|
|
4551
|
+
_iteratorError = err;
|
|
4552
|
+
} finally{
|
|
4553
|
+
try {
|
|
4554
|
+
if (!_iteratorNormalCompletion && _iterator.return != null) {
|
|
4555
|
+
_iterator.return();
|
|
4556
|
+
}
|
|
4557
|
+
} finally{
|
|
4558
|
+
if (_didIteratorError) {
|
|
4559
|
+
throw _iteratorError;
|
|
4560
|
+
}
|
|
4561
|
+
}
|
|
4562
|
+
}
|
|
4563
|
+
out = [];
|
|
4564
|
+
_iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
|
|
4565
|
+
_state.label = 1;
|
|
4566
|
+
case 1:
|
|
4567
|
+
_state.trys.push([
|
|
4568
|
+
1,
|
|
4569
|
+
6,
|
|
4570
|
+
7,
|
|
4571
|
+
8
|
|
4572
|
+
]);
|
|
4573
|
+
_iterator1 = keysByType[Symbol.iterator]();
|
|
4574
|
+
_state.label = 2;
|
|
4575
|
+
case 2:
|
|
4576
|
+
if (!!(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done)) return [
|
|
4577
|
+
3,
|
|
4578
|
+
5
|
|
4579
|
+
];
|
|
4580
|
+
_step_value = _sliced_to_array$2(_step1.value, 2), modelType = _step_value[0], keys = _step_value[1];
|
|
4581
|
+
return [
|
|
4582
|
+
4,
|
|
4583
|
+
readInChunks({
|
|
4584
|
+
modelType: modelType,
|
|
4585
|
+
keys: keys,
|
|
4586
|
+
auth: ctx.auth,
|
|
4587
|
+
readDocuments: deps.readDocuments
|
|
4588
|
+
})
|
|
4589
|
+
];
|
|
4590
|
+
case 3:
|
|
4591
|
+
merged = _state.sent();
|
|
4592
|
+
out.push({
|
|
4593
|
+
modelType: modelType,
|
|
4594
|
+
results: merged.results,
|
|
4595
|
+
errors: merged.errors
|
|
4596
|
+
});
|
|
4597
|
+
_state.label = 4;
|
|
4598
|
+
case 4:
|
|
4599
|
+
_iteratorNormalCompletion1 = true;
|
|
4600
|
+
return [
|
|
4601
|
+
3,
|
|
4602
|
+
2
|
|
4603
|
+
];
|
|
4604
|
+
case 5:
|
|
4605
|
+
return [
|
|
4606
|
+
3,
|
|
4607
|
+
8
|
|
4608
|
+
];
|
|
4609
|
+
case 6:
|
|
4610
|
+
err = _state.sent();
|
|
4611
|
+
_didIteratorError1 = true;
|
|
4612
|
+
_iteratorError1 = err;
|
|
4613
|
+
return [
|
|
4614
|
+
3,
|
|
4615
|
+
8
|
|
4616
|
+
];
|
|
4617
|
+
case 7:
|
|
4618
|
+
try {
|
|
4619
|
+
if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
|
|
4620
|
+
_iterator1.return();
|
|
4621
|
+
}
|
|
4622
|
+
} finally{
|
|
4623
|
+
if (_didIteratorError1) {
|
|
4624
|
+
throw _iteratorError1;
|
|
4625
|
+
}
|
|
4626
|
+
}
|
|
4627
|
+
return [
|
|
4628
|
+
7
|
|
4629
|
+
];
|
|
4630
|
+
case 8:
|
|
4631
|
+
return [
|
|
4632
|
+
2,
|
|
4633
|
+
out
|
|
4634
|
+
];
|
|
4635
|
+
}
|
|
4636
|
+
});
|
|
4637
|
+
})();
|
|
4638
|
+
}
|
|
4639
|
+
function readInChunks(input) {
|
|
4640
|
+
return _async_to_generator$4(function() {
|
|
4641
|
+
var modelType, keys, auth, readDocuments, merged, offset, _merged_results, _merged_errors, batch, partial;
|
|
4642
|
+
return _ts_generator$4(this, function(_state) {
|
|
4643
|
+
switch(_state.label){
|
|
4644
|
+
case 0:
|
|
4645
|
+
modelType = input.modelType, keys = input.keys, auth = input.auth, readDocuments = input.readDocuments;
|
|
4646
|
+
merged = {
|
|
4647
|
+
results: [],
|
|
4648
|
+
errors: []
|
|
4649
|
+
};
|
|
4650
|
+
offset = 0;
|
|
4651
|
+
_state.label = 1;
|
|
4652
|
+
case 1:
|
|
4653
|
+
if (!(offset < keys.length)) return [
|
|
4654
|
+
3,
|
|
4655
|
+
4
|
|
4656
|
+
];
|
|
4657
|
+
batch = keys.slice(offset, offset + MCP_MODEL_GET_BATCH_SIZE);
|
|
4658
|
+
return [
|
|
4659
|
+
4,
|
|
4660
|
+
readDocuments(modelType, batch, auth)
|
|
4661
|
+
];
|
|
4662
|
+
case 2:
|
|
4663
|
+
partial = _state.sent();
|
|
4664
|
+
(_merged_results = merged.results).push.apply(_merged_results, _to_consumable_array$3(partial.results));
|
|
4665
|
+
(_merged_errors = merged.errors).push.apply(_merged_errors, _to_consumable_array$3(partial.errors));
|
|
4666
|
+
_state.label = 3;
|
|
4667
|
+
case 3:
|
|
4668
|
+
offset += MCP_MODEL_GET_BATCH_SIZE;
|
|
4669
|
+
return [
|
|
4670
|
+
3,
|
|
4671
|
+
1
|
|
4672
|
+
];
|
|
4673
|
+
case 4:
|
|
4674
|
+
return [
|
|
4675
|
+
2,
|
|
4676
|
+
merged
|
|
4677
|
+
];
|
|
2882
4678
|
}
|
|
2883
|
-
}
|
|
2884
|
-
}
|
|
4679
|
+
});
|
|
4680
|
+
})();
|
|
2885
4681
|
}
|
|
2886
4682
|
// MARK: Schemas
|
|
2887
|
-
var
|
|
2888
|
-
type: 'object',
|
|
2889
|
-
properties: {},
|
|
2890
|
-
additionalProperties: false
|
|
2891
|
-
};
|
|
2892
|
-
var WHOAMI_OUTPUT_SCHEMA = {
|
|
4683
|
+
var URL_MODELS_INPUT_SCHEMA = {
|
|
2893
4684
|
type: 'object',
|
|
2894
4685
|
required: [
|
|
2895
|
-
'
|
|
2896
|
-
'claims',
|
|
2897
|
-
'roles',
|
|
2898
|
-
'claimDetails',
|
|
2899
|
-
'unknownClaimKeys'
|
|
4686
|
+
'url'
|
|
2900
4687
|
],
|
|
2901
|
-
description: 'Caller identity, raw token claims, decoded role set, and per-claim descriptions for every key present on the live token.',
|
|
2902
4688
|
properties: {
|
|
2903
|
-
|
|
2904
|
-
type: '
|
|
4689
|
+
url: {
|
|
4690
|
+
type: 'string',
|
|
4691
|
+
minLength: 1,
|
|
4692
|
+
description: 'Full URL or pathname, e.g. "https://app.example.co/worker/abc/timesheets/list".'
|
|
2905
4693
|
},
|
|
2906
|
-
|
|
2907
|
-
type: '
|
|
4694
|
+
models: {
|
|
4695
|
+
type: 'array',
|
|
4696
|
+
items: {
|
|
4697
|
+
type: 'string'
|
|
4698
|
+
},
|
|
4699
|
+
description: 'Restrict the output to these model types.'
|
|
2908
4700
|
},
|
|
2909
|
-
|
|
2910
|
-
type: '
|
|
4701
|
+
keysOnly: {
|
|
4702
|
+
type: 'boolean',
|
|
4703
|
+
description: 'Return only the resolved keys (no descriptions or documents). Cannot combine with "load".'
|
|
2911
4704
|
},
|
|
2912
|
-
|
|
2913
|
-
type: 'boolean'
|
|
4705
|
+
load: {
|
|
4706
|
+
type: 'boolean',
|
|
4707
|
+
description: 'Load each resolved document via the permission-checked read path. Cannot combine with "keysOnly".'
|
|
2914
4708
|
},
|
|
2915
|
-
|
|
4709
|
+
currentUserUid: {
|
|
4710
|
+
type: 'string',
|
|
4711
|
+
minLength: 1,
|
|
4712
|
+
description: "Override the uid used to fill `{authUid}` placeholders when resolving model keys (defaults to the authenticated caller). Use to preview the models another user would see on a page. `load` still reads via the calling user's permissions."
|
|
4713
|
+
}
|
|
4714
|
+
},
|
|
4715
|
+
additionalProperties: false
|
|
4716
|
+
};
|
|
4717
|
+
var URL_MODELS_OUTPUT_SCHEMA = {
|
|
4718
|
+
type: 'object',
|
|
4719
|
+
required: [
|
|
4720
|
+
'url',
|
|
4721
|
+
'pathname',
|
|
4722
|
+
'matched'
|
|
4723
|
+
],
|
|
4724
|
+
properties: {
|
|
4725
|
+
url: {
|
|
2916
4726
|
type: 'string'
|
|
2917
4727
|
},
|
|
2918
|
-
|
|
2919
|
-
type: '
|
|
2920
|
-
additionalProperties: true
|
|
4728
|
+
pathname: {
|
|
4729
|
+
type: 'string'
|
|
2921
4730
|
},
|
|
2922
|
-
|
|
2923
|
-
type:
|
|
2924
|
-
|
|
2925
|
-
|
|
4731
|
+
matched: {
|
|
4732
|
+
type: [
|
|
4733
|
+
'object',
|
|
4734
|
+
'null'
|
|
4735
|
+
],
|
|
4736
|
+
description: 'The matched page and its models, or null when no state matched.',
|
|
4737
|
+
properties: {
|
|
4738
|
+
state: {
|
|
4739
|
+
type: 'object'
|
|
4740
|
+
},
|
|
4741
|
+
via: {
|
|
4742
|
+
type: 'string'
|
|
4743
|
+
},
|
|
4744
|
+
params: {
|
|
4745
|
+
type: 'object'
|
|
4746
|
+
},
|
|
4747
|
+
models: {
|
|
4748
|
+
type: 'array',
|
|
4749
|
+
items: {
|
|
4750
|
+
type: 'object'
|
|
4751
|
+
}
|
|
4752
|
+
},
|
|
4753
|
+
loaded: {
|
|
4754
|
+
type: 'array',
|
|
4755
|
+
items: {
|
|
4756
|
+
type: 'object'
|
|
4757
|
+
}
|
|
4758
|
+
}
|
|
2926
4759
|
}
|
|
2927
4760
|
},
|
|
2928
|
-
|
|
4761
|
+
ambiguous: {
|
|
2929
4762
|
type: 'array',
|
|
2930
4763
|
items: {
|
|
2931
|
-
type: 'object'
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
'description',
|
|
2935
|
-
'grantedRoles',
|
|
2936
|
-
'inverse',
|
|
2937
|
-
'tags'
|
|
2938
|
-
],
|
|
2939
|
-
properties: {
|
|
2940
|
-
key: {
|
|
2941
|
-
type: 'string'
|
|
2942
|
-
},
|
|
2943
|
-
interfaceName: {
|
|
2944
|
-
type: 'string'
|
|
2945
|
-
},
|
|
2946
|
-
description: {
|
|
2947
|
-
type: 'string'
|
|
2948
|
-
},
|
|
2949
|
-
grantedRoles: {
|
|
2950
|
-
type: 'array',
|
|
2951
|
-
items: {
|
|
2952
|
-
type: 'string'
|
|
2953
|
-
}
|
|
2954
|
-
},
|
|
2955
|
-
inverse: {
|
|
2956
|
-
type: 'boolean'
|
|
2957
|
-
},
|
|
2958
|
-
tags: {
|
|
2959
|
-
type: 'array',
|
|
2960
|
-
items: {
|
|
2961
|
-
type: 'string'
|
|
2962
|
-
}
|
|
2963
|
-
}
|
|
2964
|
-
}
|
|
2965
|
-
}
|
|
4764
|
+
type: 'object'
|
|
4765
|
+
},
|
|
4766
|
+
description: 'Competing states when the URL matched more than one.'
|
|
2966
4767
|
},
|
|
2967
|
-
|
|
4768
|
+
candidates: {
|
|
2968
4769
|
type: 'array',
|
|
2969
4770
|
items: {
|
|
2970
|
-
type: '
|
|
2971
|
-
}
|
|
4771
|
+
type: 'object'
|
|
4772
|
+
},
|
|
4773
|
+
description: 'Closest near-miss states when nothing matched.'
|
|
2972
4774
|
}
|
|
2973
4775
|
}
|
|
2974
4776
|
};
|
|
@@ -3048,7 +4850,7 @@ function _non_iterable_rest$1() {
|
|
|
3048
4850
|
function _sliced_to_array$1(arr, i) {
|
|
3049
4851
|
return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest$1();
|
|
3050
4852
|
}
|
|
3051
|
-
function _type_of$
|
|
4853
|
+
function _type_of$2(obj) {
|
|
3052
4854
|
"@swc/helpers - typeof";
|
|
3053
4855
|
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
3054
4856
|
}
|
|
@@ -3222,7 +5024,7 @@ function _ts_generator$3(thisArg, body) {
|
|
|
3222
5024
|
};
|
|
3223
5025
|
var name = BATCH_EXECUTE_TOOL_NAME;
|
|
3224
5026
|
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.';
|
|
3225
|
-
return {
|
|
5027
|
+
return buildStaticToolDefinition({
|
|
3226
5028
|
name: name,
|
|
3227
5029
|
description: description,
|
|
3228
5030
|
inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
|
|
@@ -3232,20 +5034,11 @@ function _ts_generator$3(thisArg, body) {
|
|
|
3232
5034
|
modelType: BATCH_EXECUTE_DISPATCH_MODEL_TYPE
|
|
3233
5035
|
},
|
|
3234
5036
|
staticHandler: handler,
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
effectiveReadOnly: false
|
|
3241
|
-
},
|
|
3242
|
-
staticWireEntry: buildStaticWireEntry({
|
|
3243
|
-
name: name,
|
|
3244
|
-
description: description,
|
|
3245
|
-
inputSchema: BATCH_EXECUTE_INPUT_SCHEMA,
|
|
3246
|
-
outputSchema: BATCH_EXECUTE_OUTPUT_SCHEMA
|
|
3247
|
-
})
|
|
3248
|
-
};
|
|
5037
|
+
effectiveReadOnly: false,
|
|
5038
|
+
rule: {
|
|
5039
|
+
requireAuthenticated: true
|
|
5040
|
+
}
|
|
5041
|
+
});
|
|
3249
5042
|
}
|
|
3250
5043
|
// MARK: Handler
|
|
3251
5044
|
function batchExecuteToolHandler(args, ctx, deps) {
|
|
@@ -3442,7 +5235,7 @@ function parseJsonArrayOperations(fileText) {
|
|
|
3442
5235
|
return parsed;
|
|
3443
5236
|
}
|
|
3444
5237
|
function validateOperation(value, index) {
|
|
3445
|
-
if (value == null || (typeof value === "undefined" ? "undefined" : _type_of$
|
|
5238
|
+
if (value == null || (typeof value === "undefined" ? "undefined" : _type_of$2(value)) !== 'object') {
|
|
3446
5239
|
throw new Error("batch-execute: operation[".concat(index, "] must be an object."));
|
|
3447
5240
|
}
|
|
3448
5241
|
var candidate = value;
|
|
@@ -3934,12 +5727,50 @@ function _non_iterable_rest() {
|
|
|
3934
5727
|
function _non_iterable_spread$2() {
|
|
3935
5728
|
throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
|
|
3936
5729
|
}
|
|
5730
|
+
function _object_spread(target) {
|
|
5731
|
+
for(var i = 1; i < arguments.length; i++){
|
|
5732
|
+
var source = arguments[i] != null ? arguments[i] : {};
|
|
5733
|
+
var ownKeys = Object.keys(source);
|
|
5734
|
+
if (typeof Object.getOwnPropertySymbols === "function") {
|
|
5735
|
+
ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
|
|
5736
|
+
return Object.getOwnPropertyDescriptor(source, sym).enumerable;
|
|
5737
|
+
}));
|
|
5738
|
+
}
|
|
5739
|
+
ownKeys.forEach(function(key) {
|
|
5740
|
+
_define_property$3(target, key, source[key]);
|
|
5741
|
+
});
|
|
5742
|
+
}
|
|
5743
|
+
return target;
|
|
5744
|
+
}
|
|
5745
|
+
function ownKeys(object, enumerableOnly) {
|
|
5746
|
+
var keys = Object.keys(object);
|
|
5747
|
+
if (Object.getOwnPropertySymbols) {
|
|
5748
|
+
var symbols = Object.getOwnPropertySymbols(object);
|
|
5749
|
+
keys.push.apply(keys, symbols);
|
|
5750
|
+
}
|
|
5751
|
+
return keys;
|
|
5752
|
+
}
|
|
5753
|
+
function _object_spread_props(target, source) {
|
|
5754
|
+
source = source != null ? source : {};
|
|
5755
|
+
if (Object.getOwnPropertyDescriptors) {
|
|
5756
|
+
Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
|
|
5757
|
+
} else {
|
|
5758
|
+
ownKeys(Object(source)).forEach(function(key) {
|
|
5759
|
+
Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
|
|
5760
|
+
});
|
|
5761
|
+
}
|
|
5762
|
+
return target;
|
|
5763
|
+
}
|
|
3937
5764
|
function _sliced_to_array(arr, i) {
|
|
3938
5765
|
return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest();
|
|
3939
5766
|
}
|
|
3940
5767
|
function _to_consumable_array$2(arr) {
|
|
3941
5768
|
return _array_without_holes$2(arr) || _iterable_to_array$2(arr) || _unsupported_iterable_to_array$2(arr) || _non_iterable_spread$2();
|
|
3942
5769
|
}
|
|
5770
|
+
function _type_of$1(obj) {
|
|
5771
|
+
"@swc/helpers - typeof";
|
|
5772
|
+
return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
|
|
5773
|
+
}
|
|
3943
5774
|
function _unsupported_iterable_to_array$2(o, minLen) {
|
|
3944
5775
|
if (!o) return;
|
|
3945
5776
|
if (typeof o === "string") return _array_like_to_array$2(o, minLen);
|
|
@@ -4068,10 +5899,14 @@ var McpServerFactoryService_1;
|
|
|
4068
5899
|
_define_property$3(this, "_cachedStaticTools", void 0);
|
|
4069
5900
|
_define_property$3(this, "_cachedManifest", void 0);
|
|
4070
5901
|
_define_property$3(this, "_cachedManifestModels", void 0);
|
|
5902
|
+
_define_property$3(this, "_cachedManifestEnums", void 0);
|
|
4071
5903
|
_define_property$3(this, "_cachedManifestAuth", void 0);
|
|
5904
|
+
_define_property$3(this, "_cachedRouteManifest", void 0);
|
|
5905
|
+
_define_property$3(this, "_routeManifestLoaded", false);
|
|
4072
5906
|
_define_property$3(this, "_manifestLoaded", false);
|
|
4073
5907
|
_define_property$3(this, "_loggedSkips", false);
|
|
4074
5908
|
_define_property$3(this, "_warnedMissingRoleReader", false);
|
|
5909
|
+
_define_property$3(this, "_resolvedReasonConfig", void 0);
|
|
4075
5910
|
_define_property$3(this, "_analyticsService", void 0);
|
|
4076
5911
|
this.mcpConfig = mcpConfig;
|
|
4077
5912
|
this.dispatchService = dispatchService;
|
|
@@ -4343,15 +6178,39 @@ var McpServerFactoryService_1;
|
|
|
4343
6178
|
return getService.getModelIdentity(modelType, auth);
|
|
4344
6179
|
}
|
|
4345
6180
|
}));
|
|
6181
|
+
// `url-models` reuses the model-get read/identity path, so it is only offered when the get
|
|
6182
|
+
// service is wired AND a route manifest with at least one state was loaded.
|
|
6183
|
+
var routeManifest = this._resolveRouteManifest();
|
|
6184
|
+
if (routeManifest != null && routeManifest.states.length > 0) {
|
|
6185
|
+
staticTools.push(createUrlModelsTool({
|
|
6186
|
+
routeManifest: routeManifest,
|
|
6187
|
+
readDocuments: function readDocuments(modelType, keys, auth) {
|
|
6188
|
+
return getService.readDocuments(modelType, keys, auth);
|
|
6189
|
+
},
|
|
6190
|
+
resolveIdentity: function resolveIdentity(modelType, auth) {
|
|
6191
|
+
return getService.getModelIdentity(modelType, auth);
|
|
6192
|
+
}
|
|
6193
|
+
}));
|
|
6194
|
+
}
|
|
4346
6195
|
}
|
|
4347
6196
|
var modelManifest = this._cachedManifestModels;
|
|
6197
|
+
var enumManifest = this._cachedManifestEnums;
|
|
4348
6198
|
if (modelManifest != null && modelManifest.length > 0) {
|
|
4349
|
-
staticTools.push(createModelInfoTool({
|
|
6199
|
+
staticTools.push(createModelInfoTool(_object_spread({
|
|
4350
6200
|
manifest: modelManifest
|
|
4351
|
-
}
|
|
6201
|
+
}, enumManifest == null ? {} : {
|
|
6202
|
+
enums: enumManifest
|
|
6203
|
+
})), createModelDecodeTool({
|
|
4352
6204
|
manifest: modelManifest
|
|
4353
6205
|
}));
|
|
4354
6206
|
}
|
|
6207
|
+
// `enum-info` only needs the enum value tables — register it whenever the manifest carries a
|
|
6208
|
+
// non-empty `enums` block, independent of the model catalog.
|
|
6209
|
+
if (enumManifest != null && Object.keys(enumManifest).length > 0) {
|
|
6210
|
+
staticTools.push(createEnumInfoTool({
|
|
6211
|
+
enums: enumManifest
|
|
6212
|
+
}));
|
|
6213
|
+
}
|
|
4355
6214
|
var authManifest = this._cachedManifestAuth;
|
|
4356
6215
|
if (authManifest != null) {
|
|
4357
6216
|
staticTools.push(createWhoamiTool({
|
|
@@ -4513,9 +6372,55 @@ var McpServerFactoryService_1;
|
|
|
4513
6372
|
value: function _resetManifestCache() {
|
|
4514
6373
|
this._cachedManifest = undefined;
|
|
4515
6374
|
this._cachedManifestModels = undefined;
|
|
6375
|
+
this._cachedManifestEnums = undefined;
|
|
4516
6376
|
this._cachedManifestAuth = undefined;
|
|
4517
6377
|
}
|
|
4518
6378
|
},
|
|
6379
|
+
{
|
|
6380
|
+
/**
|
|
6381
|
+
* Reads the pre-rendered route manifest JSON once, validates its version, and caches the result
|
|
6382
|
+
* for the process lifetime. Drives whether the built-in `url-models` static tool is registered.
|
|
6383
|
+
*
|
|
6384
|
+
* Missing file or wrong version fall back to "no route manifest" with a single boot warning;
|
|
6385
|
+
* the `url-models` tool is then simply not offered.
|
|
6386
|
+
*
|
|
6387
|
+
* @returns The cached route manifest, or `undefined` when none was loaded.
|
|
6388
|
+
*/ key: "_resolveRouteManifest",
|
|
6389
|
+
value: function _resolveRouteManifest() {
|
|
6390
|
+
if (!this._routeManifestLoaded) {
|
|
6391
|
+
this._routeManifestLoaded = true;
|
|
6392
|
+
var path = this.mcpConfig.mcpRouteManifestPath;
|
|
6393
|
+
if (path == null) {
|
|
6394
|
+
this._cachedRouteManifest = undefined;
|
|
6395
|
+
} else if (node_fs.existsSync(path)) {
|
|
6396
|
+
this._parseRouteManifestFile(path);
|
|
6397
|
+
} else {
|
|
6398
|
+
this._logger.warn("MCP route manifest path is set but the file is missing: ".concat(path, ". The url-models tool will not be registered."));
|
|
6399
|
+
this._cachedRouteManifest = undefined;
|
|
6400
|
+
}
|
|
6401
|
+
}
|
|
6402
|
+
return this._cachedRouteManifest;
|
|
6403
|
+
}
|
|
6404
|
+
},
|
|
6405
|
+
{
|
|
6406
|
+
key: "_parseRouteManifestFile",
|
|
6407
|
+
value: function _parseRouteManifestFile(path) {
|
|
6408
|
+
try {
|
|
6409
|
+
var raw = node_fs.readFileSync(path, 'utf8');
|
|
6410
|
+
var parsed = JSON.parse(raw);
|
|
6411
|
+
if (parsed.version === ROUTE_MANIFEST_VERSION) {
|
|
6412
|
+
this._cachedRouteManifest = parsed;
|
|
6413
|
+
this._logger.log("Loaded MCP route manifest from ".concat(path, ": ").concat(parsed.states.length, " states."));
|
|
6414
|
+
} else {
|
|
6415
|
+
this._logger.warn("MCP route manifest version mismatch at ".concat(path, ": got ").concat(String(parsed.version), ", expected ").concat(ROUTE_MANIFEST_VERSION, ". The url-models tool will not be registered."));
|
|
6416
|
+
this._cachedRouteManifest = undefined;
|
|
6417
|
+
}
|
|
6418
|
+
} catch (error) {
|
|
6419
|
+
this._logger.warn("Failed to read MCP route manifest at ".concat(path, ": ").concat(error.message, ". The url-models tool will not be registered."));
|
|
6420
|
+
this._cachedRouteManifest = undefined;
|
|
6421
|
+
}
|
|
6422
|
+
}
|
|
6423
|
+
},
|
|
4519
6424
|
{
|
|
4520
6425
|
key: "_parseManifestFile",
|
|
4521
6426
|
value: function _parseManifestFile(path) {
|
|
@@ -4562,11 +6467,14 @@ var McpServerFactoryService_1;
|
|
|
4562
6467
|
}
|
|
4563
6468
|
var models = Array.isArray(parsed.models) && parsed.models.length > 0 ? parsed.models : undefined;
|
|
4564
6469
|
var modelSuffix = models == null ? '' : ", ".concat(models.length, " model entries");
|
|
6470
|
+
var enums = parsed.enums != null && _type_of$1(parsed.enums) === 'object' && Object.keys(parsed.enums).length > 0 ? parsed.enums : undefined;
|
|
6471
|
+
var enumSuffix = enums == null ? '' : ", ".concat(Object.keys(enums).length, " enum entries");
|
|
4565
6472
|
var auth = parsed.auth != null && Array.isArray(parsed.auth.claims) ? parsed.auth : undefined;
|
|
4566
6473
|
var authSuffix = auth == null ? '' : ", ".concat(auth.claims.length, " auth claim entries");
|
|
4567
|
-
this._logger.log("Loaded MCP manifest from ".concat(path, ": ").concat(map.size, " tool entries").concat(modelSuffix).concat(authSuffix, "."));
|
|
6474
|
+
this._logger.log("Loaded MCP manifest from ".concat(path, ": ").concat(map.size, " tool entries").concat(modelSuffix).concat(enumSuffix).concat(authSuffix, "."));
|
|
4568
6475
|
this._cachedManifest = map;
|
|
4569
6476
|
this._cachedManifestModels = models;
|
|
6477
|
+
this._cachedManifestEnums = enums;
|
|
4570
6478
|
this._cachedManifestAuth = auth;
|
|
4571
6479
|
}
|
|
4572
6480
|
},
|
|
@@ -4701,11 +6609,32 @@ var McpServerFactoryService_1;
|
|
|
4701
6609
|
},
|
|
4702
6610
|
{
|
|
4703
6611
|
/**
|
|
6612
|
+
* Resolves the app's reason-parameter config once and caches it for the process lifetime.
|
|
6613
|
+
*
|
|
6614
|
+
* The underlying {@link McpModuleConfig.reasonParameter} value is fixed at boot, so the normalized
|
|
6615
|
+
* form is safe to memoize and reuse across every `tools/list` and `tools/call`.
|
|
6616
|
+
*
|
|
6617
|
+
* @returns The resolved reason-parameter config (defaults applied).
|
|
6618
|
+
*/ key: "_resolveReasonConfig",
|
|
6619
|
+
value: function _resolveReasonConfig() {
|
|
6620
|
+
var result = this._resolvedReasonConfig;
|
|
6621
|
+
if (result == null) {
|
|
6622
|
+
result = resolveMcpReasonParameterConfig(this.mcpConfig.reasonParameter);
|
|
6623
|
+
this._resolvedReasonConfig = result;
|
|
6624
|
+
}
|
|
6625
|
+
return result;
|
|
6626
|
+
}
|
|
6627
|
+
},
|
|
6628
|
+
{
|
|
6629
|
+
/**
|
|
4704
6630
|
* Resolves the wire-shape `tools/list` entry for a single tool.
|
|
4705
6631
|
*
|
|
4706
6632
|
* Hot-path short-circuit: tools without a `toolDetailsBuilder` reuse the precomputed,
|
|
4707
6633
|
* frozen {@link McpToolDefinition.staticWireEntry} verbatim — zero allocations per
|
|
4708
|
-
* request for the common case.
|
|
6634
|
+
* request for the common case. When the auto-injected reason parameter is enabled (the
|
|
6635
|
+
* default), the entry is no longer returned frozen-verbatim: its `inputSchema` is wrapped
|
|
6636
|
+
* with the reason property per request (`tools/list` is low-frequency, so the allocation is
|
|
6637
|
+
* acceptable). Tools that already declare the parameter name are still reused verbatim.
|
|
4709
6638
|
*
|
|
4710
6639
|
* Tools that opted in to {@link McpToolDetailsBuilder} get a fresh wire entry built
|
|
4711
6640
|
* from the builder's overrides. If the builder throws, the framework falls back to
|
|
@@ -4717,9 +6646,20 @@ var McpServerFactoryService_1;
|
|
|
4717
6646
|
* @returns The wire-shape entry to emit for this tool on `tools/list`.
|
|
4718
6647
|
*/ key: "_buildToolListEntry",
|
|
4719
6648
|
value: function _buildToolListEntry(tool, ctx, scopes) {
|
|
6649
|
+
var reasonConfig = this._resolveReasonConfig();
|
|
4720
6650
|
var result;
|
|
4721
6651
|
if (tool.toolDetailsBuilder == null) {
|
|
4722
6652
|
result = tool.staticWireEntry;
|
|
6653
|
+
if (reasonConfig.enabled) {
|
|
6654
|
+
var reasoned = applyMcpReasonParameterToSchema(tool.staticWireEntry.inputSchema, reasonConfig);
|
|
6655
|
+
// applyMcpReasonParameterToSchema self-skips (returns the same reference) on collision, so the
|
|
6656
|
+
// frozen-verbatim hot path still holds for tools that already declare the parameter name.
|
|
6657
|
+
if (reasoned !== tool.staticWireEntry.inputSchema) {
|
|
6658
|
+
result = _object_spread_props(_object_spread({}, tool.staticWireEntry), {
|
|
6659
|
+
inputSchema: reasoned
|
|
6660
|
+
});
|
|
6661
|
+
}
|
|
6662
|
+
}
|
|
4723
6663
|
} else {
|
|
4724
6664
|
var description = tool.description;
|
|
4725
6665
|
var inputSchema = tool.inputSchema;
|
|
@@ -4740,16 +6680,23 @@ var McpServerFactoryService_1;
|
|
|
4740
6680
|
} catch (error) {
|
|
4741
6681
|
this._logger.warn("MCP tool ".concat(tool.name, " toolDetails builder threw; falling back to defaults: ").concat(error.message));
|
|
4742
6682
|
}
|
|
6683
|
+
var resolvedInputSchema = inputSchema !== null && inputSchema !== void 0 ? inputSchema : {
|
|
6684
|
+
type: 'object'
|
|
6685
|
+
};
|
|
6686
|
+
if (reasonConfig.enabled) {
|
|
6687
|
+
resolvedInputSchema = applyMcpReasonParameterToSchema(resolvedInputSchema, reasonConfig);
|
|
6688
|
+
}
|
|
4743
6689
|
var wire = {
|
|
4744
6690
|
name: tool.name,
|
|
4745
6691
|
description: description,
|
|
4746
|
-
inputSchema:
|
|
4747
|
-
type: 'object'
|
|
4748
|
-
}
|
|
6692
|
+
inputSchema: resolvedInputSchema
|
|
4749
6693
|
};
|
|
4750
6694
|
if (tool.outputSchema != null) {
|
|
4751
6695
|
wire.outputSchema = tool.outputSchema;
|
|
4752
6696
|
}
|
|
6697
|
+
if (tool.annotations != null) {
|
|
6698
|
+
wire.annotations = tool.annotations;
|
|
6699
|
+
}
|
|
4753
6700
|
result = wire;
|
|
4754
6701
|
}
|
|
4755
6702
|
return result;
|
|
@@ -4772,14 +6719,20 @@ var McpServerFactoryService_1;
|
|
|
4772
6719
|
* @returns The MCP tool response.
|
|
4773
6720
|
*/ function _handleToolCall(request, definitionsByName, ctx) {
|
|
4774
6721
|
return _async_to_generator$2(function() {
|
|
4775
|
-
var _request_params_arguments, _ctx_auth, toolName, definition,
|
|
6722
|
+
var _request_params_arguments, _ctx_auth, toolName, definition, rawArgs, startedAt, reasonConfig, declaresOwn, _extractMcpReasonFromArgs, reason, args, outcome, isSuccessful, toolKind;
|
|
4776
6723
|
return _ts_generator$2(this, function(_state) {
|
|
4777
6724
|
switch(_state.label){
|
|
4778
6725
|
case 0:
|
|
4779
6726
|
toolName = request.params.name;
|
|
4780
6727
|
definition = definitionsByName.get(toolName);
|
|
4781
|
-
|
|
6728
|
+
rawArgs = (_request_params_arguments = request.params.arguments) !== null && _request_params_arguments !== void 0 ? _request_params_arguments : {};
|
|
4782
6729
|
startedAt = Date.now();
|
|
6730
|
+
// Split the auto-injected reason out of the args: forward it to analytics, but never let it reach
|
|
6731
|
+
// the underlying handler. Tools that declare their own field of the same name keep it (driven by
|
|
6732
|
+
// the tool's own resolved inputSchema, not the reason-augmented wire schema).
|
|
6733
|
+
reasonConfig = this._resolveReasonConfig();
|
|
6734
|
+
declaresOwn = mcpSchemaDeclaresProperty(definition === null || definition === void 0 ? void 0 : definition.inputSchema, reasonConfig.parameterName);
|
|
6735
|
+
_extractMcpReasonFromArgs = extractMcpReasonFromArgs(rawArgs, reasonConfig, declaresOwn), reason = _extractMcpReasonFromArgs.reason, args = _extractMcpReasonFromArgs.args;
|
|
4783
6736
|
if (!(definition == null)) return [
|
|
4784
6737
|
3,
|
|
4785
6738
|
1
|
|
@@ -4829,6 +6782,7 @@ var McpServerFactoryService_1;
|
|
|
4829
6782
|
auth: ctx.auth,
|
|
4830
6783
|
readOnly: this.mcpConfig.readOnly === true,
|
|
4831
6784
|
args: args,
|
|
6785
|
+
reason: reason,
|
|
4832
6786
|
isSuccessful: isSuccessful,
|
|
4833
6787
|
error: outcome.error,
|
|
4834
6788
|
durationMs: Date.now() - startedAt
|
|
@@ -5670,18 +7624,20 @@ var FirebaseServerMcpAnalyticsService_1;
|
|
|
5670
7624
|
if (this._logEvents) {
|
|
5671
7625
|
var uidSuffix = event.uid ? " uid=".concat(event.uid) : '';
|
|
5672
7626
|
var durationSuffix = event.durationMs == null ? '' : " (".concat(event.durationMs, "ms)");
|
|
7627
|
+
var reasonSuffix = event.reason ? ' reason="'.concat(event.reason, '"') : '';
|
|
5673
7628
|
var outcome = event.isSuccessful ? 'Succeeded' : 'Failed';
|
|
5674
|
-
this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix));
|
|
7629
|
+
this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix).concat(reasonSuffix));
|
|
5675
7630
|
}
|
|
5676
7631
|
if (this.analyticsService != null) {
|
|
5677
|
-
var _event_call, _event_modelType, _event_specifier;
|
|
7632
|
+
var _event_call, _event_modelType, _event_specifier, _event_reason;
|
|
5678
7633
|
this.analyticsService.sendEventData(event.uid, this._eventName, {
|
|
5679
7634
|
tool: event.toolName,
|
|
5680
7635
|
toolKind: event.toolKind,
|
|
5681
7636
|
call: (_event_call = event.call) !== null && _event_call !== void 0 ? _event_call : '',
|
|
5682
7637
|
modelType: (_event_modelType = event.modelType) !== null && _event_modelType !== void 0 ? _event_modelType : '',
|
|
5683
7638
|
specifier: (_event_specifier = event.specifier) !== null && _event_specifier !== void 0 ? _event_specifier : '',
|
|
5684
|
-
success: event.isSuccessful
|
|
7639
|
+
success: event.isSuccessful,
|
|
7640
|
+
reason: (_event_reason = event.reason) !== null && _event_reason !== void 0 ? _event_reason : ''
|
|
5685
7641
|
});
|
|
5686
7642
|
}
|
|
5687
7643
|
}
|
|
@@ -5775,10 +7731,18 @@ exports.DEFAULT_BATCH_EXECUTE_MAX_PARALLEL = DEFAULT_BATCH_EXECUTE_MAX_PARALLEL;
|
|
|
5775
7731
|
exports.DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS = DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS;
|
|
5776
7732
|
exports.DEFAULT_MCP_ANALYTICS_EVENT_NAME = DEFAULT_MCP_ANALYTICS_EVENT_NAME;
|
|
5777
7733
|
exports.DEFAULT_MCP_PATH = DEFAULT_MCP_PATH;
|
|
7734
|
+
exports.DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION = DEFAULT_MCP_REASON_PARAMETER_DESCRIPTION;
|
|
7735
|
+
exports.DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH = DEFAULT_MCP_REASON_PARAMETER_MAX_LENGTH;
|
|
7736
|
+
exports.DEFAULT_MCP_REASON_PARAMETER_NAME = DEFAULT_MCP_REASON_PARAMETER_NAME;
|
|
7737
|
+
exports.DEFAULT_MCP_REASON_PARAMETER_REQUIRED = DEFAULT_MCP_REASON_PARAMETER_REQUIRED;
|
|
5778
7738
|
exports.DEFAULT_MCP_SERVER_INSTRUCTIONS = DEFAULT_MCP_SERVER_INSTRUCTIONS;
|
|
5779
7739
|
exports.DEFAULT_MCP_SERVER_NAME = DEFAULT_MCP_SERVER_NAME;
|
|
5780
7740
|
exports.DEFAULT_SPECIFIER_KEY = DEFAULT_SPECIFIER_KEY;
|
|
5781
7741
|
exports.DEFAULT_VOID_MCP_SUCCESS_VALUE = DEFAULT_VOID_MCP_SUCCESS_VALUE;
|
|
7742
|
+
exports.ENUM_INFO_DISPATCH_CALL = ENUM_INFO_DISPATCH_CALL;
|
|
7743
|
+
exports.ENUM_INFO_DISPATCH_MODEL_TYPE = ENUM_INFO_DISPATCH_MODEL_TYPE;
|
|
7744
|
+
exports.ENUM_INFO_TOOL_NAME = ENUM_INFO_TOOL_NAME;
|
|
7745
|
+
exports.ENUM_TABLE_SCHEMA = ENUM_TABLE_SCHEMA;
|
|
5782
7746
|
exports.FIREBASE_SERVER_MCP_ANALYTICS_CONFIG = FIREBASE_SERVER_MCP_ANALYTICS_CONFIG;
|
|
5783
7747
|
exports.FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE = FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE;
|
|
5784
7748
|
exports.MAX_BATCH_EXECUTE_FILE_BYTES = MAX_BATCH_EXECUTE_FILE_BYTES;
|
|
@@ -5790,6 +7754,7 @@ exports.MCP_MANIFEST_VERSION = MCP_MANIFEST_VERSION;
|
|
|
5790
7754
|
exports.MCP_MODEL_GET_BATCH_SIZE = MCP_MODEL_GET_BATCH_SIZE;
|
|
5791
7755
|
exports.MCP_TOOL_NAME_MAX_LENGTH = MCP_TOOL_NAME_MAX_LENGTH;
|
|
5792
7756
|
exports.MCP_TOOL_NAME_WARN_LENGTH = MCP_TOOL_NAME_WARN_LENGTH;
|
|
7757
|
+
exports.MCP_WRITE_TOOL_DESCRIPTION_PREFIX = MCP_WRITE_TOOL_DESCRIPTION_PREFIX;
|
|
5793
7758
|
exports.MODEL_DECODE_DISPATCH_CALL = MODEL_DECODE_DISPATCH_CALL;
|
|
5794
7759
|
exports.MODEL_DECODE_DISPATCH_MODEL_TYPE = MODEL_DECODE_DISPATCH_MODEL_TYPE;
|
|
5795
7760
|
exports.MODEL_DECODE_TOOL_NAME = MODEL_DECODE_TOOL_NAME;
|
|
@@ -5803,27 +7768,43 @@ exports.MODEL_INFO_TOOL_NAME = MODEL_INFO_TOOL_NAME;
|
|
|
5803
7768
|
exports.MODEL_INFO_UNGROUPED_LABEL = MODEL_INFO_UNGROUPED_LABEL;
|
|
5804
7769
|
exports.McpAnalyticsService = McpAnalyticsService;
|
|
5805
7770
|
exports.McpModuleConfig = McpModuleConfig;
|
|
7771
|
+
exports.ROUTE_MANIFEST_VERSION = ROUTE_MANIFEST_VERSION;
|
|
7772
|
+
exports.URL_MODELS_DISPATCH_CALL = URL_MODELS_DISPATCH_CALL;
|
|
7773
|
+
exports.URL_MODELS_DISPATCH_MODEL_TYPE = URL_MODELS_DISPATCH_MODEL_TYPE;
|
|
7774
|
+
exports.URL_MODELS_TOOL_NAME = URL_MODELS_TOOL_NAME;
|
|
5806
7775
|
exports.abbreviateMcpCallType = abbreviateMcpCallType;
|
|
5807
7776
|
exports.appMcpAnalyticsModuleMetadata = appMcpAnalyticsModuleMetadata;
|
|
7777
|
+
exports.applyMcpReasonParameterToSchema = applyMcpReasonParameterToSchema;
|
|
7778
|
+
exports.applyWriteMarker = applyWriteMarker;
|
|
5808
7779
|
exports.batchOperationCoordKey = batchOperationCoordKey;
|
|
5809
7780
|
exports.buildDefaultMcpToolDescription = buildDefaultMcpToolDescription;
|
|
5810
7781
|
exports.buildDisambiguatedMcpToolName = buildDisambiguatedMcpToolName;
|
|
5811
7782
|
exports.buildMcpToolName = buildMcpToolName;
|
|
7783
|
+
exports.buildStaticToolDefinition = buildStaticToolDefinition;
|
|
5812
7784
|
exports.buildStaticWireEntry = buildStaticWireEntry;
|
|
5813
7785
|
exports.classifyVisibility = classifyVisibility;
|
|
5814
7786
|
exports.createBatchExecuteTool = createBatchExecuteTool;
|
|
7787
|
+
exports.createEnumInfoTool = createEnumInfoTool;
|
|
5815
7788
|
exports.createModelDecodeTool = createModelDecodeTool;
|
|
5816
7789
|
exports.createModelGetTool = createModelGetTool;
|
|
5817
7790
|
exports.createModelInfoTool = createModelInfoTool;
|
|
7791
|
+
exports.createUrlModelsTool = createUrlModelsTool;
|
|
5818
7792
|
exports.decodeFirestoreModelKey = decodeFirestoreModelKey;
|
|
7793
|
+
exports.extractMcpReasonFromArgs = extractMcpReasonFromArgs;
|
|
5819
7794
|
exports.findModelEntry = findModelEntry;
|
|
5820
7795
|
exports.formatMcpToolErrorResponse = formatMcpToolErrorResponse;
|
|
5821
7796
|
exports.formatMcpToolResponse = formatMcpToolResponse;
|
|
5822
7797
|
exports.generateMcpToolDefinitions = generateMcpToolDefinitions;
|
|
5823
7798
|
exports.handleStreamableHttpMcpRequest = handleStreamableHttpMcpRequest;
|
|
7799
|
+
exports.matchRouteManifestUrl = matchRouteManifestUrl;
|
|
5824
7800
|
exports.mcpManifestKey = mcpManifestKey;
|
|
5825
7801
|
exports.mcpModuleMetadata = mcpModuleMetadata;
|
|
7802
|
+
exports.mcpSchemaDeclaresProperty = mcpSchemaDeclaresProperty;
|
|
5826
7803
|
exports.noopMcpAnalyticsService = noopMcpAnalyticsService;
|
|
7804
|
+
exports.parseUrlModelsPathname = parseUrlModelsPathname;
|
|
5827
7805
|
exports.resolveEffectiveReadOnly = resolveEffectiveReadOnly;
|
|
7806
|
+
exports.resolveEnumInfoOutput = resolveEnumInfoOutput;
|
|
7807
|
+
exports.resolveMcpReasonParameterConfig = resolveMcpReasonParameterConfig;
|
|
7808
|
+
exports.resolveMcpToolAnnotations = resolveMcpToolAnnotations;
|
|
5828
7809
|
exports.resolveRequiredScope = resolveRequiredScope;
|
|
5829
7810
|
exports.validateMcpToolName = validateMcpToolName;
|