Skip to content

Docs: Best practices for emitting custom spans from tools, prompts, and resources #3888

@strawgate

Description

@strawgate

Summary

The telemetry docs show how to enable tracing and what FastMCP emits automatically, but don't guide users on how to instrument their own tool/prompt/resource implementations. Users building production MCP servers need guidance on:

Proposed content

Adding spans inside tools

from fastmcp import FastMCP
from fastmcp.telemetry import get_tracer

mcp = FastMCP("my-server")

@mcp.tool
async def search(query: str) -> str:
    tracer = get_tracer()

    with tracer.start_as_current_span("search.fetch") as span:
        span.set_attribute("search.query_length", len(query))
        results = await fetch_results(query)
        span.set_attribute("search.result_count", len(results))

    with tracer.start_as_current_span("search.rank") as span:
        ranked = rank_results(results)

    return format_results(ranked)

Recommended patterns

  • Span naming: Use {tool_name}.{operation} for child spans (e.g., search.fetch, search.rank)
  • What to trace: External calls (APIs, databases), expensive computations, anything >100ms
  • What NOT to trace: Every function call, simple transformations, fast in-memory operations
  • Attributes: Add domain-specific attributes that help debugging (counts, sizes, IDs) — not PII or secrets
  • Error recording: Let exceptions propagate — FastMCP's server_span records them automatically. Don't double-record.

Instrumenting sampling calls

For servers that use ctx.sample() for LLM calls, recommend using logfire.instrument_google_genai() or equivalent to get per-LLM-call spans with token counts nested inside the tool span.

Connecting to backends

  • Logfire: logfire.configure() — FastMCP spans flow automatically
  • Jaeger/OTLP: opentelemetry-instrument CLI or programmatic SDK setup
  • Console (debugging): ConsoleSpanExporter for raw span output

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationUpdates to docs, examples, or guides. Primary change is documentation-related.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions