Skip to content
Open
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
2 changes: 2 additions & 0 deletions lib/mcp/server/transports/streamable_http_transport.rb
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,10 @@ def handle_delete(request)
end

return missing_session_id_response unless (session_id = request.env["HTTP_MCP_SESSION_ID"])
return session_not_found_response unless session_exists?(session_id)

cleanup_session(session_id)

success_response
end

Expand Down
78 changes: 78 additions & 0 deletions test/mcp/server/transports/streamable_http_transport_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,84 @@ class StreamableHTTPTransportTest < ActiveSupport::TestCase
assert body["success"]
end

test "handles DELETE request with invalid session ID" do
request = create_rack_request(
"DELETE",
"/",
{ "HTTP_MCP_SESSION_ID" => "invalid_id" },
)

response = @transport.handle_request(request)
assert_equal 404, response[0]
assert_equal({ "Content-Type" => "application/json" }, response[1])

body = JSON.parse(response[2][0])
assert_equal "Session not found", body["error"]
end

test "POST returns 404 after session is deleted" do
init_request = create_rack_request(
"POST",
"/",
{ "CONTENT_TYPE" => "application/json" },
{ jsonrpc: "2.0", method: "initialize", id: "init" }.to_json,
)
init_response = @transport.handle_request(init_request)
session_id = init_response[1]["Mcp-Session-Id"]

delete_request = create_rack_request(
"DELETE",
"/",
{ "HTTP_MCP_SESSION_ID" => session_id },
)
@transport.handle_request(delete_request)

post_request = create_rack_request(
"POST",
"/",
{
"CONTENT_TYPE" => "application/json",
"HTTP_MCP_SESSION_ID" => session_id,
},
{ jsonrpc: "2.0", method: "ping", id: "456" }.to_json,
)
response = @transport.handle_request(post_request)
assert_equal 404, response[0]

body = JSON.parse(response[2][0])
assert_equal "Session not found", body["error"]
end

test "DELETE returns 404 after session is already deleted" do
init_request = create_rack_request(
"POST",
"/",
{ "CONTENT_TYPE" => "application/json" },
{ jsonrpc: "2.0", method: "initialize", id: "init" }.to_json,
)
init_response = @transport.handle_request(init_request)
session_id = init_response[1]["Mcp-Session-Id"]

first_delete = create_rack_request(
"DELETE",
"/",
{ "HTTP_MCP_SESSION_ID" => session_id },
)
response = @transport.handle_request(first_delete)
assert_equal 200, response[0]

second_delete = create_rack_request(
"DELETE",
"/",
{ "HTTP_MCP_SESSION_ID" => session_id },
)
response = @transport.handle_request(second_delete)
assert_equal 404, response[0]

body = JSON.parse(response[2][0])
assert_equal "Session not found", body["error"]
end

test "handles DELETE request with missing session ID" do
request = create_rack_request(
"DELETE",
Expand Down