From b8e66a114468944bfb8101d89ad64af0fafa3f48 Mon Sep 17 00:00:00 2001 From: Evan Mattson <35585003+moonbox3@users.noreply.github.com> Date: Mon, 4 May 2026 08:08:56 +0900 Subject: [PATCH] Python: Document that W3C trace context injection does not apply to Foundry hosted/toolbox MCP tools (#5580) * docs: clarify MCP trace-context propagation scope for hosted/toolbox tools (#5547) Automatic W3C trace-context injection via params._meta applies only to MCP sessions opened by the agent process (MCPStreamableHTTPTool, MCPStdioTool, MCPWebsocketTool). Hosted MCP tools (FoundryChatClient.get_mcp_tool) and toolbox-fetched tools (FoundryChatClient.get_toolbox) execute inside the Foundry agent service runtime; the framework never issues the tools/call for those and therefore cannot inject traceparent/tracestate. The previous wording ("for all transports") implied coverage that does not exist. The updated section: - removes the inaccurate "for all transports" claim - adds a Scope paragraph naming the three client-opened transports that are covered - explicitly states that propagation across the agent-to-toolbox-to-MCP boundary is the responsibility of the Foundry service runtime - documents the workaround (use MCPStreamableHTTPTool directly) for users who need end-to-end distributed tracing today Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: broaden MCP _meta scope note to cover all provider-managed transports (#5547) - List OpenAIChatClient.get_mcp_tool() and AnthropicClient.get_mcp_tool() alongside FoundryChatClient.get_mcp_tool() as hosted/provider-managed exceptions; restricting the carve-out to Foundry was misleading for readers using other providers - Fix get_toolbox() wording: use 'await client.get_toolbox(...)' and note that toolbox.tools is passed into Agent(tools=...) so it reads as an async instance method call, not a static/class method call - Add parenthetical '(or any other client-opened MCPTool subclass)' to future-proof the list of covered transports Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: add GeminiChatClient to MCP scope note and add learn-site observability doc (#5547) - Add GeminiChatClient.get_mcp_tool(...) to the hosted/provider-managed list in the MCP trace propagation scope note; Gemini's get_mcp_tool() returns a types.Tool with an McpServer entry executed by the Gemini service runtime, so it belongs alongside FoundryChatClient, OpenAIChatClient, and AnthropicClient in that list. - Create docs/features/observability/README.md as the learn-site documentation surface for observability, covering telemetry setup and MCP trace propagation with the same scope note (including GeminiChatClient) so that both doc surfaces are consistent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unneeded observability docs README Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- python/samples/02-agents/observability/README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/python/samples/02-agents/observability/README.md b/python/samples/02-agents/observability/README.md index 95aa3fc174..b2fbf7400f 100644 --- a/python/samples/02-agents/observability/README.md +++ b/python/samples/02-agents/observability/README.md @@ -24,7 +24,9 @@ Next to what happens in the code when you run, we also make setting up observabi ### MCP trace propagation -Whenever there is an active OpenTelemetry span context, Agent Framework automatically propagates trace context to MCP servers via the `params._meta` field of `tools/call` requests. It uses the globally-configured OpenTelemetry propagator(s) (W3C Trace Context by default, producing `traceparent` and `tracestate`), so custom propagators (B3, Jaeger, etc.) are also supported. This enables distributed tracing across agent-to-MCP-server boundaries for all transports (stdio, HTTP, WebSocket), compliant with the [MCP `_meta` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic#_meta). +Whenever there is an active OpenTelemetry span context, Agent Framework automatically propagates trace context to MCP servers via the `params._meta` field of `tools/call` requests. It uses the globally-configured OpenTelemetry propagator(s) (W3C Trace Context by default, producing `traceparent` and `tracestate`), so custom propagators (B3, Jaeger, etc.) are also supported. This enables distributed tracing across agent-to-MCP-server boundaries, compliant with the [MCP `_meta` specification](https://modelcontextprotocol.io/specification/2025-11-25/basic#_meta). + +**Scope:** automatic `_meta` injection applies only to MCP sessions that the agent process itself opens — `MCPStreamableHTTPTool`, `MCPStdioTool`, and `MCPWebsocketTool` (or any other client-opened `MCPTool` subclass). It does **not** apply to hosted/provider-managed MCP tool configurations such as `FoundryChatClient.get_mcp_tool(...)`, `OpenAIChatClient.get_mcp_tool(...)`, `AnthropicClient.get_mcp_tool(...)`, `GeminiChatClient.get_mcp_tool(...)`, or toolbox-fetched tools (for example, `toolbox = await client.get_toolbox(...)`, then passing `toolbox.tools` into `Agent(tools=...)`), because in those cases the `tools/call` message is issued by the provider service runtime rather than by the agent process. As a result, the framework has no opportunity to inject trace context into those requests, and propagating `traceparent`/`tracestate` across that hosted-service boundary is the responsibility of the service runtime, not Agent Framework. If end-to-end distributed tracing to the downstream MCP server is required, use a client-opened MCP transport instead of a hosted connector. ### Five patterns for configuring observability