feat: seed default MCP servers (Findings, SBOM, DAST) on dashboard startup
Some checks failed
CI / Format (push) Failing after 3s
CI / Clippy (push) Failing after 2m35s
CI / Security Audit (push) Has been skipped
CI / Tests (push) Has been skipped
CI / Format (pull_request) Failing after 3s
CI / Deploy MCP (push) Has been cancelled
CI / Deploy Docs (push) Has been cancelled
CI / Deploy Agent (push) Has been cancelled
CI / Deploy Dashboard (push) Has been cancelled
CI / Detect Changes (push) Has been cancelled
CI / Clippy (pull_request) Failing after 2m40s
CI / Security Audit (pull_request) Has been skipped
CI / Tests (pull_request) Has been skipped
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
Some checks failed
CI / Format (push) Failing after 3s
CI / Clippy (push) Failing after 2m35s
CI / Security Audit (push) Has been skipped
CI / Tests (push) Has been skipped
CI / Format (pull_request) Failing after 3s
CI / Deploy MCP (push) Has been cancelled
CI / Deploy Docs (push) Has been cancelled
CI / Deploy Agent (push) Has been cancelled
CI / Deploy Dashboard (push) Has been cancelled
CI / Detect Changes (push) Has been cancelled
CI / Clippy (pull_request) Failing after 2m40s
CI / Security Audit (pull_request) Has been skipped
CI / Tests (pull_request) Has been skipped
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 MCP_ENDPOINT_URL env var to configure MCP server base URL - Seed three default MCP server configs on dashboard startup if not present - Each server has its own tool subset: findings (3 tools), SBOM (2 tools), DAST (2 tools) - Uses upsert-by-name to avoid duplicates on restart Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -38,6 +38,9 @@ GIT_CLONE_BASE_PATH=/tmp/compliance-scanner/repos
|
||||
DASHBOARD_PORT=8080
|
||||
AGENT_API_URL=http://localhost:3001
|
||||
|
||||
# MCP Server
|
||||
MCP_ENDPOINT_URL=http://localhost:8090
|
||||
|
||||
# Keycloak (required for authentication)
|
||||
KEYCLOAK_URL=http://localhost:8080
|
||||
KEYCLOAK_REALM=compliance
|
||||
|
||||
@@ -35,4 +35,5 @@ pub struct DashboardConfig {
|
||||
pub mongodb_database: String,
|
||||
pub agent_api_url: String,
|
||||
pub dashboard_port: u16,
|
||||
pub mcp_endpoint_url: Option<String>,
|
||||
}
|
||||
|
||||
@@ -14,5 +14,6 @@ pub fn load_config() -> Result<DashboardConfig, DashboardError> {
|
||||
.ok()
|
||||
.and_then(|p| p.parse().ok())
|
||||
.unwrap_or(8080),
|
||||
mcp_endpoint_url: std::env::var("MCP_ENDPOINT_URL").ok().filter(|v| !v.is_empty()),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -4,6 +4,9 @@ use dioxus::prelude::*;
|
||||
use time::Duration;
|
||||
use tower_sessions::{cookie::Key, MemoryStore, SessionManagerLayer};
|
||||
|
||||
use compliance_core::models::{McpServerConfig, McpServerStatus, McpTransport};
|
||||
use mongodb::bson::doc;
|
||||
|
||||
use super::config;
|
||||
use super::database::Database;
|
||||
use super::error::DashboardError;
|
||||
@@ -22,6 +25,9 @@ pub fn server_start(app: fn() -> Element) -> Result<(), DashboardError> {
|
||||
KeycloakConfig::from_env().map(|kc| &*Box::leak(Box::new(kc)));
|
||||
let db = Database::connect(&config.mongodb_uri, &config.mongodb_database).await?;
|
||||
|
||||
// Seed default MCP server configs
|
||||
seed_default_mcp_servers(&db, config.mcp_endpoint_url.as_deref()).await;
|
||||
|
||||
if let Some(kc) = keycloak {
|
||||
tracing::info!("Keycloak configured for realm '{}'", kc.realm);
|
||||
} else {
|
||||
@@ -70,3 +76,76 @@ pub fn server_start(app: fn() -> Element) -> Result<(), DashboardError> {
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Seed three default MCP server configs (Findings, SBOM, DAST) if they don't already exist.
|
||||
async fn seed_default_mcp_servers(db: &Database, mcp_endpoint_url: Option<&str>) {
|
||||
let endpoint = mcp_endpoint_url.unwrap_or("http://localhost:8090");
|
||||
|
||||
let defaults = [
|
||||
(
|
||||
"Findings MCP",
|
||||
"Exposes security findings, triage data, and finding summaries to LLM agents",
|
||||
vec![
|
||||
"list_findings",
|
||||
"get_finding",
|
||||
"findings_summary",
|
||||
],
|
||||
),
|
||||
(
|
||||
"SBOM MCP",
|
||||
"Exposes software bill of materials and vulnerability reports to LLM agents",
|
||||
vec![
|
||||
"list_sbom_packages",
|
||||
"sbom_vuln_report",
|
||||
],
|
||||
),
|
||||
(
|
||||
"DAST MCP",
|
||||
"Exposes DAST scan findings and scan summaries to LLM agents",
|
||||
vec![
|
||||
"list_dast_findings",
|
||||
"dast_scan_summary",
|
||||
],
|
||||
),
|
||||
];
|
||||
|
||||
let collection = db.mcp_servers();
|
||||
|
||||
for (name, description, tools) in defaults {
|
||||
// Skip if already exists
|
||||
let exists = collection
|
||||
.find_one(doc! { "name": name })
|
||||
.await
|
||||
.ok()
|
||||
.flatten()
|
||||
.is_some();
|
||||
|
||||
if exists {
|
||||
continue;
|
||||
}
|
||||
|
||||
let now = chrono::Utc::now();
|
||||
let token = format!("mcp_{}", uuid::Uuid::new_v4().to_string().replace('-', ""));
|
||||
|
||||
let server = McpServerConfig {
|
||||
id: None,
|
||||
name: name.to_string(),
|
||||
endpoint_url: format!("{endpoint}/mcp"),
|
||||
transport: McpTransport::Http,
|
||||
port: Some(8090),
|
||||
status: McpServerStatus::Stopped,
|
||||
access_token: token,
|
||||
tools_enabled: tools.into_iter().map(|s| s.to_string()).collect(),
|
||||
description: Some(description.to_string()),
|
||||
mongodb_uri: None,
|
||||
mongodb_database: None,
|
||||
created_at: now,
|
||||
updated_at: now,
|
||||
};
|
||||
|
||||
match collection.insert_one(server).await {
|
||||
Ok(_) => tracing::info!("Seeded default MCP server: {name}"),
|
||||
Err(e) => tracing::warn!("Failed to seed MCP server '{name}': {e}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user