Skip to content

Conversation

@peteroden
Copy link

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._meta for exactly this kind of client/server metadata: "The _meta property/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 uses opentelemetry.propagate.inject() to write the current trace context into a carrier dict, then merges it into the MCP request _meta. This is wired into MCPTool.call_tool() — the single chokepoint for all transports (stdio, SSE, streamable HTTP).

Key design decisions:

  • Propagator-agnostic: forwards whatever keys the configured propagator(s) produce (W3C traceparent/tracestate, B3, etc.) rather than hardcoding specific headers
  • Optional dependency: OpenTelemetry import is guarded by try/except ImportError so the framework works unchanged when OTel is not installed
  • Merge-not-clobber: never overwrites existing _meta keys
  • No gate on OBSERVABILITY_SETTINGS: propagation happens whenever a valid span context exists, independent of the framework's observability configuration

Files changed:

  • packages/core/agent_framework/_mcp.py — added _inject_otel_into_mcp_meta() helper, wired into MCPTool.call_tool()
  • packages/core/tests/core/test_mcp.py — added parametrized test covering span/no-span cases
  • samples/getting_started/observability/README.md — added MCP trace propagation documentation note

Contribution Checklist

  • The code builds clean without any errors or warnings
  • The PR follows the Contribution Guidelines
  • All unit tests pass, and I have added new tests where possible
  • Is this a breaking change? No — this is additive behavior with no API changes.

Copilot AI review requested due to automatic review settings February 10, 2026 02:35
@markwallace-microsoft markwallace-microsoft added documentation Improvements or additions to documentation python labels Feb 10, 2026
@github-actions github-actions bot changed the title feature: Inject OpenTelemetry trace context into MCP requests and update… Python: feature: Inject OpenTelemetry trace context into MCP requests and update… Feb 10, 2026
@markwallace-microsoft
Copy link
Member

markwallace-microsoft commented Feb 10, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
packages/core/agent_framework
   _mcp.py4025386%114, 176, 185, 248, 256, 277, 383, 450, 485, 487, 491–492, 494–495, 549, 564, 582, 623, 729, 742–747, 769, 793, 796–798, 813–814, 820–822, 841, 850, 853–855, 870–871, 875–879, 896–900, 1040
TOTAL17171212587% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
4083 225 💤 0 ❌ 0 🔥 1m 8s ⏱️

Copy link
Contributor

Copilot AI left a 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 _meta carrier.
  • 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.

@peteroden
Copy link
Author

@copilot open a new pull request to apply changes based on the comments in this thread

peteroden and others added 4 commits February 10, 2026 09:07
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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: [Feature]: Propagate OpenTelemetry trace context to MCP servers via params._meta

3 participants