Skip to content

feat(mcp): trace client operations and propagate context - #1025

Open
Abhijeet Prasad (AbhiPrasad) wants to merge 6 commits into
abhi/add-mcp-instrumentation-b534c1c8from
abhi/mcp-client-tracing-ae460b73
Open

Abhijeet Prasad (AbhiPrasad) wants to merge 6 commits into
abhi/add-mcp-instrumentation-b534c1c8from
abhi/mcp-client-tracing-ae460b73

Conversation

@AbhiPrasad

@AbhiPrasad Abhijeet Prasad (AbhiPrasad) commented Oct 29, 2026 •

Copy link
Copy Markdown
Member

🤖 This text was AI-generated.

Stacked on #1024, which adds MCP server instrumentation. This is PR 2 of the MCP instrumentation work.

Problem

Server instrumentation records MCP execution, but the caller has no span for the round trip. Without automatic context propagation, the agent and server appear in separate traces:

agent                         # caller trace

tools/call add             # server trace
└─ nested-work

Solution

Add wrap_mcp_client(client_or_session, capture_content=True) to trace outgoing requests and propagate W3C trace context and Braintrust baggage through params._meta.

from braintrust.integrations.mcp import wrap_mcp_client

client = wrap_mcp_client(client)

Each side works independently. With both client and server wrapped, nested work joins the caller's trace:

agent
└─ tools/call add (client)
   └─ tools/call add (server)
      └─ nested-work

Supports official mcp>=1.28.1,<3 clients and sessions, standalone fastmcp>=2.14.7,<5 clients, and corresponding fastmcp-slim releases. MCP dependencies remain optional.

  • Client spans share server names, types, and payload shaping. metadata["mcp.span.kind"] = "client" identifies the round trip.
  • Content capture is enabled by default. Pass capture_content=False to omit arguments and results; discovery inventories are always omitted.
  • Propagation preserves the original request and existing baggage. Concurrent requests keep their own parentage.
  • Errors, timeouts, cancellation, and disconnects finalize spans without changing application behavior. Returned tool errors retain their results; cancellation alone does not mark the span as failed.

Wrap before connecting to include negotiation, or wrap an active client/session. Repeated wrapping updates settings without adding spans, and FastMCP reconnects inherit those settings.

Framework tool spans can parent the MCP round trip. When opentelemetry-instrumentation-mcp is enabled, its instrumentor owns client spans, propagation, and capture settings; Braintrust adds no duplicate client span.

Integration tests use real clients and servers in memory, over localhost HTTP, and over stdio subprocesses. They assert span payloads, parentage, and received trace metadata directly, without cassettes or external LLM calls.

Scope and next steps

One-way notifications, session lifetimes, and detached task APIs do not create client operation spans. Automatic client setup and documentation follow in PR 3. MCPIntegration.setup() continues to enable server tracing independently.

Refs #1023

@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) force-pushed the abhi/mcp-client-tracing-ae460b73 branch from 08f5717 to 12477ab Compare October 29, 2026 19:14
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) force-pushed the abhi/mcp-client-tracing-ae460b73 branch 2 times, most recently from 21b913d to 3c53e63 Compare October 29, 2026 20:44
@AbhiPrasad
Abhijeet Prasad (AbhiPrasad) marked this pull request as ready for review October 29, 2026 20:48
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-29T21:18:36.367247Z dd14cdc New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

> 🤖 **This text was AI-generated.**

The server integration no longer provides ask_llm or cassette setup. Client
coverage still depended on both and stored version-specific protocol snapshots.

Use the real add tool for connected HTTP and subprocess tests:

```text
agent -> MCP client -> MCP server -> nested-work
```

Remove client cassettes and stdio recording hooks. Assert propagated trace
metadata on the actual server context, preserving baggage, content opt-out,
client-only operation, and connected parentage checks without external LLM calls.

Refs #1023

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant