Stage 1: dtrack-stdio nutzt dtrack-tools + Config-Resolve (Datei/env)
CI / test (push) Successful in 11m58s
CI / test (push) Successful in 11m58s
This commit is contained in:
@@ -1,93 +1,7 @@
|
|||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use dtrack_core::DtrackClient;
|
use dtrack_core::{DtrackClient, DtrackConfig};
|
||||||
use rmcp::{
|
use dtrack_tools::DtrackServer;
|
||||||
handler::server::router::tool::ToolRouter,
|
use rmcp::{transport::stdio, ServiceExt};
|
||||||
handler::server::wrapper::Parameters,
|
|
||||||
model::{
|
|
||||||
CallToolResult, Content, Implementation, ProtocolVersion, ServerCapabilities, ServerInfo,
|
|
||||||
},
|
|
||||||
tool, tool_handler, tool_router,
|
|
||||||
transport::stdio,
|
|
||||||
ErrorData as McpError, ServerHandler, ServiceExt,
|
|
||||||
};
|
|
||||||
use schemars::JsonSchema;
|
|
||||||
use serde::Deserialize;
|
|
||||||
|
|
||||||
/// MCP-Server fuer Dependency-Track. Haelt den DT-Client + den vom Macro
|
|
||||||
/// generierten ToolRouter.
|
|
||||||
#[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(),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
@@ -98,7 +12,10 @@ async fn main() -> Result<()> {
|
|||||||
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
.with_env_filter(tracing_subscriber::EnvFilter::from_default_env())
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
let client = DtrackClient::from_env()?;
|
// Config: Datei (DTRACK_CONFIG) hat Vorrang, sonst Umgebungsvariablen.
|
||||||
|
let cfg = DtrackConfig::resolve()?;
|
||||||
|
let client = DtrackClient::from_config(&cfg)?;
|
||||||
|
|
||||||
let service = DtrackServer::new(client).serve(stdio()).await?;
|
let service = DtrackServer::new(client).serve(stdio()).await?;
|
||||||
service.waiting().await?;
|
service.waiting().await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Reference in New Issue
Block a user