Skip to content

Commit f677365

Browse files
authored
Fix StreamableHttpTransport JSON-RPC envelope handling (#18)
* Fix StreamableHttpTransport to build JSON-RPC envelope and extract result The StreamableHttpTransport::request method was passing the params directly to the server instead of wrapping them in a JSON-RPC envelope. It was also returning the full JSON-RPC response instead of extracting the result. Fixes: - Build proper JSON-RPC request with jsonrpc, method, params, and id - Extract result from JSON-RPC response envelope - Handle JSON-RPC errors by throwing TransportError * Fix clang-format for streaming_demo.cpp and sse.cpp
1 parent 164f642 commit f677365

3 files changed

Lines changed: 24 additions & 8 deletions

File tree

examples/streaming_demo.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,8 @@ int main()
4848
std::thread sse_thread(
4949
[&, port]()
5050
{
51-
// Create client inside thread - httplib::Client is not thread-safe across threads on Linux
51+
// Create client inside thread - httplib::Client is not thread-safe across threads on
52+
// Linux
5253
httplib::Client cli("127.0.0.1", port);
5354
cli.set_connection_timeout(std::chrono::seconds(10));
5455
cli.set_read_timeout(std::chrono::seconds(20));

src/client/transports.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -924,7 +924,7 @@ fastmcpp::Json StreamableHttpTransport::parse_response(const std::string& body,
924924
}
925925
}
926926

927-
fastmcpp::Json StreamableHttpTransport::request(const std::string& /*route*/,
927+
fastmcpp::Json StreamableHttpTransport::request(const std::string& route,
928928
const fastmcpp::Json& payload)
929929
{
930930
auto url = parse_url(base_url_);
@@ -951,11 +951,13 @@ fastmcpp::Json StreamableHttpTransport::request(const std::string& /*route*/,
951951
request_headers.emplace("Mcp-Session-Id", session_id_);
952952
}
953953

954-
// Payload is the full JSON-RPC request
955-
// (StreamableHttp transport accepts complete JSON-RPC requests, unlike other transports)
954+
// Build JSON-RPC request (route is method, payload is params)
955+
int64_t id = next_id_.fetch_add(1, std::memory_order_relaxed);
956+
fastmcpp::Json rpc_request = {
957+
{"jsonrpc", "2.0"}, {"method", route}, {"params", payload}, {"id", id}};
956958

957959
// Send request
958-
auto res = cli.Post(mcp_path_.c_str(), request_headers, payload.dump(), "application/json");
960+
auto res = cli.Post(mcp_path_.c_str(), request_headers, rpc_request.dump(), "application/json");
959961

960962
if (!res)
961963
throw fastmcpp::TransportError("StreamableHttp request failed: no response");
@@ -982,8 +984,20 @@ fastmcpp::Json StreamableHttpTransport::request(const std::string& /*route*/,
982984
// Parse response
983985
auto rpc_response = parse_response(res->body, content_type);
984986

985-
// Return full JSON-RPC response (caller handles error/result extraction)
986-
return rpc_response;
987+
// Check for JSON-RPC error
988+
if (rpc_response.contains("error"))
989+
{
990+
auto error = rpc_response["error"];
991+
std::string message = error.value("message", "Unknown error");
992+
throw fastmcpp::TransportError("JSON-RPC error: " + message);
993+
}
994+
995+
// Extract result from JSON-RPC envelope
996+
if (rpc_response.contains("result"))
997+
return rpc_response["result"];
998+
999+
// If no result or error, return empty object
1000+
return fastmcpp::Json::object();
9871001
}
9881002

9891003
} // namespace fastmcpp::client

tests/server/sse.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ int main()
6666
std::thread sse_thread(
6767
[&, port]()
6868
{
69-
// Create client inside thread - httplib::Client is not thread-safe across threads on Linux
69+
// Create client inside thread - httplib::Client is not thread-safe across threads on
70+
// Linux
7071
httplib::Client sse_client("127.0.0.1", port);
7172
sse_client.set_read_timeout(std::chrono::seconds(20));
7273
sse_client.set_connection_timeout(std::chrono::seconds(10));

0 commit comments

Comments
 (0)