143 lines
4.2 KiB
Rust
Raw Permalink Normal View History

2025-10-07 10:59:52 +01:00
#!/usr/bin/env -S cargo run --
//! Simple Rust-native MCP Server for Provisioning
//!
//! A minimal working implementation that shows Rust feasibility
use anyhow::Result;
use clap::Parser;
use std::path::PathBuf;
use tracing::{info, error, debug};
use serde_json::json;
mod config;
mod provisioning;
mod tools;
mod errors;
use config::Config;
use provisioning::ProvisioningEngine;
use tools::ProvisioningTools;
#[derive(Parser, Debug)]
#[command(name = "provisioning-mcp-server")]
#[command(about = "Rust-native MCP server for Cloud Native Provisioning")]
#[command(version)]
struct Args {
/// Configuration file path
#[arg(short, long, env = "PROVISIONING_MCP_CONFIG")]
config: Option<PathBuf>,
/// Provisioning system path
#[arg(short, long, env = "PROVISIONING_PATH")]
provisioning_path: Option<PathBuf>,
/// Debug mode
#[arg(short, long, env = "PROVISIONING_DEBUG")]
debug: bool,
}
#[tokio::main]
async fn main() -> Result<()> {
let args = Args::parse();
// Initialize tracing
tracing_subscriber::fmt()
.with_max_level(if args.debug {
tracing::Level::DEBUG
} else {
tracing::Level::INFO
})
.init();
info!("🦀 Starting Rust-native MCP Server for Provisioning");
// Load configuration
let config = Config::load(
args.config,
args.provisioning_path,
args.debug,
)?;
info!("Configuration loaded successfully");
info!("Provisioning path: {}", config.provisioning_path.display());
info!("AI enabled: {}", config.is_ai_available());
// Initialize components
let engine = ProvisioningEngine::new(&config)?;
let tools = ProvisioningTools::new(&config);
info!("🚀 MCP Server components initialized");
// Run basic tests to verify functionality
test_components(&engine, &tools).await?;
// Run performance tests
info!("⚡ Running performance benchmarks...");
let performance_results = provisioning_mcp_server::performance_test::run_performance_tests();
println!("\n{}", performance_results);
info!("✅ Rust MCP Server validation complete");
Ok(())
}
async fn test_components(engine: &ProvisioningEngine, tools: &ProvisioningTools) -> Result<()> {
info!("🧪 Testing server components...");
// Test configuration parsing
let test_description = "Create 2 servers with 4 CPU cores for kubernetes cluster on AWS";
match tools.parse_server_description(test_description) {
Ok(server_json) => {
info!("✅ Server parsing test passed");
info!(" Parsed: {} x {} servers for {}",
server_json.get("count").and_then(|v| v.as_u64()).unwrap_or(1),
server_json.get("instance_type").and_then(|v| v.as_str()).unwrap_or("unknown"),
server_json.get("purpose").and_then(|v| v.as_str()).unwrap_or("general"));
}
Err(e) => {
error!("❌ Server parsing test failed: {}", e);
}
}
// Test AI status
let ai_status = tools.get_ai_status()?;
info!("🤖 AI Status:\n{}", ai_status);
// Test basic infrastructure status
match engine.get_status(None, false) {
Ok(status) => {
info!("✅ Infrastructure status test passed");
debug!("Status: {}", status);
}
Err(e) => {
info!(" Infrastructure status (expected if no infrastructure exists): {}", e);
}
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn test_server_creation() {
let config = Config::default();
let engine = ProvisioningEngine::new(&config).expect("Failed to create engine");
let tools = ProvisioningTools::new(&config);
// Test parsing
let result = tools.parse_server_description("Create 1 server for web hosting");
assert!(result.is_ok());
let server_config = result.unwrap();
assert_eq!(server_config.count, 1);
}
#[test]
fn test_config_loading() {
let config = Config::default();
assert!(!config.debug);
assert!(config.provisioning_path.exists() || !config.provisioning_path.to_string_lossy().contains("/usr/local/provisioning"));
}
}