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