@frontmcp/observability 1.11.2 → 1.12.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -9,7 +9,7 @@ export declare function createSink(config: SinkConfig): LogSink;
9
9
  /**
10
10
  * Create an array of LogSink instances from an array of SinkConfig.
11
11
  *
12
- * If no configs are provided, defaults to StdoutSink in Node.js
13
- * or ConsoleSink in browser environments.
12
+ * Without configs it returns no sinks; `@FrontMcp({ observability: { logging } })` passes a stdout sink
13
+ * (a console sink in a browser) when `logging` names none.
14
14
  */
15
15
  export declare function createSinks(configs?: SinkConfig[]): LogSink[];
@@ -5,7 +5,7 @@
5
5
  * This propagator uses the existing FrontMCP trace context parser
6
6
  * to extract and inject W3C traceparent headers.
7
7
  */
8
- import { type Context, type TextMapGetter, type TextMapSetter, type TextMapPropagator } from '@opentelemetry/api';
8
+ import { type Context, type TextMapGetter, type TextMapPropagator, type TextMapSetter } from '@opentelemetry/api';
9
9
  /**
10
10
  * FrontMcpPropagator — OTel TextMapPropagator that reads/writes
11
11
  * the W3C traceparent header using the same format as the SDK.
@@ -61,7 +61,7 @@ export declare const FrontMcpAttributes: {
61
61
  readonly SESSION_CREATED: "frontmcp.session.created";
62
62
  /** Auth mode: "public" | "transparent" | "orchestrated" */
63
63
  readonly AUTH_MODE: "frontmcp.auth.mode";
64
- /** Auth result: "authorized" | "unauthorized" | "anonymous" */
64
+ /** Auth result: "authorized" | "anonymous" | "unauthorized" | "forbidden" | "error" */
65
65
  readonly AUTH_RESULT: "frontmcp.auth.result";
66
66
  /** OAuth grant type: "authorization_code" | "refresh_token" | "anonymous" */
67
67
  readonly OAUTH_GRANT_TYPE: "frontmcp.oauth.grant_type";
@@ -127,7 +127,7 @@ export interface TracingOptions {
127
127
  flowStageEvents?: boolean;
128
128
  /** Instrument transport flows — SSE, streamable-http, stateless-http (default: true) */
129
129
  transportSpans?: boolean;
130
- /** Instrument auth verify/session verify flows (default: true) */
130
+ /** An `auth session:verify` span for each HTTP request's authentication, with `frontmcp.auth.result` (default: true) */
131
131
  authSpans?: boolean;
132
132
  /** Instrument OAuth flows — token, authorize, callback, register (default: true) */
133
133
  oauthSpans?: boolean;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Auth Span — authentication and session verification instrumentation.
3
3
  */
4
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
4
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
5
5
  export interface AuthSpanOptions {
6
6
  /** Auth flow name (e.g., "auth:verify", "session:verify") */
7
7
  flowName: string;
@@ -4,7 +4,7 @@
4
4
  * Wraps fetch() calls made via FrontMcpContext.fetch() to create
5
5
  * client HTTP spans following OTel HTTP semantic conventions.
6
6
  */
7
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
7
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
8
8
  export interface FetchSpanOptions {
9
9
  /** HTTP method */
10
10
  method: string;
@@ -5,7 +5,7 @@
5
5
  * to keep trace depth manageable. When hookSpans is enabled, each hook
6
6
  * gets its own child span.
7
7
  */
8
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
8
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
9
9
  export interface HookSpanOptions {
10
10
  /** Hook stage name (e.g., "willExecute") */
11
11
  stage: string;
@@ -3,7 +3,7 @@
3
3
  *
4
4
  * @see https://opentelemetry.io/docs/specs/semconv/http/http-spans/
5
5
  */
6
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
6
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
7
7
  export interface HttpServerSpanOptions {
8
8
  method: string;
9
9
  path: string;
@@ -8,8 +8,8 @@
8
8
  * ↳ SPAN tools/call [36008509] 8ms rpc.system=mcp mcp.session.id=5bfdd288
9
9
  * ↳ SPAN tool get_weather [36008509] 5ms mcp.component.type=tool enduser.id=client-42
10
10
  */
11
- import type { SpanExporter, ReadableSpan } from '@opentelemetry/sdk-trace-base';
12
11
  import type { ExportResult } from '@opentelemetry/core';
12
+ import type { ReadableSpan, SpanExporter } from '@opentelemetry/sdk-trace-base';
13
13
  export declare class PrettySpanExporter implements SpanExporter {
14
14
  private useAnsi;
15
15
  constructor();
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Prompt Span — FrontMCP prompt invocation instrumentation.
3
3
  */
4
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
4
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
5
5
  export interface PromptSpanOptions {
6
6
  /** Prompt name */
7
7
  name: string;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Resource Read Span — FrontMCP resource read instrumentation.
3
3
  */
4
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
4
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
5
5
  export interface ResourceSpanOptions {
6
6
  /** Resource URI */
7
7
  uri: string;
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * @see https://opentelemetry.io/docs/specs/semconv/rpc/rpc-spans/
9
9
  */
10
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
10
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
11
11
  export interface RpcSpanOptions {
12
12
  /** MCP method (e.g., "tools/call", "resources/read") */
13
13
  method: string;
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Span utility helpers for creating and managing OTel spans.
3
3
  */
4
- import { type Tracer, type Span, type Context, SpanKind } from '@opentelemetry/api';
4
+ import { SpanKind, type Context, type Span, type Tracer } from '@opentelemetry/api';
5
5
  /**
6
6
  * Options for starting a span.
7
7
  */
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tool Execution Span — FrontMCP tool invocation instrumentation.
3
3
  */
4
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
4
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
5
5
  export interface ToolSpanOptions {
6
6
  /** Tool name */
7
7
  name: string;
@@ -4,7 +4,7 @@
4
4
  * Created for each transport-level flow that handles session creation,
5
5
  * protocol routing, and message dispatch.
6
6
  */
7
- import { type Tracer, type Span, type Context } from '@opentelemetry/api';
7
+ import { type Context, type Span, type Tracer } from '@opentelemetry/api';
8
8
  export interface TransportSpanOptions {
9
9
  /** Transport type: "legacy-sse" | "streamable-http" | "stateless-http" */
10
10
  type: string;
@@ -6,7 +6,7 @@
6
6
  * This bridge allows OTel spans to be created as children of
7
7
  * the existing trace, preserving the trace ID across the boundary.
8
8
  */
9
- import { type SpanContext, type Context as OTelContext } from '@opentelemetry/api';
9
+ import { type Context as OTelContext, type SpanContext } from '@opentelemetry/api';
10
10
  /**
11
11
  * Minimal TraceContext interface — matches the SDK's TraceContext type
12
12
  * without importing it directly.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@frontmcp/observability",
3
- "version": "1.11.2",
3
+ "version": "1.12.0-rc.1",
4
4
  "description": "OpenTelemetry tracing, structured JSON logging, request logs and Prometheus-format metrics for FrontMCP servers",
5
5
  "author": "AgentFront <info@agentfront.dev>",
6
6
  "license": "Apache-2.0",
@@ -53,8 +53,8 @@
53
53
  "@opentelemetry/api": "^1.9.0"
54
54
  },
55
55
  "peerDependencies": {
56
- "@frontmcp/sdk": "1.11.2",
57
- "@frontmcp/utils": "1.11.2",
56
+ "@frontmcp/sdk": "1.12.0-rc.1",
57
+ "@frontmcp/utils": "1.12.0-rc.1",
58
58
  "@opentelemetry/exporter-trace-otlp-http": "^0.219.0",
59
59
  "@opentelemetry/sdk-node": "^0.219.0",
60
60
  "@opentelemetry/sdk-trace-base": "^2.8.0",
@@ -99,10 +99,10 @@ export declare function onTransportWillStart(transportType: string, options: Tra
99
99
  export declare function onTransportDidRoute(flowCtx: any): void;
100
100
  export declare function onTransportStage(stageName: string, flowCtx: any): void;
101
101
  export declare function onTransportDidFinalize(flowCtx: any): void;
102
- export declare function onAuthWillStart(flowName: string, options: TracingOptions, flowCtx: any): void;
103
- export declare function onAuthDidDetermineMode(flowCtx: any): void;
104
- export declare function onAuthStage(stageName: string, flowCtx: any): void;
105
- export declare function onAuthDidFinalize(flowCtx: any): void;
102
+ /** Opens the `auth session:verify` span of the request's authentication, inside its HTTP span. */
103
+ export declare function onHttpWillAuthenticate(options: TracingOptions, flowCtx: any): void;
104
+ /** Ends the authentication span, whatever the stage's outcome, with `frontmcp.auth.result`. */
105
+ export declare function onHttpDidAuthenticate(flowCtx: any): void;
106
106
  export declare function wrapContextFetch(options: TracingOptions, flowCtx: any): void;
107
107
  export declare function onAgentDidExecuteEnrich(flowCtx: any): void;
108
108
  export type { HookObserver };
@@ -12,7 +12,7 @@ import type { ObservabilityPluginOptions, ObservabilityPluginOptionsInput } from
12
12
  * - Prompt invocations (parseInput → find → execute → validate → finalize)
13
13
  * - Agent calls (parseInput → find → auth → validate → execute → finalize)
14
14
  * - Skills (search, load)
15
- * - List operations (tools, resources, prompts, resource templates)
15
+ * - List operations (tools, resources, prompts, resource templates, events)
16
16
  * - Completions
17
17
  * - Session lifecycle (creation, auth verification)
18
18
  *
@@ -39,6 +39,7 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
39
39
  _httpDidSemaphore(ctx: unknown): void;
40
40
  _httpWillAuth(ctx: unknown): void;
41
41
  _httpDidAuth(ctx: unknown): void;
42
+ _httpFinallyAuth(ctx: unknown): void;
42
43
  _httpWillRoute(ctx: unknown): void;
43
44
  _httpDidRoute(ctx: unknown): void;
44
45
  _httpFinallyFinalize(ctx: unknown): void;
@@ -88,6 +89,52 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
88
89
  _listPromptsWill(ctx: unknown): void;
89
90
  _listPromptsDidFilter(ctx: unknown): void;
90
91
  _listPromptsDone(ctx: unknown): void;
92
+ /** Start the events/list span. */
93
+ _listEventsWill(ctx: unknown): void;
94
+ /** Record the filterByAuthorities stage on the events/list span. */
95
+ _listEventsDidFilter(ctx: unknown): void;
96
+ /** End the events/list span, however the listing ended. */
97
+ _listEventsDone(ctx: unknown): void;
98
+ /** Start the events/subscribe span. */
99
+ _eventSubscribeWill(ctx: unknown): void;
100
+ /** Record the verifyCallback stage on the events/subscribe span. */
101
+ _eventSubscribeDidVerify(ctx: unknown): void;
102
+ /** End the events/subscribe span, however the subscribe ended. */
103
+ _eventSubscribeDone(ctx: unknown): void;
104
+ /** Start the events/unsubscribe span. */
105
+ _eventUnsubscribeWill(ctx: unknown): void;
106
+ /** End the events/unsubscribe span, however the unsubscribe ended. */
107
+ _eventUnsubscribeDone(ctx: unknown): void;
108
+ /** Start the events/publish span. */
109
+ _eventPublishWill(ctx: unknown): void;
110
+ /** Record the match stage on the events/publish span. */
111
+ _eventPublishDidMatch(ctx: unknown): void;
112
+ /** End the events/publish span once its result is built. */
113
+ _eventPublishDone(ctx: unknown): void;
114
+ /** Starts the span of a request to the HTTP publish endpoint. */
115
+ _eventPublishHttpWill(ctx: unknown): void;
116
+ /** Marks on the span that the endpoint knows its caller. */
117
+ _eventPublishHttpDidAuthenticate(ctx: unknown): void;
118
+ /** Ends the span, however the request ended. */
119
+ _eventPublishHttpDone(ctx: unknown): void;
120
+ /** Start the events/deliver span. */
121
+ _eventDeliverWill(ctx: unknown): void;
122
+ /** Record the send stage on the events/deliver span. */
123
+ _eventDeliverDidSend(ctx: unknown): void;
124
+ /** End the events/deliver span once its result is built. */
125
+ _eventDeliverDone(ctx: unknown): void;
126
+ /** Start the events/poll span. */
127
+ _eventPollWill(ctx: unknown): void;
128
+ /** Record the readEvents stage on the events/poll span. */
129
+ _eventPollDidRead(ctx: unknown): void;
130
+ /** End the events/poll span, however the poll ended. */
131
+ _eventPollDone(ctx: unknown): void;
132
+ /** Start the events/stream span. */
133
+ _eventStreamWill(ctx: unknown): void;
134
+ /** Record the openStream stage on the events/stream span. */
135
+ _eventStreamDidOpen(ctx: unknown): void;
136
+ /** End the events/stream span, however the stream ended. */
137
+ _eventStreamDone(ctx: unknown): void;
91
138
  _skillSearchWill(ctx: unknown): void;
92
139
  _skillSearchDone(ctx: unknown): void;
93
140
  _skillLoadWill(ctx: unknown): void;
@@ -112,13 +159,6 @@ export default class ObservabilityPlugin extends DynamicPlugin<ObservabilityPlug
112
159
  _slhttpWillParse(ctx: unknown): void;
113
160
  _slhttpDidHandle(ctx: unknown): void;
114
161
  _slhttpFinallyCleanup(ctx: unknown): void;
115
- _authVerifyWill(ctx: unknown): void;
116
- _authVerifyDidMode(ctx: unknown): void;
117
- _authVerifyDidToken(ctx: unknown): void;
118
- _authVerifyDidBuild(ctx: unknown): void;
119
- _sessionVerifyWill(ctx: unknown): void;
120
- _sessionVerifyDidJwt(ctx: unknown): void;
121
- _sessionVerifyDidBuild(ctx: unknown): void;
122
162
  _oauthTokenWill(ctx: unknown): void;
123
163
  _oauthTokenDone(ctx: unknown): void;
124
164
  _oauthAuthzWill(ctx: unknown): void;
@@ -21,7 +21,7 @@ export interface ObservabilityPluginOptions {
21
21
  * Logging options within the plugin.
22
22
  */
23
23
  export interface ObservabilityLoggingOptions {
24
- /** Sink configurations (default: StdoutSink in Node.js, ConsoleSink in browser) */
24
+ /** Sink configurations; through `@FrontMcp({ observability })`, a stdout sink (console in a browser) when omitted */
25
25
  sinks?: SinkConfig[];
26
26
  /** Field names to redact from log attributes */
27
27
  redactFields?: string[];
@@ -1,3 +1,3 @@
1
- export type { RequestLog, RequestLogEntry, RequestLogCollectorOptions } from './request-log.types';
1
+ export type { RequestLog, RequestLogEntry, RequestLogCollectorOptions, RequestLogSummary } from './request-log.types';
2
2
  export { RequestLogCollector } from './request-log.collector';
3
3
  export { REQUEST_LOG_COLLECTOR } from './request-log.tokens';
@@ -10,6 +10,7 @@ export declare class RequestLogCollector {
10
10
  private readonly entries;
11
11
  private readonly hooksTriggered;
12
12
  private readonly maxEntries;
13
+ private readonly includeSummaries;
13
14
  private readonly onComplete?;
14
15
  private readonly requestId;
15
16
  private readonly traceId;
@@ -27,6 +28,8 @@ export declare class RequestLogCollector {
27
28
  private status;
28
29
  private statusCode?;
29
30
  private error?;
31
+ private inputSummary?;
32
+ private outputSummary?;
30
33
  private finalized;
31
34
  private finalizedLog?;
32
35
  constructor(context: {
@@ -65,6 +68,14 @@ export declare class RequestLogCollector {
65
68
  * Set the prompt name being invoked.
66
69
  */
67
70
  setPromptName(name: string): void;
71
+ /**
72
+ * Summarize the call's arguments, with `includeSummaries`.
73
+ */
74
+ setInput(args: unknown): void;
75
+ /**
76
+ * Summarize the call's result, with `includeSummaries`.
77
+ */
78
+ setOutput(result: unknown): void;
68
79
  /**
69
80
  * Set authentication info.
70
81
  */
@@ -21,6 +21,8 @@ export declare function currentRequestLog(flowCtx: RequestLogFlowContext): Reque
21
21
  export declare function startRequestLog(flowCtx: RequestLogFlowContext, options: RequestLogCollectorOptions): void;
22
22
  /** Records why an entry flow failed (its `state.flowError`) on the request's log, as the client sees it. */
23
23
  export declare function recordRequestLogFailure(flowCtx: RequestLogFlowContext): void;
24
+ /** Summarizes an entry flow's answer (its `state.output`) on the request's log, with `includeSummaries`. */
25
+ export declare function recordRequestLogOutput(flowCtx: RequestLogFlowContext): void;
24
26
  /**
25
27
  * Records how the HTTP flow authenticated the request (its `state.verifyResult`): `auth_type` is the scheme of
26
28
  * the `Authorization` header (`bearer`), or `anonymous` for a caller without one or with an anonymous subject.
@@ -0,0 +1,5 @@
1
+ import type { RequestLogSummary } from './request-log.types';
2
+ /** The argument names and size of a call's arguments. */
3
+ export declare function summarizeInput(args: unknown): RequestLogSummary;
4
+ /** The size, content types, `structuredContent` keys and error flag of a call's result. */
5
+ export declare function summarizeOutput(result: unknown): RequestLogSummary;
@@ -68,6 +68,23 @@ export interface RequestLog {
68
68
  hooks_triggered: string[];
69
69
  /** All structured log entries for this request */
70
70
  entries: RequestLogEntry[];
71
+ /** The arguments of a `tools/call` or `prompts/get`, without their values */
72
+ input_summary?: RequestLogSummary;
73
+ /** The result of a `tools/call`, `resources/read` or `prompts/get`, without its content */
74
+ output_summary?: RequestLogSummary;
75
+ }
76
+ /**
77
+ * The shape and size of a call's arguments or result, never its values.
78
+ */
79
+ export interface RequestLogSummary {
80
+ /** Size of the value as JSON, in bytes */
81
+ bytes?: number;
82
+ /** The argument names of an input; the `structuredContent` keys of a tool's result */
83
+ keys?: string[];
84
+ /** The content types of a result: `text`, `image`, … for a tool or prompt, each content's `mimeType` for a resource */
85
+ content_types?: string[];
86
+ /** Whether a tool's result is an error result */
87
+ is_error?: boolean;
71
88
  }
72
89
  /**
73
90
  * Options for RequestLogCollector.
@@ -75,7 +92,10 @@ export interface RequestLog {
75
92
  export interface RequestLogCollectorOptions {
76
93
  /** Maximum entries to collect per request (default: 500) */
77
94
  maxEntries?: number;
78
- /** Accepted, but not read yet: request logs carry no input or output summaries. */
95
+ /**
96
+ * Add `input_summary` and `output_summary` to the log of a `tools/call`, `resources/read` or `prompts/get`: the
97
+ * argument names, result keys, content types and sizes, never the values (default: false).
98
+ */
79
99
  includeSummaries?: boolean;
80
100
  /** Callback when request log is complete */
81
101
  onRequestComplete?: (log: RequestLog) => void | Promise<void>;