Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/mcp/server/streamable_http_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ async def run_server(*, task_status: TaskStatus[None] = anyio.TASK_STATUS_IGNORE
# Unknown or expired session ID - return 404 per MCP spec
# TODO: Align error code once spec clarifies
# See: https://github.com/modelcontextprotocol/python-sdk/issues/1821
logger.info(f"Rejected request with unknown or expired session ID: {request_mcp_session_id[:64]}")
error_response = JSONRPCError(
jsonrpc="2.0",
id=None,
Expand Down
7 changes: 5 additions & 2 deletions tests/server/test_streamable_http_manager.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Tests for StreamableHTTPSessionManager."""

import json
import logging
from typing import Any
from unittest.mock import AsyncMock, patch

Expand Down Expand Up @@ -269,7 +270,7 @@ async def mock_receive():


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

await manager.handle_request(scope, mock_receive, mock_send)
with caplog.at_level(logging.INFO):
await manager.handle_request(scope, mock_receive, mock_send)

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


@pytest.mark.anyio
Expand Down