@frontmcp/observability 1.0.4 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -378,173 +378,129 @@ __export(index_exports, {
378
378
  module.exports = __toCommonJS(index_exports);
379
379
 
380
380
  // libs/observability/src/plugin/observability.plugin.ts
381
- var import_sdk2 = require("@frontmcp/sdk");
382
381
  var import_api14 = require("@opentelemetry/api");
382
+ var import_sdk2 = require("@frontmcp/sdk");
383
383
 
384
- // libs/observability/src/otel/otel.tokens.ts
385
- var OTEL_TRACER = /* @__PURE__ */ Symbol.for("frontmcp:observability:otel-tracer");
386
- var OTEL_CONFIG = /* @__PURE__ */ Symbol.for("frontmcp:observability:otel-config");
387
-
388
- // libs/observability/src/request-log/request-log.tokens.ts
389
- var REQUEST_LOG_COLLECTOR = /* @__PURE__ */ Symbol.for("frontmcp:observability:request-log-collector");
390
-
391
- // libs/observability/src/request-log/request-log.collector.ts
392
- var RequestLogCollector = class {
393
- constructor(context, options) {
394
- this.entries = [];
395
- this.hooksTriggered = /* @__PURE__ */ new Set();
396
- this.authenticated = false;
397
- this.status = "ok";
398
- this.finalized = false;
399
- this.requestId = context.requestId;
400
- this.traceId = context.traceId;
401
- this.sessionIdHash = context.sessionIdHash;
402
- this.scopeId = context.scopeId;
403
- this.startTime = /* @__PURE__ */ new Date();
404
- this.maxEntries = options?.maxEntries ?? 500;
405
- this.onComplete = options?.onRequestComplete;
406
- }
407
- /**
408
- * Add a structured log entry to this request's log.
409
- * Called by StructuredLogTransport for each log record that
410
- * matches this request's requestId.
411
- */
412
- addEntry(entry) {
413
- if (this.finalized || this.entries.length >= this.maxEntries) return;
414
- const logEntry = {
415
- timestamp: entry.timestamp,
416
- level: entry.level,
417
- message: entry.message
418
- };
419
- if (entry.flow_name) {
420
- logEntry.stage = entry.flow_name;
421
- }
422
- if (entry.elapsed_ms !== void 0) {
423
- logEntry.elapsed_ms = entry.elapsed_ms;
424
- }
425
- if (entry.attributes && Object.keys(entry.attributes).length > 0) {
426
- logEntry.attributes = entry.attributes;
427
- }
428
- this.entries.push(logEntry);
384
+ // libs/observability/src/logging/sinks/stdout.sink.ts
385
+ var StdoutSink = class {
386
+ constructor(options) {
387
+ this.stream = options?.stream ?? process.stdout;
388
+ this.pretty = options?.pretty ?? false;
429
389
  }
430
- /**
431
- * Record a hook stage that was triggered during this request.
432
- */
433
- addHook(stage) {
434
- this.hooksTriggered.add(stage);
390
+ write(entry) {
391
+ const line = this.pretty ? JSON.stringify(entry, null, 2) : JSON.stringify(entry);
392
+ this.stream.write(line + "\n");
435
393
  }
436
- /**
437
- * Set HTTP request metadata.
438
- */
439
- setHttpInfo(method, path) {
440
- this.httpMethod = method;
441
- this.httpPath = path;
394
+ };
395
+
396
+ // libs/observability/src/logging/sinks/console.sink.ts
397
+ var ConsoleSink = class {
398
+ write(entry) {
399
+ const method = levelToConsoleMethod(entry.level);
400
+ const formatted = formatEntry(entry);
401
+ method(formatted);
442
402
  }
443
- /**
444
- * Set the MCP JSON-RPC method being invoked.
445
- */
446
- setRpcMethod(method) {
447
- this.rpcMethod = method;
403
+ };
404
+ function formatEntry(entry) {
405
+ const useAnsi = typeof process !== "undefined" && !!process.stdout?.isTTY;
406
+ const ts = entry.timestamp.slice(11, 23);
407
+ const level = entry.level.toUpperCase().padEnd(7);
408
+ const traceShort = entry.trace_id ? entry.trace_id.slice(0, 8) : "";
409
+ const reqShort = entry.request_id ? entry.request_id.slice(0, 8) : "";
410
+ const parts = [];
411
+ const DIM2 = useAnsi ? "\x1B[2m" : "";
412
+ const BOLD2 = useAnsi ? "\x1B[1m" : "";
413
+ const RESET2 = useAnsi ? "\x1B[0m" : "";
414
+ const levelColor = useAnsi ? LEVEL_COLORS[entry.level] ?? "" : "";
415
+ parts.push(`${DIM2}[${ts}]${RESET2}`);
416
+ parts.push(`${BOLD2}${levelColor}${level}${RESET2}`);
417
+ if (traceShort || reqShort) {
418
+ parts.push(`${DIM2}[${traceShort}${reqShort ? ":" + reqShort : ""}]${RESET2}`);
448
419
  }
449
- /**
450
- * Set the tool name being invoked.
451
- */
452
- setToolName(name) {
453
- this.toolName = name;
420
+ if (entry.prefix) parts.push(`${DIM2}[${entry.prefix}]${RESET2}`);
421
+ parts.push(entry.message);
422
+ if (entry.attributes && Object.keys(entry.attributes).length > 0) {
423
+ const attrs = Object.entries(entry.attributes).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
424
+ parts.push(`${DIM2}{ ${attrs} }${RESET2}`);
454
425
  }
455
- /**
456
- * Set the resource URI being read.
457
- */
458
- setResourceUri(uri) {
459
- this.resourceUri = uri;
426
+ if (entry.error) {
427
+ parts.push(`[${entry.error.type}: ${entry.error.message}]`);
460
428
  }
461
- /**
462
- * Set the prompt name being invoked.
463
- */
464
- setPromptName(name) {
465
- this.promptName = name;
429
+ if (entry.elapsed_ms !== void 0) {
430
+ parts.push(`${DIM2}(${entry.elapsed_ms}ms)${RESET2}`);
466
431
  }
467
- /**
468
- * Set authentication info.
469
- */
470
- setAuthInfo(type, authenticated) {
471
- this.authType = type;
472
- this.authenticated = authenticated;
432
+ return parts.join(" ");
433
+ }
434
+ var LEVEL_COLORS = {
435
+ debug: "\x1B[34m",
436
+ verbose: "\x1B[90m",
437
+ info: "\x1B[32m",
438
+ warn: "\x1B[33m",
439
+ error: "\x1B[31m"
440
+ };
441
+ function levelToConsoleMethod(level) {
442
+ switch (level) {
443
+ case "debug":
444
+ case "verbose":
445
+ return console.debug;
446
+ case "info":
447
+ return console.info;
448
+ case "warn":
449
+ return console.warn;
450
+ case "error":
451
+ return console.error;
452
+ default:
453
+ return console.log;
473
454
  }
474
- /**
475
- * Set request status.
476
- */
477
- setStatus(status, statusCode) {
478
- this.status = status;
479
- this.statusCode = statusCode;
455
+ }
456
+
457
+ // libs/observability/src/logging/sinks/callback.sink.ts
458
+ var CallbackSink = class {
459
+ constructor(fn) {
460
+ this.fn = fn;
480
461
  }
481
- /**
482
- * Set error details.
483
- */
484
- setError(error) {
485
- this.error = error;
486
- this.status = "error";
462
+ write(entry) {
463
+ this.fn(entry);
487
464
  }
488
- /**
489
- * Finalize and produce the complete RequestLog.
490
- * Fires the onRequestComplete callback if configured.
491
- */
492
- async finalize() {
493
- if (this.finalized) {
494
- return this.finalizedLog;
465
+ };
466
+
467
+ // libs/observability/src/logging/sink.factory.ts
468
+ function createSink(config) {
469
+ switch (config.type) {
470
+ case "stdout":
471
+ return new StdoutSink({ stream: config.stream, pretty: config.pretty });
472
+ case "console":
473
+ return new ConsoleSink();
474
+ case "winston": {
475
+ const { WinstonSink: WinstonSink2 } = (init_winston_sink(), __toCommonJS(winston_sink_exports));
476
+ return new WinstonSink2(config.logger);
495
477
  }
496
- this.finalized = true;
497
- const log = this.toRequestLog();
498
- this.finalizedLog = log;
499
- if (this.onComplete) {
500
- try {
501
- await this.onComplete(log);
502
- } catch {
503
- }
478
+ case "pino": {
479
+ const { PinoSink: PinoSink2 } = (init_pino_sink(), __toCommonJS(pino_sink_exports));
480
+ return new PinoSink2(config.logger);
504
481
  }
505
- return log;
506
- }
507
- /**
508
- * Build the RequestLog object from accumulated state.
509
- */
510
- toRequestLog() {
511
- const endTime = /* @__PURE__ */ new Date();
512
- return {
513
- request_id: this.requestId,
514
- trace_id: this.traceId,
515
- session_id_hash: this.sessionIdHash,
516
- scope_id: this.scopeId,
517
- start_time: this.startTime.toISOString(),
518
- end_time: endTime.toISOString(),
519
- duration_ms: endTime.getTime() - this.startTime.getTime(),
520
- http_method: this.httpMethod,
521
- http_path: this.httpPath,
522
- rpc_method: this.rpcMethod,
523
- tool_name: this.toolName,
524
- resource_uri: this.resourceUri,
525
- prompt_name: this.promptName,
526
- auth_type: this.authType,
527
- authenticated: this.authenticated,
528
- status: this.status,
529
- status_code: this.statusCode,
530
- error: this.error,
531
- hooks_triggered: Array.from(this.hooksTriggered),
532
- entries: [...this.entries]
533
- };
534
- }
535
- /**
536
- * Check if the collector has been finalized.
537
- */
538
- isFinalized() {
539
- return this.finalized;
482
+ case "callback":
483
+ return new CallbackSink(config.fn);
484
+ case "otlp": {
485
+ const { OtlpSink: OtlpSink2 } = (init_otlp_sink(), __toCommonJS(otlp_sink_exports));
486
+ return new OtlpSink2({
487
+ endpoint: config.endpoint ?? (typeof process !== "undefined" ? process.env?.["OTEL_EXPORTER_OTLP_ENDPOINT"] : void 0) ?? "http://localhost:4318",
488
+ headers: config.headers,
489
+ batchSize: config.batchSize,
490
+ flushIntervalMs: config.flushIntervalMs,
491
+ serviceName: config.serviceName
492
+ });
493
+ }
494
+ default:
495
+ throw new Error(`Unknown sink type: ${config.type}`);
540
496
  }
541
- /**
542
- * Get the number of accumulated entries.
543
- */
544
- getEntryCount() {
545
- return this.entries.length;
497
+ }
498
+ function createSinks(configs) {
499
+ if (configs && configs.length > 0) {
500
+ return configs.map(createSink);
546
501
  }
547
- };
502
+ return [];
503
+ }
548
504
 
549
505
  // libs/observability/src/logging/structured-log-transport.ts
550
506
  var import_sdk = require("@frontmcp/sdk");
@@ -688,126 +644,170 @@ StructuredLogTransport = __decorateClass([
688
644
  })
689
645
  ], StructuredLogTransport);
690
646
 
691
- // libs/observability/src/logging/sinks/stdout.sink.ts
692
- var StdoutSink = class {
693
- constructor(options) {
694
- this.stream = options?.stream ?? process.stdout;
695
- this.pretty = options?.pretty ?? false;
647
+ // libs/observability/src/otel/otel.tokens.ts
648
+ var OTEL_TRACER = /* @__PURE__ */ Symbol.for("frontmcp:observability:otel-tracer");
649
+ var OTEL_CONFIG = /* @__PURE__ */ Symbol.for("frontmcp:observability:otel-config");
650
+
651
+ // libs/observability/src/request-log/request-log.collector.ts
652
+ var RequestLogCollector = class {
653
+ constructor(context, options) {
654
+ this.entries = [];
655
+ this.hooksTriggered = /* @__PURE__ */ new Set();
656
+ this.authenticated = false;
657
+ this.status = "ok";
658
+ this.finalized = false;
659
+ this.requestId = context.requestId;
660
+ this.traceId = context.traceId;
661
+ this.sessionIdHash = context.sessionIdHash;
662
+ this.scopeId = context.scopeId;
663
+ this.startTime = /* @__PURE__ */ new Date();
664
+ this.maxEntries = options?.maxEntries ?? 500;
665
+ this.onComplete = options?.onRequestComplete;
696
666
  }
697
- write(entry) {
698
- const line = this.pretty ? JSON.stringify(entry, null, 2) : JSON.stringify(entry);
699
- this.stream.write(line + "\n");
667
+ /**
668
+ * Add a structured log entry to this request's log.
669
+ * Called by StructuredLogTransport for each log record that
670
+ * matches this request's requestId.
671
+ */
672
+ addEntry(entry) {
673
+ if (this.finalized || this.entries.length >= this.maxEntries) return;
674
+ const logEntry = {
675
+ timestamp: entry.timestamp,
676
+ level: entry.level,
677
+ message: entry.message
678
+ };
679
+ if (entry.flow_name) {
680
+ logEntry.stage = entry.flow_name;
681
+ }
682
+ if (entry.elapsed_ms !== void 0) {
683
+ logEntry.elapsed_ms = entry.elapsed_ms;
684
+ }
685
+ if (entry.attributes && Object.keys(entry.attributes).length > 0) {
686
+ logEntry.attributes = entry.attributes;
687
+ }
688
+ this.entries.push(logEntry);
700
689
  }
701
- };
702
-
703
- // libs/observability/src/logging/sinks/console.sink.ts
704
- var ConsoleSink = class {
705
- write(entry) {
706
- const method = levelToConsoleMethod(entry.level);
707
- const formatted = formatEntry(entry);
708
- method(formatted);
690
+ /**
691
+ * Record a hook stage that was triggered during this request.
692
+ */
693
+ addHook(stage) {
694
+ this.hooksTriggered.add(stage);
709
695
  }
710
- };
711
- function formatEntry(entry) {
712
- const useAnsi = typeof process !== "undefined" && !!process.stdout?.isTTY;
713
- const ts = entry.timestamp.slice(11, 23);
714
- const level = entry.level.toUpperCase().padEnd(7);
715
- const traceShort = entry.trace_id ? entry.trace_id.slice(0, 8) : "";
716
- const reqShort = entry.request_id ? entry.request_id.slice(0, 8) : "";
717
- const parts = [];
718
- const DIM2 = useAnsi ? "\x1B[2m" : "";
719
- const BOLD2 = useAnsi ? "\x1B[1m" : "";
720
- const RESET2 = useAnsi ? "\x1B[0m" : "";
721
- const levelColor = useAnsi ? LEVEL_COLORS[entry.level] ?? "" : "";
722
- parts.push(`${DIM2}[${ts}]${RESET2}`);
723
- parts.push(`${BOLD2}${levelColor}${level}${RESET2}`);
724
- if (traceShort || reqShort) {
725
- parts.push(`${DIM2}[${traceShort}${reqShort ? ":" + reqShort : ""}]${RESET2}`);
696
+ /**
697
+ * Set HTTP request metadata.
698
+ */
699
+ setHttpInfo(method, path) {
700
+ this.httpMethod = method;
701
+ this.httpPath = path;
726
702
  }
727
- if (entry.prefix) parts.push(`${DIM2}[${entry.prefix}]${RESET2}`);
728
- parts.push(entry.message);
729
- if (entry.attributes && Object.keys(entry.attributes).length > 0) {
730
- const attrs = Object.entries(entry.attributes).map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");
731
- parts.push(`${DIM2}{ ${attrs} }${RESET2}`);
703
+ /**
704
+ * Set the MCP JSON-RPC method being invoked.
705
+ */
706
+ setRpcMethod(method) {
707
+ this.rpcMethod = method;
732
708
  }
733
- if (entry.error) {
734
- parts.push(`[${entry.error.type}: ${entry.error.message}]`);
709
+ /**
710
+ * Set the tool name being invoked.
711
+ */
712
+ setToolName(name) {
713
+ this.toolName = name;
735
714
  }
736
- if (entry.elapsed_ms !== void 0) {
737
- parts.push(`${DIM2}(${entry.elapsed_ms}ms)${RESET2}`);
715
+ /**
716
+ * Set the resource URI being read.
717
+ */
718
+ setResourceUri(uri) {
719
+ this.resourceUri = uri;
738
720
  }
739
- return parts.join(" ");
740
- }
741
- var LEVEL_COLORS = {
742
- debug: "\x1B[34m",
743
- verbose: "\x1B[90m",
744
- info: "\x1B[32m",
745
- warn: "\x1B[33m",
746
- error: "\x1B[31m"
747
- };
748
- function levelToConsoleMethod(level) {
749
- switch (level) {
750
- case "debug":
751
- case "verbose":
752
- return console.debug;
753
- case "info":
754
- return console.info;
755
- case "warn":
756
- return console.warn;
757
- case "error":
758
- return console.error;
759
- default:
760
- return console.log;
721
+ /**
722
+ * Set the prompt name being invoked.
723
+ */
724
+ setPromptName(name) {
725
+ this.promptName = name;
761
726
  }
762
- }
763
-
764
- // libs/observability/src/logging/sinks/callback.sink.ts
765
- var CallbackSink = class {
766
- constructor(fn) {
767
- this.fn = fn;
727
+ /**
728
+ * Set authentication info.
729
+ */
730
+ setAuthInfo(type, authenticated) {
731
+ this.authType = type;
732
+ this.authenticated = authenticated;
768
733
  }
769
- write(entry) {
770
- this.fn(entry);
734
+ /**
735
+ * Set request status.
736
+ */
737
+ setStatus(status, statusCode) {
738
+ this.status = status;
739
+ this.statusCode = statusCode;
771
740
  }
772
- };
773
-
774
- // libs/observability/src/logging/sink.factory.ts
775
- function createSink(config) {
776
- switch (config.type) {
777
- case "stdout":
778
- return new StdoutSink({ stream: config.stream, pretty: config.pretty });
779
- case "console":
780
- return new ConsoleSink();
781
- case "winston": {
782
- const { WinstonSink: WinstonSink2 } = (init_winston_sink(), __toCommonJS(winston_sink_exports));
783
- return new WinstonSink2(config.logger);
784
- }
785
- case "pino": {
786
- const { PinoSink: PinoSink2 } = (init_pino_sink(), __toCommonJS(pino_sink_exports));
787
- return new PinoSink2(config.logger);
741
+ /**
742
+ * Set error details.
743
+ */
744
+ setError(error) {
745
+ this.error = error;
746
+ this.status = "error";
747
+ }
748
+ /**
749
+ * Finalize and produce the complete RequestLog.
750
+ * Fires the onRequestComplete callback if configured.
751
+ */
752
+ async finalize() {
753
+ if (this.finalized) {
754
+ return this.finalizedLog;
788
755
  }
789
- case "callback":
790
- return new CallbackSink(config.fn);
791
- case "otlp": {
792
- const { OtlpSink: OtlpSink2 } = (init_otlp_sink(), __toCommonJS(otlp_sink_exports));
793
- return new OtlpSink2({
794
- endpoint: config.endpoint ?? (typeof process !== "undefined" ? process.env?.["OTEL_EXPORTER_OTLP_ENDPOINT"] : void 0) ?? "http://localhost:4318",
795
- headers: config.headers,
796
- batchSize: config.batchSize,
797
- flushIntervalMs: config.flushIntervalMs,
798
- serviceName: config.serviceName
799
- });
756
+ this.finalized = true;
757
+ const log = this.toRequestLog();
758
+ this.finalizedLog = log;
759
+ if (this.onComplete) {
760
+ try {
761
+ await this.onComplete(log);
762
+ } catch {
763
+ }
800
764
  }
801
- default:
802
- throw new Error(`Unknown sink type: ${config.type}`);
765
+ return log;
766
+ }
767
+ /**
768
+ * Build the RequestLog object from accumulated state.
769
+ */
770
+ toRequestLog() {
771
+ const endTime = /* @__PURE__ */ new Date();
772
+ return {
773
+ request_id: this.requestId,
774
+ trace_id: this.traceId,
775
+ session_id_hash: this.sessionIdHash,
776
+ scope_id: this.scopeId,
777
+ start_time: this.startTime.toISOString(),
778
+ end_time: endTime.toISOString(),
779
+ duration_ms: endTime.getTime() - this.startTime.getTime(),
780
+ http_method: this.httpMethod,
781
+ http_path: this.httpPath,
782
+ rpc_method: this.rpcMethod,
783
+ tool_name: this.toolName,
784
+ resource_uri: this.resourceUri,
785
+ prompt_name: this.promptName,
786
+ auth_type: this.authType,
787
+ authenticated: this.authenticated,
788
+ status: this.status,
789
+ status_code: this.statusCode,
790
+ error: this.error,
791
+ hooks_triggered: Array.from(this.hooksTriggered),
792
+ entries: [...this.entries]
793
+ };
803
794
  }
804
- }
805
- function createSinks(configs) {
806
- if (configs && configs.length > 0) {
807
- return configs.map(createSink);
795
+ /**
796
+ * Check if the collector has been finalized.
797
+ */
798
+ isFinalized() {
799
+ return this.finalized;
808
800
  }
809
- return [];
810
- }
801
+ /**
802
+ * Get the number of accumulated entries.
803
+ */
804
+ getEntryCount() {
805
+ return this.entries.length;
806
+ }
807
+ };
808
+
809
+ // libs/observability/src/request-log/request-log.tokens.ts
810
+ var REQUEST_LOG_COLLECTOR = /* @__PURE__ */ Symbol.for("frontmcp:observability:request-log-collector");
811
811
 
812
812
  // libs/observability/src/telemetry/telemetry.accessor.ts
813
813
  var import_api13 = require("@opentelemetry/api");
@@ -838,11 +838,8 @@ function createOTelContextFromTrace(tc) {
838
838
  }
839
839
 
840
840
  // libs/observability/src/plugin/observability.hooks.ts
841
- var import_utils = require("@frontmcp/utils");
842
841
  var import_api12 = require("@opentelemetry/api");
843
-
844
- // libs/observability/src/otel/spans/http-server.span.ts
845
- var import_api3 = require("@opentelemetry/api");
842
+ var import_utils = require("@frontmcp/utils");
846
843
 
847
844
  // libs/observability/src/otel/otel.types.ts
848
845
  var McpAttributes = {
@@ -957,6 +954,9 @@ var EnduserAttributes = {
957
954
  SCOPE: "enduser.scope"
958
955
  };
959
956
 
957
+ // libs/observability/src/otel/spans/auth.span.ts
958
+ var import_api3 = require("@opentelemetry/api");
959
+
960
960
  // libs/observability/src/otel/spans/span.utils.ts
961
961
  var import_api2 = require("@opentelemetry/api");
962
962
  function startSpan(tracer, options) {
@@ -998,7 +998,43 @@ async function withSpan(tracer, options, fn) {
998
998
  });
999
999
  }
1000
1000
 
1001
+ // libs/observability/src/otel/spans/auth.span.ts
1002
+ function startAuthSpan(tracer, options) {
1003
+ return startSpan(tracer, {
1004
+ name: `auth ${options.flowName}`,
1005
+ kind: import_api3.SpanKind.INTERNAL,
1006
+ attributes: {
1007
+ [FrontMcpAttributes.FLOW_NAME]: options.flowName
1008
+ },
1009
+ parentContext: options.parentContext
1010
+ });
1011
+ }
1012
+ function setAuthMode(span, mode) {
1013
+ span.setAttribute(FrontMcpAttributes.AUTH_MODE, mode);
1014
+ }
1015
+ function setAuthResult(span, result) {
1016
+ span.setAttribute(FrontMcpAttributes.AUTH_RESULT, result);
1017
+ }
1018
+
1019
+ // libs/observability/src/otel/spans/fetch.span.ts
1020
+ var import_api4 = require("@opentelemetry/api");
1021
+ function startFetchSpan(tracer, options) {
1022
+ return startSpan(tracer, {
1023
+ name: options.method.toUpperCase(),
1024
+ kind: import_api4.SpanKind.CLIENT,
1025
+ attributes: {
1026
+ [HttpAttributes.METHOD]: options.method.toUpperCase(),
1027
+ [HttpAttributes.URL_FULL]: options.url
1028
+ },
1029
+ parentContext: options.parentContext
1030
+ });
1031
+ }
1032
+ function setFetchResponseStatus(span, statusCode) {
1033
+ span.setAttribute(HttpAttributes.STATUS_CODE, statusCode);
1034
+ }
1035
+
1001
1036
  // libs/observability/src/otel/spans/http-server.span.ts
1037
+ var import_api5 = require("@opentelemetry/api");
1002
1038
  function startHttpServerSpan(tracer, options) {
1003
1039
  const attributes = {
1004
1040
  [HttpAttributes.METHOD]: options.method.toUpperCase(),
@@ -1021,7 +1057,7 @@ function startHttpServerSpan(tracer, options) {
1021
1057
  }
1022
1058
  return startSpan(tracer, {
1023
1059
  name: `${options.method.toUpperCase()} ${options.path}`,
1024
- kind: import_api3.SpanKind.SERVER,
1060
+ kind: import_api5.SpanKind.SERVER,
1025
1061
  attributes,
1026
1062
  parentContext: options.parentContext
1027
1063
  });
@@ -1030,8 +1066,43 @@ function setHttpResponseStatus(span, statusCode) {
1030
1066
  span.setAttribute(HttpAttributes.STATUS_CODE, statusCode);
1031
1067
  }
1032
1068
 
1069
+ // libs/observability/src/otel/spans/prompt.span.ts
1070
+ var import_api6 = require("@opentelemetry/api");
1071
+ function startPromptSpan(tracer, options) {
1072
+ return startSpan(tracer, {
1073
+ name: `prompt ${options.name}`,
1074
+ kind: import_api6.SpanKind.INTERNAL,
1075
+ attributes: {
1076
+ [FrontMcpAttributes.PROMPT_NAME]: options.name,
1077
+ [McpAttributes.COMPONENT_TYPE]: "prompt",
1078
+ [McpAttributes.COMPONENT_KEY]: `prompt:${options.name}`
1079
+ },
1080
+ parentContext: options.parentContext
1081
+ });
1082
+ }
1083
+
1084
+ // libs/observability/src/otel/spans/resource.span.ts
1085
+ var import_api7 = require("@opentelemetry/api");
1086
+ function startResourceSpan(tracer, options) {
1087
+ const attributes = {
1088
+ [FrontMcpAttributes.RESOURCE_URI]: options.uri,
1089
+ [McpAttributes.RESOURCE_URI]: options.uri,
1090
+ [McpAttributes.COMPONENT_TYPE]: "resource",
1091
+ [McpAttributes.COMPONENT_KEY]: `resource:${options.uri}`
1092
+ };
1093
+ if (options.name) {
1094
+ attributes[FrontMcpAttributes.RESOURCE_NAME] = options.name;
1095
+ }
1096
+ return startSpan(tracer, {
1097
+ name: `resource ${options.uri}`,
1098
+ kind: import_api7.SpanKind.INTERNAL,
1099
+ attributes,
1100
+ parentContext: options.parentContext
1101
+ });
1102
+ }
1103
+
1033
1104
  // libs/observability/src/otel/spans/rpc.span.ts
1034
- var import_api4 = require("@opentelemetry/api");
1105
+ var import_api8 = require("@opentelemetry/api");
1035
1106
  function startRpcSpan(tracer, options) {
1036
1107
  const attributes = {
1037
1108
  [RpcAttributes.SYSTEM]: "mcp",
@@ -1055,14 +1126,35 @@ function startRpcSpan(tracer, options) {
1055
1126
  }
1056
1127
  return startSpan(tracer, {
1057
1128
  name: options.method,
1058
- kind: import_api4.SpanKind.SERVER,
1129
+ kind: import_api8.SpanKind.SERVER,
1059
1130
  attributes,
1060
1131
  parentContext: options.parentContext
1061
1132
  });
1062
1133
  }
1063
1134
 
1135
+ // libs/observability/src/otel/spans/startup.span.ts
1136
+ var import_api9 = require("@opentelemetry/api");
1137
+ function emitStartupReport(tracer, data) {
1138
+ const attributes = {
1139
+ [FrontMcpAttributes.STARTUP_TOOLS_COUNT]: data.toolsCount,
1140
+ [FrontMcpAttributes.STARTUP_RESOURCES_COUNT]: data.resourcesCount,
1141
+ [FrontMcpAttributes.STARTUP_PROMPTS_COUNT]: data.promptsCount,
1142
+ [FrontMcpAttributes.STARTUP_PLUGINS_COUNT]: data.pluginsCount,
1143
+ [FrontMcpAttributes.STARTUP_DURATION_MS]: data.durationMs
1144
+ };
1145
+ if (data.scopeId) {
1146
+ attributes[FrontMcpAttributes.SCOPE_ID] = data.scopeId;
1147
+ }
1148
+ const { span } = startSpan(tracer, {
1149
+ name: "frontmcp.startup",
1150
+ kind: import_api9.SpanKind.INTERNAL,
1151
+ attributes
1152
+ });
1153
+ endSpanOk(span);
1154
+ }
1155
+
1064
1156
  // libs/observability/src/otel/spans/tool.span.ts
1065
- var import_api5 = require("@opentelemetry/api");
1157
+ var import_api10 = require("@opentelemetry/api");
1066
1158
  function startToolSpan(tracer, options) {
1067
1159
  const attributes = {
1068
1160
  [FrontMcpAttributes.TOOL_NAME]: options.name,
@@ -1080,49 +1172,14 @@ function startToolSpan(tracer, options) {
1080
1172
  }
1081
1173
  return startSpan(tracer, {
1082
1174
  name: `tool ${options.name}`,
1083
- kind: import_api5.SpanKind.INTERNAL,
1084
- attributes,
1085
- parentContext: options.parentContext
1086
- });
1087
- }
1088
-
1089
- // libs/observability/src/otel/spans/resource.span.ts
1090
- var import_api6 = require("@opentelemetry/api");
1091
- function startResourceSpan(tracer, options) {
1092
- const attributes = {
1093
- [FrontMcpAttributes.RESOURCE_URI]: options.uri,
1094
- [McpAttributes.RESOURCE_URI]: options.uri,
1095
- [McpAttributes.COMPONENT_TYPE]: "resource",
1096
- [McpAttributes.COMPONENT_KEY]: `resource:${options.uri}`
1097
- };
1098
- if (options.name) {
1099
- attributes[FrontMcpAttributes.RESOURCE_NAME] = options.name;
1100
- }
1101
- return startSpan(tracer, {
1102
- name: `resource ${options.uri}`,
1103
- kind: import_api6.SpanKind.INTERNAL,
1175
+ kind: import_api10.SpanKind.INTERNAL,
1104
1176
  attributes,
1105
1177
  parentContext: options.parentContext
1106
1178
  });
1107
1179
  }
1108
1180
 
1109
- // libs/observability/src/otel/spans/prompt.span.ts
1110
- var import_api7 = require("@opentelemetry/api");
1111
- function startPromptSpan(tracer, options) {
1112
- return startSpan(tracer, {
1113
- name: `prompt ${options.name}`,
1114
- kind: import_api7.SpanKind.INTERNAL,
1115
- attributes: {
1116
- [FrontMcpAttributes.PROMPT_NAME]: options.name,
1117
- [McpAttributes.COMPONENT_TYPE]: "prompt",
1118
- [McpAttributes.COMPONENT_KEY]: `prompt:${options.name}`
1119
- },
1120
- parentContext: options.parentContext
1121
- });
1122
- }
1123
-
1124
1181
  // libs/observability/src/otel/spans/transport.span.ts
1125
- var import_api8 = require("@opentelemetry/api");
1182
+ var import_api11 = require("@opentelemetry/api");
1126
1183
  function startTransportSpan(tracer, options) {
1127
1184
  const attributes = {
1128
1185
  [FrontMcpAttributes.TRANSPORT_TYPE]: options.type
@@ -1135,7 +1192,7 @@ function startTransportSpan(tracer, options) {
1135
1192
  }
1136
1193
  return startSpan(tracer, {
1137
1194
  name: `transport ${options.type}`,
1138
- kind: import_api8.SpanKind.INTERNAL,
1195
+ kind: import_api11.SpanKind.INTERNAL,
1139
1196
  attributes,
1140
1197
  parentContext: options.parentContext
1141
1198
  });
@@ -1144,63 +1201,6 @@ function setTransportRequestType(span, requestType) {
1144
1201
  span.setAttribute(FrontMcpAttributes.TRANSPORT_REQUEST_TYPE, requestType);
1145
1202
  }
1146
1203
 
1147
- // libs/observability/src/otel/spans/auth.span.ts
1148
- var import_api9 = require("@opentelemetry/api");
1149
- function startAuthSpan(tracer, options) {
1150
- return startSpan(tracer, {
1151
- name: `auth ${options.flowName}`,
1152
- kind: import_api9.SpanKind.INTERNAL,
1153
- attributes: {
1154
- [FrontMcpAttributes.FLOW_NAME]: options.flowName
1155
- },
1156
- parentContext: options.parentContext
1157
- });
1158
- }
1159
- function setAuthMode(span, mode) {
1160
- span.setAttribute(FrontMcpAttributes.AUTH_MODE, mode);
1161
- }
1162
- function setAuthResult(span, result) {
1163
- span.setAttribute(FrontMcpAttributes.AUTH_RESULT, result);
1164
- }
1165
-
1166
- // libs/observability/src/otel/spans/fetch.span.ts
1167
- var import_api10 = require("@opentelemetry/api");
1168
- function startFetchSpan(tracer, options) {
1169
- return startSpan(tracer, {
1170
- name: options.method.toUpperCase(),
1171
- kind: import_api10.SpanKind.CLIENT,
1172
- attributes: {
1173
- [HttpAttributes.METHOD]: options.method.toUpperCase(),
1174
- [HttpAttributes.URL_FULL]: options.url
1175
- },
1176
- parentContext: options.parentContext
1177
- });
1178
- }
1179
- function setFetchResponseStatus(span, statusCode) {
1180
- span.setAttribute(HttpAttributes.STATUS_CODE, statusCode);
1181
- }
1182
-
1183
- // libs/observability/src/otel/spans/startup.span.ts
1184
- var import_api11 = require("@opentelemetry/api");
1185
- function emitStartupReport(tracer, data) {
1186
- const attributes = {
1187
- [FrontMcpAttributes.STARTUP_TOOLS_COUNT]: data.toolsCount,
1188
- [FrontMcpAttributes.STARTUP_RESOURCES_COUNT]: data.resourcesCount,
1189
- [FrontMcpAttributes.STARTUP_PROMPTS_COUNT]: data.promptsCount,
1190
- [FrontMcpAttributes.STARTUP_PLUGINS_COUNT]: data.pluginsCount,
1191
- [FrontMcpAttributes.STARTUP_DURATION_MS]: data.durationMs
1192
- };
1193
- if (data.scopeId) {
1194
- attributes[FrontMcpAttributes.SCOPE_ID] = data.scopeId;
1195
- }
1196
- const { span } = startSpan(tracer, {
1197
- name: "frontmcp.startup",
1198
- kind: import_api11.SpanKind.INTERNAL,
1199
- attributes
1200
- });
1201
- endSpanOk(span);
1202
- }
1203
-
1204
1204
  // libs/observability/src/plugin/observability.hooks.ts
1205
1205
  var SPAN_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:span");
1206
1206
  var SPAN_CTX_KEY = /* @__PURE__ */ Symbol.for("frontmcp:otel:span-ctx");
@@ -1335,6 +1335,16 @@ function onToolWillCheckAuth(flowCtx) {
1335
1335
  const span = flowCtx.state?.[SPAN_KEY];
1336
1336
  if (span) recordStageEvent(span, "checkToolAuthorization", flowCtx.state);
1337
1337
  }
1338
+ function onEntryWillCheckAuthorities(flowCtx) {
1339
+ const span = flowCtx.state?.[SPAN_KEY];
1340
+ if (span) recordStageEvent(span, "checkEntryAuthorities", flowCtx.state);
1341
+ }
1342
+ function onEntryDidCheckAuthorities(flowCtx) {
1343
+ const span = flowCtx.state?.[SPAN_KEY];
1344
+ if (!span) return;
1345
+ recordStageEvent(span, "checkEntryAuthorities.done", flowCtx.state);
1346
+ span.setAttribute("auth.authorities.result", "granted");
1347
+ }
1338
1348
  function onToolWillCreateContext(flowCtx) {
1339
1349
  const span = flowCtx.state?.[SPAN_KEY];
1340
1350
  if (span) recordStageEvent(span, "createToolCallContext", flowCtx.state);
@@ -1973,6 +1983,12 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
1973
1983
  _toolWillCheckAuth(ctx) {
1974
1984
  if (this.tracingEnabled) onToolWillCheckAuth(ctx);
1975
1985
  }
1986
+ _toolWillCheckAuthorities(ctx) {
1987
+ if (this.tracingEnabled) onEntryWillCheckAuthorities(ctx);
1988
+ }
1989
+ _toolDidCheckAuthorities(ctx) {
1990
+ if (this.tracingEnabled) onEntryDidCheckAuthorities(ctx);
1991
+ }
1976
1992
  _toolWillCreateCtx(ctx) {
1977
1993
  if (this.tracingEnabled) onToolWillCreateContext(ctx);
1978
1994
  }
@@ -2000,6 +2016,12 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
2000
2016
  _resourceWillFind(ctx) {
2001
2017
  if (this.tracingEnabled) onResourceWillFind(ctx);
2002
2018
  }
2019
+ _resourceWillCheckAuthorities(ctx) {
2020
+ if (this.tracingEnabled) onEntryWillCheckAuthorities(ctx);
2021
+ }
2022
+ _resourceDidCheckAuthorities(ctx) {
2023
+ if (this.tracingEnabled) onEntryDidCheckAuthorities(ctx);
2024
+ }
2003
2025
  _resourceWillExecute(ctx) {
2004
2026
  if (this.tracingEnabled) onResourceWillExecute(this.tracingOpts, ctx);
2005
2027
  }
@@ -2015,6 +2037,12 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
2015
2037
  _promptWillFind(ctx) {
2016
2038
  if (this.tracingEnabled) onPromptWillFind(ctx);
2017
2039
  }
2040
+ _promptWillCheckAuthorities(ctx) {
2041
+ if (this.tracingEnabled) onEntryWillCheckAuthorities(ctx);
2042
+ }
2043
+ _promptDidCheckAuthorities(ctx) {
2044
+ if (this.tracingEnabled) onEntryDidCheckAuthorities(ctx);
2045
+ }
2018
2046
  _promptWillExecute(ctx) {
2019
2047
  if (this.tracingEnabled) onPromptWillExecute(this.tracingOpts, ctx);
2020
2048
  }
@@ -2030,6 +2058,12 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
2030
2058
  _agentWillFind(ctx) {
2031
2059
  if (this.tracingEnabled) onAgentWillFind(ctx);
2032
2060
  }
2061
+ _agentWillCheckAuthorities(ctx) {
2062
+ if (this.tracingEnabled) onEntryWillCheckAuthorities(ctx);
2063
+ }
2064
+ _agentDidCheckAuthorities(ctx) {
2065
+ if (this.tracingEnabled) onEntryDidCheckAuthorities(ctx);
2066
+ }
2033
2067
  _agentWillExecute(ctx) {
2034
2068
  if (this.tracingEnabled) onAgentWillExecute(this.tracingOpts, ctx);
2035
2069
  }
@@ -2045,24 +2079,36 @@ var ObservabilityPlugin = class extends import_sdk2.DynamicPlugin {
2045
2079
  _listToolsDidFind(ctx) {
2046
2080
  if (this.tracingEnabled) onGenericFlowStage("findTools", ctx);
2047
2081
  }
2082
+ _listToolsDidFilter(ctx) {
2083
+ if (this.tracingEnabled) onGenericFlowStage("filterByAuthorities", ctx);
2084
+ }
2048
2085
  _listToolsDone(ctx) {
2049
2086
  if (this.tracingEnabled) onGenericFlowDidFinalize(ctx);
2050
2087
  }
2051
2088
  _listResourcesWill(ctx) {
2052
2089
  if (this.tracingEnabled) onGenericFlowWillStart("resources/list", this.tracingOpts, ctx);
2053
2090
  }
2091
+ _listResourcesDidFilter(ctx) {
2092
+ if (this.tracingEnabled) onGenericFlowStage("filterByAuthorities", ctx);
2093
+ }
2054
2094
  _listResourcesDone(ctx) {
2055
2095
  if (this.tracingEnabled) onGenericFlowDidFinalize(ctx);
2056
2096
  }
2057
2097
  _listTemplatesWill(ctx) {
2058
2098
  if (this.tracingEnabled) onGenericFlowWillStart("resources/listTemplates", this.tracingOpts, ctx);
2059
2099
  }
2100
+ _listTemplatesDidFilter(ctx) {
2101
+ if (this.tracingEnabled) onGenericFlowStage("filterByAuthorities", ctx);
2102
+ }
2060
2103
  _listTemplatesDone(ctx) {
2061
2104
  if (this.tracingEnabled) onGenericFlowDidFinalize(ctx);
2062
2105
  }
2063
2106
  _listPromptsWill(ctx) {
2064
2107
  if (this.tracingEnabled) onGenericFlowWillStart("prompts/list", this.tracingOpts, ctx);
2065
2108
  }
2109
+ _listPromptsDidFilter(ctx) {
2110
+ if (this.tracingEnabled) onGenericFlowStage("filterByAuthorities", ctx);
2111
+ }
2066
2112
  _listPromptsDone(ctx) {
2067
2113
  if (this.tracingEnabled) onGenericFlowDidFinalize(ctx);
2068
2114
  }
@@ -2376,6 +2422,12 @@ __decorateClass([
2376
2422
  __decorateClass([
2377
2423
  import_sdk2.ToolHook.Will("checkToolAuthorization", { priority: -1e3 })
2378
2424
  ], ObservabilityPlugin.prototype, "_toolWillCheckAuth", 1);
2425
+ __decorateClass([
2426
+ import_sdk2.ToolHook.Will("checkEntryAuthorities", { priority: -1e3 })
2427
+ ], ObservabilityPlugin.prototype, "_toolWillCheckAuthorities", 1);
2428
+ __decorateClass([
2429
+ import_sdk2.ToolHook.Did("checkEntryAuthorities", { priority: 1e3 })
2430
+ ], ObservabilityPlugin.prototype, "_toolDidCheckAuthorities", 1);
2379
2431
  __decorateClass([
2380
2432
  import_sdk2.ToolHook.Will("createToolCallContext", { priority: -1e3 })
2381
2433
  ], ObservabilityPlugin.prototype, "_toolWillCreateCtx", 1);
@@ -2403,6 +2455,12 @@ __decorateClass([
2403
2455
  __decorateClass([
2404
2456
  import_sdk2.ResourceHook.Will("findResource", { priority: -1e3 })
2405
2457
  ], ObservabilityPlugin.prototype, "_resourceWillFind", 1);
2458
+ __decorateClass([
2459
+ import_sdk2.ResourceHook.Will("checkEntryAuthorities", { priority: -1e3 })
2460
+ ], ObservabilityPlugin.prototype, "_resourceWillCheckAuthorities", 1);
2461
+ __decorateClass([
2462
+ import_sdk2.ResourceHook.Did("checkEntryAuthorities", { priority: 1e3 })
2463
+ ], ObservabilityPlugin.prototype, "_resourceDidCheckAuthorities", 1);
2406
2464
  __decorateClass([
2407
2465
  import_sdk2.ResourceHook.Will("execute", { priority: -1e3 })
2408
2466
  ], ObservabilityPlugin.prototype, "_resourceWillExecute", 1);
@@ -2418,6 +2476,12 @@ __decorateClass([
2418
2476
  __decorateClass([
2419
2477
  PromptHook.Will("findPrompt", { priority: -1e3 })
2420
2478
  ], ObservabilityPlugin.prototype, "_promptWillFind", 1);
2479
+ __decorateClass([
2480
+ PromptHook.Will("checkEntryAuthorities", { priority: -1e3 })
2481
+ ], ObservabilityPlugin.prototype, "_promptWillCheckAuthorities", 1);
2482
+ __decorateClass([
2483
+ PromptHook.Did("checkEntryAuthorities", { priority: 1e3 })
2484
+ ], ObservabilityPlugin.prototype, "_promptDidCheckAuthorities", 1);
2421
2485
  __decorateClass([
2422
2486
  PromptHook.Will("execute", { priority: -1e3 })
2423
2487
  ], ObservabilityPlugin.prototype, "_promptWillExecute", 1);
@@ -2433,6 +2497,12 @@ __decorateClass([
2433
2497
  __decorateClass([
2434
2498
  import_sdk2.AgentCallHook.Will("findAgent", { priority: -1e3 })
2435
2499
  ], ObservabilityPlugin.prototype, "_agentWillFind", 1);
2500
+ __decorateClass([
2501
+ import_sdk2.AgentCallHook.Will("checkEntryAuthorities", { priority: -1e3 })
2502
+ ], ObservabilityPlugin.prototype, "_agentWillCheckAuthorities", 1);
2503
+ __decorateClass([
2504
+ import_sdk2.AgentCallHook.Did("checkEntryAuthorities", { priority: 1e3 })
2505
+ ], ObservabilityPlugin.prototype, "_agentDidCheckAuthorities", 1);
2436
2506
  __decorateClass([
2437
2507
  import_sdk2.AgentCallHook.Will("execute", { priority: -1e3 })
2438
2508
  ], ObservabilityPlugin.prototype, "_agentWillExecute", 1);
@@ -2448,24 +2518,36 @@ __decorateClass([
2448
2518
  __decorateClass([
2449
2519
  import_sdk2.ListToolsHook.Did("findTools", { priority: 1e3 })
2450
2520
  ], ObservabilityPlugin.prototype, "_listToolsDidFind", 1);
2521
+ __decorateClass([
2522
+ import_sdk2.ListToolsHook.Did("filterByAuthorities", { priority: 1e3 })
2523
+ ], ObservabilityPlugin.prototype, "_listToolsDidFilter", 1);
2451
2524
  __decorateClass([
2452
2525
  import_sdk2.ListToolsHook.Did("parseTools", { priority: 1e3 })
2453
2526
  ], ObservabilityPlugin.prototype, "_listToolsDone", 1);
2454
2527
  __decorateClass([
2455
2528
  import_sdk2.ListResourcesHook.Will("parseInput", { priority: -1e3 })
2456
2529
  ], ObservabilityPlugin.prototype, "_listResourcesWill", 1);
2530
+ __decorateClass([
2531
+ import_sdk2.ListResourcesHook.Did("filterByAuthorities", { priority: 1e3 })
2532
+ ], ObservabilityPlugin.prototype, "_listResourcesDidFilter", 1);
2457
2533
  __decorateClass([
2458
2534
  import_sdk2.ListResourcesHook.Did("parseResources", { priority: 1e3 })
2459
2535
  ], ObservabilityPlugin.prototype, "_listResourcesDone", 1);
2460
2536
  __decorateClass([
2461
2537
  import_sdk2.ListResourceTemplatesHook.Will("parseInput", { priority: -1e3 })
2462
2538
  ], ObservabilityPlugin.prototype, "_listTemplatesWill", 1);
2539
+ __decorateClass([
2540
+ import_sdk2.ListResourceTemplatesHook.Did("filterByAuthorities", { priority: 1e3 })
2541
+ ], ObservabilityPlugin.prototype, "_listTemplatesDidFilter", 1);
2463
2542
  __decorateClass([
2464
2543
  import_sdk2.ListResourceTemplatesHook.Did("parseTemplates", { priority: 1e3 })
2465
2544
  ], ObservabilityPlugin.prototype, "_listTemplatesDone", 1);
2466
2545
  __decorateClass([
2467
2546
  ListPromptsHook.Will("parseInput", { priority: -1e3 })
2468
2547
  ], ObservabilityPlugin.prototype, "_listPromptsWill", 1);
2548
+ __decorateClass([
2549
+ ListPromptsHook.Did("filterByAuthorities", { priority: 1e3 })
2550
+ ], ObservabilityPlugin.prototype, "_listPromptsDidFilter", 1);
2469
2551
  __decorateClass([
2470
2552
  ListPromptsHook.Did("parsePrompts", { priority: 1e3 })
2471
2553
  ], ObservabilityPlugin.prototype, "_listPromptsDone", 1);