use serde_json::Value;
use trusty_common::console_metrics::{make_report, ServiceHealth};
use super::DispatchError;
pub(super) fn descriptor() -> Value {
serde_json::json!({
"name": "console_metrics",
"description": "Return health and operational metrics for trusty-console polling. \
No arguments required. Returns a ConsoleMetricsReport JSON envelope \
with service_id='trusty-analyze', version, status (ok/degraded), and \
a metrics object containing search_reachable.",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
}
})
}
pub(super) async fn handle_console_metrics(
server: &super::AnalyzerMcpServer,
) -> Result<Value, DispatchError> {
let health = server.get("/health").await;
let search_reachable = health
.as_ref()
.ok()
.and_then(|v| v.get("search_reachable"))
.and_then(Value::as_bool)
.unwrap_or(false);
let status = if search_reachable {
ServiceHealth::Ok
} else {
ServiceHealth::Degraded
};
let metrics = serde_json::json!({
"search_reachable": search_reachable,
});
let report = make_report(
"trusty-analyze",
"Trusty Analyze",
env!("CARGO_PKG_VERSION"),
status,
metrics,
1, );
serde_json::to_value(&report)
.map_err(|e| DispatchError::Transport(format!("console_metrics: to_value failed: {e}")))
}
#[cfg(test)]
mod tests {
use trusty_common::console_metrics::parse_report;
use super::*;
#[test]
fn descriptor_name_matches_contract() {
let d = descriptor();
assert_eq!(
d.get("name").and_then(Value::as_str),
Some(trusty_common::console_metrics::CONSOLE_METRICS_METHOD),
"descriptor name must match CONSOLE_METRICS_METHOD"
);
}
#[test]
fn parse_report_round_trip() {
let report = make_report(
"trusty-analyze",
"Trusty Analyze",
"0.7.0",
ServiceHealth::Degraded,
serde_json::json!({ "search_reachable": false }),
1,
);
let raw_value = serde_json::to_value(&report).expect("to_value must succeed");
let wrapped = serde_json::json!({
"content": [{
"type": "text",
"text": serde_json::to_string_pretty(&raw_value)
.expect("to_string_pretty must succeed"),
}],
"isError": false,
});
let decoded = parse_report(&wrapped).expect("parse must succeed");
assert_eq!(decoded.service_id, "trusty-analyze");
assert_eq!(decoded.display_name, "Trusty Analyze");
assert_eq!(decoded.version, "0.7.0");
assert_eq!(decoded.status, ServiceHealth::Degraded);
assert_eq!(decoded.metrics_schema_version, 1);
assert_eq!(decoded.metrics["search_reachable"], false);
}
#[test]
fn descriptor_has_input_schema() {
let d = descriptor();
assert!(
d.get("inputSchema").is_some(),
"descriptor must have inputSchema"
);
}
}