Skip to content

Commit fc757d4

Browse files
authored
fix: allow deserializing notifications without params field (#729)
1 parent 1158cfe commit fc757d4

2 files changed

Lines changed: 25 additions & 3 deletions

File tree

crates/rmcp/src/model.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3834,4 +3834,15 @@ mod tests {
38343834
});
38353835
assert_eq!(json_url, expected_url_json);
38363836
}
3837+
3838+
#[test]
3839+
fn notification_without_params_should_deserialize_as_bare_jsonrpc_message() {
3840+
let payload = b"{\"method\":\"notifications/initialized\",\"jsonrpc\":\"2.0\"}";
3841+
let result: Result<JsonRpcMessage, _> = serde_json::from_slice(payload);
3842+
assert!(
3843+
matches!(result, Ok(JsonRpcMessage::Notification(_))),
3844+
"Expected Ok(Notification), got: {:?}",
3845+
result
3846+
);
3847+
}
38373848
}

crates/rmcp/src/model/serde_impl.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -246,16 +246,27 @@ where
246246
where
247247
D: serde::Deserializer<'de>,
248248
{
249-
let body = Proxy::deserialize(deserializer)?;
250-
let _meta = body.params._meta.map(|m| m.into_owned());
249+
let body = ProxyOptionalParam::<'_, _, R>::deserialize(deserializer)?;
250+
let (_meta, params) = match body.params {
251+
Some(with_meta) => {
252+
let meta = with_meta._meta.map(|m| m.into_owned());
253+
(meta, with_meta._rest)
254+
}
255+
None => {
256+
// JSON-RPC 2.0: params is optional. Treat absent params as {}.
257+
let empty = serde_json::Value::Object(serde_json::Map::new());
258+
let r = R::deserialize(empty).map_err(serde::de::Error::custom)?;
259+
(None, r)
260+
}
261+
};
251262
let mut extensions = Extensions::new();
252263
if let Some(meta) = _meta {
253264
extensions.insert(meta);
254265
}
255266
Ok(Notification {
256267
extensions,
257268
method: body.method,
258-
params: body.params._rest,
269+
params,
259270
})
260271
}
261272
}

0 commit comments

Comments
 (0)