@@ -3,13 +3,14 @@ use std::{collections::HashMap, error::Error, sync::Arc, time::Duration, vec};
33use hyper:: StatusCode ;
44use rust_mcp_schema:: {
55 schema_utils:: {
6- ClientJsonrpcRequest , ClientMessage , ClientMessages , FromMessage , NotificationFromServer ,
7- ResultFromServer , RpcMessage , SdkError , SdkErrorCodes , ServerJsonrpcNotification ,
8- ServerJsonrpcResponse , ServerMessages ,
6+ ClientJsonrpcRequest , ClientJsonrpcResponse , ClientMessage , ClientMessages , FromMessage ,
7+ NotificationFromServer , RequestFromServer , ResultFromServer , RpcMessage , SdkError ,
8+ SdkErrorCodes , ServerJsonrpcNotification , ServerJsonrpcRequest , ServerJsonrpcResponse ,
9+ ServerMessages ,
910 } ,
10- CallToolRequest , CallToolRequestParams , ListToolsRequest , LoggingLevel ,
11- LoggingMessageNotificationParams , RequestId , RootsListChangedNotification , ServerNotification ,
12- ServerResult ,
11+ CallToolRequest , CallToolRequestParams , ListPromptsRequestParams , ListRootsRequestParams ,
12+ ListRootsResult , ListToolsRequest , LoggingLevel , LoggingMessageNotificationParams , RequestId ,
13+ RootsListChangedNotification , ServerNotification , ServerRequest , ServerResult ,
1314} ;
1415use rust_mcp_sdk:: mcp_server:: HyperServerOptions ;
1516use serde_json:: { json, Map , Value } ;
@@ -364,6 +365,80 @@ async fn should_establish_standalone_stream_and_receive_server_messages() {
364365 server. hyper_runtime . await_server ( ) . await . unwrap ( )
365366}
366367
368+ // should establish standalone SSE stream and receive server-initiated messages
369+ #[ tokio:: test]
370+ async fn should_establish_standalone_stream_and_receive_server_requests ( ) {
371+ let ( server, session_id) = initialize_server ( None ) . await . unwrap ( ) ;
372+ let response = get_standalone_stream ( & server. streamable_url , & session_id) . await ;
373+
374+ assert_eq ! ( response. status( ) , StatusCode :: OK ) ;
375+
376+ assert_eq ! (
377+ response
378+ . headers( )
379+ . get( "mcp-session-id" )
380+ . unwrap( )
381+ . to_str( )
382+ . unwrap( ) ,
383+ session_id
384+ ) ;
385+
386+ assert_eq ! (
387+ response
388+ . headers( )
389+ . get( "content-type" )
390+ . unwrap( )
391+ . to_str( )
392+ . unwrap( ) ,
393+ "text/event-stream"
394+ ) ;
395+
396+ let hyper_server = Arc :: new ( server. hyper_runtime ) ;
397+ let hyper_server_clone = hyper_server. clone ( ) ;
398+ let session_id_clone = session_id. to_string ( ) ;
399+
400+ tokio:: spawn ( async move {
401+ // Send a server-initiated notification that should appear on SSE stream with a valid request_id
402+ hyper_server_clone
403+ . list_roots ( & session_id_clone, None )
404+ . await
405+ . unwrap ( ) ;
406+ } ) ;
407+
408+ tokio:: time:: sleep ( Duration :: from_millis ( 2250 ) ) . await ;
409+
410+ let json_rpc_message: ClientJsonrpcResponse = ClientJsonrpcResponse :: new (
411+ RequestId :: Integer ( 0 ) ,
412+ ListRootsResult {
413+ meta : None ,
414+ roots : vec ! [ ] ,
415+ }
416+ . into ( ) ,
417+ ) ;
418+
419+ send_post_request (
420+ & server. streamable_url ,
421+ & serde_json:: to_string ( & json_rpc_message) . unwrap ( ) ,
422+ Some ( & session_id) ,
423+ None ,
424+ )
425+ . await
426+ . expect ( "Request failed" ) ;
427+
428+ let event = read_sse_event ( response) . await . unwrap ( ) ;
429+
430+ let message: ServerJsonrpcRequest = serde_json:: from_str ( & event) . unwrap ( ) ;
431+
432+ println ! ( ">>> message {:?} " , message) ;
433+
434+ let RequestFromServer :: ServerRequest ( ServerRequest :: ListRootsRequest ( _) ) = message. request
435+ else {
436+ panic ! ( "invalid message received!" ) ;
437+ } ;
438+
439+ hyper_server. graceful_shutdown ( ONE_MILLISECOND ) ;
440+ }
441+
367442// should not close GET SSE stream after sending multiple server notifications
368443#[ tokio:: test]
369444async fn should_not_close_get_sse_stream ( ) {
0 commit comments