@@ -40,24 +40,11 @@ impl McpServer {
4040
4141 debug ! ( "Received: {}" , line) ;
4242
43- let request_value: Value = match serde_json:: from_str ( & line) {
44- Ok ( value) => value,
45- Err ( e) => {
46- error ! ( "Failed to parse request: {}" , e) ;
47- let resp = JsonRpcResponse :: error ( None , -32700 , format ! ( "Parse error: {}" , e) ) ;
48- Self :: write_response ( & mut stdout, & resp) . await ?;
49- continue ;
50- }
51- } ;
52- let is_notification = request_value
53- . as_object ( )
54- . is_some_and ( |request| !request. contains_key ( "id" ) ) ;
55- let request: JsonRpcRequest = match serde_json:: from_value ( request_value) {
43+ let ( request, is_notification) = match Self :: parse_request ( & line) {
5644 Ok ( request) => request,
57- Err ( e) => {
58- error ! ( "Failed to parse request: {}" , e) ;
59- let resp = JsonRpcResponse :: error ( None , -32700 , format ! ( "Parse error: {}" , e) ) ;
60- Self :: write_response ( & mut stdout, & resp) . await ?;
45+ Err ( response) => {
46+ error ! ( "Rejected invalid JSON-RPC input" ) ;
47+ Self :: write_response ( & mut stdout, & response) . await ?;
6148 continue ;
6249 }
6350 } ;
@@ -71,6 +58,36 @@ impl McpServer {
7158 Ok ( ( ) )
7259 }
7360
61+ fn parse_request ( line : & str ) -> Result < ( JsonRpcRequest , bool ) , Box < JsonRpcResponse > > {
62+ let request_value: Value = serde_json:: from_str ( line) . map_err ( |error| {
63+ Box :: new ( JsonRpcResponse :: error (
64+ None ,
65+ -32700 ,
66+ format ! ( "Parse error: {error}" ) ,
67+ ) )
68+ } ) ?;
69+ let is_notification = request_value
70+ . as_object ( )
71+ . is_some_and ( |request| !request. contains_key ( "id" ) ) ;
72+ let request: JsonRpcRequest = serde_json:: from_value ( request_value) . map_err ( |error| {
73+ Box :: new ( JsonRpcResponse :: error (
74+ None ,
75+ -32600 ,
76+ format ! ( "Invalid Request: {error}" ) ,
77+ ) )
78+ } ) ?;
79+
80+ if request. jsonrpc != "2.0" {
81+ return Err ( Box :: new ( JsonRpcResponse :: error (
82+ None ,
83+ -32600 ,
84+ "Invalid Request: jsonrpc must be \" 2.0\" " . to_string ( ) ,
85+ ) ) ) ;
86+ }
87+
88+ Ok ( ( request, is_notification) )
89+ }
90+
7491 async fn write_response ( stdout : & mut io:: Stdout , response : & JsonRpcResponse ) -> Result < ( ) > {
7592 let response_str = serde_json:: to_string ( response) ?;
7693 debug ! ( "Sending: {}" , response_str) ;
@@ -193,4 +210,21 @@ mod tests {
193210 assert ! ( response. get( "id" ) . is_some( ) ) ;
194211 assert ! ( response[ "id" ] . is_null( ) ) ;
195212 }
213+
214+ #[ test]
215+ fn distinguishes_malformed_json_from_invalid_requests ( ) {
216+ let malformed = McpServer :: parse_request ( "{" ) . unwrap_err ( ) ;
217+ let invalid = McpServer :: parse_request ( r#"{"jsonrpc":"2.0","id":1}"# ) . unwrap_err ( ) ;
218+
219+ assert_eq ! ( malformed. error. unwrap( ) . code, -32700 ) ;
220+ assert_eq ! ( invalid. error. unwrap( ) . code, -32600 ) ;
221+ }
222+
223+ #[ test]
224+ fn rejects_unsupported_json_rpc_versions ( ) {
225+ let response =
226+ McpServer :: parse_request ( r#"{"jsonrpc":"1.0","id":1,"method":"ping"}"# ) . unwrap_err ( ) ;
227+
228+ assert_eq ! ( response. error. unwrap( ) . code, -32600 ) ;
229+ }
196230}
0 commit comments