Skip to content

Commit cf1d578

Browse files
committed
Return 404 for invalid session ID in handle_regular_request
## Motivation and Context The MCP specification requires that when a server receives a request containing a session ID that is no longer valid, it MUST respond with HTTP 404 Not Found. The `handle_get` path already returned 404 correctly, but `handle_regular_request` (the POST path) was returning 400 "Invalid session ID" instead. Ref: https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#session-management > The server MAY terminate the session at any time, after which it MUST respond > to requests containing that session ID with HTTP 404 Not Found. ## How Has This Been Tested? Added a test for POST requests with an invalid session ID, verifying that the response is 404 with "Session not found" error message. All existing tests pass. ## Breaking Change POST requests with an invalid session ID now return HTTP 404 "Session not found" instead of HTTP 400 "Invalid session ID". Clients that match on the 400 status code or the old error message will need to be updated. However, this change is considered a bug fix because it brings the behavior into compliance with the MCP specification.
1 parent 6e35d13 commit cf1d578

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

lib/mcp/server/transports/streamable_http_transport.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ def handle_regular_request(body_string, session_id)
261261
unless @stateless
262262
# If session ID is provided, but not in the sessions hash, return an error
263263
if session_id && !@sessions.key?(session_id)
264-
return [400, { "Content-Type" => "application/json" }, [{ error: "Invalid session ID" }.to_json]]
264+
return session_not_found_response
265265
end
266266
end
267267

test/mcp/server/transports/streamable_http_transport_test.rb

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,25 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
287287
assert_equal "Session not found", body["error"]
288288
end
289289

290+
test "handles POST request with invalid session ID" do
291+
request = create_rack_request(
292+
"POST",
293+
"/",
294+
{
295+
"CONTENT_TYPE" => "application/json",
296+
"HTTP_MCP_SESSION_ID" => "invalid_id",
297+
},
298+
{ jsonrpc: "2.0", method: "ping", id: "456" }.to_json,
299+
)
300+
301+
response = @transport.handle_request(request)
302+
assert_equal 404, response[0]
303+
assert_equal({ "Content-Type" => "application/json" }, response[1])
304+
305+
body = JSON.parse(response[2][0])
306+
assert_equal "Session not found", body["error"]
307+
end
308+
290309
test "handles DELETE request with valid session ID" do
291310
# First create a session with initialize
292311
init_request = create_rack_request(

0 commit comments

Comments
 (0)