@@ -145,7 +145,17 @@ pub mod call_tool_result {
145145 } ,
146146 }
147147
148- let format = ResultFormat :: deserialize ( deserializer) ?;
148+ let original_value = serde_json:: Value :: deserialize ( deserializer) ?;
149+
150+ let format = ResultFormat :: deserialize ( & original_value) . map_err ( |e| {
151+ tracing:: debug!(
152+ "Failed to deserialize call_tool_result: {}. Original data: {}" ,
153+ e,
154+ serde_json:: to_string( & original_value)
155+ . unwrap_or_else( |_| "<invalid json>" . to_string( ) )
156+ ) ;
157+ serde:: de:: Error :: custom ( e)
158+ } ) ?;
149159
150160 match format {
151161 ResultFormat :: SuccessWithCallToolResult { status, value } => {
@@ -184,4 +194,87 @@ pub mod call_tool_result {
184194 }
185195 }
186196 }
197+
198+ pub fn validate ( result : ToolResult < CallToolResult > ) -> ToolResult < CallToolResult > {
199+ match & result {
200+ Ok ( call_tool_result) => match serde_json:: to_string ( call_tool_result) {
201+ Ok ( json_str) => match serde_json:: from_str :: < CallToolResult > ( & json_str) {
202+ Ok ( _) => result,
203+ Err ( e) => {
204+ tracing:: error!( "CallToolResult failed validation by deserialization: {}. Original data: {}" , e, json_str) ;
205+ Err ( ErrorData {
206+ code : ErrorCode :: INTERNAL_ERROR ,
207+ message : Cow :: from ( format ! ( "Tool result validation failed: {}" , e) ) ,
208+ data : None ,
209+ } )
210+ }
211+ } ,
212+ Err ( e) => {
213+ tracing:: error!( "CallToolResult failed serialization: {}" , e) ;
214+ Err ( ErrorData {
215+ code : ErrorCode :: INTERNAL_ERROR ,
216+ message : Cow :: from ( format ! ( "Tool result serialization failed: {}" , e) ) ,
217+ data : None ,
218+ } )
219+ }
220+ } ,
221+ Err ( _) => result,
222+ }
223+ }
224+ }
225+
226+ #[ cfg( test) ]
227+ mod tests {
228+ use super :: * ;
229+ use rmcp:: model:: { CallToolResult , Content , ErrorCode , ErrorData } ;
230+ use std:: borrow:: Cow ;
231+ #[ test]
232+ fn test_validate_accepts_valid_call_tool_result ( ) {
233+ let valid_result = CallToolResult {
234+ content : vec ! [ Content :: text( "test" ) ] ,
235+ is_error : Some ( false ) ,
236+ structured_content : None ,
237+ meta : None ,
238+ } ;
239+
240+ let tool_result: ToolResult < CallToolResult > = Ok ( valid_result) ;
241+ let validated = call_tool_result:: validate ( tool_result) ;
242+
243+ assert ! (
244+ validated. is_ok( ) ,
245+ "Expected validation to pass for valid CallToolResult"
246+ ) ;
247+ }
248+ #[ test]
249+ fn test_validate_returns_error_for_invalid_calltoolresult ( ) {
250+ let valid_result = CallToolResult {
251+ content : vec ! [ ] ,
252+ is_error : Some ( false ) ,
253+ structured_content : None ,
254+ meta : None ,
255+ } ;
256+
257+ let tool_result: ToolResult < CallToolResult > = Ok ( valid_result) ;
258+ let validated = call_tool_result:: validate ( tool_result) ;
259+
260+ assert ! ( validated. is_err( ) ) ;
261+ assert ! ( validated
262+ . unwrap_err( )
263+ . message
264+ . contains( "Tool result validation failed" ) )
265+ }
266+
267+ #[ test]
268+ fn test_validate_passes_through_errors ( ) {
269+ let error_result: ToolResult < CallToolResult > = Err ( ErrorData {
270+ code : ErrorCode :: INTERNAL_ERROR ,
271+ message : Cow :: from ( "test error" ) ,
272+ data : None ,
273+ } ) ;
274+
275+ let validated = call_tool_result:: validate ( error_result. clone ( ) ) ;
276+
277+ assert ! ( validated. is_err( ) ) ;
278+ assert_eq ! ( validated. unwrap_err( ) . message, "test error" ) ;
279+ }
187280}
0 commit comments