diff --git a/hive-matrix-mcp/src/protocol.rs b/hive-matrix-mcp/src/protocol.rs index efc5affd..d5982620 100644 --- a/hive-matrix-mcp/src/protocol.rs +++ b/hive-matrix-mcp/src/protocol.rs @@ -68,8 +68,11 @@ pub enum DaemonRequest { #[serde(rename = "read_room")] ReadRoom { room: String, limit: Option }, - /// Liveness probe used by the stdio MCP bridge on connect — fast - /// "are you up?" round-trip that doesn't touch matrix-sdk. + /// Liveness probe — fast "are you up?" round-trip that doesn't + /// touch matrix-sdk. Not used by the in-tree stdio MCP bridge + /// (which surfaces a daemon-down condition as a normal tool-call + /// connect error); reserved for external clients that want an + /// explicit health check without doing real work. #[serde(rename = "ping")] Ping, } @@ -86,10 +89,14 @@ pub enum DaemonResponse { impl DaemonResponse { /// Convenience: build an Ok response from any serializable value. + /// Serialisation failure (impossible for the small handler structs + /// we use, but the API is generic) surfaces as a structured + /// `{"serialise_error": "..."}` payload so callers see WHY the + /// data is missing instead of a silent `null`. pub fn ok(payload: &T) -> Self { - Self::Ok { - payload: serde_json::to_value(payload).unwrap_or(serde_json::Value::Null), - } + let payload = serde_json::to_value(payload) + .unwrap_or_else(|e| serde_json::json!({ "serialise_error": e.to_string() })); + Self::Ok { payload } } /// Convenience: build an Error response from any `Display` value.