A session in @sedata-ai/mcp is a single instrumented process. It begins
when instrumentServer is called and ends when telemetry.shutdown() runs.
Session id
TelemetryManager mints one UUID per process and adds it to every span and
every metric as mcp.session.id.
mcp.session.id = "f3a4b9c2-..." // constant for the lifetime of the process
You’ll see this attribute on:
- every span produced by tool calls
- every metric data point
- every custom span you record via
telemetry.startActiveSpan
Session start
Implicit. Created when you construct the TelemetryManager:
const telemetry = instrumentServer(server, telemetryConfig)
// ↑ session begins here
Session duration
When you call telemetry.shutdown(), the package records a histogram:
| Metric | Unit | Tag |
|---|
mcp.server.session.duration | seconds | mcp.session.id |
Wire it up to your process exit:
const exit = async (code = 0) => {
await telemetry.shutdown()
process.exit(code)
}
process.on('SIGINT', () => exit(0))
process.on('SIGTERM', () => exit(0))
process.on('uncaughtException', () => exit(1))
Skipping shutdown() means the final batch of metrics never leaves your
process — including session.duration. Always wire it.
What “session” doesn’t mean
- It’s not a per-client session. If two MCP clients connect to the same
server process, they share one
mcp.session.id. Use mcp.request.id for
per-call correlation, and client.address to differentiate.
- It’s not a transport-level connection. A stdio server has one logical
client; an HTTP server may have many.
Per-call ids
For correlating logs to a single tool call:
| Attribute | Where it comes from |
|---|
mcp.request.id | UUID generated for each tools/call invocation. |
mcp.session.id | UUID per process. |
mcp.tool.name | Tool that was called. |
Combine (mcp.session.id, mcp.request.id) for unique-per-call identity.