feat: add health check for MCP servers on dashboard
Some checks failed
CI / Check (pull_request) Failing after 1m44s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped

Add /health endpoint to the MCP server and probe it from the dashboard
on page load to update server status (running/stopped) in real time.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Sharang Parnerkar
2026-03-20 22:51:39 +01:00
parent c62e9fdcd4
commit fad8bbbd65
3 changed files with 73 additions and 2 deletions

View File

@@ -113,6 +113,64 @@ pub async fn add_mcp_server(
Ok(())
}
/// Probe each MCP server's health endpoint and update status in MongoDB.
#[server]
pub async fn refresh_mcp_status() -> Result<(), ServerFnError> {
use chrono::Utc;
use compliance_core::models::McpServerStatus;
use mongodb::bson::doc;
let state: super::server_state::ServerState =
dioxus_fullstack::FullstackContext::extract().await?;
let mut cursor = state
.db
.mcp_servers()
.find(doc! {})
.await
.map_err(|e| ServerFnError::new(e.to_string()))?;
let client = reqwest::Client::builder()
.timeout(std::time::Duration::from_secs(5))
.build()
.map_err(|e| ServerFnError::new(e.to_string()))?;
while cursor
.advance()
.await
.map_err(|e| ServerFnError::new(e.to_string()))?
{
let server: compliance_core::models::McpServerConfig = cursor
.deserialize_current()
.map_err(|e| ServerFnError::new(e.to_string()))?;
let Some(oid) = server.id else { continue };
// Derive health URL from the endpoint (replace trailing /mcp with /health)
let health_url = if server.endpoint_url.ends_with("/mcp") {
format!("{}health", &server.endpoint_url[..server.endpoint_url.len() - 3])
} else {
format!("{}/health", server.endpoint_url.trim_end_matches('/'))
};
let new_status = match client.get(&health_url).send().await {
Ok(resp) if resp.status().is_success() => McpServerStatus::Running,
_ => McpServerStatus::Stopped,
};
let _ = state
.db
.mcp_servers()
.update_one(
doc! { "_id": oid },
doc! { "$set": { "status": bson::to_bson(&new_status).unwrap(), "updated_at": Utc::now().to_rfc3339() } },
)
.await;
}
Ok(())
}
#[server]
pub async fn delete_mcp_server(server_id: String) -> Result<(), ServerFnError> {
use mongodb::bson::doc;