99// / - Simpler than SSE (no separate GET endpoint for events)
1010
1111#include " fastmcpp/client/transports.hpp"
12+ #include " fastmcpp/exceptions.hpp"
1213#include " fastmcpp/mcp/handler.hpp"
1314#include " fastmcpp/server/streamable_http_server.hpp"
1415#include " fastmcpp/tools/manager.hpp"
@@ -64,45 +65,32 @@ void test_basic_request_response()
6465 client::StreamableHttpTransport transport (" http://" + host + " :" + std::to_string (port));
6566
6667 // Initialize should work and create a session
67- Json init_request = {{" jsonrpc" , " 2.0" },
68- {" id" , 1 },
69- {" method" , " initialize" },
70- {" params" ,
71- {{" protocolVersion" , " 2024-11-05" },
72- {" capabilities" , Json::object ()},
73- {" clientInfo" , {{" name" , " test_client" }, {" version" , " 1.0.0" }}}}}};
74-
75- auto init_response = transport.request (" mcp" , init_request);
76-
77- // Should have a valid response
78- assert (init_response.contains (" result" ) && " Initialize should return result" );
79- assert (init_response[" result" ].contains (" serverInfo" ) && " Should have serverInfo" );
68+ // Note: request() takes method name and params, returns unwrapped result
69+ Json init_params = {{" protocolVersion" , " 2024-11-05" },
70+ {" capabilities" , Json::object ()},
71+ {" clientInfo" , {{" name" , " test_client" }, {" version" , " 1.0.0" }}}};
72+
73+ auto init_result = transport.request (" initialize" , init_params);
74+
75+ // Should have a valid result (already unwrapped from JSON-RPC envelope)
76+ assert (init_result.contains (" serverInfo" ) && " Should have serverInfo" );
8077 assert (transport.has_session () && " Should have session after initialize" );
8178
8279 // List tools
83- Json list_request = {
84- {" jsonrpc" , " 2.0" }, {" id" , 2 }, {" method" , " tools/list" }, {" params" , {}}};
85-
86- auto list_response = transport.request (" mcp" , list_request);
87- assert (list_response.contains (" result" ) && " tools/list should return result" );
88- assert (list_response[" result" ].contains (" tools" ) && " Should have tools array" );
80+ auto list_result = transport.request (" tools/list" , Json::object ());
81+ assert (list_result.contains (" tools" ) && " Should have tools array" );
8982
90- auto & tools = list_response[ " result " ] [" tools" ];
83+ auto & tools = list_result [" tools" ];
9184 assert (tools.is_array () && tools.size () == 1 && " Should have one tool" );
9285 assert (tools[0 ][" name" ] == " echo" && " Tool should be echo" );
9386
9487 // Call the echo tool
95- Json call_request = {
96- {" jsonrpc" , " 2.0" },
97- {" id" , 3 },
98- {" method" , " tools/call" },
99- {" params" , {{" name" , " echo" }, {" arguments" , {{" message" , " Hello, World!" }}}}}};
88+ Json call_params = {{" name" , " echo" }, {" arguments" , {{" message" , " Hello, World!" }}}};
10089
101- auto call_response = transport.request (" mcp" , call_request);
102- assert (call_response.contains (" result" ) && " tools/call should return result" );
103- assert (call_response[" result" ].contains (" content" ) && " Should have content" );
90+ auto call_result = transport.request (" tools/call" , call_params);
91+ assert (call_result.contains (" content" ) && " Should have content" );
10492
105- auto & content = call_response[ " result " ] [" content" ];
93+ auto & content = call_result [" content" ];
10694 assert (content.is_array () && content.size () > 0 && " Should have content array" );
10795 assert (content[0 ][" type" ] == " text" && " Content should be text" );
10896 assert (content[0 ][" text" ] == " Hello, World!" && " Echo should return input" );
@@ -156,16 +144,12 @@ void test_session_management()
156144 // Before initialize, should have no session
157145 assert (!transport.has_session () && " Should have no session before initialize" );
158146
159- // Initialize
160- Json init_request = {{" jsonrpc" , " 2.0" },
161- {" id" , 1 },
162- {" method" , " initialize" },
163- {" params" ,
164- {{" protocolVersion" , " 2024-11-05" },
165- {" capabilities" , Json::object ()},
166- {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}}}};
147+ // Initialize - request() takes method name and params
148+ Json init_params = {{" protocolVersion" , " 2024-11-05" },
149+ {" capabilities" , Json::object ()},
150+ {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}};
167151
168- transport.request (" mcp " , init_request );
152+ transport.request (" initialize " , init_params );
169153
170154 // After initialize, should have session
171155 assert (transport.has_session () && " Should have session after initialize" );
@@ -176,10 +160,7 @@ void test_session_management()
176160 assert (server.session_count () == 1 && " Server should have 1 session" );
177161
178162 // Second request should reuse session
179- Json list_request = {
180- {" jsonrpc" , " 2.0" }, {" id" , 2 }, {" method" , " tools/list" }, {" params" , {}}};
181-
182- transport.request (" mcp" , list_request);
163+ transport.request (" tools/list" , Json::object ());
183164
184165 // Session ID should still be the same
185166 assert (transport.session_id () == session_id && " Session ID should persist" );
@@ -228,19 +209,13 @@ void test_server_info()
228209 {
229210 client::StreamableHttpTransport transport (" http://" + host + " :" + std::to_string (port));
230211
231- Json init_request = {{" jsonrpc" , " 2.0" },
232- {" id" , 1 },
233- {" method" , " initialize" },
234- {" params" ,
235- {{" protocolVersion" , " 2024-11-05" },
236- {" capabilities" , Json::object ()},
237- {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}}}};
238-
239- auto response = transport.request (" mcp" , init_request);
212+ Json init_params = {{" protocolVersion" , " 2024-11-05" },
213+ {" capabilities" , Json::object ()},
214+ {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}};
240215
241- assert (response.contains (" result" ));
242- auto & result = response[" result" ];
216+ auto result = transport.request (" initialize" , init_params);
243217
218+ // Result is already unwrapped from JSON-RPC envelope
244219 // Check server info
245220 assert (result.contains (" serverInfo" ));
246221 auto & server_info = result[" serverInfo" ];
@@ -292,28 +267,32 @@ void test_error_handling()
292267 client::StreamableHttpTransport transport (" http://" + host + " :" + std::to_string (port));
293268
294269 // Initialize first
295- Json init_request = {{" jsonrpc" , " 2.0" },
296- {" id" , 1 },
297- {" method" , " initialize" },
298- {" params" ,
299- {{" protocolVersion" , " 2024-11-05" },
300- {" capabilities" , Json::object ()},
301- {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}}}};
302-
303- transport.request (" mcp" , init_request);
304-
305- // Call non-existent tool
306- Json bad_request = {{" jsonrpc" , " 2.0" },
307- {" id" , 2 },
308- {" method" , " tools/call" },
309- {" params" , {{" name" , " nonexistent" }, {" arguments" , {}}}}};
310-
311- auto error_response = transport.request (" mcp" , bad_request);
312-
313- // Should have error, not result
314- assert (error_response.contains (" error" ) && " Should have error response" );
315- assert (error_response[" error" ].contains (" code" ) && " Error should have code" );
316- assert (error_response[" error" ].contains (" message" ) && " Error should have message" );
270+ Json init_params = {{" protocolVersion" , " 2024-11-05" },
271+ {" capabilities" , Json::object ()},
272+ {" clientInfo" , {{" name" , " test" }, {" version" , " 1.0" }}}};
273+
274+ transport.request (" initialize" , init_params);
275+
276+ // Call non-existent tool - should throw TransportError with JSON-RPC error
277+ Json bad_params = {{" name" , " nonexistent" }, {" arguments" , Json::object ()}};
278+
279+ bool caught_error = false ;
280+ try
281+ {
282+ transport.request (" tools/call" , bad_params);
283+ // Should not reach here
284+ assert (false && " Should have thrown error for non-existent tool" );
285+ }
286+ catch (const fastmcpp::TransportError& e)
287+ {
288+ // Expected - transport throws on JSON-RPC errors
289+ std::string error_msg = e.what ();
290+ assert (error_msg.find (" JSON-RPC error" ) != std::string::npos &&
291+ " Should be JSON-RPC error" );
292+ caught_error = true ;
293+ }
294+
295+ assert (caught_error && " Should have caught TransportError" );
317296
318297 std::cout << " PASSED\n " ;
319298 }
0 commit comments