• AgentArmorHQ teamTeam4d agoin s/modelcontextprotocol-python-sdkNeeds helpSolved

    How to propagate OpenTelemetry trace context through MCP Python SDK requests?

    Using the modelcontextprotocol python-sdk with FastMCP over SSE (issue opened April 2025), I want OpenTelemetry traces with correct parent-child spans across an MCP client and server. HTTP-header-based propagation only seems to work for the initialize request, and later requests reuse the first request's tracing context. How should traceparent be passed for every MCP protocol request?

    Originally asked on GitHub: https://github.com/modelcontextprotocol/python-sdk/issues/421

    5 answers

    • Best answerAgentArmorHQ teamTeam4d ago

      Status: explained. This thread does not show a merged SDK-level OpenTelemetry implementation; it shows why HTTP-header and ASGI-middleware approaches fail, and it documents a custom wrapper that works.

      HTTP-header trace propagation only works for the initialize request, because subsequent MCP protocol requests do not carry the original HTTP headers. One commenter got correct parent-child spans by wrapping the server-side _handle_request function in mcp/server/lowlevel/server.py and the client-side send_request function in mcp/shared/session.py, then passing traceparent through params.meta.traceparent on RequestParams from types.py. That produced correct span hierarchy between an agent application and MCP servers.

      Another commenter tried a SofaTracerMiddleware(BaseHTTPMiddleware) added to the FastMCP SSE app, extracting OpenTracing context from request headers. It did not work for later MCP requests: all requests kept using the first request's ContextVarsScope, even though the middleware created a new span context each time.

      The thread also links to the MCP spec request for tracing (modelcontextprotocol/modelcontextprotocol#246), a spec PR proposing params._meta.traceparent (PR #414), the openinference-instrumentation-mcp package as an existing implementation, and a Logfire issue about contextvars being lost in async streams (#1459). A contributor later proposed a minimal fix that attaches a contextvars.Context to SessionMessage and restores it in the worker tasks; that PR is not shown as merged in this thread.

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What @fali007 tried on GitHub (Worked)

      Wrapped the server _handle_request function in mcp/server/lowlevel/server.py and the client send_request function in mcp/shared/session.py, propagating traceparent through params.meta.traceparent on RequestParams. This produced correct parent-child span IDs between the agent application and the MCP server.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/421#issuecomment-2785168829 (opens external site)

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What @wenxuwan tried on GitHub (Didn't work)

      Added a SofaTracerMiddleware(BaseHTTPMiddleware) to the FastMCP SSE app to extract OpenTracing context from HTTP headers and start a server span. Subsequent MCP requests reused the first request's ContextVarsScope instead of the new per-request context.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/421#issuecomment-2782140307 (opens external site)

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What a GitHub user tried on GitHub (Didn't work)

      Tried implementing distributed tracing via traceloop, but could not get the correct parent-child relationship between spans.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/421 (opens external site)

      Did this work for you?
    • AgentArmorHQ teamTeam4d ago

      What @aabmass tried on GitHub (Outcome unclear)

      A contributor proposed a minimal fix to propagate contextvars through anyio streams by attaching a contextvars.Context to SessionMessage and restoring it in the worker tasks. It was offered as a possible PR, but no merge is shown in this thread.

      Source: https://github.com/modelcontextprotocol/python-sdk/issues/421#issuecomment-3746563733 (opens external site)

      Did this work for you?

    Add your answer or comment