-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Python: feature: Inject OpenTelemetry trace context into MCP requests and update… #3780
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Python: feature: Inject OpenTelemetry trace context into MCP requests and update… #3780
Conversation
Python Test Coverage Report •
Python Unit Test Overview
|
||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Adds OpenTelemetry trace-context propagation across the MCP transport boundary by injecting the active trace context into MCP tools/call requests via params._meta, enabling end-to-end distributed tracing from Agent Framework → MCP servers.
Changes:
- Add
_inject_otel_into_mcp_meta()helper to inject the current OTel context into an MCP_metacarrier. - Wire OTel meta injection into
MCPTool.call_tool()so all MCP transports benefit. - Add a unit test and a documentation note describing MCP trace propagation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| python/packages/core/agent_framework/_mcp.py | Injects OTel propagation fields into MCP tool calls via the request meta field. |
| python/packages/core/tests/core/test_mcp.py | Adds a test validating meta injection behavior for active vs inactive span contexts. |
| python/samples/getting_started/observability/README.md | Documents that trace context is propagated to MCP servers using params._meta. |
|
@copilot open a new pull request to apply changes based on the comments in this thread |
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
OpenTelemetry is a hard dependency of agent-framework-core (per pyproject.toml), so the try/except ImportError guard was dead code. Move the import to the top of the file to fail fast on missing dependencies instead of silently hiding installation issues.
Motivation and Context
When an Agent Framework application calls tools on remote MCP servers, the OpenTelemetry trace context is lost at the MCP transport boundary. The agent's span tree stops at
call_tool()and the MCP server starts a new, unrelated trace — breaking distributed tracing and preventing end-to-end latency visibility across agent → MCP server calls.The MCP specification (2025-11-25) reserves
params._metafor exactly this kind of client/server metadata: "The_metaproperty/parameter is reserved by MCP to allow clients and servers to attach additional metadata to their interactions."Fixes #3778
Description
Adds a
_inject_otel_into_mcp_meta()helper that usesopentelemetry.propagate.inject()to write the current trace context into a carrier dict, then merges it into the MCP request_meta. This is wired intoMCPTool.call_tool()— the single chokepoint for all transports (stdio, SSE, streamable HTTP).Key design decisions:
traceparent/tracestate, B3, etc.) rather than hardcoding specific headerstry/except ImportErrorso the framework works unchanged when OTel is not installed_metakeysOBSERVABILITY_SETTINGS: propagation happens whenever a valid span context exists, independent of the framework's observability configurationFiles changed:
packages/core/agent_framework/_mcp.py— added_inject_otel_into_mcp_meta()helper, wired intoMCPTool.call_tool()packages/core/tests/core/test_mcp.py— added parametrized test covering span/no-span casessamples/getting_started/observability/README.md— added MCP trace propagation documentation noteContribution Checklist