Skip to content

fix(mcp): support mcp>=2.x — renamed streamable_http_client and 2-tuple stream yield - #221

Open
jjcav84 wants to merge 1 commit into
future-agi:mainfrom
jjcav84:fix/mcp-v2-streamable-http-compat
Open

jjcav84 wants to merge 1 commit into
future-agi:mainfrom
jjcav84:fix/mcp-v2-streamable-http-compat

Conversation

@jjcav84

@jjcav84 jjcav84 commented Oct 5, 2026

Copy link
Copy Markdown

What does this PR do?

Makes traceai-mcp work on mcp>=2.x. The instrumentor's post-import hook for
mcp.client.streamable_http wraps streamablehttp_client, which mcp 2.x
renamed to streamable_http_client — so instrument() raises AttributeError
on any environment where the module exposes only the new name. The same client
factory also now yields a 2-tuple (read, write) instead of v1's 3-tuple with
a session-id callback, which _wrap_transport_with_callback would fail to
unpack. The hook now wraps whichever name the installed SDK provides, and the
wrapper handles both yield shapes.

Why?

mcp 2.x is the current SDK. On it, the instrumentor crashes at
instrument() time (post-import hook fires immediately when the module is
already imported) or at first use of the streamable-HTTP transport — i.e. the
transport that current deployments standardize on. We hit this while
instrumenting a live streamable-HTTP MCP deployment.

Note: mcp 2.x also ships native OTel instrumentation (per-request CLIENT spans

  • W3C _meta context propagation, mcp/shared/_otel.py, SEP-414), so the
    transport-wrapping approach is increasingly belt-and-suspenders on v2 — but the
    instrumentor should at least not crash on current SDKs.

How was it tested?

Two new regression tests in tests/test_framework_mcp.py
(TestMCPSdkV2Compat):

  • test_wrap_transport_with_callback_two_tuple — 2-tuple yield, fails
    pre-patch with the unpack ValueError
  • test_streamable_http_hook_wraps_v2_name — hook must wrap the v2 name,
    fails pre-patch (hooks the removed streamablehttp_client)

Suite result on mcp==2.3.0 (Python 3.12):

19 passed, 1 failed in 1.32s

The single failure is test_instrumentation_dependencies, which asserts
len(_instruments) >= 2 while package.py declares ("mcp >= 0.1.0",) —
pre-existing on a clean checkout, unrelated to this change. Reverting this
patch makes both new tests fail, as expected.

Also verified end-to-end: MCPInstrumentor().instrument() +
streamable_http_client against a live streamable-HTTP MCP server
(mcp 2.3.0) — client connects, requests complete, spans export.

  • Unit tests added / updated (pytest or vitest)
  • Integration tests pass (or N/A — no gateway behavior changed)
  • ruff check / mypy / npm run typecheck / npm run lint all pass
  • Public types, env vars, or SDK behavior changes are documented in the relevant README

Checklist

  • Branch is off main
  • Commit messages follow Conventional Commits (feat:, fix:, docs:, chore: …)
  • No TODOs or commented-out code left in
  • No real API keys or secrets in the diff
  • If prose was added or changed: checked against docs/VOCABULARY.md

Notes for reviewers

AI use: Devin (Cognition) drafted the fix and tests; verified against a
live MCP deployment before opening. Human reviewed the diff and this body.

Worth a separate look (out of scope here): _uninstrument only unwraps
mcp.client.stdio/mcp.server.stdio — the SSE, streamable-HTTP and
ServerSession wraps stay installed after uninstrument(). Happy to file a
follow-up issue/PR if wanted.

mcp 2.x renamed streamablehttp_client to streamable_http_client and the
client factory now yields (read, write) instead of the v1 3-tuple with a
session-id callback. The post-import hook for mcp.client.streamable_http
crashed with AttributeError on any module exposing only the new name,
and _wrap_transport_with_callback would fail unpacking a 2-tuple.

Resolve the wrapped attribute by whichever name the installed SDK
provides, and handle both yield shapes in the callback wrapper.

Regression tests: two tests that fail without the fix (unpack crash on
2-tuple; hook wrapping the removed v1 name).
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