@dereekb/firebase-server 14.4.0 → 14.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/calcom/package.json +11 -10
  2. package/discord/package.json +14 -10
  3. package/index.esm.js +1295 -317
  4. package/mailgun/package.json +9 -9
  5. package/mcp/index.esm.js +483 -83
  6. package/mcp/package.json +12 -12
  7. package/mcp/src/lib/mcp.config.d.ts +73 -3
  8. package/mcp/src/lib/service/index.d.ts +1 -0
  9. package/mcp/src/lib/service/mcp.server.factory.d.ts +3 -2
  10. package/mcp/src/lib/service/mcp.tool-generator.d.ts +9 -0
  11. package/mcp/src/lib/service/tools/mcp.tool.cli-token.d.ts +62 -0
  12. package/model/package.json +13 -10
  13. package/oidc/index.esm.js +3186 -1456
  14. package/oidc/package.json +11 -11
  15. package/oidc/src/lib/controller/index.d.ts +3 -0
  16. package/oidc/src/lib/controller/oidc.cli-token.config.d.ts +323 -0
  17. package/oidc/src/lib/controller/oidc.cli-token.controller.d.ts +45 -0
  18. package/oidc/src/lib/controller/oidc.cli-token.service.d.ts +138 -0
  19. package/oidc/src/lib/controller/oidc.interaction.controller.d.ts +38 -0
  20. package/oidc/src/lib/middleware/oauth-auth.module.d.ts +8 -0
  21. package/oidc/src/lib/oidc.config.d.ts +9 -0
  22. package/oidc/src/lib/oidc.module.d.ts +1 -1
  23. package/oidc/src/lib/service/index.d.ts +1 -0
  24. package/oidc/src/lib/service/oidc.config.service.d.ts +8 -3
  25. package/oidc/src/lib/service/oidc.download-signer.d.ts +17 -0
  26. package/oidc/src/lib/service/oidc.jwt-signing.service.d.ts +35 -0
  27. package/package.json +13 -13
  28. package/src/lib/nest/controller/download/download.api.config.d.ts +203 -0
  29. package/src/lib/nest/controller/download/download.api.controller.d.ts +25 -0
  30. package/src/lib/nest/controller/download/download.api.module.d.ts +47 -0
  31. package/src/lib/nest/controller/download/download.api.service.d.ts +111 -0
  32. package/src/lib/nest/controller/download/index.d.ts +4 -0
  33. package/src/lib/nest/controller/index.d.ts +2 -0
  34. package/src/lib/nest/controller/request.ip.d.ts +60 -0
  35. package/test/index.esm.js +1 -0
  36. package/test/package.json +12 -12
  37. package/test/src/lib/oidc/oidc.test.flow.d.ts +10 -0
  38. package/twilio/package.json +8 -8
  39. package/zoho/package.json +14 -10
package/mcp/index.esm.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Injectable, Inject, Optional, Logger, Post, Req, Res, Get, Delete, Controller, HttpStatus } from '@nestjs/common';
2
2
  import { existsSync, readFileSync } from 'node:fs';
3
3
  import { McpServer, isLegacyRequest, isJsonContentType, createMcpHandler } from '@modelcontextprotocol/server';
4
- import { callModelOidcScopeForCallType, resolveEffectiveOidcScopeTerms, inferKeyFromTwoWayFlatFirestoreModelKey, oidcScopeTermsSatisfied } from '@dereekb/firebase';
4
+ import { callModelOidcScopeForCallType, resolveEffectiveOidcScopeTerms, CLI_TOKEN_OIDC_SCOPE, inferKeyFromTwoWayFlatFirestoreModelKey, oidcScopeTermsSatisfied } from '@dereekb/firebase';
5
5
  import { getOidcScopesFromRequest, OidcProviderConfigService } from '@dereekb/firebase-server/oidc';
6
- import { makeValuesGroupMap, IMPERSONATION_URL_QUERY_PARAM, performAsyncTasks, authRolesSetHasRoles } from '@dereekb/util';
7
- import { ModelApiCallModelDispatchService, ModelApiGetService, FirebaseServerStorageService, FirebaseServerEnvService, FirebaseServerAnalyticsService } from '@dereekb/firebase-server';
6
+ import { makeValuesGroupMap, AUTH_ADMIN_ROLE, IMPERSONATION_URL_QUERY_PARAM, performAsyncTasks, authRolesSetHasRoles } from '@dereekb/util';
7
+ import { requestClientIp, ModelApiCallModelDispatchService, ModelApiGetService, FirebaseServerStorageService, FirebaseServerEnvService, FirebaseServerAnalyticsService } from '@dereekb/firebase-server';
8
8
  import { inspect } from 'node:util';
9
9
  import { arktypeToJsonSchemaForExport } from '@dereekb/model';
10
10
  import { toWebRequest, toNodeHandler, NodeStreamableHTTPServerTransport } from '@modelcontextprotocol/node';
@@ -12,7 +12,7 @@ import { toWebRequest, toNodeHandler, NodeStreamableHTTPServerTransport } from '
12
12
  function _class_call_check$5(instance, Constructor) {
13
13
  if (!(instance instanceof Constructor)) throw new TypeError("Cannot call a class as a function");
14
14
  }
15
- function _define_property$a(obj, key, value) {
15
+ function _define_property$c(obj, key, value) {
16
16
  if (key in obj) {
17
17
  Object.defineProperty(obj, key, {
18
18
  value: value,
@@ -81,7 +81,7 @@ function _define_property$a(obj, key, value) {
81
81
  * discovery document. Claude custom-connector reads this to discover the OIDC issuer.
82
82
  *
83
83
  * @example 'https://api.example.com/oidc'
84
- */ _define_property$a(this, "oidcIssuer", void 0);
84
+ */ _define_property$c(this, "oidcIssuer", void 0);
85
85
  /**
86
86
  * The canonical resource URL of the MCP endpoint.
87
87
  *
@@ -89,7 +89,7 @@ function _define_property$a(obj, key, value) {
89
89
  * and used as the audience the access token's `aud` claim should match.
90
90
  *
91
91
  * @example 'https://api.example.com/mcp'
92
- */ _define_property$a(this, "mcpUrl", void 0);
92
+ */ _define_property$c(this, "mcpUrl", void 0);
93
93
  /**
94
94
  * Optional filter applied to the OIDC provider's scope list when building the
95
95
  * protected-resource discovery document's `scopes_supported` (RFC 9728 §2).
@@ -98,9 +98,11 @@ function _define_property$a(obj, key, value) {
98
98
  * injected {@link OidcProviderConfigService.clientRequestableScopesSupported}, so
99
99
  * the MCP resource advertises the scopes the issuer grants an arbitrary client
100
100
  * without the app restating them. Scopes only an admin-assigned provider profile
101
- * unlocks are already excluded — requesting one is fatal at the consent unlock
102
- * gate. Provide this only to narrow the set further; it returns the subset to
103
- * advertise. When unset, the whole base list is advertised.
101
+ * unlocks are excluded from that base list, since an unassigned client can never
102
+ * be granted one. Provide this to narrow the set further — or to add such a gated
103
+ * scope back deliberately, which is safe: the consent URL builder withholds it
104
+ * from any client whose profiles do not unlock it, so that client's flow completes
105
+ * without it rather than failing. When unset, the whole base list is advertised.
104
106
  *
105
107
  * Advertising these matters because dynamic-registration MCP clients (the Claude
106
108
  * Code CLI) read `scopes_supported` to decide which scopes to request on the
@@ -108,19 +110,19 @@ function _define_property$a(obj, key, value) {
108
110
  * the OIDC provider nothing to grant and ending the interaction in `access_denied`.
109
111
  *
110
112
  * @example (allScopes) => allScopes.filter((scope) => scope === 'openid' || scope.startsWith('model.'))
111
- */ _define_property$a(this, "scopesSupported", void 0);
113
+ */ _define_property$c(this, "scopesSupported", void 0);
112
114
  /**
113
115
  * Optional name advertised on the MCP `initialize` handshake. Defaults to
114
116
  * {@link DEFAULT_MCP_SERVER_NAME}.
115
- */ _define_property$a(this, "serverName", void 0);
117
+ */ _define_property$c(this, "serverName", void 0);
116
118
  /**
117
119
  * Optional version advertised on the MCP `initialize` handshake.
118
- */ _define_property$a(this, "serverVersion", void 0);
120
+ */ _define_property$c(this, "serverVersion", void 0);
119
121
  /**
120
122
  * Optional override for the `instructions` string passed to `new McpServer(...)` and
121
123
  * advertised on the JSON-RPC `initialize` handshake. Defaults to
122
124
  * {@link DEFAULT_MCP_SERVER_INSTRUCTIONS}.
123
- */ _define_property$a(this, "serverInstructions", void 0);
125
+ */ _define_property$c(this, "serverInstructions", void 0);
124
126
  /**
125
127
  * Absolute path to a pre-rendered MCP manifest JSON file produced by
126
128
  * `dbx-cli-generate-mcp-manifest`. When set, the runtime reads it once at
@@ -130,7 +132,7 @@ function _define_property$a(obj, key, value) {
130
132
  * Optional. When unset or the file is missing, the runtime falls back to
131
133
  * today's behavior (auto-generated descriptions, ArkType-derived input
132
134
  * schemas, no output schemas) and emits a single boot warning.
133
- */ _define_property$a(this, "mcpManifestPath", void 0);
135
+ */ _define_property$c(this, "mcpManifestPath", void 0);
134
136
  /**
135
137
  * Absolute path to a pre-rendered route manifest JSON file produced by
136
138
  * `dbx-cli-generate-route-manifest`. When set, the runtime reads it once at
@@ -140,7 +142,7 @@ function _define_property$a(obj, key, value) {
140
142
  * Optional. When unset or the file is missing, the runtime skips registering
141
143
  * `url-models` and emits a single boot warning when the path was set but
142
144
  * unreadable.
143
- */ _define_property$a(this, "mcpRouteManifestPath", void 0);
145
+ */ _define_property$c(this, "mcpRouteManifestPath", void 0);
144
146
  /**
145
147
  * When `true`, the MCP server only advertises tools whose effective read-only classification is `true`.
146
148
  *
@@ -150,7 +152,7 @@ function _define_property$a(obj, key, value) {
150
152
  *
151
153
  * The advertised `serverName` on the JSON-RPC `initialize` handshake is suffixed with
152
154
  * ` (read-only)` so the client surface reflects the mode.
153
- */ _define_property$a(this, "readOnly", void 0);
155
+ */ _define_property$c(this, "readOnly", void 0);
154
156
  /**
155
157
  * Controls the auto-injected `reason` parameter added to every advertised tool's input schema.
156
158
  *
@@ -160,7 +162,7 @@ function _define_property$a(obj, key, value) {
160
162
  * When enabled, every advertised tool's `inputSchema` carries a required `reason` string the model
161
163
  * fills with a short justification for the call. The value is forwarded to analytics and stripped
162
164
  * from the dispatched handler body. See {@link McpReasonParameterConfig}.
163
- */ _define_property$a(this, "reasonParameter", void 0);
165
+ */ _define_property$c(this, "reasonParameter", void 0);
164
166
  /**
165
167
  * Default OIDC scope group term required on EVERY `callModel` op, mirrored into MCP tool-list
166
168
  * visibility, unless a finer term overrides it (a per-function `requiredScope`, then a
@@ -170,13 +172,13 @@ function _define_property$a(obj, key, value) {
170
172
  *
171
173
  * Set this to the SAME value passed to `ModelApiDispatchConfig.defaultRequiredScope` to
172
174
  * keep tool visibility and enforcement in lockstep.
173
- */ _define_property$a(this, "defaultRequiredScope", void 0);
175
+ */ _define_property$c(this, "defaultRequiredScope", void 0);
174
176
  /**
175
177
  * Per-model OIDC scope group-term overrides, keyed by {@link FirestoreModelType}, mirrored into MCP
176
178
  * tool-list visibility. Set this to the SAME value passed to
177
179
  * `ModelApiDispatchConfig.modelRequiredScopes` so per-model / verb-keyed restrictions that
178
180
  * confine a subset client apply identically to the advertised tool list.
179
- */ _define_property$a(this, "modelRequiredScopes", void 0);
181
+ */ _define_property$c(this, "modelRequiredScopes", void 0);
180
182
  };
181
183
  /**
182
184
  * NestJS injection token for the optional {@link McpAuthRoleReader} provider.
@@ -184,6 +186,9 @@ function _define_property$a(obj, key, value) {
184
186
  /**
185
187
  * NestJS injection token for the optional {@link McpModelRolesTargetUidPredicate} provider.
186
188
  */ var MCP_MODEL_ROLES_TARGET_UID_PREDICATE = 'MCP_MODEL_ROLES_TARGET_UID_PREDICATE';
189
+ /**
190
+ * NestJS injection token for the optional {@link McpCliTokenMinter} provider.
191
+ */ var MCP_CLI_TOKEN_MINTER = 'MCP_CLI_TOKEN_MINTER';
187
192
 
188
193
  function _type_of$5(obj) {
189
194
  "@swc/helpers - typeof";
@@ -213,7 +218,7 @@ function _array_like_to_array$b(arr, len) {
213
218
  function _array_without_holes$7(arr) {
214
219
  if (Array.isArray(arr)) return _array_like_to_array$b(arr);
215
220
  }
216
- function _define_property$9(obj, key, value) {
221
+ function _define_property$b(obj, key, value) {
217
222
  if (key in obj) {
218
223
  Object.defineProperty(obj, key, {
219
224
  value: value,
@@ -232,7 +237,7 @@ function _iterable_to_array$7(iter) {
232
237
  function _non_iterable_spread$7() {
233
238
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
234
239
  }
235
- function _object_spread$7(target) {
240
+ function _object_spread$9(target) {
236
241
  for(var i = 1; i < arguments.length; i++){
237
242
  var source = arguments[i] != null ? arguments[i] : {};
238
243
  var ownKeys = Object.keys(source);
@@ -242,7 +247,7 @@ function _object_spread$7(target) {
242
247
  }));
243
248
  }
244
249
  ownKeys.forEach(function(key) {
245
- _define_property$9(target, key, source[key]);
250
+ _define_property$b(target, key, source[key]);
246
251
  });
247
252
  }
248
253
  return target;
@@ -351,9 +356,9 @@ function _unsupported_iterable_to_array$b(o, minLen) {
351
356
  var _base_type;
352
357
  var base = (typeof inputSchema === "undefined" ? "undefined" : _type_of$4(inputSchema)) === 'object' && inputSchema != null ? inputSchema : {};
353
358
  var existingProperties = _type_of$4(base.properties) === 'object' && base.properties != null ? base.properties : {};
354
- var next = _object_spread_props$3(_object_spread$7({}, base), {
359
+ var next = _object_spread_props$3(_object_spread$9({}, base), {
355
360
  type: (_base_type = base.type) !== null && _base_type !== void 0 ? _base_type : 'object',
356
- properties: _object_spread_props$3(_object_spread$7({}, existingProperties), _define_property$9({}, resolved.parameterName, {
361
+ properties: _object_spread_props$3(_object_spread$9({}, existingProperties), _define_property$b({}, resolved.parameterName, {
357
362
  type: 'string',
358
363
  maxLength: resolved.maxLength,
359
364
  description: resolved.description
@@ -387,7 +392,7 @@ function _unsupported_iterable_to_array$b(o, minLen) {
387
392
  var result;
388
393
  if (resolved.enabled && !toolDeclaresOwnReason && Object.prototype.hasOwnProperty.call(args, resolved.parameterName)) {
389
394
  var rawValue = args[resolved.parameterName];
390
- var nextArgs = _object_spread$7({}, args);
395
+ var nextArgs = _object_spread$9({}, args);
391
396
  delete nextArgs[resolved.parameterName];
392
397
  var stringValue = rawValue == null ? '' : String(rawValue);
393
398
  var clamped = stringValue.length > resolved.maxLength ? stringValue.slice(0, resolved.maxLength) : stringValue;
@@ -740,7 +745,7 @@ function scoreCandidates(states, pathname) {
740
745
  });
741
746
  }
742
747
 
743
- function asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, key, arg) {
748
+ function asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, key, arg) {
744
749
  try {
745
750
  var info = gen[key](arg);
746
751
  var value = info.value;
@@ -751,16 +756,16 @@ function asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, key, arg) {
751
756
  if (info.done) resolve(value);
752
757
  else Promise.resolve(value).then(_next, _throw);
753
758
  }
754
- function _async_to_generator$7(fn) {
759
+ function _async_to_generator$8(fn) {
755
760
  return function() {
756
761
  var self = this, args = arguments;
757
762
  return new Promise(function(resolve, reject) {
758
763
  var gen = fn.apply(self, args);
759
764
  function _next(value) {
760
- asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "next", value);
765
+ asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, "next", value);
761
766
  }
762
767
  function _throw(err) {
763
- asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "throw", err);
768
+ asyncGeneratorStep$8(gen, resolve, reject, _next, _throw, "throw", err);
764
769
  }
765
770
  _next(undefined);
766
771
  });
@@ -772,7 +777,7 @@ function _instanceof$1(left, right) {
772
777
  return !!right[Symbol.hasInstance](left);
773
778
  } else return left instanceof right;
774
779
  }
775
- function _ts_generator$7(thisArg, body) {
780
+ function _ts_generator$8(thisArg, body) {
776
781
  var f, y, t, _ = {
777
782
  label: 0,
778
783
  sent: function() {
@@ -900,9 +905,9 @@ function _ts_generator$7(thisArg, body) {
900
905
  * @param details - The handler-level API details (carries the mapper + Tier 2/3 formatters).
901
906
  * @returns The MCP tool response content.
902
907
  */ function formatMcpToolResponse(result, params, details) {
903
- return _async_to_generator$7(function() {
908
+ return _async_to_generator$8(function() {
904
909
  var mcp, value, _tmp, context, response, summary;
905
- return _ts_generator$7(this, function(_state) {
910
+ return _ts_generator$8(this, function(_state) {
906
911
  switch(_state.label){
907
912
  case 0:
908
913
  mcp = details === null || details === void 0 ? void 0 : details.mcp;
@@ -1096,6 +1101,17 @@ function _array_like_to_array$9(arr, len) {
1096
1101
  function _array_with_holes$4(arr) {
1097
1102
  if (Array.isArray(arr)) return arr;
1098
1103
  }
1104
+ function _define_property$a(obj, key, value) {
1105
+ if (key in obj) {
1106
+ Object.defineProperty(obj, key, {
1107
+ value: value,
1108
+ enumerable: true,
1109
+ configurable: true,
1110
+ writable: true
1111
+ });
1112
+ } else obj[key] = value;
1113
+ return obj;
1114
+ }
1099
1115
  function _iterable_to_array_limit$4(arr, i) {
1100
1116
  var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
1101
1117
  if (_i == null) return;
@@ -1123,6 +1139,21 @@ function _iterable_to_array_limit$4(arr, i) {
1123
1139
  function _non_iterable_rest$4() {
1124
1140
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1125
1141
  }
1142
+ function _object_spread$8(target) {
1143
+ for(var i = 1; i < arguments.length; i++){
1144
+ var source = arguments[i] != null ? arguments[i] : {};
1145
+ var ownKeys = Object.keys(source);
1146
+ if (typeof Object.getOwnPropertySymbols === "function") {
1147
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
1148
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
1149
+ }));
1150
+ }
1151
+ ownKeys.forEach(function(key) {
1152
+ _define_property$a(target, key, source[key]);
1153
+ });
1154
+ }
1155
+ return target;
1156
+ }
1126
1157
  function _sliced_to_array$4(arr, i) {
1127
1158
  return _array_with_holes$4(arr) || _iterable_to_array_limit$4(arr, i) || _unsupported_iterable_to_array$9(arr, i) || _non_iterable_rest$4();
1128
1159
  }
@@ -1214,7 +1245,7 @@ function _unsupported_iterable_to_array$9(o, minLen) {
1214
1245
  * @param input - The tool identity, schemas, dispatch target, static handler, and read-only classification.
1215
1246
  * @returns A statically-registered {@link McpToolDefinition} to append to the MCP server factory's tool registry.
1216
1247
  */ function buildStaticToolDefinition(input) {
1217
- var name = input.name, inputSchema = input.inputSchema, outputSchema = input.outputSchema, dispatch = input.dispatch, staticHandler = input.staticHandler, effectiveReadOnly = input.effectiveReadOnly, rule = input.rule;
1248
+ var name = input.name, inputSchema = input.inputSchema, outputSchema = input.outputSchema, dispatch = input.dispatch, staticHandler = input.staticHandler, effectiveReadOnly = input.effectiveReadOnly, rule = input.rule, requiredScopeTerms = input.requiredScopeTerms;
1218
1249
  var annotations = resolveMcpToolAnnotations(effectiveReadOnly);
1219
1250
  var description = applyWriteMarker(input.description, annotations);
1220
1251
  return {
@@ -1225,11 +1256,13 @@ function _unsupported_iterable_to_array$9(o, minLen) {
1225
1256
  annotations: annotations,
1226
1257
  dispatch: dispatch,
1227
1258
  staticHandler: staticHandler,
1228
- filterMetadata: {
1259
+ filterMetadata: _object_spread$8({
1229
1260
  visibilityKind: 'declarative',
1230
1261
  rule: rule !== null && rule !== void 0 ? rule : {},
1231
1262
  effectiveReadOnly: effectiveReadOnly
1232
- },
1263
+ }, requiredScopeTerms == null ? undefined : {
1264
+ requiredScopeTerms: requiredScopeTerms
1265
+ }),
1233
1266
  staticWireEntry: buildStaticWireEntry({
1234
1267
  name: name,
1235
1268
  description: description,
@@ -1762,7 +1795,7 @@ function _array_like_to_array$8(arr, len) {
1762
1795
  function _array_without_holes$6(arr) {
1763
1796
  if (Array.isArray(arr)) return _array_like_to_array$8(arr);
1764
1797
  }
1765
- function asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, key, arg) {
1798
+ function asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, key, arg) {
1766
1799
  try {
1767
1800
  var info = gen[key](arg);
1768
1801
  var value = info.value;
@@ -1773,16 +1806,16 @@ function asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, key, arg) {
1773
1806
  if (info.done) resolve(value);
1774
1807
  else Promise.resolve(value).then(_next, _throw);
1775
1808
  }
1776
- function _async_to_generator$6(fn) {
1809
+ function _async_to_generator$7(fn) {
1777
1810
  return function() {
1778
1811
  var self = this, args = arguments;
1779
1812
  return new Promise(function(resolve, reject) {
1780
1813
  var gen = fn.apply(self, args);
1781
1814
  function _next(value) {
1782
- asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "next", value);
1815
+ asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "next", value);
1783
1816
  }
1784
1817
  function _throw(err) {
1785
- asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "throw", err);
1818
+ asyncGeneratorStep$7(gen, resolve, reject, _next, _throw, "throw", err);
1786
1819
  }
1787
1820
  _next(undefined);
1788
1821
  });
@@ -1799,7 +1832,7 @@ function _non_iterable_spread$6() {
1799
1832
  function _to_consumable_array$6(arr) {
1800
1833
  return _array_without_holes$6(arr) || _iterable_to_array$6(arr) || _unsupported_iterable_to_array$8(arr) || _non_iterable_spread$6();
1801
1834
  }
1802
- function _ts_generator$6(thisArg, body) {
1835
+ function _ts_generator$7(thisArg, body) {
1803
1836
  var f, y, t, _ = {
1804
1837
  label: 0,
1805
1838
  sent: function() {
@@ -1968,9 +2001,9 @@ function _unsupported_iterable_to_array$8(o, minLen) {
1968
2001
  }
1969
2002
  // MARK: Handler
1970
2003
  function modelGetToolHandler(args, ctx, deps) {
1971
- return _async_to_generator$6(function() {
2004
+ return _async_to_generator$7(function() {
1972
2005
  var result, input, identity, resolvedKeys, merged, error;
1973
- return _ts_generator$6(this, function(_state) {
2006
+ return _ts_generator$7(this, function(_state) {
1974
2007
  switch(_state.label){
1975
2008
  case 0:
1976
2009
  _state.trys.push([
@@ -2077,9 +2110,9 @@ function resolveKeys$1(keys, identity) {
2077
2110
  return resolved;
2078
2111
  }
2079
2112
  function readInChunks$1(input) {
2080
- return _async_to_generator$6(function() {
2113
+ return _async_to_generator$7(function() {
2081
2114
  var modelType, keys, auth, readDocuments, merged, offset, _merged_results, _merged_errors, batch, partial;
2082
- return _ts_generator$6(this, function(_state) {
2115
+ return _ts_generator$7(this, function(_state) {
2083
2116
  switch(_state.label){
2084
2117
  case 0:
2085
2118
  modelType = input.modelType, keys = input.keys, auth = input.auth, readDocuments = input.readDocuments;
@@ -2193,7 +2226,7 @@ var MODEL_GET_OUTPUT_SCHEMA = {
2193
2226
  }
2194
2227
  };
2195
2228
 
2196
- function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
2229
+ function asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, key, arg) {
2197
2230
  try {
2198
2231
  var info = gen[key](arg);
2199
2232
  var value = info.value;
@@ -2204,22 +2237,22 @@ function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
2204
2237
  if (info.done) resolve(value);
2205
2238
  else Promise.resolve(value).then(_next, _throw);
2206
2239
  }
2207
- function _async_to_generator$5(fn) {
2240
+ function _async_to_generator$6(fn) {
2208
2241
  return function() {
2209
2242
  var self = this, args = arguments;
2210
2243
  return new Promise(function(resolve, reject) {
2211
2244
  var gen = fn.apply(self, args);
2212
2245
  function _next(value) {
2213
- asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "next", value);
2246
+ asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "next", value);
2214
2247
  }
2215
2248
  function _throw(err) {
2216
- asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "throw", err);
2249
+ asyncGeneratorStep$6(gen, resolve, reject, _next, _throw, "throw", err);
2217
2250
  }
2218
2251
  _next(undefined);
2219
2252
  });
2220
2253
  };
2221
2254
  }
2222
- function _define_property$8(obj, key, value) {
2255
+ function _define_property$9(obj, key, value) {
2223
2256
  if (key in obj) {
2224
2257
  Object.defineProperty(obj, key, {
2225
2258
  value: value,
@@ -2230,7 +2263,7 @@ function _define_property$8(obj, key, value) {
2230
2263
  } else obj[key] = value;
2231
2264
  return obj;
2232
2265
  }
2233
- function _object_spread$6(target) {
2266
+ function _object_spread$7(target) {
2234
2267
  for(var i = 1; i < arguments.length; i++){
2235
2268
  var source = arguments[i] != null ? arguments[i] : {};
2236
2269
  var ownKeys = Object.keys(source);
@@ -2240,12 +2273,12 @@ function _object_spread$6(target) {
2240
2273
  }));
2241
2274
  }
2242
2275
  ownKeys.forEach(function(key) {
2243
- _define_property$8(target, key, source[key]);
2276
+ _define_property$9(target, key, source[key]);
2244
2277
  });
2245
2278
  }
2246
2279
  return target;
2247
2280
  }
2248
- function _ts_generator$5(thisArg, body) {
2281
+ function _ts_generator$6(thisArg, body) {
2249
2282
  var f, y, t, _ = {
2250
2283
  label: 0,
2251
2284
  sent: function() {
@@ -2408,9 +2441,9 @@ function _ts_generator$5(thisArg, body) {
2408
2441
  }
2409
2442
  // MARK: Handler
2410
2443
  function modelRolesToolHandler(args, ctx, deps) {
2411
- return _async_to_generator$5(function() {
2444
+ return _async_to_generator$6(function() {
2412
2445
  var result, input, identity, targetUid, keys, resolved, error;
2413
- return _ts_generator$5(this, function(_state) {
2446
+ return _ts_generator$6(this, function(_state) {
2414
2447
  switch(_state.label){
2415
2448
  case 0:
2416
2449
  _state.trys.push([
@@ -2437,7 +2470,7 @@ function modelRolesToolHandler(args, ctx, deps) {
2437
2470
  keys = resolveKeys(input.keys, identity);
2438
2471
  return [
2439
2472
  4,
2440
- deps.readRoleMaps(_object_spread$6({
2473
+ deps.readRoleMaps(_object_spread$7({
2441
2474
  modelType: input.modelType,
2442
2475
  keys: keys,
2443
2476
  auth: ctx.auth
@@ -2486,9 +2519,9 @@ function modelRolesToolHandler(args, ctx, deps) {
2486
2519
  * @returns The uid to resolve as, or `undefined` to resolve as the caller.
2487
2520
  * @throws {Error} When another user's uid is requested and the predicate denies (or is absent).
2488
2521
  */ function resolveTargetUid(input) {
2489
- return _async_to_generator$5(function() {
2522
+ return _async_to_generator$6(function() {
2490
2523
  var requestedUid, auth, canTargetOtherUids, result, allowed, _tmp;
2491
- return _ts_generator$5(this, function(_state) {
2524
+ return _ts_generator$6(this, function(_state) {
2492
2525
  switch(_state.label){
2493
2526
  case 0:
2494
2527
  requestedUid = input.requestedUid, auth = input.auth, canTargetOtherUids = input.canTargetOtherUids;
@@ -2551,7 +2584,7 @@ function parseModelRolesInput(args) {
2551
2584
  }
2552
2585
  return value;
2553
2586
  });
2554
- return _object_spread$6({
2587
+ return _object_spread$7({
2555
2588
  modelType: modelType,
2556
2589
  keys: normalizedKeys
2557
2590
  }, uid === undefined ? {} : {
@@ -2702,7 +2735,7 @@ function _array_like_to_array$7(arr, len) {
2702
2735
  function _array_without_holes$5(arr) {
2703
2736
  if (Array.isArray(arr)) return _array_like_to_array$7(arr);
2704
2737
  }
2705
- function _define_property$7(obj, key, value) {
2738
+ function _define_property$8(obj, key, value) {
2706
2739
  if (key in obj) {
2707
2740
  Object.defineProperty(obj, key, {
2708
2741
  value: value,
@@ -2721,7 +2754,7 @@ function _iterable_to_array$5(iter) {
2721
2754
  function _non_iterable_spread$5() {
2722
2755
  throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2723
2756
  }
2724
- function _object_spread$5(target) {
2757
+ function _object_spread$6(target) {
2725
2758
  for(var i = 1; i < arguments.length; i++){
2726
2759
  var source = arguments[i] != null ? arguments[i] : {};
2727
2760
  var ownKeys = Object.keys(source);
@@ -2731,7 +2764,7 @@ function _object_spread$5(target) {
2731
2764
  }));
2732
2765
  }
2733
2766
  ownKeys.forEach(function(key) {
2734
- _define_property$7(target, key, source[key]);
2767
+ _define_property$8(target, key, source[key]);
2735
2768
  });
2736
2769
  }
2737
2770
  return target;
@@ -2930,7 +2963,7 @@ function resolveModelInfoOutput(input, manifest) {
2930
2963
  }
2931
2964
  }
2932
2965
  if (tables.length > 0) {
2933
- result = _object_spread_props$2(_object_spread$5({}, output), {
2966
+ result = _object_spread_props$2(_object_spread$6({}, output), {
2934
2967
  enums: tables
2935
2968
  });
2936
2969
  }
@@ -2984,7 +3017,7 @@ function parseModelInfoInput(args) {
2984
3017
  var modelGroup = parseModelGroupArg(args['modelGroup']);
2985
3018
  var all = parseBooleanArg(args['all'], 'all');
2986
3019
  var fields = parseBooleanArg(args['fields'], 'fields');
2987
- return _object_spread$5(_object_spread_props$2(_object_spread$5(_object_spread_props$2(_object_spread$5({}, modelQueries == null ? {} : {
3020
+ return _object_spread$6(_object_spread_props$2(_object_spread$6(_object_spread_props$2(_object_spread$6({}, modelQueries == null ? {} : {
2988
3021
  modelQueries: modelQueries
2989
3022
  }), {
2990
3023
  modelIsArray: Array.isArray(args['model'])
@@ -3147,7 +3180,7 @@ function toModelRow(entry, detailed) {
3147
3180
  return detailed ? entry : toSummaryRow(entry);
3148
3181
  }
3149
3182
  function toSummaryRow(entry) {
3150
- return _object_spread$5({
3183
+ return _object_spread$6({
3151
3184
  modelType: entry.modelType,
3152
3185
  modelName: entry.modelName,
3153
3186
  identityConst: entry.identityConst,
@@ -3482,7 +3515,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
3482
3515
  type: 'string',
3483
3516
  description: 'Present when `mode` is `"list"` from a `modelGroup` filter. The canonical group name.'
3484
3517
  },
3485
- model: _object_spread_props$2(_object_spread$5({}, MODEL_ROW_SCHEMA), {
3518
+ model: _object_spread_props$2(_object_spread$6({}, MODEL_ROW_SCHEMA), {
3486
3519
  description: 'Present when `mode` is `"single"`. The matched model entry (full detail unless `fields:false`).'
3487
3520
  }),
3488
3521
  notFound: {
@@ -3555,7 +3588,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
3555
3588
  ]
3556
3589
  };
3557
3590
 
3558
- function _define_property$6(obj, key, value) {
3591
+ function _define_property$7(obj, key, value) {
3559
3592
  if (key in obj) {
3560
3593
  Object.defineProperty(obj, key, {
3561
3594
  value: value,
@@ -3566,7 +3599,7 @@ function _define_property$6(obj, key, value) {
3566
3599
  } else obj[key] = value;
3567
3600
  return obj;
3568
3601
  }
3569
- function _object_spread$4(target) {
3602
+ function _object_spread$5(target) {
3570
3603
  for(var i = 1; i < arguments.length; i++){
3571
3604
  var source = arguments[i] != null ? arguments[i] : {};
3572
3605
  var ownKeys = Object.keys(source);
@@ -3576,7 +3609,7 @@ function _object_spread$4(target) {
3576
3609
  }));
3577
3610
  }
3578
3611
  ownKeys.forEach(function(key) {
3579
- _define_property$6(target, key, source[key]);
3612
+ _define_property$7(target, key, source[key]);
3580
3613
  });
3581
3614
  }
3582
3615
  return target;
@@ -3705,7 +3738,7 @@ function parseModelDecodeInput(args) {
3705
3738
  };
3706
3739
  }
3707
3740
  function toSegment(prefix, id, entry) {
3708
- var segment = entry ? _object_spread$4({
3741
+ var segment = entry ? _object_spread$5({
3709
3742
  prefix: prefix,
3710
3743
  id: id,
3711
3744
  modelType: entry.modelType,
@@ -4003,7 +4036,7 @@ function _array_like_to_array$6(arr, len) {
4003
4036
  function _array_with_holes$3(arr) {
4004
4037
  if (Array.isArray(arr)) return arr;
4005
4038
  }
4006
- function _define_property$5(obj, key, value) {
4039
+ function _define_property$6(obj, key, value) {
4007
4040
  if (key in obj) {
4008
4041
  Object.defineProperty(obj, key, {
4009
4042
  value: value,
@@ -4041,7 +4074,7 @@ function _iterable_to_array_limit$3(arr, i) {
4041
4074
  function _non_iterable_rest$3() {
4042
4075
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
4043
4076
  }
4044
- function _object_spread$3(target) {
4077
+ function _object_spread$4(target) {
4045
4078
  for(var i = 1; i < arguments.length; i++){
4046
4079
  var source = arguments[i] != null ? arguments[i] : {};
4047
4080
  var ownKeys = Object.keys(source);
@@ -4051,7 +4084,7 @@ function _object_spread$3(target) {
4051
4084
  }));
4052
4085
  }
4053
4086
  ownKeys.forEach(function(key) {
4054
- _define_property$5(target, key, source[key]);
4087
+ _define_property$6(target, key, source[key]);
4055
4088
  });
4056
4089
  }
4057
4090
  return target;
@@ -4167,7 +4200,7 @@ function whoamiToolHandler(args, ctx, deps) {
4167
4200
  if (claim1 == null) {
4168
4201
  unknownClaimKeys.push(key);
4169
4202
  } else {
4170
- claimDetails.push(_object_spread$3({
4203
+ claimDetails.push(_object_spread$4({
4171
4204
  key: claim1.key,
4172
4205
  description: claim1.description,
4173
4206
  grantedRoles: claim1.mapping.roles,
@@ -4192,7 +4225,7 @@ function whoamiToolHandler(args, ctx, deps) {
4192
4225
  }
4193
4226
  }
4194
4227
  }
4195
- var output = _object_spread$3({
4228
+ var output = _object_spread$4({
4196
4229
  authenticated: true,
4197
4230
  uid: auth.uid,
4198
4231
  roles: roles,
@@ -4204,12 +4237,12 @@ function whoamiToolHandler(args, ctx, deps) {
4204
4237
  }, token.email_verified == null ? {} : {
4205
4238
  emailVerified: token.email_verified
4206
4239
  }, detail === 'summary' ? {} : {
4207
- claims: _object_spread$3({}, token)
4240
+ claims: _object_spread$4({}, token)
4208
4241
  }, detail === 'full' ? {
4209
4242
  claimDetails: claimDetails,
4210
4243
  unknownClaimKeys: unknownClaimKeys
4211
4244
  } : {});
4212
- var text = renderText(output, detail);
4245
+ var text = renderText$1(output, detail);
4213
4246
  return buildResult(output, text);
4214
4247
  }
4215
4248
  // Coerces the `detail` input into a WhoamiDetailLevel, defaulting unknown or absent values to `summary`.
@@ -4228,7 +4261,7 @@ function buildResult(output, text) {
4228
4261
  structuredContent: output
4229
4262
  };
4230
4263
  }
4231
- function renderText(output, detail) {
4264
+ function renderText$1(output, detail) {
4232
4265
  var lines = [
4233
4266
  '# whoami',
4234
4267
  ''
@@ -4445,6 +4478,361 @@ var WHOAMI_OUTPUT_SCHEMA = {
4445
4478
  }
4446
4479
  };
4447
4480
 
4481
+ function asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, key, arg) {
4482
+ try {
4483
+ var info = gen[key](arg);
4484
+ var value = info.value;
4485
+ } catch (error) {
4486
+ reject(error);
4487
+ return;
4488
+ }
4489
+ if (info.done) resolve(value);
4490
+ else Promise.resolve(value).then(_next, _throw);
4491
+ }
4492
+ function _async_to_generator$5(fn) {
4493
+ return function() {
4494
+ var self = this, args = arguments;
4495
+ return new Promise(function(resolve, reject) {
4496
+ var gen = fn.apply(self, args);
4497
+ function _next(value) {
4498
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "next", value);
4499
+ }
4500
+ function _throw(err) {
4501
+ asyncGeneratorStep$5(gen, resolve, reject, _next, _throw, "throw", err);
4502
+ }
4503
+ _next(undefined);
4504
+ });
4505
+ };
4506
+ }
4507
+ function _define_property$5(obj, key, value) {
4508
+ if (key in obj) {
4509
+ Object.defineProperty(obj, key, {
4510
+ value: value,
4511
+ enumerable: true,
4512
+ configurable: true,
4513
+ writable: true
4514
+ });
4515
+ } else obj[key] = value;
4516
+ return obj;
4517
+ }
4518
+ function _object_spread$3(target) {
4519
+ for(var i = 1; i < arguments.length; i++){
4520
+ var source = arguments[i] != null ? arguments[i] : {};
4521
+ var ownKeys = Object.keys(source);
4522
+ if (typeof Object.getOwnPropertySymbols === "function") {
4523
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
4524
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
4525
+ }));
4526
+ }
4527
+ ownKeys.forEach(function(key) {
4528
+ _define_property$5(target, key, source[key]);
4529
+ });
4530
+ }
4531
+ return target;
4532
+ }
4533
+ function _ts_generator$5(thisArg, body) {
4534
+ var f, y, t, _ = {
4535
+ label: 0,
4536
+ sent: function() {
4537
+ if (t[0] & 1) throw t[1];
4538
+ return t[1];
4539
+ },
4540
+ trys: [],
4541
+ ops: []
4542
+ }, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype), d = Object.defineProperty;
4543
+ return d(g, "next", {
4544
+ value: verb(0)
4545
+ }), d(g, "throw", {
4546
+ value: verb(1)
4547
+ }), d(g, "return", {
4548
+ value: verb(2)
4549
+ }), typeof Symbol === "function" && d(g, Symbol.iterator, {
4550
+ value: function() {
4551
+ return this;
4552
+ }
4553
+ }), g;
4554
+ function verb(n) {
4555
+ return function(v) {
4556
+ return step([
4557
+ n,
4558
+ v
4559
+ ]);
4560
+ };
4561
+ }
4562
+ function step(op) {
4563
+ if (f) throw new TypeError("Generator is already executing.");
4564
+ while(g && (g = 0, op[0] && (_ = 0)), _)try {
4565
+ 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;
4566
+ if (y = 0, t) op = [
4567
+ op[0] & 2,
4568
+ t.value
4569
+ ];
4570
+ switch(op[0]){
4571
+ case 0:
4572
+ case 1:
4573
+ t = op;
4574
+ break;
4575
+ case 4:
4576
+ _.label++;
4577
+ return {
4578
+ value: op[1],
4579
+ done: false
4580
+ };
4581
+ case 5:
4582
+ _.label++;
4583
+ y = op[1];
4584
+ op = [
4585
+ 0
4586
+ ];
4587
+ continue;
4588
+ case 7:
4589
+ op = _.ops.pop();
4590
+ _.trys.pop();
4591
+ continue;
4592
+ default:
4593
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) {
4594
+ _ = 0;
4595
+ continue;
4596
+ }
4597
+ if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) {
4598
+ _.label = op[1];
4599
+ break;
4600
+ }
4601
+ if (op[0] === 6 && _.label < t[1]) {
4602
+ _.label = t[1];
4603
+ t = op;
4604
+ break;
4605
+ }
4606
+ if (t && _.label < t[2]) {
4607
+ _.label = t[2];
4608
+ _.ops.push(op);
4609
+ break;
4610
+ }
4611
+ if (t[2]) _.ops.pop();
4612
+ _.trys.pop();
4613
+ continue;
4614
+ }
4615
+ op = body.call(thisArg, _);
4616
+ } catch (e) {
4617
+ op = [
4618
+ 6,
4619
+ e
4620
+ ];
4621
+ y = 0;
4622
+ } finally{
4623
+ f = t = 0;
4624
+ }
4625
+ if (op[0] & 5) throw op[1];
4626
+ return {
4627
+ value: op[0] ? op[1] : void 0,
4628
+ done: true
4629
+ };
4630
+ }
4631
+ }
4632
+ // MARK: Constants
4633
+ /**
4634
+ * Reserved tool name for the built-in `cli-token` static tool.
4635
+ */ var CLI_TOKEN_TOOL_NAME = 'cli-token';
4636
+ /**
4637
+ * Synthetic call type used in the tool's dispatch identity. `create` so the visibility classifier
4638
+ * treats the tool as a write — minting a credential is not a read.
4639
+ */ var CLI_TOKEN_DISPATCH_CALL = 'create';
4640
+ /**
4641
+ * Synthetic model type used in the tool's dispatch identity.
4642
+ */ var CLI_TOKEN_DISPATCH_MODEL_TYPE = 'auth';
4643
+ // MARK: Factory
4644
+ /**
4645
+ * Builds the built-in `cli-token` MCP tool definition — the agent-facing half of the CLI handoff.
4646
+ *
4647
+ * Mints a short-lived CLI login credential carrying no more privilege than the calling session and
4648
+ * returns the one-time claim code that unwraps it, optionally alongside a signed download URL for
4649
+ * the CLI binary so a bare machine can go from nothing to logged in without a human.
4650
+ *
4651
+ * Three independent gates apply before the handler ever runs:
4652
+ *
4653
+ * - `requiredScopeTerms: [token.cli]` — the tool is invisible to `tools/list` AND uncallable without
4654
+ * the scope, through the factory's existing scope filter.
4655
+ * - `visibility.requiredRoles: [admin]` — the declarative role gate, which fails closed when the app
4656
+ * wires no `McpAuthRoleReader`.
4657
+ * - The mint endpoint's own admin predicate, inside the minter.
4658
+ *
4659
+ * @param deps - The app-supplied minter.
4660
+ * @returns A statically-registered {@link McpToolDefinition} to append to the MCP server factory's tool registry.
4661
+ */ function createCliTokenTool(deps) {
4662
+ var handler = function handler(args, ctx) {
4663
+ return cliTokenToolHandler(args, ctx, deps);
4664
+ };
4665
+ return buildStaticToolDefinition({
4666
+ name: CLI_TOKEN_TOOL_NAME,
4667
+ description: 'Mints a short-lived CLI login credential for YOU (the calling session) and returns a one-time claim code plus, when available, a signed download URL for the CLI binary. The credential is capped at one hour, carries no more privilege than this session (never `token.cli` or `token.service`), and expires with this session if that is sooner. The refresh token is never returned here — redeem the claim code with `<cli> auth handoff <code>` within two minutes.',
4668
+ inputSchema: CLI_TOKEN_INPUT_SCHEMA,
4669
+ outputSchema: CLI_TOKEN_OUTPUT_SCHEMA,
4670
+ dispatch: {
4671
+ call: CLI_TOKEN_DISPATCH_CALL,
4672
+ modelType: CLI_TOKEN_DISPATCH_MODEL_TYPE
4673
+ },
4674
+ staticHandler: handler,
4675
+ effectiveReadOnly: false,
4676
+ requiredScopeTerms: [
4677
+ CLI_TOKEN_OIDC_SCOPE
4678
+ ],
4679
+ rule: {
4680
+ requireAuthenticated: true,
4681
+ requiredRoles: [
4682
+ AUTH_ADMIN_ROLE
4683
+ ]
4684
+ }
4685
+ });
4686
+ }
4687
+ // MARK: Handler
4688
+ function cliTokenToolHandler(args, ctx, deps) {
4689
+ return _async_to_generator$5(function() {
4690
+ var minted, output;
4691
+ return _ts_generator$5(this, function(_state) {
4692
+ switch(_state.label){
4693
+ case 0:
4694
+ return [
4695
+ 4,
4696
+ deps.minter({
4697
+ auth: ctx.auth,
4698
+ scopes: parseScopes(args['scopes']),
4699
+ ttlSeconds: parseTtlSeconds(args['ttlSeconds']),
4700
+ includeDownloadUrl: args['includeDownloadUrl'] !== false,
4701
+ // resolved from the tool call's raw request so an MCP mint records the same address an HTTP mint
4702
+ // does — see McpCliTokenMintInput.requestIp
4703
+ requestIp: requestClientIp(ctx.rawRequest)
4704
+ })
4705
+ ];
4706
+ case 1:
4707
+ minted = _state.sent();
4708
+ output = buildOutput(minted);
4709
+ return [
4710
+ 2,
4711
+ {
4712
+ content: [
4713
+ {
4714
+ type: 'text',
4715
+ text: renderText(output)
4716
+ }
4717
+ ],
4718
+ structuredContent: output
4719
+ }
4720
+ ];
4721
+ }
4722
+ });
4723
+ })();
4724
+ }
4725
+ function buildOutput(minted) {
4726
+ var _minted_cliName;
4727
+ var cliName = (_minted_cliName = minted.cliName) !== null && _minted_cliName !== void 0 ? _minted_cliName : '<cli>';
4728
+ return _object_spread$3({
4729
+ claimCode: minted.claimCode,
4730
+ claimExpiresAt: minted.claimExpiresAt,
4731
+ expiresAt: minted.expiresAt,
4732
+ scope: minted.scope,
4733
+ handoffCommand: "".concat(cliName, " auth handoff ").concat(minted.claimCode)
4734
+ }, minted.cliName == null ? {} : {
4735
+ cliName: minted.cliName
4736
+ }, minted.downloadUrl == null ? {} : {
4737
+ downloadUrl: minted.downloadUrl
4738
+ }, minted.downloadSha256 == null ? {} : {
4739
+ downloadSha256: minted.downloadSha256
4740
+ });
4741
+ }
4742
+ // Reads the optional `scopes` input as a string array, ignoring anything that is not a non-empty string.
4743
+ function parseScopes(value) {
4744
+ var result;
4745
+ if (Array.isArray(value)) {
4746
+ var scopes = value.filter(function(entry) {
4747
+ return typeof entry === 'string' && entry.length > 0;
4748
+ });
4749
+ result = scopes.length > 0 ? scopes : undefined;
4750
+ }
4751
+ return result;
4752
+ }
4753
+ // Reads the optional `ttlSeconds` input, ignoring non-positive or non-finite values (the minter clamps the rest).
4754
+ function parseTtlSeconds(value) {
4755
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? Math.floor(value) : undefined;
4756
+ }
4757
+ function renderText(output) {
4758
+ var lines = [
4759
+ '# CLI credential minted',
4760
+ ''
4761
+ ];
4762
+ if (output.downloadUrl == null) {
4763
+ lines.push('## Log in', '');
4764
+ } else {
4765
+ var _output_cliName;
4766
+ var cliName = (_output_cliName = output.cliName) !== null && _output_cliName !== void 0 ? _output_cliName : 'cli';
4767
+ lines.push('## 1. Download the CLI', '', '```sh', "curl -fsSL -o ".concat(cliName, ' "').concat(output.downloadUrl, '" && chmod +x ').concat(cliName), '```', '');
4768
+ if (output.downloadSha256 != null) {
4769
+ lines.push("SHA-256: `".concat(output.downloadSha256, "`"), '');
4770
+ }
4771
+ lines.push('## 2. Log it in', '');
4772
+ }
4773
+ lines.push('```sh', "./".concat(output.handoffCommand), '```', '', "- **claim code expires:** ".concat(output.claimExpiresAt, " (one-time use)"), "- **credential expires:** ".concat(output.expiresAt), "- **scopes:** `".concat(output.scope, "`"), '', '_The claim code is single-use and short-lived; the credential it unwraps is capped at one hour. Re-run this tool for a fresh one rather than trying to extend either._');
4774
+ return lines.join('\n');
4775
+ }
4776
+ // MARK: Schemas
4777
+ var CLI_TOKEN_INPUT_SCHEMA = {
4778
+ type: 'object',
4779
+ properties: {
4780
+ scopes: {
4781
+ type: 'array',
4782
+ items: {
4783
+ type: 'string'
4784
+ },
4785
+ description: 'Optional subset of YOUR OWN scopes to grant the credential. May only narrow — a scope you do not hold is ignored, and `token.cli` / `token.service` are always stripped. Defaults to every scope this session holds.'
4786
+ },
4787
+ ttlSeconds: {
4788
+ type: 'integer',
4789
+ description: 'Optional requested lifetime in seconds. Clamped to one hour and to the remaining life of this session.'
4790
+ },
4791
+ includeDownloadUrl: {
4792
+ type: 'boolean',
4793
+ description: 'Also mint a signed download URL for the CLI binary (default true). Has no effect when the app does not publish one.'
4794
+ }
4795
+ },
4796
+ additionalProperties: false
4797
+ };
4798
+ var CLI_TOKEN_OUTPUT_SCHEMA = {
4799
+ type: 'object',
4800
+ required: [
4801
+ 'claimCode',
4802
+ 'claimExpiresAt',
4803
+ 'expiresAt',
4804
+ 'scope',
4805
+ 'handoffCommand'
4806
+ ],
4807
+ description: 'The one-time claim code and the minted credential’s metadata. The refresh token itself is never returned here.',
4808
+ properties: {
4809
+ claimCode: {
4810
+ type: 'string'
4811
+ },
4812
+ claimExpiresAt: {
4813
+ type: 'string'
4814
+ },
4815
+ expiresAt: {
4816
+ type: 'string'
4817
+ },
4818
+ scope: {
4819
+ type: 'string'
4820
+ },
4821
+ cliName: {
4822
+ type: 'string'
4823
+ },
4824
+ downloadUrl: {
4825
+ type: 'string'
4826
+ },
4827
+ downloadSha256: {
4828
+ type: 'string'
4829
+ },
4830
+ handoffCommand: {
4831
+ type: 'string'
4832
+ }
4833
+ }
4834
+ };
4835
+
4448
4836
  function _array_like_to_array$5(arr, len) {
4449
4837
  if (len == null || len > arr.length) len = arr.length;
4450
4838
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
@@ -6517,7 +6905,7 @@ var McpServerFactoryService_1;
6517
6905
  * per request and has no session concept at all — and it is equally what the SDK
6518
6906
  * recommends for stateless 2025-era serving, so one factory backs both eras.
6519
6907
  */ var McpServerFactoryService = McpServerFactoryService_1 = /*#__PURE__*/ function() {
6520
- function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader, analyticsService, storageService, modelRolesTargetUidPredicate) {
6908
+ function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader, analyticsService, storageService, modelRolesTargetUidPredicate, cliTokenMinter) {
6521
6909
  _class_call_check$3(this, McpServerFactoryService);
6522
6910
  _define_property$3(this, "mcpConfig", void 0);
6523
6911
  _define_property$3(this, "dispatchService", void 0);
@@ -6525,6 +6913,7 @@ var McpServerFactoryService_1;
6525
6913
  _define_property$3(this, "roleReader", void 0);
6526
6914
  _define_property$3(this, "storageService", void 0);
6527
6915
  _define_property$3(this, "modelRolesTargetUidPredicate", void 0);
6916
+ _define_property$3(this, "cliTokenMinter", void 0);
6528
6917
  _define_property$3(this, "_logger", new Logger(McpServerFactoryService_1.name));
6529
6918
  _define_property$3(this, "_cachedTools", void 0);
6530
6919
  _define_property$3(this, "_cachedStaticTools", void 0);
@@ -6545,6 +6934,7 @@ var McpServerFactoryService_1;
6545
6934
  this.roleReader = roleReader;
6546
6935
  this.storageService = storageService;
6547
6936
  this.modelRolesTargetUidPredicate = modelRolesTargetUidPredicate;
6937
+ this.cliTokenMinter = cliTokenMinter;
6548
6938
  this._analyticsService = analyticsService !== null && analyticsService !== void 0 ? analyticsService : noopMcpAnalyticsService();
6549
6939
  }
6550
6940
  _create_class$3(McpServerFactoryService, [
@@ -6864,6 +7254,13 @@ var McpServerFactoryService_1;
6864
7254
  roleReader: this.roleReader
6865
7255
  }));
6866
7256
  }
7257
+ // `cli-token` only exists when the app wires a minter — the mint needs the OIDC provider,
7258
+ // which this package deliberately does not depend on.
7259
+ if (this.cliTokenMinter != null) {
7260
+ staticTools.push(createCliTokenTool({
7261
+ minter: this.cliTokenMinter
7262
+ }));
7263
+ }
6867
7264
  // Guard against the auto-generated tools accidentally claiming a static tool name. The first
6868
7265
  // dispatch wins via Map.set order, so a collision would silently shadow one side.
6869
7266
  var generatedNames = new Set((_ref = (_this__cachedTools = this._cachedTools) === null || _this__cachedTools === void 0 ? void 0 : _this__cachedTools.tools.map(function(t) {
@@ -7578,7 +7975,9 @@ McpServerFactoryService = McpServerFactoryService_1 = __decorate([
7578
7975
  __param(5, Optional()),
7579
7976
  __param(5, Inject(FirebaseServerStorageService)),
7580
7977
  __param(6, Optional()),
7581
- __param(6, Inject(MCP_MODEL_ROLES_TARGET_UID_PREDICATE))
7978
+ __param(6, Inject(MCP_MODEL_ROLES_TARGET_UID_PREDICATE)),
7979
+ __param(7, Optional()),
7980
+ __param(7, Inject(MCP_CLI_TOKEN_MINTER))
7582
7981
  ], McpServerFactoryService);
7583
7982
 
7584
7983
  function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
@@ -8292,9 +8691,10 @@ function _unsupported_iterable_to_array$2(o, minLen) {
8292
8691
  var _this_mcpConfig = this.mcpConfig, mcpUrl = _this_mcpConfig.mcpUrl, oidcIssuer = _this_mcpConfig.oidcIssuer, scopesFilter = _this_mcpConfig.scopesSupported;
8293
8692
  // Base scope list is what the issuer grants an arbitrary client, NOT its full
8294
8693
  // `scopes_supported`: a dynamic-registration client copies this list verbatim onto
8295
- // `/authorize`, and a provider-profile-gated scope in it would be hard-rejected at the
8296
- // consent unlock gate (`access_denied`) for every client lacking that profile assignment.
8297
- // The optional filter narrows the list further.
8694
+ // `/authorize`, and a provider-profile-gated scope in it is useless to every client lacking
8695
+ // that profile assignment. The optional filter adjusts the list — usually narrowing it, but
8696
+ // an app may also add a gated scope back so an assigned client can request it at all (the
8697
+ // consent builder withholds it from the unassigned ones, so their flow still completes).
8298
8698
  var providerScopes = this.oidcProviderConfigService.clientRequestableScopesSupported;
8299
8699
  var scopes = scopesFilter ? scopesFilter(providerScopes) : providerScopes;
8300
8700
  return _object_spread({
@@ -8620,4 +9020,4 @@ function _unsupported_iterable_to_array(o, minLen) {
8620
9020
  };
8621
9021
  }
8622
9022
 
8623
- 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_MODEL_ROLES_MAX_KEYS, MCP_MODEL_ROLES_TARGET_UID_PREDICATE, 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, MODEL_ROLES_DISPATCH_CALL, MODEL_ROLES_DISPATCH_MODEL_TYPE, MODEL_ROLES_TOOL_NAME, 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, createModelRolesTool, createUrlModelsTool, decodeFirestoreModelKey, extractMcpReasonFromArgs, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, matchRouteManifestUrl, mcpManifestKey, mcpModuleMetadata, mcpSchemaDeclaresProperty, noopMcpAnalyticsService, parseUrlModelsPathname, readUrlModelsImpersonationUid, resolveEffectiveReadOnly, resolveEnumInfoOutput, resolveMcpReasonParameterConfig, resolveMcpToolAnnotations, resolveRequiredScope, validateMcpToolName };
9023
+ export { BATCH_EXECUTE_DISPATCH_CALL, BATCH_EXECUTE_DISPATCH_MODEL_TYPE, BATCH_EXECUTE_TOOL_NAME, CLI_TOKEN_DISPATCH_CALL, CLI_TOKEN_DISPATCH_MODEL_TYPE, CLI_TOKEN_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_CLI_TOKEN_MINTER, MCP_MANIFEST_VERSION, MCP_MODEL_GET_BATCH_SIZE, MCP_MODEL_ROLES_MAX_KEYS, MCP_MODEL_ROLES_TARGET_UID_PREDICATE, 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, MODEL_ROLES_DISPATCH_CALL, MODEL_ROLES_DISPATCH_MODEL_TYPE, MODEL_ROLES_TOOL_NAME, 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, createCliTokenTool, createEnumInfoTool, createModelDecodeTool, createModelGetTool, createModelInfoTool, createModelRolesTool, createUrlModelsTool, decodeFirestoreModelKey, extractMcpReasonFromArgs, findModelEntry, formatMcpToolErrorResponse, formatMcpToolResponse, generateMcpToolDefinitions, handleStreamableHttpMcpRequest, matchRouteManifestUrl, mcpManifestKey, mcpModuleMetadata, mcpSchemaDeclaresProperty, noopMcpAnalyticsService, parseUrlModelsPathname, readUrlModelsImpersonationUid, resolveEffectiveReadOnly, resolveEnumInfoOutput, resolveMcpReasonParameterConfig, resolveMcpToolAnnotations, resolveRequiredScope, validateMcpToolName };