Skip to content

Commit 952c642

Browse files
author
Funan Zhou
committed
fix(streamable-http): demote stateless termination log to debug
1 parent 98f8ef2 commit 952c642

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

src/mcp/server/streamable_http.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,10 @@ async def terminate(self) -> None:
767767
"""
768768

769769
self._terminated = True
770-
logger.info(f"Terminating session: {self.mcp_session_id}")
770+
if self.mcp_session_id:
771+
logger.info(f"Terminating session: {self.mcp_session_id}")
772+
else:
773+
logger.debug("Stateless request completed, cleaning up transport")
771774

772775
# We need a copy of the keys to avoid modification during iteration
773776
request_stream_keys = list(self._request_streams.keys())

tests/server/test_streamable_http_manager.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,48 @@ async def mock_receive():
269269
assert len(transport._request_streams) == 0, "Transport should have no active request streams"
270270

271271

272+
@pytest.mark.anyio
273+
async def test_stateless_termination_logs_debug_not_info(caplog: pytest.LogCaptureFixture):
274+
"""Stateless mode termination should use DEBUG logs and avoid INFO-level "None" session text."""
275+
app = Server("test-stateless-log-level")
276+
manager = StreamableHTTPSessionManager(app=app, stateless=True)
277+
278+
async with manager.run():
279+
app.run = AsyncMock(return_value=None)
280+
281+
async def mock_send(message: Message):
282+
del message
283+
284+
scope = {
285+
"type": "http",
286+
"method": "POST",
287+
"path": "/mcp",
288+
"headers": [
289+
(b"content-type", b"application/json"),
290+
(b"accept", b"application/json, text/event-stream"),
291+
],
292+
}
293+
294+
async def mock_receive():
295+
return {
296+
"type": "http.request",
297+
"body": b"",
298+
"more_body": False,
299+
}
300+
301+
with caplog.at_level(logging.DEBUG, logger="mcp.server.streamable_http"):
302+
await manager.handle_request(scope, mock_receive, mock_send)
303+
304+
streamable_http_messages = [
305+
record.getMessage()
306+
for record in caplog.records
307+
if record.name == "mcp.server.streamable_http"
308+
]
309+
310+
assert "Stateless request completed, cleaning up transport" in streamable_http_messages
311+
assert "Terminating session: None" not in streamable_http_messages
312+
313+
272314
@pytest.mark.anyio
273315
async def test_unknown_session_id_returns_404(caplog: pytest.LogCaptureFixture):
274316
"""Test that requests with unknown session IDs return HTTP 404 per MCP spec."""

0 commit comments

Comments
 (0)