Skip to content

Commit bea4746

Browse files
atesgoralclaude
andcommitted
Handle 202 Accepted response in HTTP client
The Streamable HTTP spec allows a server to respond 202 Accepted when it has received the request but will deliver the response later via an SSE stream. The client previously errored on 202 because the response has no parseable Content-Type. Return `{ "accepted" => true }` so the caller can decide how to proceed. Actually picking up the deferred response requires listening on an SSE stream (GET-for-SSE), which is not yet implemented. This PR only prevents the hard error on a valid server response. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent 9fcafa2 commit bea4746

2 files changed

Lines changed: 19 additions & 0 deletions

File tree

lib/mcp/client/http.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,10 @@ def parse_response_body(response, method, params)
106106
parse_sse_response(response.body, method, params)
107107
elsif content_type&.include?("application/json")
108108
response.body
109+
elsif response.status == 202
110+
# Server accepted the request and will deliver the response via an SSE stream.
111+
# https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#sending-messages-to-the-server
112+
{ "accepted" => true }
109113
else
110114
raise RequestHandlerError.new(
111115
"Unsupported Content-Type: #{content_type.inspect}. Expected application/json or text/event-stream.",

test/mcp/client/http_test.rb

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,21 @@ def test_send_request_parses_sse_error_response
369369
assert_equal("Invalid request", response.dig("error", "message"))
370370
end
371371

372+
def test_send_request_returns_accepted_for_202_response
373+
request = {
374+
jsonrpc: "2.0",
375+
method: "notifications/initialized",
376+
}
377+
378+
stub_request(:post, url)
379+
.with(body: request.to_json)
380+
.to_return(status: 202, body: "")
381+
382+
response = client.send_request(request: request)
383+
384+
assert_equal({ "accepted" => true }, response)
385+
end
386+
372387
def test_send_request_raises_error_for_sse_without_response
373388
request = {
374389
jsonrpc: "2.0",

0 commit comments

Comments
 (0)