@dereekb/firebase-server 13.12.1 → 13.12.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/mcp/index.cjs.js CHANGED
@@ -12,12 +12,12 @@ var model = require('@dereekb/model');
12
12
  var firebase = require('@dereekb/firebase');
13
13
  var streamableHttp_js = require('@modelcontextprotocol/sdk/server/streamableHttp.js');
14
14
 
15
- function _class_call_check$3(instance, Constructor) {
15
+ function _class_call_check$5(instance, Constructor) {
16
16
  if (!(instance instanceof Constructor)) {
17
17
  throw new TypeError("Cannot call a class as a function");
18
18
  }
19
19
  }
20
- function _define_property$6(obj, key, value) {
20
+ function _define_property$7(obj, key, value) {
21
21
  if (key in obj) {
22
22
  Object.defineProperty(obj, key, {
23
23
  value: value,
@@ -43,6 +43,10 @@ function _define_property$6(obj, key, value) {
43
43
  * Apps may override this via {@link McpModuleConfig.serverName} to identify their
44
44
  * deployment (e.g., `demo-api-mcp`, `hellosubs-api-mcp`).
45
45
  */ var DEFAULT_MCP_SERVER_NAME = 'dbx-firebase-server-mcp';
46
+ /**
47
+ * Default `instructions` string advertised by the MCP server on the JSON-RPC `initialize`
48
+ * handshake. Apps may override this via {@link McpModuleConfig.serverInstructions}.
49
+ */ var DEFAULT_MCP_SERVER_INSTRUCTIONS = 'A set of call-model tools generated automatically.';
46
50
  /**
47
51
  * Configuration for the firebase-server/mcp module.
48
52
  *
@@ -59,7 +63,7 @@ function _define_property$6(obj, key, value) {
59
63
  * The OAuth bearer middleware that authenticates `/mcp` is configured on
60
64
  * {@link OidcModuleConfig.protectedPaths} — that's outside this config's scope.
61
65
  */ var McpModuleConfig = function McpModuleConfig() {
62
- _class_call_check$3(this, McpModuleConfig);
66
+ _class_call_check$5(this, McpModuleConfig);
63
67
  /**
64
68
  * The canonical issuer URL of the OIDC provider that gates this MCP endpoint.
65
69
  *
@@ -67,7 +71,7 @@ function _define_property$6(obj, key, value) {
67
71
  * discovery document. Claude custom-connector reads this to discover the OIDC issuer.
68
72
  *
69
73
  * @example 'https://api.example.com/oidc'
70
- */ _define_property$6(this, "oidcIssuer", void 0);
74
+ */ _define_property$7(this, "oidcIssuer", void 0);
71
75
  /**
72
76
  * The canonical resource URL of the MCP endpoint.
73
77
  *
@@ -75,14 +79,19 @@ function _define_property$6(obj, key, value) {
75
79
  * and used as the audience the access token's `aud` claim should match.
76
80
  *
77
81
  * @example 'https://api.example.com/mcp'
78
- */ _define_property$6(this, "mcpUrl", void 0);
82
+ */ _define_property$7(this, "mcpUrl", void 0);
79
83
  /**
80
84
  * Optional name advertised on the MCP `initialize` handshake. Defaults to
81
85
  * {@link DEFAULT_MCP_SERVER_NAME}.
82
- */ _define_property$6(this, "serverName", void 0);
86
+ */ _define_property$7(this, "serverName", void 0);
83
87
  /**
84
88
  * Optional version advertised on the MCP `initialize` handshake.
85
- */ _define_property$6(this, "serverVersion", void 0);
89
+ */ _define_property$7(this, "serverVersion", void 0);
90
+ /**
91
+ * Optional override for the `instructions` string passed to `new McpServer(...)` and
92
+ * advertised on the JSON-RPC `initialize` handshake. Defaults to
93
+ * {@link DEFAULT_MCP_SERVER_INSTRUCTIONS}.
94
+ */ _define_property$7(this, "serverInstructions", void 0);
86
95
  /**
87
96
  * Absolute path to a pre-rendered MCP manifest JSON file produced by
88
97
  * `dbx-cli-generate-mcp-manifest`. When set, the runtime reads it once at
@@ -92,7 +101,7 @@ function _define_property$6(obj, key, value) {
92
101
  * Optional. When unset or the file is missing, the runtime falls back to
93
102
  * today's behavior (auto-generated descriptions, ArkType-derived input
94
103
  * schemas, no output schemas) and emits a single boot warning.
95
- */ _define_property$6(this, "mcpManifestPath", void 0);
104
+ */ _define_property$7(this, "mcpManifestPath", void 0);
96
105
  /**
97
106
  * When `true`, the MCP server only advertises tools whose effective read-only classification is `true`.
98
107
  *
@@ -102,19 +111,19 @@ function _define_property$6(obj, key, value) {
102
111
  *
103
112
  * The advertised `serverName` on the JSON-RPC `initialize` handshake is suffixed with
104
113
  * ` (read-only)` so the client surface reflects the mode.
105
- */ _define_property$6(this, "readOnly", void 0);
114
+ */ _define_property$7(this, "readOnly", void 0);
106
115
  };
107
116
  /**
108
117
  * NestJS injection token for the optional {@link McpAuthRoleReader} provider.
109
118
  */ var MCP_AUTH_ROLE_READER = 'MCP_AUTH_ROLE_READER';
110
119
 
111
- function _type_of$1(obj) {
120
+ function _type_of$2(obj) {
112
121
  "@swc/helpers - typeof";
113
122
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
114
123
  }
115
124
  function __decorate(decorators, target, key, desc) {
116
125
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
117
- if ((typeof Reflect === "undefined" ? "undefined" : _type_of$1(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
126
+ if ((typeof Reflect === "undefined" ? "undefined" : _type_of$2(Reflect)) === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
118
127
  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;
119
128
  return c > 3 && r && Object.defineProperty(target, key, r), r;
120
129
  }
@@ -128,6 +137,39 @@ typeof SuppressedError === "function" ? SuppressedError : function(error, suppre
128
137
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
129
138
  };
130
139
 
140
+ function _class_call_check$4(instance, Constructor) {
141
+ if (!(instance instanceof Constructor)) {
142
+ throw new TypeError("Cannot call a class as a function");
143
+ }
144
+ }
145
+ /**
146
+ * Abstract analytics service that apps implement to process MCP analytics events.
147
+ *
148
+ * Analogous to {@link OnCallModelAnalyticsService} but scoped to the MCP transport.
149
+ * Apps extend this class and provide it via {@link MCP_ANALYTICS_SERVICE}.
150
+ */ var McpAnalyticsService = function McpAnalyticsService() {
151
+ _class_call_check$4(this, McpAnalyticsService);
152
+ };
153
+ /**
154
+ * Injection token for the MCP analytics service.
155
+ * Apps provide this in their MCP module to enable analytics in the MCP dispatch chain.
156
+ */ var MCP_ANALYTICS_SERVICE = 'MCP_ANALYTICS_SERVICE';
157
+ /**
158
+ * Creates a no-op {@link McpAnalyticsService} that silently discards all events.
159
+ *
160
+ * Used as the default fallback by {@link McpServerFactoryService} when no analytics
161
+ * service is registered.
162
+ *
163
+ * @returns An {@link McpAnalyticsService} that discards all analytics events.
164
+ * @__NO_SIDE_EFFECTS__
165
+ */ function noopMcpAnalyticsService() {
166
+ return {
167
+ handleMcpAnalyticsEvent: function handleMcpAnalyticsEvent() {
168
+ return undefined;
169
+ }
170
+ };
171
+ }
172
+
131
173
  /**
132
174
  * Version stamp embedded in the build-time MCP manifest JSON. Runtime loaders
133
175
  * refuse manifests whose `version` does not match this constant.
@@ -315,7 +357,7 @@ function stringifyResult(result) {
315
357
  return firebase.callModelOidcScopeForCallType(callType);
316
358
  }
317
359
 
318
- function _array_like_to_array$4(arr, len) {
360
+ function _array_like_to_array$5(arr, len) {
319
361
  if (len == null || len > arr.length) len = arr.length;
320
362
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
321
363
  return arr2;
@@ -351,19 +393,19 @@ function _non_iterable_rest$2() {
351
393
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
352
394
  }
353
395
  function _sliced_to_array$2(arr, i) {
354
- return _array_with_holes$2(arr) || _iterable_to_array_limit$2(arr, i) || _unsupported_iterable_to_array$4(arr, i) || _non_iterable_rest$2();
396
+ return _array_with_holes$2(arr) || _iterable_to_array_limit$2(arr, i) || _unsupported_iterable_to_array$5(arr, i) || _non_iterable_rest$2();
355
397
  }
356
- function _type_of(obj) {
398
+ function _type_of$1(obj) {
357
399
  "@swc/helpers - typeof";
358
400
  return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
359
401
  }
360
- function _unsupported_iterable_to_array$4(o, minLen) {
402
+ function _unsupported_iterable_to_array$5(o, minLen) {
361
403
  if (!o) return;
362
- if (typeof o === "string") return _array_like_to_array$4(o, minLen);
404
+ if (typeof o === "string") return _array_like_to_array$5(o, minLen);
363
405
  var n = Object.prototype.toString.call(o).slice(8, -1);
364
406
  if (n === "Object" && o.constructor) n = o.constructor.name;
365
407
  if (n === "Map" || n === "Set") return Array.from(n);
366
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
408
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$5(o, minLen);
367
409
  }
368
410
  /**
369
411
  * Default `toJsonSchema()` options.
@@ -630,7 +672,7 @@ function resolveInputSchema(context) {
630
672
  var result;
631
673
  try {
632
674
  var exported = model.arktypeToJsonSchemaForExport(handlerDetails.inputType);
633
- if (exported && (typeof exported === "undefined" ? "undefined" : _type_of(exported)) === 'object') {
675
+ if (exported && (typeof exported === "undefined" ? "undefined" : _type_of$1(exported)) === 'object') {
634
676
  result = exported;
635
677
  } else {
636
678
  // arktypeToJsonSchemaForExport returned a non-object (shouldn't happen for object schemas).
@@ -649,13 +691,13 @@ function resolveInputSchema(context) {
649
691
  return result;
650
692
  }
651
693
 
652
- function _array_like_to_array$3(arr, len) {
694
+ function _array_like_to_array$4(arr, len) {
653
695
  if (len == null || len > arr.length) len = arr.length;
654
696
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
655
697
  return arr2;
656
698
  }
657
- function _array_without_holes$3(arr) {
658
- if (Array.isArray(arr)) return _array_like_to_array$3(arr);
699
+ function _array_without_holes$4(arr) {
700
+ if (Array.isArray(arr)) return _array_like_to_array$4(arr);
659
701
  }
660
702
  function asyncGeneratorStep$3(gen, resolve, reject, _next, _throw, key, arg) {
661
703
  try {
@@ -686,22 +728,22 @@ function _async_to_generator$3(fn) {
686
728
  });
687
729
  };
688
730
  }
689
- function _iterable_to_array$3(iter) {
731
+ function _iterable_to_array$4(iter) {
690
732
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
691
733
  }
692
- function _non_iterable_spread$3() {
734
+ function _non_iterable_spread$4() {
693
735
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
694
736
  }
695
- function _to_consumable_array$3(arr) {
696
- return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
737
+ function _to_consumable_array$4(arr) {
738
+ return _array_without_holes$4(arr) || _iterable_to_array$4(arr) || _unsupported_iterable_to_array$4(arr) || _non_iterable_spread$4();
697
739
  }
698
- function _unsupported_iterable_to_array$3(o, minLen) {
740
+ function _unsupported_iterable_to_array$4(o, minLen) {
699
741
  if (!o) return;
700
- if (typeof o === "string") return _array_like_to_array$3(o, minLen);
742
+ if (typeof o === "string") return _array_like_to_array$4(o, minLen);
701
743
  var n = Object.prototype.toString.call(o).slice(8, -1);
702
744
  if (n === "Object" && o.constructor) n = o.constructor.name;
703
745
  if (n === "Map" || n === "Set") return Array.from(n);
704
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
746
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$4(o, minLen);
705
747
  }
706
748
  function _ts_generator$3(thisArg, body) {
707
749
  var f, y, t, _ = {
@@ -1006,8 +1048,8 @@ function readInChunks(input) {
1006
1048
  ];
1007
1049
  case 2:
1008
1050
  partial = _state.sent();
1009
- (_merged_results = merged.results).push.apply(_merged_results, _to_consumable_array$3(partial.results));
1010
- (_merged_errors = merged.errors).push.apply(_merged_errors, _to_consumable_array$3(partial.errors));
1051
+ (_merged_results = merged.results).push.apply(_merged_results, _to_consumable_array$4(partial.results));
1052
+ (_merged_errors = merged.errors).push.apply(_merged_errors, _to_consumable_array$4(partial.errors));
1011
1053
  _state.label = 3;
1012
1054
  case 3:
1013
1055
  offset += MCP_MODEL_GET_BATCH_SIZE;
@@ -1098,7 +1140,7 @@ var MODEL_GET_OUTPUT_SCHEMA = {
1098
1140
  }
1099
1141
  };
1100
1142
 
1101
- function _define_property$5(obj, key, value) {
1143
+ function _define_property$6(obj, key, value) {
1102
1144
  if (key in obj) {
1103
1145
  Object.defineProperty(obj, key, {
1104
1146
  value: value,
@@ -1121,7 +1163,7 @@ function _object_spread$2(target) {
1121
1163
  }));
1122
1164
  }
1123
1165
  ownKeys.forEach(function(key) {
1124
- _define_property$5(target, key, source[key]);
1166
+ _define_property$6(target, key, source[key]);
1125
1167
  });
1126
1168
  }
1127
1169
  return target;
@@ -1475,7 +1517,7 @@ var MODEL_INFO_OUTPUT_SCHEMA = {
1475
1517
  ]
1476
1518
  };
1477
1519
 
1478
- function _define_property$4(obj, key, value) {
1520
+ function _define_property$5(obj, key, value) {
1479
1521
  if (key in obj) {
1480
1522
  Object.defineProperty(obj, key, {
1481
1523
  value: value,
@@ -1498,7 +1540,7 @@ function _object_spread$1(target) {
1498
1540
  }));
1499
1541
  }
1500
1542
  ownKeys.forEach(function(key) {
1501
- _define_property$4(target, key, source[key]);
1543
+ _define_property$5(target, key, source[key]);
1502
1544
  });
1503
1545
  }
1504
1546
  return target;
@@ -1734,7 +1776,7 @@ var MODEL_DECODE_OUTPUT_SCHEMA = {
1734
1776
  }
1735
1777
  };
1736
1778
 
1737
- function _array_like_to_array$2(arr, len) {
1779
+ function _array_like_to_array$3(arr, len) {
1738
1780
  if (len == null || len > arr.length) len = arr.length;
1739
1781
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
1740
1782
  return arr2;
@@ -1742,10 +1784,10 @@ function _array_like_to_array$2(arr, len) {
1742
1784
  function _array_with_holes$1(arr) {
1743
1785
  if (Array.isArray(arr)) return arr;
1744
1786
  }
1745
- function _array_without_holes$2(arr) {
1746
- if (Array.isArray(arr)) return _array_like_to_array$2(arr);
1787
+ function _array_without_holes$3(arr) {
1788
+ if (Array.isArray(arr)) return _array_like_to_array$3(arr);
1747
1789
  }
1748
- function _define_property$3(obj, key, value) {
1790
+ function _define_property$4(obj, key, value) {
1749
1791
  if (key in obj) {
1750
1792
  Object.defineProperty(obj, key, {
1751
1793
  value: value,
@@ -1758,7 +1800,7 @@ function _define_property$3(obj, key, value) {
1758
1800
  }
1759
1801
  return obj;
1760
1802
  }
1761
- function _iterable_to_array$2(iter) {
1803
+ function _iterable_to_array$3(iter) {
1762
1804
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
1763
1805
  }
1764
1806
  function _iterable_to_array_limit$1(arr, i) {
@@ -1788,7 +1830,7 @@ function _iterable_to_array_limit$1(arr, i) {
1788
1830
  function _non_iterable_rest$1() {
1789
1831
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1790
1832
  }
1791
- function _non_iterable_spread$2() {
1833
+ function _non_iterable_spread$3() {
1792
1834
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
1793
1835
  }
1794
1836
  function _object_spread(target) {
@@ -1801,24 +1843,24 @@ function _object_spread(target) {
1801
1843
  }));
1802
1844
  }
1803
1845
  ownKeys.forEach(function(key) {
1804
- _define_property$3(target, key, source[key]);
1846
+ _define_property$4(target, key, source[key]);
1805
1847
  });
1806
1848
  }
1807
1849
  return target;
1808
1850
  }
1809
1851
  function _sliced_to_array$1(arr, i) {
1810
- return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest$1();
1852
+ return _array_with_holes$1(arr) || _iterable_to_array_limit$1(arr, i) || _unsupported_iterable_to_array$3(arr, i) || _non_iterable_rest$1();
1811
1853
  }
1812
- function _to_consumable_array$2(arr) {
1813
- return _array_without_holes$2(arr) || _iterable_to_array$2(arr) || _unsupported_iterable_to_array$2(arr) || _non_iterable_spread$2();
1854
+ function _to_consumable_array$3(arr) {
1855
+ return _array_without_holes$3(arr) || _iterable_to_array$3(arr) || _unsupported_iterable_to_array$3(arr) || _non_iterable_spread$3();
1814
1856
  }
1815
- function _unsupported_iterable_to_array$2(o, minLen) {
1857
+ function _unsupported_iterable_to_array$3(o, minLen) {
1816
1858
  if (!o) return;
1817
- if (typeof o === "string") return _array_like_to_array$2(o, minLen);
1859
+ if (typeof o === "string") return _array_like_to_array$3(o, minLen);
1818
1860
  var n = Object.prototype.toString.call(o).slice(8, -1);
1819
1861
  if (n === "Object" && o.constructor) n = o.constructor.name;
1820
1862
  if (n === "Map" || n === "Set") return Array.from(n);
1821
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$2(o, minLen);
1863
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$3(o, minLen);
1822
1864
  }
1823
1865
  // MARK: Constants
1824
1866
  /**
@@ -1899,7 +1941,7 @@ function whoamiToolHandler(ctx, deps) {
1899
1941
  return key;
1900
1942
  });
1901
1943
  var roleSet = deps.roleReader == null ? new Set() : deps.roleReader(token);
1902
- var roles = _to_consumable_array$2(roleSet).sort(function(a, b) {
1944
+ var roles = _to_consumable_array$3(roleSet).sort(function(a, b) {
1903
1945
  return a.localeCompare(b);
1904
1946
  });
1905
1947
  var claimsByKey = new Map();
@@ -2168,7 +2210,7 @@ var WHOAMI_OUTPUT_SCHEMA = {
2168
2210
  }
2169
2211
  };
2170
2212
 
2171
- function _array_like_to_array$1(arr, len) {
2213
+ function _array_like_to_array$2(arr, len) {
2172
2214
  if (len == null || len > arr.length) len = arr.length;
2173
2215
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
2174
2216
  return arr2;
@@ -2176,8 +2218,8 @@ function _array_like_to_array$1(arr, len) {
2176
2218
  function _array_with_holes(arr) {
2177
2219
  if (Array.isArray(arr)) return arr;
2178
2220
  }
2179
- function _array_without_holes$1(arr) {
2180
- if (Array.isArray(arr)) return _array_like_to_array$1(arr);
2221
+ function _array_without_holes$2(arr) {
2222
+ if (Array.isArray(arr)) return _array_like_to_array$2(arr);
2181
2223
  }
2182
2224
  function asyncGeneratorStep$2(gen, resolve, reject, _next, _throw, key, arg) {
2183
2225
  try {
@@ -2208,12 +2250,12 @@ function _async_to_generator$2(fn) {
2208
2250
  });
2209
2251
  };
2210
2252
  }
2211
- function _class_call_check$2(instance, Constructor) {
2253
+ function _class_call_check$3(instance, Constructor) {
2212
2254
  if (!(instance instanceof Constructor)) {
2213
2255
  throw new TypeError("Cannot call a class as a function");
2214
2256
  }
2215
2257
  }
2216
- function _defineProperties$2(target, props) {
2258
+ function _defineProperties$3(target, props) {
2217
2259
  for(var i = 0; i < props.length; i++){
2218
2260
  var descriptor = props[i];
2219
2261
  descriptor.enumerable = descriptor.enumerable || false;
@@ -2222,11 +2264,11 @@ function _defineProperties$2(target, props) {
2222
2264
  Object.defineProperty(target, descriptor.key, descriptor);
2223
2265
  }
2224
2266
  }
2225
- function _create_class$2(Constructor, protoProps, staticProps) {
2226
- if (protoProps) _defineProperties$2(Constructor.prototype, protoProps);
2267
+ function _create_class$3(Constructor, protoProps, staticProps) {
2268
+ if (protoProps) _defineProperties$3(Constructor.prototype, protoProps);
2227
2269
  return Constructor;
2228
2270
  }
2229
- function _define_property$2(obj, key, value) {
2271
+ function _define_property$3(obj, key, value) {
2230
2272
  if (key in obj) {
2231
2273
  Object.defineProperty(obj, key, {
2232
2274
  value: value,
@@ -2239,7 +2281,7 @@ function _define_property$2(obj, key, value) {
2239
2281
  }
2240
2282
  return obj;
2241
2283
  }
2242
- function _iterable_to_array$1(iter) {
2284
+ function _iterable_to_array$2(iter) {
2243
2285
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
2244
2286
  }
2245
2287
  function _iterable_to_array_limit(arr, i) {
@@ -2269,22 +2311,22 @@ function _iterable_to_array_limit(arr, i) {
2269
2311
  function _non_iterable_rest() {
2270
2312
  throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2271
2313
  }
2272
- function _non_iterable_spread$1() {
2314
+ function _non_iterable_spread$2() {
2273
2315
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
2274
2316
  }
2275
2317
  function _sliced_to_array(arr, i) {
2276
- return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$1(arr, i) || _non_iterable_rest();
2318
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array$2(arr, i) || _non_iterable_rest();
2277
2319
  }
2278
- function _to_consumable_array$1(arr) {
2279
- return _array_without_holes$1(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread$1();
2320
+ function _to_consumable_array$2(arr) {
2321
+ return _array_without_holes$2(arr) || _iterable_to_array$2(arr) || _unsupported_iterable_to_array$2(arr) || _non_iterable_spread$2();
2280
2322
  }
2281
- function _unsupported_iterable_to_array$1(o, minLen) {
2323
+ function _unsupported_iterable_to_array$2(o, minLen) {
2282
2324
  if (!o) return;
2283
- if (typeof o === "string") return _array_like_to_array$1(o, minLen);
2325
+ if (typeof o === "string") return _array_like_to_array$2(o, minLen);
2284
2326
  var n = Object.prototype.toString.call(o).slice(8, -1);
2285
2327
  if (n === "Object" && o.constructor) n = o.constructor.name;
2286
2328
  if (n === "Map" || n === "Set") return Array.from(n);
2287
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
2329
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$2(o, minLen);
2288
2330
  }
2289
2331
  function _ts_generator$2(thisArg, body) {
2290
2332
  var f, y, t, _ = {
@@ -2394,27 +2436,29 @@ var McpServerFactoryService_1;
2394
2436
  * recommends a fresh `McpServer` + transport pair per stateless JSON-RPC request,
2395
2437
  * which sidesteps session bookkeeping for the common Claude-connector case.
2396
2438
  */ exports.McpServerFactoryService = McpServerFactoryService_1 = /*#__PURE__*/ function() {
2397
- function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader) {
2398
- _class_call_check$2(this, McpServerFactoryService);
2399
- _define_property$2(this, "mcpConfig", void 0);
2400
- _define_property$2(this, "dispatchService", void 0);
2401
- _define_property$2(this, "modelApiGetService", void 0);
2402
- _define_property$2(this, "roleReader", void 0);
2403
- _define_property$2(this, "_logger", new common.Logger(McpServerFactoryService_1.name));
2404
- _define_property$2(this, "_cachedTools", void 0);
2405
- _define_property$2(this, "_cachedStaticTools", void 0);
2406
- _define_property$2(this, "_cachedManifest", void 0);
2407
- _define_property$2(this, "_cachedManifestModels", void 0);
2408
- _define_property$2(this, "_cachedManifestAuth", void 0);
2409
- _define_property$2(this, "_manifestLoaded", false);
2410
- _define_property$2(this, "_loggedSkips", false);
2411
- _define_property$2(this, "_warnedMissingRoleReader", false);
2439
+ function McpServerFactoryService(mcpConfig, dispatchService, modelApiGetService, roleReader, analyticsService) {
2440
+ _class_call_check$3(this, McpServerFactoryService);
2441
+ _define_property$3(this, "mcpConfig", void 0);
2442
+ _define_property$3(this, "dispatchService", void 0);
2443
+ _define_property$3(this, "modelApiGetService", void 0);
2444
+ _define_property$3(this, "roleReader", void 0);
2445
+ _define_property$3(this, "_logger", new common.Logger(McpServerFactoryService_1.name));
2446
+ _define_property$3(this, "_cachedTools", void 0);
2447
+ _define_property$3(this, "_cachedStaticTools", void 0);
2448
+ _define_property$3(this, "_cachedManifest", void 0);
2449
+ _define_property$3(this, "_cachedManifestModels", void 0);
2450
+ _define_property$3(this, "_cachedManifestAuth", void 0);
2451
+ _define_property$3(this, "_manifestLoaded", false);
2452
+ _define_property$3(this, "_loggedSkips", false);
2453
+ _define_property$3(this, "_warnedMissingRoleReader", false);
2454
+ _define_property$3(this, "_analyticsService", void 0);
2412
2455
  this.mcpConfig = mcpConfig;
2413
2456
  this.dispatchService = dispatchService;
2414
2457
  this.modelApiGetService = modelApiGetService;
2415
2458
  this.roleReader = roleReader;
2459
+ this._analyticsService = analyticsService !== null && analyticsService !== void 0 ? analyticsService : noopMcpAnalyticsService();
2416
2460
  }
2417
- _create_class$2(McpServerFactoryService, [
2461
+ _create_class$3(McpServerFactoryService, [
2418
2462
  {
2419
2463
  /**
2420
2464
  * Builds a configured MCP server with tool listing + dispatch handlers wired up.
@@ -2424,14 +2468,14 @@ var McpServerFactoryService_1;
2424
2468
  */ key: "createServer",
2425
2469
  value: function createServer(ctx) {
2426
2470
  var _this = this;
2427
- var _this_mcpConfig_serverName, _this_mcpConfig_serverVersion;
2471
+ var _this_mcpConfig_serverName, _this_mcpConfig_serverVersion, _this_mcpConfig_serverInstructions;
2428
2472
  var baseServerName = (_this_mcpConfig_serverName = this.mcpConfig.serverName) !== null && _this_mcpConfig_serverName !== void 0 ? _this_mcpConfig_serverName : DEFAULT_MCP_SERVER_NAME;
2429
2473
  var serverName = this.mcpConfig.readOnly === true ? "".concat(baseServerName, " (read-only)") : baseServerName;
2430
2474
  var server = new mcp_js.McpServer({
2431
2475
  name: serverName,
2432
2476
  version: (_this_mcpConfig_serverVersion = this.mcpConfig.serverVersion) !== null && _this_mcpConfig_serverVersion !== void 0 ? _this_mcpConfig_serverVersion : '0.0.0'
2433
2477
  }, {
2434
- instructions: 'Model-bound RPC tools generated from the callModel _apiDetails tree.'
2478
+ instructions: (_this_mcpConfig_serverInstructions = this.mcpConfig.serverInstructions) !== null && _this_mcpConfig_serverInstructions !== void 0 ? _this_mcpConfig_serverInstructions : DEFAULT_MCP_SERVER_INSTRUCTIONS
2435
2479
  });
2436
2480
  server.server.registerCapabilities({
2437
2481
  tools: {}
@@ -2440,7 +2484,7 @@ var McpServerFactoryService_1;
2440
2484
  var staticTools = this._resolveStaticTools();
2441
2485
  var scopes = this._resolveScopes(ctx);
2442
2486
  var authRoles = this._resolveAuthRoles(ctx);
2443
- var combinedTools = _to_consumable_array$1(toolGeneration.tools).concat(_to_consumable_array$1(staticTools));
2487
+ var combinedTools = _to_consumable_array$2(toolGeneration.tools).concat(_to_consumable_array$2(staticTools));
2444
2488
  var visibleTools = this._filterToolsForRequest(combinedTools, {
2445
2489
  ctx: ctx,
2446
2490
  scopes: scopes,
@@ -2891,19 +2935,36 @@ var McpServerFactoryService_1;
2891
2935
  },
2892
2936
  {
2893
2937
  key: "_handleToolCall",
2894
- value: function _handleToolCall(request, definitionsByName, ctx) {
2938
+ value: /**
2939
+ * Central dispatch point for every MCP tool call. Runs the underlying handler — callModel,
2940
+ * static, or unknown-tool — then emits a single analytics event on completion so every call
2941
+ * is tracked uniformly.
2942
+ *
2943
+ * Success vs error is decided by the resolved outcome: an outcome that carries a thrown
2944
+ * error, or a response flagged `isError`, counts as a failure. The original thrown error
2945
+ * (when present) is forwarded on the event.
2946
+ *
2947
+ * @param request - The `tools/call` request carrying the tool name and arguments.
2948
+ * @param definitionsByName - The visible tool definitions keyed by name for this request.
2949
+ * @param ctx - The per-request context (auth, raw request) forwarded to the handler.
2950
+ * @returns The MCP tool response.
2951
+ */ function _handleToolCall(request, definitionsByName, ctx) {
2895
2952
  return _async_to_generator$2(function() {
2896
- var _request_params_arguments, definition, args, response;
2953
+ var _request_params_arguments, _ctx_auth, toolName, definition, args, startedAt, outcome, isSuccessful, toolKind;
2897
2954
  return _ts_generator$2(this, function(_state) {
2898
2955
  switch(_state.label){
2899
2956
  case 0:
2900
- definition = definitionsByName.get(request.params.name);
2957
+ toolName = request.params.name;
2958
+ definition = definitionsByName.get(toolName);
2901
2959
  args = (_request_params_arguments = request.params.arguments) !== null && _request_params_arguments !== void 0 ? _request_params_arguments : {};
2960
+ startedAt = Date.now();
2902
2961
  if (!(definition == null)) return [
2903
2962
  3,
2904
2963
  1
2905
2964
  ];
2906
- response = formatMcpToolErrorResponse(new Error("Unknown tool: ".concat(request.params.name)));
2965
+ outcome = {
2966
+ response: formatMcpToolErrorResponse(new Error("Unknown tool: ".concat(toolName)))
2967
+ };
2907
2968
  return [
2908
2969
  3,
2909
2970
  5
@@ -2918,7 +2979,7 @@ var McpServerFactoryService_1;
2918
2979
  this._handleCallModelToolCall(definition, args, ctx)
2919
2980
  ];
2920
2981
  case 2:
2921
- response = _state.sent();
2982
+ outcome = _state.sent();
2922
2983
  return [
2923
2984
  3,
2924
2985
  5
@@ -2929,23 +2990,57 @@ var McpServerFactoryService_1;
2929
2990
  this._handleStaticToolCall(definition.staticHandler, args, ctx)
2930
2991
  ];
2931
2992
  case 4:
2932
- response = _state.sent();
2993
+ outcome = _state.sent();
2933
2994
  _state.label = 5;
2934
2995
  case 5:
2996
+ isSuccessful = outcome.error == null && outcome.response.isError !== true;
2997
+ // Unknown tools never reached a handler; classify as 'static' since no callModel dispatch occurred.
2998
+ toolKind = definition != null && definition.staticHandler == null ? 'callModel' : 'static';
2999
+ this._emitMcpAnalytics({
3000
+ event: toolName,
3001
+ toolName: toolName,
3002
+ toolKind: toolKind,
3003
+ call: definition === null || definition === void 0 ? void 0 : definition.dispatch.call,
3004
+ modelType: definition === null || definition === void 0 ? void 0 : definition.dispatch.modelType,
3005
+ specifier: definition === null || definition === void 0 ? void 0 : definition.dispatch.specifier,
3006
+ uid: (_ctx_auth = ctx.auth) === null || _ctx_auth === void 0 ? void 0 : _ctx_auth.uid,
3007
+ auth: ctx.auth,
3008
+ readOnly: this.mcpConfig.readOnly === true,
3009
+ args: args,
3010
+ isSuccessful: isSuccessful,
3011
+ error: outcome.error,
3012
+ durationMs: Date.now() - startedAt
3013
+ });
2935
3014
  return [
2936
3015
  2,
2937
- response
3016
+ outcome.response
2938
3017
  ];
2939
3018
  }
2940
3019
  });
2941
3020
  }).call(this);
2942
3021
  }
2943
3022
  },
3023
+ {
3024
+ /**
3025
+ * Forwards an event to the registered {@link McpAnalyticsService}, swallowing any failure so
3026
+ * a faulty analytics implementation can never break tool dispatch (fail-soft, matching the
3027
+ * visibility-predicate guards above).
3028
+ *
3029
+ * @param event - The MCP analytics event to forward.
3030
+ */ key: "_emitMcpAnalytics",
3031
+ value: function _emitMcpAnalytics(event) {
3032
+ try {
3033
+ this._analyticsService.handleMcpAnalyticsEvent(event);
3034
+ } catch (error) {
3035
+ this._logger.warn("MCP analytics handler threw for tool ".concat(event.toolName, "; ignoring: ").concat(error.message));
3036
+ }
3037
+ }
3038
+ },
2944
3039
  {
2945
3040
  key: "_handleStaticToolCall",
2946
3041
  value: function _handleStaticToolCall(staticHandler, args, ctx) {
2947
3042
  return _async_to_generator$2(function() {
2948
- var response, error;
3043
+ var outcome, _tmp, error;
2949
3044
  return _ts_generator$2(this, function(_state) {
2950
3045
  switch(_state.label){
2951
3046
  case 0:
@@ -2955,19 +3050,23 @@ var McpServerFactoryService_1;
2955
3050
  ,
2956
3051
  3
2957
3052
  ]);
3053
+ _tmp = {};
2958
3054
  return [
2959
3055
  4,
2960
3056
  staticHandler(args, ctx)
2961
3057
  ];
2962
3058
  case 1:
2963
- response = _state.sent();
3059
+ outcome = (_tmp.response = _state.sent(), _tmp);
2964
3060
  return [
2965
3061
  3,
2966
3062
  3
2967
3063
  ];
2968
3064
  case 2:
2969
3065
  error = _state.sent();
2970
- response = formatMcpToolErrorResponse(error);
3066
+ outcome = {
3067
+ response: formatMcpToolErrorResponse(error),
3068
+ error: error
3069
+ };
2971
3070
  return [
2972
3071
  3,
2973
3072
  3
@@ -2975,7 +3074,7 @@ var McpServerFactoryService_1;
2975
3074
  case 3:
2976
3075
  return [
2977
3076
  2,
2978
- response
3077
+ outcome
2979
3078
  ];
2980
3079
  }
2981
3080
  });
@@ -2986,7 +3085,7 @@ var McpServerFactoryService_1;
2986
3085
  key: "_handleCallModelToolCall",
2987
3086
  value: function _handleCallModelToolCall(definition, args, ctx) {
2988
3087
  return _async_to_generator$2(function() {
2989
- var params, response, result, error;
3088
+ var params, outcome, result, error;
2990
3089
  return _ts_generator$2(this, function(_state) {
2991
3090
  switch(_state.label){
2992
3091
  case 0:
@@ -3010,14 +3109,19 @@ var McpServerFactoryService_1;
3010
3109
  ];
3011
3110
  case 2:
3012
3111
  result = _state.sent();
3013
- response = formatMcpToolResponse(result, params, definition.details);
3112
+ outcome = {
3113
+ response: formatMcpToolResponse(result, params, definition.details)
3114
+ };
3014
3115
  return [
3015
3116
  3,
3016
3117
  4
3017
3118
  ];
3018
3119
  case 3:
3019
3120
  error = _state.sent();
3020
- response = formatMcpToolErrorResponse(error);
3121
+ outcome = {
3122
+ response: formatMcpToolErrorResponse(error),
3123
+ error: error
3124
+ };
3021
3125
  return [
3022
3126
  3,
3023
3127
  4
@@ -3025,7 +3129,7 @@ var McpServerFactoryService_1;
3025
3129
  case 4:
3026
3130
  return [
3027
3131
  2,
3028
- response
3132
+ outcome
3029
3133
  ];
3030
3134
  }
3031
3135
  });
@@ -3042,7 +3146,9 @@ exports.McpServerFactoryService = McpServerFactoryService_1 = __decorate([
3042
3146
  __param(2, common.Optional()),
3043
3147
  __param(2, common.Inject(firebaseServer.ModelApiGetService)),
3044
3148
  __param(3, common.Optional()),
3045
- __param(3, common.Inject(MCP_AUTH_ROLE_READER))
3149
+ __param(3, common.Inject(MCP_AUTH_ROLE_READER)),
3150
+ __param(4, common.Optional()),
3151
+ __param(4, common.Inject(MCP_ANALYTICS_SERVICE))
3046
3152
  ], exports.McpServerFactoryService);
3047
3153
 
3048
3154
  function asyncGeneratorStep$1(gen, resolve, reject, _next, _throw, key, arg) {
@@ -3250,12 +3356,12 @@ function _async_to_generator(fn) {
3250
3356
  });
3251
3357
  };
3252
3358
  }
3253
- function _class_call_check$1(instance, Constructor) {
3359
+ function _class_call_check$2(instance, Constructor) {
3254
3360
  if (!(instance instanceof Constructor)) {
3255
3361
  throw new TypeError("Cannot call a class as a function");
3256
3362
  }
3257
3363
  }
3258
- function _defineProperties$1(target, props) {
3364
+ function _defineProperties$2(target, props) {
3259
3365
  for(var i = 0; i < props.length; i++){
3260
3366
  var descriptor = props[i];
3261
3367
  descriptor.enumerable = descriptor.enumerable || false;
@@ -3264,11 +3370,11 @@ function _defineProperties$1(target, props) {
3264
3370
  Object.defineProperty(target, descriptor.key, descriptor);
3265
3371
  }
3266
3372
  }
3267
- function _create_class$1(Constructor, protoProps, staticProps) {
3268
- if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
3373
+ function _create_class$2(Constructor, protoProps, staticProps) {
3374
+ if (protoProps) _defineProperties$2(Constructor.prototype, protoProps);
3269
3375
  return Constructor;
3270
3376
  }
3271
- function _define_property$1(obj, key, value) {
3377
+ function _define_property$2(obj, key, value) {
3272
3378
  if (key in obj) {
3273
3379
  Object.defineProperty(obj, key, {
3274
3380
  value: value,
@@ -3393,12 +3499,12 @@ var McpController_1;
3393
3499
  * be layered on later if streaming tool output becomes a requirement.
3394
3500
  */ exports.McpController = McpController_1 = /*#__PURE__*/ function() {
3395
3501
  function McpController(factory) {
3396
- _class_call_check$1(this, McpController);
3397
- _define_property$1(this, "factory", void 0);
3398
- _define_property$1(this, "_logger", new common.Logger(McpController_1.name));
3502
+ _class_call_check$2(this, McpController);
3503
+ _define_property$2(this, "factory", void 0);
3504
+ _define_property$2(this, "_logger", new common.Logger(McpController_1.name));
3399
3505
  this.factory = factory;
3400
3506
  }
3401
- _create_class$1(McpController, [
3507
+ _create_class$2(McpController, [
3402
3508
  {
3403
3509
  key: "handleMcpRequest",
3404
3510
  value: function handleMcpRequest(req, res) {
@@ -3465,12 +3571,12 @@ exports.McpController = McpController_1 = __decorate([
3465
3571
  __param(0, common.Inject(exports.McpServerFactoryService))
3466
3572
  ], exports.McpController);
3467
3573
 
3468
- function _class_call_check(instance, Constructor) {
3574
+ function _class_call_check$1(instance, Constructor) {
3469
3575
  if (!(instance instanceof Constructor)) {
3470
3576
  throw new TypeError("Cannot call a class as a function");
3471
3577
  }
3472
3578
  }
3473
- function _defineProperties(target, props) {
3579
+ function _defineProperties$1(target, props) {
3474
3580
  for(var i = 0; i < props.length; i++){
3475
3581
  var descriptor = props[i];
3476
3582
  descriptor.enumerable = descriptor.enumerable || false;
@@ -3479,11 +3585,11 @@ function _defineProperties(target, props) {
3479
3585
  Object.defineProperty(target, descriptor.key, descriptor);
3480
3586
  }
3481
3587
  }
3482
- function _create_class(Constructor, protoProps, staticProps) {
3483
- if (protoProps) _defineProperties(Constructor.prototype, protoProps);
3588
+ function _create_class$1(Constructor, protoProps, staticProps) {
3589
+ if (protoProps) _defineProperties$1(Constructor.prototype, protoProps);
3484
3590
  return Constructor;
3485
3591
  }
3486
- function _define_property(obj, key, value) {
3592
+ function _define_property$1(obj, key, value) {
3487
3593
  if (key in obj) {
3488
3594
  Object.defineProperty(obj, key, {
3489
3595
  value: value,
@@ -3507,11 +3613,11 @@ function _define_property(obj, key, value) {
3507
3613
  * in `firebase-server/oidc` for the corresponding OIDC excludes).
3508
3614
  */ exports.McpWellKnownController = /*#__PURE__*/ function() {
3509
3615
  function McpWellKnownController(mcpConfig) {
3510
- _class_call_check(this, McpWellKnownController);
3511
- _define_property(this, "mcpConfig", void 0);
3616
+ _class_call_check$1(this, McpWellKnownController);
3617
+ _define_property$1(this, "mcpConfig", void 0);
3512
3618
  this.mcpConfig = mcpConfig;
3513
3619
  }
3514
- _create_class(McpWellKnownController, [
3620
+ _create_class$1(McpWellKnownController, [
3515
3621
  {
3516
3622
  key: "getProtectedResourceMetadata",
3517
3623
  value: function getProtectedResourceMetadata() {
@@ -3534,30 +3640,30 @@ exports.McpWellKnownController = __decorate([
3534
3640
  __param(0, common.Inject(McpModuleConfig))
3535
3641
  ], exports.McpWellKnownController);
3536
3642
 
3537
- function _array_like_to_array(arr, len) {
3643
+ function _array_like_to_array$1(arr, len) {
3538
3644
  if (len == null || len > arr.length) len = arr.length;
3539
3645
  for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
3540
3646
  return arr2;
3541
3647
  }
3542
- function _array_without_holes(arr) {
3543
- if (Array.isArray(arr)) return _array_like_to_array(arr);
3648
+ function _array_without_holes$1(arr) {
3649
+ if (Array.isArray(arr)) return _array_like_to_array$1(arr);
3544
3650
  }
3545
- function _iterable_to_array(iter) {
3651
+ function _iterable_to_array$1(iter) {
3546
3652
  if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
3547
3653
  }
3548
- function _non_iterable_spread() {
3654
+ function _non_iterable_spread$1() {
3549
3655
  throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3550
3656
  }
3551
- function _to_consumable_array(arr) {
3552
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
3657
+ function _to_consumable_array$1(arr) {
3658
+ return _array_without_holes$1(arr) || _iterable_to_array$1(arr) || _unsupported_iterable_to_array$1(arr) || _non_iterable_spread$1();
3553
3659
  }
3554
- function _unsupported_iterable_to_array(o, minLen) {
3660
+ function _unsupported_iterable_to_array$1(o, minLen) {
3555
3661
  if (!o) return;
3556
- if (typeof o === "string") return _array_like_to_array(o, minLen);
3662
+ if (typeof o === "string") return _array_like_to_array$1(o, minLen);
3557
3663
  var n = Object.prototype.toString.call(o).slice(8, -1);
3558
3664
  if (n === "Object" && o.constructor) n = o.constructor.name;
3559
3665
  if (n === "Map" || n === "Set") return Array.from(n);
3560
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
3666
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array$1(o, minLen);
3561
3667
  }
3562
3668
  /**
3563
3669
  * Routes the firebase-server/mcp module owns. Apps should exclude these from
@@ -3594,26 +3700,254 @@ function _unsupported_iterable_to_array(o, minLen) {
3594
3700
  return {
3595
3701
  imports: [
3596
3702
  dependencyModule
3597
- ].concat(_to_consumable_array(imports !== null && imports !== void 0 ? imports : [])),
3703
+ ].concat(_to_consumable_array$1(imports !== null && imports !== void 0 ? imports : [])),
3598
3704
  controllers: [
3599
3705
  exports.McpController,
3600
3706
  exports.McpWellKnownController
3601
3707
  ],
3602
3708
  exports: [
3603
3709
  exports.McpServerFactoryService
3604
- ].concat(_to_consumable_array(exports$1 !== null && exports$1 !== void 0 ? exports$1 : [])),
3710
+ ].concat(_to_consumable_array$1(exports$1 !== null && exports$1 !== void 0 ? exports$1 : [])),
3605
3711
  providers: [
3606
3712
  exports.McpServerFactoryService
3607
- ].concat(_to_consumable_array(providers !== null && providers !== void 0 ? providers : []))
3713
+ ].concat(_to_consumable_array$1(providers !== null && providers !== void 0 ? providers : []))
3714
+ };
3715
+ }
3716
+
3717
+ /**
3718
+ * Default analytics event name used by {@link FirebaseServerMcpAnalyticsService} when
3719
+ * forwarding a completed MCP tool call to the downstream analytics pipeline.
3720
+ */ var DEFAULT_MCP_ANALYTICS_EVENT_NAME = 'mcp-tool';
3721
+ /**
3722
+ * NestJS injection token for the optional {@link FirebaseServerMcpAnalyticsConfig} provider.
3723
+ *
3724
+ * @example
3725
+ * ```typescript
3726
+ * @Module(appMcpAnalyticsModuleMetadata({ mcpAnalyticsConfig: { eventName: 'mcp-tool', logEvents: true } }))
3727
+ * export class AppMcpAnalyticsModule {}
3728
+ * ```
3729
+ */ var FIREBASE_SERVER_MCP_ANALYTICS_CONFIG = 'FIREBASE_SERVER_MCP_ANALYTICS_CONFIG';
3730
+
3731
+ function _assert_this_initialized(self) {
3732
+ if (self === void 0) {
3733
+ throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
3734
+ }
3735
+ return self;
3736
+ }
3737
+ function _call_super(_this, derived, args) {
3738
+ derived = _get_prototype_of(derived);
3739
+ return _possible_constructor_return(_this, _is_native_reflect_construct() ? Reflect.construct(derived, [], _get_prototype_of(_this).constructor) : derived.apply(_this, args));
3740
+ }
3741
+ function _class_call_check(instance, Constructor) {
3742
+ if (!(instance instanceof Constructor)) {
3743
+ throw new TypeError("Cannot call a class as a function");
3744
+ }
3745
+ }
3746
+ function _defineProperties(target, props) {
3747
+ for(var i = 0; i < props.length; i++){
3748
+ var descriptor = props[i];
3749
+ descriptor.enumerable = descriptor.enumerable || false;
3750
+ descriptor.configurable = true;
3751
+ if ("value" in descriptor) descriptor.writable = true;
3752
+ Object.defineProperty(target, descriptor.key, descriptor);
3753
+ }
3754
+ }
3755
+ function _create_class(Constructor, protoProps, staticProps) {
3756
+ if (protoProps) _defineProperties(Constructor.prototype, protoProps);
3757
+ return Constructor;
3758
+ }
3759
+ function _define_property(obj, key, value) {
3760
+ if (key in obj) {
3761
+ Object.defineProperty(obj, key, {
3762
+ value: value,
3763
+ enumerable: true,
3764
+ configurable: true,
3765
+ writable: true
3766
+ });
3767
+ } else {
3768
+ obj[key] = value;
3769
+ }
3770
+ return obj;
3771
+ }
3772
+ function _get_prototype_of(o) {
3773
+ _get_prototype_of = Object.setPrototypeOf ? Object.getPrototypeOf : function getPrototypeOf(o) {
3774
+ return o.__proto__ || Object.getPrototypeOf(o);
3775
+ };
3776
+ return _get_prototype_of(o);
3777
+ }
3778
+ function _inherits(subClass, superClass) {
3779
+ if (typeof superClass !== "function" && superClass !== null) {
3780
+ throw new TypeError("Super expression must either be null or a function");
3781
+ }
3782
+ subClass.prototype = Object.create(superClass && superClass.prototype, {
3783
+ constructor: {
3784
+ value: subClass,
3785
+ writable: true,
3786
+ configurable: true
3787
+ }
3788
+ });
3789
+ if (superClass) _set_prototype_of(subClass, superClass);
3790
+ }
3791
+ function _possible_constructor_return(self, call) {
3792
+ if (call && (_type_of(call) === "object" || typeof call === "function")) {
3793
+ return call;
3794
+ }
3795
+ return _assert_this_initialized(self);
3796
+ }
3797
+ function _set_prototype_of(o, p) {
3798
+ _set_prototype_of = Object.setPrototypeOf || function setPrototypeOf(o, p) {
3799
+ o.__proto__ = p;
3800
+ return o;
3801
+ };
3802
+ return _set_prototype_of(o, p);
3803
+ }
3804
+ function _type_of(obj) {
3805
+ "@swc/helpers - typeof";
3806
+ return obj && typeof Symbol !== "undefined" && obj.constructor === Symbol ? "symbol" : typeof obj;
3807
+ }
3808
+ function _is_native_reflect_construct() {
3809
+ try {
3810
+ var result = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function() {}));
3811
+ } catch (_) {}
3812
+ return (_is_native_reflect_construct = function() {
3813
+ return !!result;
3814
+ })();
3815
+ }
3816
+ var FirebaseServerMcpAnalyticsService_1;
3817
+ /**
3818
+ * Reusable {@link McpAnalyticsService} that forwards each completed MCP tool call to the app's
3819
+ * {@link FirebaseServerAnalyticsService}, so MCP-transport analytics feed the same downstream
3820
+ * pipeline (e.g. Segment) as model analytics.
3821
+ *
3822
+ * Registered globally via {@link appMcpAnalyticsModuleMetadata}; tuned via
3823
+ * {@link FirebaseServerMcpAnalyticsConfig}. When no analytics service is available the call is a
3824
+ * no-op aside from the optional log line.
3825
+ */ exports.FirebaseServerMcpAnalyticsService = FirebaseServerMcpAnalyticsService_1 = /*#__PURE__*/ function(McpAnalyticsService) {
3826
+ _inherits(FirebaseServerMcpAnalyticsService, McpAnalyticsService);
3827
+ function FirebaseServerMcpAnalyticsService(analyticsService, config) {
3828
+ _class_call_check(this, FirebaseServerMcpAnalyticsService);
3829
+ var _this;
3830
+ var _ref, _ref1;
3831
+ _this = _call_super(this, FirebaseServerMcpAnalyticsService), _define_property(_this, "analyticsService", void 0), _define_property(_this, "_logger", new common.Logger(FirebaseServerMcpAnalyticsService_1.name)), _define_property(_this, "_eventName", void 0), _define_property(_this, "_logEvents", void 0);
3832
+ _this.analyticsService = analyticsService;
3833
+ _this._eventName = (_ref = config === null || config === void 0 ? void 0 : config.eventName) !== null && _ref !== void 0 ? _ref : DEFAULT_MCP_ANALYTICS_EVENT_NAME;
3834
+ _this._logEvents = (_ref1 = config === null || config === void 0 ? void 0 : config.logEvents) !== null && _ref1 !== void 0 ? _ref1 : true;
3835
+ return _this;
3836
+ }
3837
+ _create_class(FirebaseServerMcpAnalyticsService, [
3838
+ {
3839
+ key: "handleMcpAnalyticsEvent",
3840
+ value: function handleMcpAnalyticsEvent(event) {
3841
+ if (this._logEvents) {
3842
+ var uidSuffix = event.uid ? " uid=".concat(event.uid) : '';
3843
+ var durationSuffix = event.durationMs != null ? " (".concat(event.durationMs, "ms)") : '';
3844
+ var outcome = event.isSuccessful ? 'Succeeded' : 'Failed';
3845
+ this._logger.log("MCP ".concat(event.toolName, " [").concat(event.toolKind, "] ").concat(outcome).concat(uidSuffix).concat(durationSuffix));
3846
+ }
3847
+ if (this.analyticsService != null) {
3848
+ var _event_call, _event_modelType, _event_specifier;
3849
+ this.analyticsService.sendEventData(event.uid, this._eventName, {
3850
+ tool: event.toolName,
3851
+ toolKind: event.toolKind,
3852
+ call: (_event_call = event.call) !== null && _event_call !== void 0 ? _event_call : '',
3853
+ modelType: (_event_modelType = event.modelType) !== null && _event_modelType !== void 0 ? _event_modelType : '',
3854
+ specifier: (_event_specifier = event.specifier) !== null && _event_specifier !== void 0 ? _event_specifier : '',
3855
+ success: event.isSuccessful
3856
+ });
3857
+ }
3858
+ }
3859
+ }
3860
+ ]);
3861
+ return FirebaseServerMcpAnalyticsService;
3862
+ }(McpAnalyticsService);
3863
+ exports.FirebaseServerMcpAnalyticsService = FirebaseServerMcpAnalyticsService_1 = __decorate([
3864
+ common.Injectable(),
3865
+ __param(0, common.Optional()),
3866
+ __param(0, common.Inject(firebaseServer.FirebaseServerAnalyticsService)),
3867
+ __param(1, common.Optional()),
3868
+ __param(1, common.Inject(FIREBASE_SERVER_MCP_ANALYTICS_CONFIG))
3869
+ ], exports.FirebaseServerMcpAnalyticsService);
3870
+
3871
+ function _array_like_to_array(arr, len) {
3872
+ if (len == null || len > arr.length) len = arr.length;
3873
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
3874
+ return arr2;
3875
+ }
3876
+ function _array_without_holes(arr) {
3877
+ if (Array.isArray(arr)) return _array_like_to_array(arr);
3878
+ }
3879
+ function _iterable_to_array(iter) {
3880
+ if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
3881
+ }
3882
+ function _non_iterable_spread() {
3883
+ throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
3884
+ }
3885
+ function _to_consumable_array(arr) {
3886
+ return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
3887
+ }
3888
+ function _unsupported_iterable_to_array(o, minLen) {
3889
+ if (!o) return;
3890
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
3891
+ var n = Object.prototype.toString.call(o).slice(8, -1);
3892
+ if (n === "Object" && o.constructor) n = o.constructor.name;
3893
+ if (n === "Map" || n === "Set") return Array.from(n);
3894
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
3895
+ }
3896
+ /**
3897
+ * Generates NestJS module metadata that registers {@link FirebaseServerMcpAnalyticsService} as the
3898
+ * MCP analytics consumer, aliased to {@link MCP_ANALYTICS_SERVICE}.
3899
+ *
3900
+ * Mirrors the convention used by `appAnalyticsModuleMetadata`. Unlike `mcpModuleMetadata`, this
3901
+ * requires no dependency module — `FirebaseServerAnalyticsService` is resolved optionally and is
3902
+ * expected to be supplied globally by the app's analytics module.
3903
+ *
3904
+ * Decorate a `@Global()` module with the result so the `MCP_ANALYTICS_SERVICE` token is visible to
3905
+ * the `McpServerFactoryService` provided by the app's MCP module.
3906
+ *
3907
+ * @param config - Optional metadata + analytics config to merge in.
3908
+ * @returns NestJS module metadata providing + exporting the MCP analytics service and token.
3909
+ *
3910
+ * @example
3911
+ * ```typescript
3912
+ * @Global()
3913
+ * @Module(appMcpAnalyticsModuleMetadata())
3914
+ * export class AppMcpAnalyticsModule {}
3915
+ * ```
3916
+ */ function appMcpAnalyticsModuleMetadata() {
3917
+ var config = arguments.length > 0 && arguments[0] !== void 0 ? arguments[0] : {};
3918
+ var mcpAnalyticsConfig = config.mcpAnalyticsConfig, imports = config.imports, exports$1 = config.exports, providers = config.providers;
3919
+ var configProviders = mcpAnalyticsConfig ? [
3920
+ {
3921
+ provide: FIREBASE_SERVER_MCP_ANALYTICS_CONFIG,
3922
+ useValue: mcpAnalyticsConfig
3923
+ }
3924
+ ] : [];
3925
+ return {
3926
+ imports: _to_consumable_array(imports !== null && imports !== void 0 ? imports : []),
3927
+ exports: [
3928
+ MCP_ANALYTICS_SERVICE,
3929
+ exports.FirebaseServerMcpAnalyticsService
3930
+ ].concat(_to_consumable_array(exports$1 !== null && exports$1 !== void 0 ? exports$1 : [])),
3931
+ providers: [
3932
+ exports.FirebaseServerMcpAnalyticsService,
3933
+ {
3934
+ provide: MCP_ANALYTICS_SERVICE,
3935
+ useExisting: exports.FirebaseServerMcpAnalyticsService
3936
+ }
3937
+ ].concat(_to_consumable_array(configProviders), _to_consumable_array(providers !== null && providers !== void 0 ? providers : []))
3608
3938
  };
3609
3939
  }
3610
3940
 
3611
3941
  exports.DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS = DEFAULT_JSON_SCHEMA_GENERATION_OPTIONS;
3942
+ exports.DEFAULT_MCP_ANALYTICS_EVENT_NAME = DEFAULT_MCP_ANALYTICS_EVENT_NAME;
3612
3943
  exports.DEFAULT_MCP_PATH = DEFAULT_MCP_PATH;
3944
+ exports.DEFAULT_MCP_SERVER_INSTRUCTIONS = DEFAULT_MCP_SERVER_INSTRUCTIONS;
3613
3945
  exports.DEFAULT_MCP_SERVER_NAME = DEFAULT_MCP_SERVER_NAME;
3614
3946
  exports.DEFAULT_SPECIFIER_KEY = DEFAULT_SPECIFIER_KEY;
3615
3947
  exports.DEFAULT_VOID_MCP_SUCCESS_VALUE = DEFAULT_VOID_MCP_SUCCESS_VALUE;
3948
+ exports.FIREBASE_SERVER_MCP_ANALYTICS_CONFIG = FIREBASE_SERVER_MCP_ANALYTICS_CONFIG;
3616
3949
  exports.FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE = FIREBASE_SERVER_MCP_ROUTES_FOR_GLOBAL_ROUTE_EXCLUDE;
3950
+ exports.MCP_ANALYTICS_SERVICE = MCP_ANALYTICS_SERVICE;
3617
3951
  exports.MCP_AUTH_ROLE_READER = MCP_AUTH_ROLE_READER;
3618
3952
  exports.MCP_MANIFEST_VERSION = MCP_MANIFEST_VERSION;
3619
3953
  exports.MCP_MODEL_GET_BATCH_SIZE = MCP_MODEL_GET_BATCH_SIZE;
@@ -3626,7 +3960,9 @@ exports.MODEL_GET_TOOL_NAME = MODEL_GET_TOOL_NAME;
3626
3960
  exports.MODEL_INFO_DISPATCH_CALL = MODEL_INFO_DISPATCH_CALL;
3627
3961
  exports.MODEL_INFO_DISPATCH_MODEL_TYPE = MODEL_INFO_DISPATCH_MODEL_TYPE;
3628
3962
  exports.MODEL_INFO_TOOL_NAME = MODEL_INFO_TOOL_NAME;
3963
+ exports.McpAnalyticsService = McpAnalyticsService;
3629
3964
  exports.McpModuleConfig = McpModuleConfig;
3965
+ exports.appMcpAnalyticsModuleMetadata = appMcpAnalyticsModuleMetadata;
3630
3966
  exports.buildDefaultMcpToolDescription = buildDefaultMcpToolDescription;
3631
3967
  exports.buildMcpToolName = buildMcpToolName;
3632
3968
  exports.buildStaticWireEntry = buildStaticWireEntry;
@@ -3642,5 +3978,6 @@ exports.generateMcpToolDefinitions = generateMcpToolDefinitions;
3642
3978
  exports.handleStreamableHttpMcpRequest = handleStreamableHttpMcpRequest;
3643
3979
  exports.mcpManifestKey = mcpManifestKey;
3644
3980
  exports.mcpModuleMetadata = mcpModuleMetadata;
3981
+ exports.noopMcpAnalyticsService = noopMcpAnalyticsService;
3645
3982
  exports.resolveEffectiveReadOnly = resolveEffectiveReadOnly;
3646
3983
  exports.resolveRequiredScope = resolveRequiredScope;