Skip to main content
This guide walks through adding production-grade observability to your FrontMCP server — from zero-config tracing to connecting Coralogix, Datadog, or any OTLP-compatible backend.
Prerequisites: A working FrontMCP server with at least one tool. See Your First Tool if you need to get started.

What You’ll Get

  • Automatic spans for every tool call, resource read, auth flow, and HTTP request
  • Structured JSON logs with trace correlation (trace_id, span_id)
  • this.telemetry API for custom spans in your tools and plugins
  • Per-request log aggregation

Step 1: Install

This installs the observability package with @opentelemetry/api as the only hard dependency (~50KB). OTel SDK packages are optional peers — install only what you need.

Step 2: Enable Observability

Add the observability field to your @FrontMcp config:
That’s it. Every flow is now instrumented. Without a TracerProvider configured, all OTel calls are no-ops with zero overhead.
For fine-grained control, pass an object instead of true:

Step 3: Configure a Backend

The @FrontMcp({ ... }) snippets below show only the observability block for brevity. Your full config still needs info: { name, version } and the rest of your server fields.
See spans printed to your terminal — great for development:

Step 4: Use this.telemetry in Tools

Every execution context (tools, resources, prompts, agents) gets a this.telemetry API when observability is enabled. No context construction: it inherits the current request’s trace. observability: true installs this.telemetry at runtime, but its type comes from @frontmcp/observability, which declares it on ExecutionContextBase and PromptContext with a declare module '@frontmcp/sdk' augmentation. TypeScript applies that augmentation only when the package is part of the compilation, so import it in the file that uses this.telemetry (a type-only import is enough, and is erased at runtime), or once in any file the project compiles, such as the server entry:
This produces:

Step 5: Structured Logging

When logging is enabled, every this.logger.info() call produces a structured JSON entry with automatic trace correlation:
Configure redaction for sensitive fields:

Step 6: Request Log Collection

Enable requestLogs to get a complete aggregated view of each request:
A request’s log opens when its HTTP request starts and closes when the HTTP response is finalized, which calls onRequestComplete once with the HTTP method and path, the JSON-RPC method, the tool, resource or prompt it served, the entries logged while it ran, its status (error for an HTTP status of 400 or more, or when the tool, resource or prompt failed, with the failure in error; status_code is the status the server actually answered with, a 401 from authentication or a 429 from the throttle included) and its duration. The callback runs off the response path: the response is sent without waiting for it. Up to 1.9.1 the callback never fired. A tool, resource or prompt that fails ends its spans with an error status, the execution span included; up to 1.9.1 a failed tool’s span was left open and never exported. The “tracing enabled but no TracerProvider configured” warning appears only when no provider is registered; up to 1.9.1 it appeared even after setupOTel() or another SDK registered one.

Step 7: Testing with Telemetry

Use the built-in testing utilities to verify your spans:

Span Hierarchy

Every request produces a span tree like this:

Attributes Reference

MCP Protocol Attributes (interoperable)

Standard OTel Attributes

FrontMCP Vendor Attributes


Best Practices

Don’t create spans with raw OTel API. Use this.telemetry.withSpan() or this.telemetry.startSpan() — they automatically inherit the trace context and add base attributes.
this.telemetry.addEvent('step-done') is cheaper than this.telemetry.startSpan('step'). Use events for milestones, spans for timed operations.
Always configure redactFields in production: ['password', 'token', 'secret', 'authorization', 'cookie'].
The otlp sink type works with all major platforms (Coralogix, Datadog, Logz.io, Grafana). Don’t build vendor-specific integrations.
The auto-instrumentation covers all SDK flows. Only add this.telemetry spans for your business logic operations (API calls, database queries, complex processing).

Next Steps

Telemetry API Reference

Full API docs for TelemetryAccessor, TelemetrySpan, and testing utilities

Rate Limiting

Add rate limiting alongside observability for production readiness