diff --git a/crates/dtrack-tools/src/lib.rs b/crates/dtrack-tools/src/lib.rs index 27c58a4..450131f 100644 --- a/crates/dtrack-tools/src/lib.rs +++ b/crates/dtrack-tools/src/lib.rs @@ -1,3 +1,5 @@ +use std::sync::Arc; + use dtrack_core::DtrackClient; use rmcp::{ handler::server::router::tool::ToolRouter, @@ -10,8 +12,20 @@ use rmcp::{ }; use schemars::JsonSchema; use serde::Deserialize; +use tokio::sync::RwLock; -/// MCP-Server fuer Dependency-Track. Haelt den DT-Client + den vom Macro +/// Laufzeit-austauschbarer Client-Handle. +/// +/// Die Admin-UI kann den Client neu bauen (geaenderte URL/Key); laufende +/// Sessions ziehen die Aenderung beim naechsten Tool-Aufruf, ohne Neustart. +pub type SharedClient = Arc>; + +/// Verpackt einen Client in einen geteilten, austauschbaren Handle. +pub fn shared_client(client: DtrackClient) -> SharedClient { + Arc::new(RwLock::new(client)) +} + +/// MCP-Server fuer Dependency-Track. Haelt den Client-Handle + den vom Macro /// generierten ToolRouter. /// /// Bewusst transport-unabhaengig: `dtrack-stdio` und `dtrack-http` bauen @@ -19,7 +33,7 @@ use serde::Deserialize; /// davor. #[derive(Clone)] pub struct DtrackServer { - client: DtrackClient, + client: SharedClient, tool_router: ToolRouter, } @@ -32,7 +46,7 @@ pub struct ProjectArg { #[tool_router] impl DtrackServer { - pub fn new(client: DtrackClient) -> Self { + pub fn new(client: SharedClient) -> Self { Self { client, tool_router: Self::tool_router(), @@ -41,8 +55,8 @@ impl DtrackServer { #[tool(description = "Listet aktive Dependency-Track-Projekte auf (Name, Version, UUID).")] async fn list_projects(&self) -> Result { - let body = self - .client + let client = self.client.read().await.clone(); + let body = client .list_projects() .await .map_err(|e| McpError::internal_error(e.to_string(), None))?; @@ -54,8 +68,8 @@ impl DtrackServer { &self, Parameters(arg): Parameters, ) -> Result { - let body = self - .client + let client = self.client.read().await.clone(); + let body = client .project_findings(&arg.uuid) .await .map_err(|e| McpError::internal_error(e.to_string(), None))?; @@ -67,8 +81,8 @@ impl DtrackServer { &self, Parameters(arg): Parameters, ) -> Result { - let body = self - .client + let client = self.client.read().await.clone(); + let body = client .project_metrics(&arg.uuid) .await .map_err(|e| McpError::internal_error(e.to_string(), None))?;