Stage 1: MCP-Server aus dtrack-stdio in dtrack-tools verschoben
CI / test (push) Successful in 12m2s
CI / test (push) Successful in 12m2s
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
use dtrack_core::DtrackClient;
|
||||
use rmcp::{
|
||||
handler::server::router::tool::ToolRouter,
|
||||
handler::server::wrapper::Parameters,
|
||||
model::{
|
||||
CallToolResult, Content, Implementation, ProtocolVersion, ServerCapabilities, ServerInfo,
|
||||
},
|
||||
tool, tool_handler, tool_router,
|
||||
ErrorData as McpError, ServerHandler,
|
||||
};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Deserialize;
|
||||
|
||||
/// MCP-Server fuer Dependency-Track. Haelt den DT-Client + den vom Macro
|
||||
/// generierten ToolRouter.
|
||||
///
|
||||
/// Bewusst transport-unabhaengig: `dtrack-stdio` und `dtrack-http` bauen
|
||||
/// denselben Server und haengen nur ein anderes Frontend (stdio bzw. HTTP)
|
||||
/// davor.
|
||||
#[derive(Clone)]
|
||||
pub struct DtrackServer {
|
||||
client: DtrackClient,
|
||||
tool_router: ToolRouter<Self>,
|
||||
}
|
||||
|
||||
/// Argument fuer projektbezogene Tools.
|
||||
#[derive(Debug, Deserialize, JsonSchema)]
|
||||
pub struct ProjectArg {
|
||||
/// UUID des Projekts (aus `list_projects`).
|
||||
pub uuid: String,
|
||||
}
|
||||
|
||||
#[tool_router]
|
||||
impl DtrackServer {
|
||||
pub fn new(client: DtrackClient) -> Self {
|
||||
Self {
|
||||
client,
|
||||
tool_router: Self::tool_router(),
|
||||
}
|
||||
}
|
||||
|
||||
#[tool(description = "Listet aktive Dependency-Track-Projekte auf (Name, Version, UUID).")]
|
||||
async fn list_projects(&self) -> Result<CallToolResult, McpError> {
|
||||
let body = self
|
||||
.client
|
||||
.list_projects()
|
||||
.await
|
||||
.map_err(|e| McpError::internal_error(e.to_string(), None))?;
|
||||
Ok(CallToolResult::success(vec![Content::text(body)]))
|
||||
}
|
||||
|
||||
#[tool(description = "Findings (Schwachstellen) eines Projekts anhand seiner UUID.")]
|
||||
async fn project_findings(
|
||||
&self,
|
||||
Parameters(arg): Parameters<ProjectArg>,
|
||||
) -> Result<CallToolResult, McpError> {
|
||||
let body = self
|
||||
.client
|
||||
.project_findings(&arg.uuid)
|
||||
.await
|
||||
.map_err(|e| McpError::internal_error(e.to_string(), None))?;
|
||||
Ok(CallToolResult::success(vec![Content::text(body)]))
|
||||
}
|
||||
|
||||
#[tool(description = "Aktuelle Sicherheits-Metriken eines Projekts anhand seiner UUID.")]
|
||||
async fn project_metrics(
|
||||
&self,
|
||||
Parameters(arg): Parameters<ProjectArg>,
|
||||
) -> Result<CallToolResult, McpError> {
|
||||
let body = self
|
||||
.client
|
||||
.project_metrics(&arg.uuid)
|
||||
.await
|
||||
.map_err(|e| McpError::internal_error(e.to_string(), None))?;
|
||||
Ok(CallToolResult::success(vec![Content::text(body)]))
|
||||
}
|
||||
}
|
||||
|
||||
#[tool_handler]
|
||||
impl ServerHandler for DtrackServer {
|
||||
fn get_info(&self) -> ServerInfo {
|
||||
ServerInfo {
|
||||
protocol_version: ProtocolVersion::V_2025_06_18,
|
||||
capabilities: ServerCapabilities::builder().enable_tools().build(),
|
||||
server_info: Implementation::from_build_env(),
|
||||
instructions: Some(
|
||||
"Read-only Zugriff auf Dependency-Track (Projekte, Findings, Metriken)."
|
||||
.to_string(),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user