When you call instrumentServer(server, config), the package patches
server.registerTool so every subsequent tool you register runs inside an
OpenTelemetry span.
Span shape
Each tool invocation produces a single span:
name: tools/call <toolName>
status: OK | ERROR
duration: ms
attributes: { ... see below ... }
Attributes
Attribute Description mcp.method.nameAlways "tools/call" for tool invocations. mcp.tool.nameThe tool name passed to registerTool. mcp.tool.titleTool title from the tool config. mcp.tool.descriptionTool description from the tool config. mcp.request.idUUID generated per request. mcp.session.idUUID generated when the SDK starts; constant for the process. mcp.operation.successtrue on OK, false on thrown error.mcp.operation.durationDuration in ms (also written as a histogram metric). client.addressFirst non-internal IPv4 address of the host (localhost if none). client.portprocess.env.PORT if set.error.typeError class name (only on failure). error.messageError message (only on failure).
Optional attributes
These show up only under specific configurations:
Attribute When mcp.request.argument.<key>When enableArgumentCollection: true. Each argument flattened into a span attribute. mcp.safety_check.contentWhen the handler is wrapped with safetyCheck. mcp.safety_check.flaggedtrue if Sedata’s safety API flagged the input.mcp.safety_check.latency_msRound-trip latency of the safety check. mcp.safety_check.successtrue if the safety API responded successfully (whether flagged or not).
enableArgumentCollection is off by default. Tool arguments often
contain user input, secrets, or PII — turn it on knowingly.
Resource attributes
The OTel resource attached to every span carries:
Key Source service.nameconfig.serverNameservice.versionconfig.serverVersionmcp.session.idUUID per process Host / OS / env detector attrs From @opentelemetry/resources detectors
These are added once per process and merged into every export.
Errors
If your handler throws, the package:
Sets the span status to ERROR with the error message.
Sets error.type, error.message, mcp.operation.success: false.
Records the duration histogram with mcp.operation.success: false.
Re-throws the original error so the MCP runtime sees it.
span.name tools/call calculate-bmi
status ERROR
status.message height cannot be zero
attributes.error.type RangeError
Sampling
By default, all spans are recorded (samplingRate: 1.0). To trim volume in
production, set a ratio:
const config : TelemetryConfig = {
// ...
samplingRate: 0.1 , // keep 10% of traces
}
The sampler is TraceIdRatioBasedSampler — head-based and deterministic per
trace id. See Sampling for tradeoffs.
What’s next
Automatic attributes reference Full table of every attribute the package writes.
Custom spans Record domain-specific operations alongside auto-spans.