Skip to content

Commit 67ca7fe

Browse files
committed
Remove client OTel session-id wrapper
1 parent 4564376 commit 67ca7fe

File tree

4 files changed

+2
-66
lines changed

4 files changed

+2
-66
lines changed

src/mcp/client/streamable_http.py

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
from collections.abc import AsyncGenerator, Awaitable, Callable
88
from contextlib import asynccontextmanager
99
from dataclasses import dataclass
10-
from types import TracebackType
1110

1211
import anyio
1312
import httpx
@@ -18,7 +17,6 @@
1817
from mcp.client._transport import TransportStreams
1918
from mcp.shared._context_streams import ContextReceiveStream, ContextSendStream, create_context_streams
2019
from mcp.shared._httpx_utils import create_mcp_http_client
21-
from mcp.shared._stream_protocols import WriteStream
2220
from mcp.shared.message import ClientMessageMetadata, SessionMessage
2321
from mcp.types import (
2422
INTERNAL_ERROR,
@@ -514,35 +512,6 @@ def get_session_id(self) -> str | None:
514512
return self.session_id # pragma: no cover
515513

516514

517-
class _SessionAwareWriteStream:
518-
"""Write-stream wrapper that exposes the transport session ID."""
519-
520-
def __init__(self, inner: WriteStream[SessionMessage], transport: StreamableHTTPTransport) -> None:
521-
self._inner = inner
522-
self._transport = transport
523-
524-
async def send(self, item: SessionMessage) -> None:
525-
await self._inner.send(item)
526-
527-
async def aclose(self) -> None:
528-
await self._inner.aclose()
529-
530-
def get_session_id(self) -> str | None:
531-
return self._transport.session_id
532-
533-
async def __aenter__(self) -> _SessionAwareWriteStream:
534-
await self._inner.__aenter__()
535-
return self
536-
537-
async def __aexit__(
538-
self,
539-
exc_type: type[BaseException] | None,
540-
exc_val: BaseException | None,
541-
exc_tb: TracebackType | None,
542-
) -> bool | None:
543-
return await self._inner.__aexit__(exc_type, exc_val, exc_tb)
544-
545-
546515
# TODO(Marcelo): I've dropped the `get_session_id` callback because it breaks the Transport protocol. Is that needed?
547516
# It's a completely wrong abstraction, so removal is a good idea. But if we need the client to find the session ID,
548517
# we should think about a better way to do it. I believe we can achieve it with other means.
@@ -612,7 +581,7 @@ def start_get_stream() -> None:
612581
)
613582

614583
try:
615-
yield read_stream, _SessionAwareWriteStream(write_stream, transport)
584+
yield read_stream, write_stream
616585
finally:
617586
if transport.session_id and terminate_on_close:
618587
await transport.terminate_session(client)

src/mcp/shared/_otel.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ def build_client_span_attributes(
4242
method: str,
4343
request_id: str | int,
4444
params: dict[str, Any] | None = None,
45-
session_id: str | None = None,
4645
) -> dict[str, Any]:
4746
"""Build OTel attributes for an MCP client request span."""
4847
attributes: dict[str, Any] = {
@@ -55,9 +54,6 @@ def build_client_span_attributes(
5554
if params is not None and (resource_uri := params.get("uri")) is not None:
5655
attributes["mcp.resource.uri"] = resource_uri
5756

58-
if session_id is not None:
59-
attributes["mcp.session.id"] = session_id
60-
6157
return attributes
6258

6359

src/mcp/shared/session.py

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
from collections.abc import Callable
66
from contextlib import AsyncExitStack
77
from types import TracebackType
8-
from typing import Any, Generic, Protocol, TypeVar, cast
8+
from typing import Any, Generic, Protocol, TypeVar
99

1010
import anyio
1111
from anyio.streams.memory import MemoryObjectSendStream
@@ -236,13 +236,6 @@ async def __aexit__(
236236
self._task_group.cancel_scope.cancel()
237237
return await self._task_group.__aexit__(exc_type, exc_val, exc_tb)
238238

239-
def _get_transport_session_id(self) -> str | None:
240-
"""Return the transport session ID when the write stream exposes it."""
241-
get_session_id = getattr(self._write_stream, "get_session_id", None)
242-
if callable(get_session_id):
243-
return cast("str | None", get_session_id())
244-
return None
245-
246239
async def send_request(
247240
self,
248241
request: SendRequestT,
@@ -287,7 +280,6 @@ async def send_request(
287280
method=request.method,
288281
request_id=request_id,
289282
params=request_data.get("params"),
290-
session_id=self._get_transport_session_id(),
291283
),
292284
):
293285
# Inject W3C trace context into _meta (SEP-414).

tests/shared/test_streamable_http.py

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
import requests
2424
import uvicorn
2525
from httpx_sse import ServerSentEvent
26-
from logfire.testing import CaptureLogfire
2726
from starlette.applications import Starlette
2827
from starlette.requests import Request
2928
from starlette.routing import Mount
@@ -1082,26 +1081,6 @@ async def test_streamable_http_client_resource_read(initialized_client_session:
10821081
assert response.contents[0].text == "Read test-resource"
10831082

10841083

1085-
@pytest.mark.anyio
1086-
@pytest.mark.filterwarnings("ignore::RuntimeWarning")
1087-
async def test_streamable_http_resource_read_spans_include_session_id(
1088-
capfire: CaptureLogfire, basic_server: None, basic_server_url: str
1089-
):
1090-
"""Verify streamable HTTP spans include the negotiated MCP session ID."""
1091-
async with streamable_http_client(f"{basic_server_url}/mcp") as (read_stream, write_stream):
1092-
async with ClientSession(read_stream, write_stream) as session:
1093-
await session.initialize()
1094-
response = await session.read_resource(uri="foobar://test-resource")
1095-
1096-
assert response.contents[0].uri == "foobar://test-resource"
1097-
1098-
spans = capfire.exporter.exported_spans_as_dict()
1099-
client_span = next(s for s in spans if s["name"] == "MCP send resources/read")
1100-
1101-
assert client_span["attributes"]["mcp.session.id"]
1102-
assert client_span["attributes"]["mcp.resource.uri"] == "foobar://test-resource"
1103-
1104-
11051084
@pytest.mark.anyio
11061085
async def test_streamable_http_client_tool_invocation(initialized_client_session: ClientSession):
11071086
"""Test client tool invocation."""

0 commit comments

Comments
 (0)