Skip to content

Commit 3041fd0

Browse files
committed
Use info level and truncate client-controlled session ID
- warning -> info: this is normal post-restart operation per spec, matches session lifecycle logs at :220 and :247 - truncate to 64 chars: unlike other session-ID logs in this file, this value is client-controlled input - add caplog assertion to existing 404 test Reported-by: Johnathan Oneal Github-Issue: #2204
1 parent 6f99c3d commit 3041fd0

File tree

2 files changed

+6
-3
lines changed

2 files changed

+6
-3
lines changed

src/mcp/server/streamable_http_manager.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ async def run_server(*, task_status: TaskStatus[None] = anyio.TASK_STATUS_IGNORE
272272
# Unknown or expired session ID - return 404 per MCP spec
273273
# TODO: Align error code once spec clarifies
274274
# See: https://github.com/modelcontextprotocol/python-sdk/issues/1821
275-
logger.warning(f"Rejected request with unknown or expired session ID: {request_mcp_session_id}")
275+
logger.info(f"Rejected request with unknown or expired session ID: {request_mcp_session_id[:64]}")
276276
error_response = JSONRPCError(
277277
jsonrpc="2.0",
278278
id=None,

tests/server/test_streamable_http_manager.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Tests for StreamableHTTPSessionManager."""
22

33
import json
4+
import logging
45
from typing import Any
56
from unittest.mock import AsyncMock, patch
67

@@ -269,7 +270,7 @@ async def mock_receive():
269270

270271

271272
@pytest.mark.anyio
272-
async def test_unknown_session_id_returns_404():
273+
async def test_unknown_session_id_returns_404(caplog: pytest.LogCaptureFixture):
273274
"""Test that requests with unknown session IDs return HTTP 404 per MCP spec."""
274275
app = Server("test-unknown-session")
275276
manager = StreamableHTTPSessionManager(app=app)
@@ -299,7 +300,8 @@ async def mock_send(message: Message):
299300
async def mock_receive():
300301
return {"type": "http.request", "body": b"{}", "more_body": False} # pragma: no cover
301302

302-
await manager.handle_request(scope, mock_receive, mock_send)
303+
with caplog.at_level(logging.INFO):
304+
await manager.handle_request(scope, mock_receive, mock_send)
303305

304306
# Find the response start message
305307
response_start = next(
@@ -315,6 +317,7 @@ async def mock_receive():
315317
assert error_data["id"] is None
316318
assert error_data["error"]["code"] == INVALID_REQUEST
317319
assert error_data["error"]["message"] == "Session not found"
320+
assert "Rejected request with unknown or expired session ID: non-existent-session-id" in caplog.text
318321

319322

320323
@pytest.mark.anyio

0 commit comments

Comments
 (0)