libs/skills/catalog/frontmcp-observability/SKILL.md
Use when adding tracing, structured logging, metrics, or monitoring to a FrontMCP server. Covers zero-config OpenTelemetry distributed tracing across all flows; the this.telemetry API for custom spans, events, and attributes in tools, plugins, agents, and skills; structured JSON logging with trace correlation and configurable sinks (Winston, Pino, stdout); the off-by-default /metrics endpoint (process and framework metrics, Prometheus-compatible); vendor integrations (Coralogix, Datadog, Logz.io, Grafana Cloud, or any OTLP backend); and testing spans, log correlation, and instrumentation. Triggers: observability, telemetry, tracing, logging, monitoring, OpenTelemetry, OTel, spans, metrics, Prometheus, Datadog, Coralogix, Logz.io, Grafana, Winston, Pino.
npx skillsauth add agentfront/frontmcp frontmcp-observabilityInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Router for adding observability to FrontMCP servers. Covers distributed tracing (OpenTelemetry), structured JSON logging, per-request log collection, the this.telemetry developer API, and vendor integrations.
this.telemetry to create custom spans in tools, plugins, or agentsfrontmcp-production-readiness)frontmcp-config)frontmcp-setup)Decision: Use this skill when you need to observe, trace, or log your server. Start with
tracing-setupfor auto-instrumentation, addstructured-loggingfor production logs, and usetelemetry-apifor custom spans in your code.
frontmcp-setup)npm install @frontmcp/observability| I want to... | Reference |
| -------------------------------------------------- | ------------------------------------- |
| Enable auto-tracing for all flows | references/tracing-setup.md |
| Add structured JSON logging with trace correlation | references/structured-logging.md |
| Create custom spans in tools/plugins | references/telemetry-api.md |
| Connect Coralogix, Datadog, Logz.io, Grafana | references/vendor-integrations.md |
| Test that spans and logs are correct | references/testing-observability.md |
| Expose Prometheus /metrics endpoint | references/metrics-endpoint.md |
The simplest way — one config line:
@FrontMcp({
observability: true,
})
This enables auto-tracing for all SDK flows. Add structured logging:
@FrontMcp({
observability: {
tracing: true,
logging: { sinks: [{ type: 'stdout' }] },
requestLogs: true,
},
})
Follow the scenario routing table above to find the right reference for your use case.
| Scenario | Reference | Description |
| ------------------------------------- | ------------------------------------- | --------------------------------------------------------------------------- |
| Enable OpenTelemetry tracing | references/tracing-setup.md | Zero-config auto-instrumentation, setupOTel(), span hierarchy |
| Add JSON logs with trace correlation | references/structured-logging.md | Sinks (stdout, console, OTLP, winston, pino), redaction, log format |
| Custom spans in tools/plugins | references/telemetry-api.md | this.telemetry.startSpan(), withSpan(), addEvent(), setAttributes() |
| Connect to monitoring platforms | references/vendor-integrations.md | Coralogix, Datadog, Logz.io, Grafana — OTLP and direct |
| Test spans and log entries | references/testing-observability.md | createTestTracer(), assertSpanExists(), integration test patterns |
| Expose Prometheus /metrics endpoint | references/metrics-endpoint.md | Off-by-default Prometheus scrape endpoint with process + framework counters |
| Pattern | Correct | Incorrect | Why |
| -------------------- | ------------------------------------------- | ------------------------------------------------- | ------------------------------------------------------------- |
| Enable observability | observability: true in @FrontMcp config | Import and install ObservabilityPlugin manually | Config-driven is the standard pattern since v1.0 |
| Custom spans | this.telemetry.withSpan('op', fn) | trace.getTracer().startSpan() directly | this.telemetry auto-inherits trace context |
| Log correlation | this.logger.info('msg', { key: val }) | console.log('msg') | SDK logger flows through StructuredLogTransport with trace_id |
| Session ID | Use mcp.session.id attribute (hashed) | Log the real session ID | Privacy: the hash is sufficient for correlation |
| Vendor integration | Use { type: 'otlp', endpoint } sink | Build vendor-specific HTTP clients | OTLP is the universal standard |
| Category | Flows | Attributes |
| -------------- | ---------------------------------------------------- | ------------------------------------------------- |
| HTTP requests | traceRequest, auth, route, finalize | http.request.method, url.path |
| Tool calls | parseInput → findTool → execute → finalize | mcp.component.type=tool, enduser.id |
| Resource reads | parseInput → findResource → execute | mcp.component.type=resource, mcp.resource.uri |
| Prompts | parseInput → findPrompt → execute | mcp.component.type=prompt |
| Agents | parseInput → findAgent → execute (nested tool calls) | mcp.component.type=agent |
| Auth | verify, session verify, OAuth flows | frontmcp.auth.mode, frontmcp.auth.result |
| Transport | SSE, Streamable HTTP, Stateless HTTP | frontmcp.transport.type |
| Skills | search, load, HTTP endpoints | frontmcp.flow.name |
@frontmcp/observability installedobservability field added to @FrontMcp configsetupOTel() or external SDK)trace_id and span_idthis.telemetry is available in tool execution contextsERROR statuscreateTestTracer()CallbackSink| Problem | Cause | Solution |
| ------------------------------------------------ | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| this.telemetry is undefined in a tool | observability not enabled on the parent @FrontMcp config | Set observability: true (or a config object) in the @FrontMcp decorator; see tracing-setup |
| Spans appear without trace_id in logs | Logger not connected to StructuredLogTransport | Use this.logger, not console; see structured-logging |
| OTLP exporter silently drops spans | Endpoint URL points at the UI, not the OTLP collector | Use the OTLP HTTP/gRPC ingest endpoint exposed by your vendor (Datadog, Coralogix, Logz, etc.); see vendor-integrations |
| Real session ID appears in span attributes | A custom span attribute writes session.id directly | Use the SDK-provided mcp.session.id (already hashed); never log the raw session token |
| Tests randomly fail with leftover spans | Exporter retained between tests | Reset the in-memory exporter in afterEach; see testing-observability |
| OTel auto-instrumentation double-traces requests | Both setupOTel() AND a vendor agent attached to the process | Pick one: either FrontMCP-managed OTel OR the vendor agent — not both |
Each reference has matching examples under examples/<reference>/:
tracing-setup| Example | Level | Description |
| ---------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------ |
| basic-tracing | Basic | Enable auto-tracing and see spans printed to your terminal. |
| production-tracing | Intermediate | Full production observability — traces to OTLP, structured logs to stdout, per-request log collection. |
structured-logging| Example | Level | Description |
| ----------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| stdout-logging | Basic | Enable NDJSON structured logging to stdout with automatic trace correlation and field redaction. |
| winston-integration | Intermediate | Forward FrontMCP structured log entries to your existing winston logger. Each entry includes trace_id and span_id as metadata. |
telemetry-api| Example | Level | Description |
| -------------------------------------------------------------------------- | ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| tool-custom-spans | Basic | Create child spans, events, and attributes inside a tool's execute method using this.telemetry. |
| plugin-telemetry | Intermediate | Add telemetry events from a custom plugin's hooks. Events appear on the tool execution span, giving you visibility into plugin behavior within the trace. |
| agent-nested-tracing | Advanced | Trace an agent's execution lifecycle including its nested tool calls. Every span shares the same trace ID. |
vendor-integrations| Example | Level | Description |
| ---------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------- |
| coralogix-setup | Intermediate | Send both traces and structured logs to Coralogix. Logs include trace_id so Coralogix links them to traces automatically. |
testing-observability| Example | Level | Description |
| ---------------------------------------------------------------------------------- | ------------ | ------------------------------------------------------------------------------------------- |
| test-custom-spans | Basic | Verify that your tool creates the expected child spans with correct attributes. |
| test-log-correlation | Intermediate | Verify that structured log entries include trace context fields for correlation with spans. |
metrics-endpoint| Example | Level | Description |
| ----------------------------------------------------------------------------------- | ----- | -------------------------------------------------------------------- |
| enable-metrics-endpoint | Basic | Turn on the /metrics endpoint with defaults and scrape it with curl. |
Skills are distributed as plain SKILL.md files plus a sibling references/
and examples/ tree, so consumers can pick whichever access mode fits:
| Mode | How it works |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Filesystem | Read libs/skills/catalog/frontmcp-observability/ directly from a clone of the catalog repo, or from a published @frontmcp/skills install. SKILL.md is the entry point. |
| frontmcp CLI | frontmcp skills list, frontmcp skills read frontmcp-observability, frontmcp skills read frontmcp-observability:references/<file>.md, frontmcp skills install frontmcp-observability — no server required. |
| MCP skill:// | When a developer mounts this skill into their own FrontMCP server (@FrontMcp({ skills: [...] })), the SDK exposes it via SEP-2640 resources: skill://frontmcp-observability/SKILL.md, skill://frontmcp-observability/references/{file}.md, etc. The server’s skill://index.json returns the SEP-2640 discovery document for everything mounted on it. |
The catalog itself is not an MCP server. The skill:// URIs only resolve
when a server has been configured to host this skill.
frontmcp-production-readiness, frontmcp-config, frontmcp-testing, frontmcp-developmenttools
Use when customizing, branding, or replacing the built-in FrontMCP OAuth pages (the login, consent, federated-select, incremental-authorization, and error pages) with your own React components. Covers the auth.ui slot-to-file map and auth.extras name-to-handler map on the auth config (no decorator, no class); the @frontmcp/ui/auth React hooks, the AuthPageWrapper component, and mountAuthPage (client-rendered via an esm.sh import-map plus a per-file server-side transform, with no bundling and no SSR); and the framework-owned CSRF and CSP. Triggers: custom login page, brand the consent screen, replace the OAuth UI, custom authorization UI, style the auth pages, multi-step login. The skill for CUSTOM AUTHORIZATION UI (distinct from auth config in frontmcp-config and permissions in frontmcp-authorities).
tools
ALWAYS use this skill when the user asks to build, modify, or audit a FrontMCP tool. Covers everything inside `@Tool({...})`: class and function-style tools, Zod input/output schemas with derived `execute()` types, dependency injection (`this.get` / `this.tryGet`), error handling (`this.fail`, MCP error classes), throttling (rate-limit / concurrency / timeout), auth providers (single / multi / vault), availability constraints (`availableWhen`), elicitation (`this.elicit`), interactive UI widgets via `@Tool({ ui })` (MCP Apps / SEP-1865 — including `.tsx` FileSource, CSP, `window.FrontMcpBridge`, host-detect `resourceMode`), annotations (`readOnlyHint` / `destructiveHint` / …), `examples` metadata, registration in `@App({ tools })`, and per-tool unit testing. Does NOT cover: - Read-only data exposed via a URI — use `create-resource` - Conversation templates / system prompts — use `create-prompt` - Multi-tool orchestration loops — use `create-agent` - Background work / pipelines — use `create-job` / `create-workflow` - Server-level config (transport, sessions, auth modes) — use `config` / `auth` Triggers: `@Tool`, ToolContext, tool decorator, MCP tool, snake_case tool name, inputSchema, outputSchema, ToolInputOf, ToolOutputOf, `@Tool({ ui })`, tool UI widget, MCP Apps widget, FileSource widget, `.tsx` widget, ui.csp, ui.resourceMode, window.FrontMcpBridge, tool annotations, readOnlyHint, destructiveHint, rate-limit tool, throttle tool, concurrency tool, tool timeout, this.fail, this.respond, this.fetch, this.notify, this.progress, this.elicit, ElicitationDisabledError, ToolContext.execute, this.get(TOKEN), this.tryGet, register tool in @App, tool examples metadata, availableWhen, missingAxes, `tool()` function builder, Tool.esm, Tool.remote, PublicMcpError, ResourceNotFoundError, MCP_ERROR_CODES, ui://widget.
development
Use when pushing real-time notifications or events into Claude Code (or another MCP client) sessions, or building two-way chat bridges. Covers channel source types: incoming webhooks (such as GitHub), app error events, agent-completion and job-completion alerts, service connectors, file watchers, and replay buffers; plus two-way conversational bridges connecting WhatsApp, Telegram, Slack, and Discord to a Claude Code session. Triggers: push notifications, real-time alerts, webhook channel, chat bridge, WhatsApp / Telegram / Slack / Discord, agent completion alert, job status notification, error forwarding, server-to-client messaging. The skill for CHANNELS and NOTIFICATIONS.
development
Use when implementing authorization and access control for FrontMCP tools, resources, prompts, or skills, deciding who may invoke what. Covers the RBAC, ABAC, and ReBAC models and when to choose each; JWT claims mapping per identity provider (Auth0, Keycloak, Okta, Cognito, Frontegg); reusable named authority profiles; and custom authority evaluators for domain-specific policy. This is about who-can-do-what (permissions, roles, scopes), distinct from configuring auth modes and login (see frontmcp-config) and custom login UI (see frontmcp-auth-ui). Triggers: authorization, access control, RBAC, ABAC, ReBAC, permissions, roles, scopes, policy enforcement, JWT claims, restrict who can call a tool.