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