Skip to main content

What is Tracing?

Tracing in Heimdall allows you to monitor and debug your MCP server operations by capturing detailed information about each tool call, resource access, and prompt execution. Each trace consists of one or more spans that represent units of work. Spans capture:
  • Start and end times for latency measurement
  • Input parameters passed to your functions
  • Output values returned from your functions
  • Error information if something goes wrong
  • Custom attributes for additional context

How It Works

┌─────────────────────────────────────────────────────────────┐
│                     Your MCP Server                         │
│                                                             │
│   @trace_mcp_tool()                                        │
│   def my_tool(query):     ──────┐                          │
│       ...                        │ Span Created            │
│       return result        ◄────┘                          │
│                                                             │
└──────────────────────────┬──────────────────────────────────┘

                           │ OTLP/HTTP (Port 4318)

┌─────────────────────────────────────────────────────────────┐
│                   Heimdall Backend                          │
│                                                             │
│   • Receives spans via OTLP protocol                       │
│   • Transforms to Heimdall trace format                    │
│   • Stores traces by project                               │
│                                                             │
└──────────────────────────┬──────────────────────────────────┘

                           │ REST API

┌─────────────────────────────────────────────────────────────┐
│                  Heimdall Dashboard                         │
│                                                             │
│   • View all traces                                        │
│   • Analyze latency and errors                             │
│   • Inspect inputs and outputs                             │
│                                                             │
└─────────────────────────────────────────────────────────────┘

Trace Structure

A typical Heimdall trace contains:
FieldDescription
trace_idUnique identifier for the trace
span_idUnique identifier for each span
nameName of the operation (usually function name)
start_timeWhen the operation started
end_timeWhen the operation completed
durationTotal time taken (calculated)
statusSuccess or error status
inputCaptured input parameters
outputCaptured return value
attributesCustom metadata

Tracing Decorators

Heimdall provides specialized decorators for different use cases:

trace_mcp_tool / traceMCPTool

Designed specifically for MCP tool functions. Automatically captures:
  • Tool name from function name
  • All input parameters
  • Return values
  • Execution duration
  • Error states

observe

A general-purpose tracing decorator for any function:
  • More control over what gets captured
  • Can be used for non-MCP functions
  • Useful for tracing internal operations

Best Practices

  • Trace your MCP tool entry points for high-level visibility
  • Add internal tracing for complex operations that need debugging
  • Avoid tracing very fast, frequently-called utility functions
  • Let the decorator use your function name when possible
  • Override with custom names when the function name isn’t descriptive
  • Use consistent naming conventions across your codebase
  • Call client.flush() before your application exits
  • This ensures all pending spans are sent to the backend
  • Especially important for short-lived processes
  • Review what inputs/outputs are being captured
  • Use capture_input=False or capture_output=False for sensitive data
  • Consider sanitizing data before returning from traced functions

Next Steps