MCP Deep Dive, Part 10: When the Agent Feels Off — Debugging and Observability for MCP in Production A developer debugging an MCP-based agent in production found that traditional request-level logging fails to capture multi-turn agent failures. By implementing OpenTelemetry-based distributed tracing with a root span per agent run, they reduced incident triage from hours to minutes. The approach correlates spans across the host, model, and servers, and adds structured logs and metrics dimensioned by tool and tenant. A web API fails loudly: a 500, a stack trace, an alert. An agent fails softly. It doesn't crash — it quietly takes six turns instead of two, calls the wrong tool, spends triple the tokens, and returns an answer that's subtly wrong. None of that throws an exception, and none of it shows up in the logs of any single request. This is Part 10 of a 15-part deep dive on Model Context Protocol MCP . Part 3 gave each tool call a span on the server; this part joins those into the whole picture — one agent run across the host, the model, and all three servers, correlated so that when something feels off you have an answer instead of a shrug. agent.run tenant, goal ================== 1.8s | +- agent.turn 0 ====== | +- agent.model call plan === | +- tool.get campaign kpis - mattrx-analytics == 120ms | +- tool.query events - mattrx-analytics === 180ms | +- agent.turn 1 ===== | +- agent.model call synthesize ==== | +- tool.create report - mattrx-reports enqueue = 90ms | +- eval gate 0.93 pass - final answer Start one root span per agent run and propagate its context across the MCP transport, so every server's spans nest under it. public async Task