Skip to content

Commit 18b3a23

Browse files
committed
fix: default CallToolResult content to empty vec on missing field
1 parent 1a4a52a commit 18b3a23

2 files changed

Lines changed: 21 additions & 8 deletions

File tree

crates/rmcp/src/model.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2697,6 +2697,7 @@ pub type ElicitationCompletionNotification =
26972697
#[non_exhaustive]
26982698
pub struct CallToolResult {
26992699
/// The content returned by the tool (text, images, etc.)
2700+
#[serde(default)]
27002701
pub content: Vec<Content>,
27012702
/// An optional JSON object that represents the structured result of the tool call
27022703
#[serde(skip_serializing_if = "Option::is_none")]

crates/rmcp/tests/test_structured_output.rs

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -298,18 +298,20 @@ async fn test_empty_content_array_with_is_error() {
298298
assert_eq!(result.is_error, Some(false));
299299
}
300300

301-
#[tokio::test]
302-
async fn test_missing_content_is_rejected() {
301+
#[test]
302+
fn test_missing_content_defaults_to_empty() {
303303
let raw = json!({ "isError": false });
304-
let result: Result<CallToolResult, _> = serde_json::from_value(raw);
305-
assert!(result.is_err());
304+
let result: CallToolResult = serde_json::from_value(raw).unwrap();
305+
assert!(result.content.is_empty());
306+
assert_eq!(result.is_error, Some(false));
306307
}
307308

308-
#[tokio::test]
309-
async fn test_missing_content_with_structured_content_is_rejected() {
309+
#[test]
310+
fn test_missing_content_with_structured_content_deserializes() {
310311
let raw = json!({ "structuredContent": {"key": "value"}, "isError": false });
311-
let result: Result<CallToolResult, _> = serde_json::from_value(raw);
312-
assert!(result.is_err());
312+
let result: CallToolResult = serde_json::from_value(raw).unwrap();
313+
assert!(result.content.is_empty());
314+
assert_eq!(result.structured_content.unwrap()["key"], "value");
313315
}
314316

315317
#[tokio::test]
@@ -333,3 +335,13 @@ async fn test_empty_content_roundtrip() {
333335
let deserialized: CallToolResult = serde_json::from_value(v).unwrap();
334336
assert_eq!(deserialized, result);
335337
}
338+
339+
#[test]
340+
fn test_call_tool_result_deserialize_without_content() {
341+
let json = json!({
342+
"structuredContent": {"message": "Hello"}
343+
});
344+
let result: CallToolResult = serde_json::from_value(json).unwrap();
345+
assert!(result.content.is_empty());
346+
assert!(result.structured_content.is_some());
347+
}

0 commit comments

Comments
 (0)