Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.agentfront.dev/llms.txt

Use this file to discover all available pages before exploring further.

The this.telemetry API is available on all execution contexts (ToolContext, ResourceContext, PromptContext, AgentContext) when observability is enabled. It provides a simple interface for creating custom spans, recording events, and setting attributes — with automatic trace context propagation.
Requires @frontmcp/observability installed and observability config enabled. See the Observability Guide for setup.

TelemetryAccessor

Available as this.telemetry in all execution contexts. One instance per request (context-scoped). Automatically inherits the current request’s trace ID, session ID, and scope.

startSpan(name, attributes?)

Create a child span under the current execution span.
startSpan(name: string, attributes?: Record<string, string | number | boolean>): TelemetrySpan
You must call span.end() or span.endWithError() when done.
const span = this.telemetry.startSpan('fetch-user', { 'user.id': userId });
try {
  const user = await this.fetch(`/api/users/${userId}`);
  span.setAttribute('user.name', user.name);
  span.end();
} catch (err) {
  span.endWithError(err);
  throw err;
}

withSpan(name, fn, attributes?)

Run a function within a span. The span is automatically ended on success or error.
withSpan<T>(
  name: string,
  fn: (span: TelemetrySpan) => Promise<T>,
  attributes?: Record<string, string | number | boolean>,
): Promise<T>
const data = await this.telemetry.withSpan('query-database', async (span) => {
  span.addEvent('query-sent');
  const results = await db.query(sql);
  span.setAttribute('rows', results.length);
  return results;
});

addEvent(name, attributes?)

Add an event to the active flow execution span (e.g., the tool span during execute()).
addEvent(name: string, attributes?: Record<string, string | number | boolean>): void
Events are lightweight markers that appear on the parent span’s timeline. Use them for milestones rather than creating child spans.
this.telemetry.addEvent('cache-checked', { hit: false });
this.telemetry.addEvent('validation-complete', { fields: 5 });
Events go on the active execution span, not a new span. If called during tool.execute(), they appear on the "tool my_tool" span. If called outside an execution context, a short-lived child span is created as a fallback.

setAttributes(attrs)

Set attributes on the active flow execution span.
setAttributes(attrs: Record<string, string | number | boolean>): void
this.telemetry.setAttributes({
  'user.tier': 'premium',
  'request.size': body.length,
  'cache.hit': true,
});

traceId

Get the current request’s trace ID. Useful for including in external API calls or logs.
get traceId(): string
const response = await this.fetch('/api/data', {
  headers: { 'X-Trace-Id': this.telemetry.traceId },
});

sessionId

Get the privacy-safe session tracing ID (16-char SHA-256 hash).
get sessionId(): string

TelemetrySpan

Returned by startSpan() and passed to withSpan() callbacks. All setter methods return this for chaining.

Methods

MethodSignatureDescription
setAttribute(key: string, value: string | number | boolean) => thisSet a single attribute
setAttributes(attrs: Record<string, string | number | boolean>) => thisSet multiple attributes
addEvent(name: string, attributes?: Record<...>) => thisAdd a named event
recordError(error: Error) => thisRecord an exception on the span
end() => voidEnd the span with OK status
endWithError(error: Error | string) => voidEnd with ERROR status
rawSpan (getter)Access the underlying OTel Span
const span = this.telemetry.startSpan('process');
span
  .setAttribute('input.size', 1024)
  .addEvent('step-1-done')
  .addEvent('step-2-done', { items: 42 });

if (failed) {
  span.recordError(new Error('processing failed'));
}

span.end(); // Preserves ERROR status if recordError was called

Testing Utilities

Import from @frontmcp/observability:
import {
  createTestTracer,
  getFinishedSpans,
  assertSpanExists,
  assertSpanAttribute,
  findSpan,
  findSpansByAttribute,
} from '@frontmcp/observability';

createTestTracer(name?)

Create an isolated test tracer with in-memory span exporter. Does not register globally — safe for parallel tests.
function createTestTracer(name?: string): {
  tracer: Tracer;
  exporter: InMemorySpanExporter;
  provider: BasicTracerProvider;
  cleanup: () => Promise<void>;
}
const { tracer, exporter, cleanup } = createTestTracer();

afterEach(() => exporter.reset());
afterAll(() => cleanup());

assertSpanExists(spans, name)

Assert that a span with the given name exists. Returns the span or throws.
function assertSpanExists(spans: ReadableSpan[], name: string): ReadableSpan
const spans = getFinishedSpans(exporter);
const toolSpan = assertSpanExists(spans, 'tool get_weather');

assertSpanAttribute(span, key, value)

Assert a span has a specific attribute value.
function assertSpanAttribute(span: ReadableSpan, key: string, value: string | number | boolean): void

findSpan(spans, name) / findSpansByAttribute(spans, key, value)

Query helpers for finding spans in test assertions.
const dbSpan = findSpan(spans, 'database-query');
const toolSpans = findSpansByAttribute(spans, 'mcp.component.type', 'tool');

Configuration Types

ObservabilityOptionsInterface

The config object for @FrontMcp({ observability: { ... } }):
PropertyTypeDefaultDescription
tracingboolean | TracingOptionstrueEnable/configure OTel tracing
loggingboolean | LoggingOptionsfalseEnable/configure structured logging
requestLogsboolean | RequestLogOptionsfalseEnable/configure per-request log collection

TracingOptions

PropertyTypeDefaultDescription
httpSpansbooleantrueHTTP request spans
executionSpansbooleantrueTool/resource/prompt/agent spans
fetchSpansbooleantrueOutbound ctx.fetch() spans
flowStageEventsbooleantrueFlow stage events on execution spans
hookSpansbooleanfalseIndividual hook spans (verbose)
transportSpansbooleantrueSSE/HTTP transport spans
authSpansbooleantrueAuth/session verify spans
oauthSpansbooleantrueOAuth flow spans
elicitationSpansbooleantrueElicitation request/result spans
startupReportbooleantrueEmit startup telemetry on first request

SinkConfig

TypeDescriptionPlatform
{ type: 'stdout' }NDJSON to stdout (12-factor)Node.js
{ type: 'console' }console.log/warn/errorBrowser, Node.js
{ type: 'otlp', endpoint, headers? }OTLP HTTP to any backendNode.js
{ type: 'winston', logger }Forward to winston instanceNode.js
{ type: 'pino', logger }Forward to pino instanceNode.js
{ type: 'callback', fn }Custom callback functionAny

Observability Guide

Step-by-step setup with vendor integrations

Observability Feature

Overview of what FrontMCP observability provides