2025-10-07 10:59:52 +01:00
#!/usr/bin/env -S cargo run --
2026-01-08 21:32:59 +00:00
#![ allow(dead_code, unused_imports, unused_variables, unused_assignments, unused) ]
#![ allow(
clippy ::excessive_nesting ,
clippy ::upper_case_acronyms ,
clippy ::collapsible_if ,
clippy ::enum_variant_names ,
clippy ::unnecessary_map_or
) ]
2025-10-07 10:59:52 +01:00
//! Cloud Native Provisioning MCP Server
2026-01-08 21:32:59 +00:00
//!
2025-10-07 10:59:52 +01:00
//! A Rust-native implementation of Model Context Protocol server
//! for infrastructure automation and AI-assisted DevOps operations.
use anyhow ::{ Context , Result } ;
use clap ::Parser ;
use rust_mcp_sdk ::Server ;
use rust_mcp_sdk ::schema ::{
CallToolRequest , CallToolResult , ServerCapabilities , TextContent , Tool
} ;
use serde_json ::json ;
use std ::path ::PathBuf ;
use tracing ::{ info , debug } ;
mod config ;
mod provisioning ;
mod tools ;
mod errors ;
use config ::Config ;
use errors ::ProvisioningError ;
use provisioning ::ProvisioningEngine ;
2026-01-08 21:32:59 +00:00
use tools ::{
ProvisioningTools , SettingsTools , SystemStatusTool , NextActionTool ,
DocFinderTool , TroubleshooterTool , ConfigValidatorTool ,
} ;
2025-10-07 10:59:52 +01:00
#[ 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 ,
/// Log level
#[ arg(short, long, env = " PROVISIONING_LOG_LEVEL " , default_value = " info " ) ]
log_level : String ,
}
/// Enhanced MCP Server for Systems Provisioning with AI Integration
pub struct ProvisioningMCPServer {
config : Config ,
engine : ProvisioningEngine ,
tools : ProvisioningTools ,
api_tools : tools ::provisioning_tools ::ProvisioningTools ,
settings_tools : std ::sync ::Arc < tokio ::sync ::Mutex < SettingsTools > > ,
2026-01-08 21:32:59 +00:00
system_status_tool : SystemStatusTool ,
next_action_tool : NextActionTool ,
doc_finder_tool : std ::sync ::Arc < tokio ::sync ::Mutex < DocFinderTool > > ,
troubleshooter_tool : TroubleshooterTool ,
config_validator_tool : ConfigValidatorTool ,
2025-10-07 10:59:52 +01:00
}
impl ProvisioningMCPServer {
/// Create new MCP server instance
pub fn new ( config : Config ) -> Result < Self > {
let engine = ProvisioningEngine ::new ( & config ) ? ;
let tools = ProvisioningTools ::new ( & config ) ;
let api_tools = tools ::provisioning_tools ::ProvisioningTools ::new (
Some ( " http://localhost:3000 " . to_string ( ) )
) ;
let settings_tools = std ::sync ::Arc ::new ( tokio ::sync ::Mutex ::new ( SettingsTools ::new ( ) ) ) ;
2026-01-08 21:32:59 +00:00
// Initialize guidance tools
let provisioning_root = config . provisioning_path . clone ( ) ;
let system_status_tool = SystemStatusTool ::new ( provisioning_root . clone ( ) ) ;
let next_action_tool = NextActionTool ::new ( provisioning_root . clone ( ) ) ;
let doc_finder_tool = std ::sync ::Arc ::new ( tokio ::sync ::Mutex ::new (
DocFinderTool ::new ( provisioning_root . clone ( ) )
) ) ;
let troubleshooter_tool = TroubleshooterTool ::new ( provisioning_root . clone ( ) ) ;
let config_validator_tool = ConfigValidatorTool ::new ( provisioning_root ) ;
2025-10-07 10:59:52 +01:00
Ok ( Self {
config ,
engine ,
tools ,
api_tools ,
settings_tools ,
2026-01-08 21:32:59 +00:00
system_status_tool ,
next_action_tool ,
doc_finder_tool ,
troubleshooter_tool ,
config_validator_tool ,
2025-10-07 10:59:52 +01:00
} )
}
/// Initialize and run the enhanced MCP server
pub async fn run ( & self ) -> Result < ( ) > {
info! ( " Starting Enhanced Systems Provisioning MCP Server v2.0 " ) ;
info! ( " New features: API integration, AI agents, dashboards, advanced analytics " ) ;
let mut server = Server ::new ( " enhanced-provisioning-server " . to_string ( ) )
. with_capabilities ( ServerCapabilities {
tools : Some ( json! ( {
" listChanged " : true
} ) ) ,
resources : Some ( json! ( {
" subscribe " : true ,
" listChanged " : true
} ) ) ,
.. Default ::default ( )
} ) ;
// Register legacy tools
server = server
. tool ( " provision_create_server " , self . handle_create_server ( ) )
. tool ( " provision_ai_template " , self . handle_ai_template ( ) )
. tool ( " provision_query " , self . handle_query ( ) )
. tool ( " provision_deploy_taskserv " , self . handle_deploy_taskserv ( ) )
. tool ( " provision_cluster_create " , self . handle_cluster_create ( ) )
. tool ( " provision_status " , self . handle_status ( ) )
. tool ( " provision_ai_config " , self . handle_ai_config ( ) ) ;
// Register enhanced API tools
server = server
. tool ( " ai_query " , self . handle_enhanced_ai_query ( ) )
. tool ( " get_infrastructure_status " , self . handle_get_infrastructure_status ( ) )
. tool ( " get_system_metrics " , self . handle_get_system_metrics ( ) )
. tool ( " get_logs " , self . handle_get_logs ( ) )
. tool ( " start_api_server " , self . handle_start_api_server ( ) )
. tool ( " create_dashboard " , self . handle_create_dashboard ( ) )
. tool ( " start_dashboard " , self . handle_start_dashboard ( ) )
. tool ( " start_ai_agents " , self . handle_start_ai_agents ( ) )
. tool ( " get_agents_status " , self . handle_get_agents_status ( ) )
. tool ( " create_servers " , self . handle_create_servers ( ) )
. tool ( " list_servers " , self . handle_list_servers ( ) )
. tool ( " delete_servers " , self . handle_delete_servers ( ) )
. tool ( " create_cluster " , self . handle_create_cluster_enhanced ( ) )
. tool ( " generate_infrastructure " , self . handle_generate_infrastructure ( ) )
. tool ( " get_cost_optimization " , self . handle_get_cost_optimization ( ) )
. tool ( " get_security_analysis " , self . handle_get_security_analysis ( ) )
. tool ( " get_performance_analysis " , self . handle_get_performance_analysis ( ) )
. tool ( " predict_issues " , self . handle_predict_issues ( ) ) ;
// Register installer settings tools
server = server
. tool ( " installer_get_settings " , self . handle_get_settings ( ) )
. tool ( " installer_complete_config " , self . handle_complete_config ( ) )
. tool ( " installer_validate_config " , self . handle_validate_config ( ) )
. tool ( " installer_get_defaults " , self . handle_get_defaults ( ) )
. tool ( " installer_platform_recommendations " , self . handle_platform_recommendations ( ) )
. tool ( " installer_service_recommendations " , self . handle_service_recommendations ( ) )
. tool ( " installer_resource_recommendations " , self . handle_resource_recommendations ( ) ) ;
2026-01-08 21:32:59 +00:00
// Register guidance tools
server = server
. tool ( " guidance_check_system_status " , self . handle_check_system_status ( ) )
. tool ( " guidance_suggest_next_action " , self . handle_suggest_next_action ( ) )
. tool ( " guidance_find_docs " , self . handle_find_docs ( ) )
. tool ( " guidance_diagnose_issue " , self . handle_diagnose_issue ( ) )
. tool ( " guidance_validate_config_file " , self . handle_validate_config_file ( ) ) ;
2025-10-07 10:59:52 +01:00
server
. run ( )
. await
. context ( " Failed to run enhanced MCP server " ) ? ;
Ok ( ( ) )
}
/// Get list of available tools
async fn get_available_tools ( & self ) -> Result < Vec < Tool > > {
Ok ( vec! [
Tool {
name : " provision_create_server " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_create_server " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Create infrastructure servers using natural language or specific configuration " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" description " : {
" type " : " string " ,
" description " : " Natural language description of the infrastructure needed "
} ,
" infra_name " : {
2026-01-08 21:32:59 +00:00
" type " : " string " ,
2025-10-07 10:59:52 +01:00
" description " : " Infrastructure name/project identifier "
} ,
" provider " : {
" type " : " string " ,
" enum " : [ " aws " , " upcloud " , " local " ] ,
" description " : " Cloud provider to use "
} ,
" check_mode " : {
" type " : " boolean " ,
" default " : true ,
" description " : " Run in check mode (no actual resources created) "
}
} ,
" required " : [ " description " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
name : " provision_ai_template " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_ai_template " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Generate infrastructure templates using AI assistance " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" description " : {
" type " : " string " ,
" description " : " Detailed description of the infrastructure template needed "
} ,
" template_type " : {
" type " : " string " ,
" enum " : [ " server " , " taskserv " , " cluster " , " full-stack " ] ,
" description " : " Type of template to generate "
} ,
" complexity " : {
" type " : " string " ,
" enum " : [ " simple " , " medium " , " complex " ] ,
" default " : " medium " ,
" description " : " Complexity level of the generated template "
}
} ,
" required " : [ " description " , " template_type " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
name : " provision_query " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_query " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Query infrastructure state and configuration using natural language " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" query " : {
" type " : " string " ,
" description " : " Natural language query about infrastructure state "
} ,
" infra_name " : {
" type " : " string " ,
" description " : " Specific infrastructure to query (optional) "
} ,
" output_format " : {
" type " : " string " ,
" enum " : [ " human " , " json " , " yaml " ] ,
" default " : " human " ,
" description " : " Output format preference "
}
} ,
" required " : [ " query " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
2026-01-08 21:32:59 +00:00
name : " provision_deploy_taskserv " . to_string ( ) ,
title : Some ( " provision_deploy_taskserv " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Deploy specific infrastructure services (databases, networking, etc.) " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" service_name " : {
" type " : " string " ,
" description " : " Name of the service to deploy (e.g., 'postgresql', 'kubernetes', 'youki') "
} ,
" infra_name " : {
" type " : " string " ,
" description " : " Target infrastructure name "
} ,
" configuration " : {
" type " : " object " ,
" description " : " Service-specific configuration options "
} ,
" check_mode " : {
" type " : " boolean " ,
" default " : true ,
" description " : " Run in check mode first "
}
} ,
" required " : [ " service_name " , " infra_name " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
name : " provision_cluster_create " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_cluster_create " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Create complete clusters with integrated services " . to_string ( ) ,
input_schema : json ! ( {
2026-01-08 21:32:59 +00:00
" type " : " object " ,
2025-10-07 10:59:52 +01:00
" properties " : {
" cluster_description " : {
" type " : " string " ,
" description " : " Natural language description of the cluster needed "
} ,
" cluster_type " : {
" type " : " string " ,
" enum " : [ " development " , " staging " , " production " , " demo " ] ,
" description " : " Type/purpose of the cluster "
} ,
" services " : {
" type " : " array " ,
" items " : { " type " : " string " } ,
" description " : " List of services to include (e.g., ['postgresql', 'redis', 'monitoring']) "
} ,
" infra_name " : {
" type " : " string " ,
" description " : " Infrastructure name for the cluster "
}
} ,
" required " : [ " cluster_description " , " cluster_type " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
name : " provision_status " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_status " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Get comprehensive status of infrastructure and services " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" infra_name " : {
" type " : " string " ,
" description " : " Specific infrastructure to check (optional, checks all if not provided) "
} ,
" detailed " : {
" type " : " boolean " ,
" default " : false ,
" description " : " Include detailed metrics and logs "
}
}
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
Tool {
name : " provision_ai_config " . to_string ( ) ,
2026-01-08 21:32:59 +00:00
title : Some ( " provision_ai_config " . to_string ( ) ) ,
2025-10-07 10:59:52 +01:00
description : " Configure and verify AI capabilities for the provisioning system " . to_string ( ) ,
input_schema : json ! ( {
" type " : " object " ,
" properties " : {
" action " : {
" type " : " string " ,
" enum " : [ " status " , " configure " , " test " ] ,
" description " : " Action to perform with AI configuration "
} ,
" provider " : {
" type " : " string " ,
" enum " : [ " openai " , " claude " , " generic " ] ,
" description " : " AI provider to configure (for configure action) "
}
} ,
" required " : [ " action " ]
} ) ,
2026-01-08 21:32:59 +00:00
annotations : None ,
meta : None ,
output_schema : None , } ,
2025-10-07 10:59:52 +01:00
] )
}
/// Handle server creation tool
fn handle_create_server ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let description = arguments . get ( " description " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " description is required " . to_string ( ) ) ) ? ;
let infra_name = arguments . get ( " infra_name " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " ai-generated " ) ;
let provider = arguments . get ( " provider " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " aws " ) ;
let check_mode = arguments . get ( " check_mode " )
. and_then ( | v | v . as_bool ( ) )
. unwrap_or ( true ) ;
info! ( " Creating server with description: {} " , description ) ;
debug! ( " Parameters: infra={}, provider={}, check={} " , infra_name , provider , check_mode ) ;
// Use AI to parse the natural language description
let parsed_json = self . tools . parse_server_description ( description ) ? ;
// Convert JSON to ServerConfig
let parsed_config = provisioning ::ServerConfig {
hostname : parsed_json . get ( " hostname " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( infra_name )
. to_string ( ) ,
instance_type : parsed_json . get ( " instance_type " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " t3.medium " )
. to_string ( ) ,
count : parsed_json . get ( " count " )
. and_then ( | v | v . as_u64 ( ) )
. unwrap_or ( 1 ) as u32 ,
provider : provider . to_string ( ) ,
region : parsed_json . get ( " region " )
. and_then ( | v | v . as_str ( ) )
. map ( | s | s . to_string ( ) ) ,
purpose : parsed_json . get ( " purpose " )
. and_then ( | v | v . as_str ( ) )
. map ( | s | s . to_string ( ) ) ,
} ;
// Execute provisioning command
let result = self . engine . create_server ( & parsed_config , check_mode ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " ✅ Server creation completed: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle AI template generation
fn handle_ai_template ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let description = arguments . get ( " description " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " description is required " . to_string ( ) ) ) ? ;
let template_type = arguments . get ( " template_type " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " template_type is required " . to_string ( ) ) ) ? ;
let complexity = arguments . get ( " complexity " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " medium " ) ;
info! ( " Generating {} template: {} " , template_type , description ) ;
let template = self . tools . generate_ai_template ( description , template_type , complexity ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🤖 Generated {} template: \n \n ```kcl \n {} \n ``` " , template_type , template ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle infrastructure queries
fn handle_query ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let query = arguments . get ( " query " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " query is required " . to_string ( ) ) ) ? ;
let infra_name = arguments . get ( " infra_name " )
. and_then ( | v | v . as_str ( ) ) ;
let output_format = arguments . get ( " output_format " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " human " ) ;
info! ( " Processing query: {} " , query ) ;
let result = self . engine . process_query ( query , infra_name , output_format ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🔍 Query result: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle task service deployment
fn handle_deploy_taskserv ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let service_name = arguments . get ( " service_name " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " service_name is required " . to_string ( ) ) ) ? ;
let infra_name = arguments . get ( " infra_name " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " infra_name is required " . to_string ( ) ) ) ? ;
let configuration = arguments . get ( " configuration " )
. cloned ( )
. unwrap_or_default ( ) ;
let check_mode = arguments . get ( " check_mode " )
. and_then ( | v | v . as_bool ( ) )
. unwrap_or ( true ) ;
info! ( " Deploying service {} to infrastructure {} " , service_name , infra_name ) ;
let result = self . engine . deploy_taskserv ( service_name , infra_name , & configuration , check_mode ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " ⚙️ Service deployment result: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle cluster creation
fn handle_cluster_create ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let cluster_description = arguments . get ( " cluster_description " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " cluster_description is required " . to_string ( ) ) ) ? ;
let cluster_type = arguments . get ( " cluster_type " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " cluster_type is required " . to_string ( ) ) ) ? ;
let services = arguments . get ( " services " )
. and_then ( | v | v . as_array ( ) )
. map ( | arr | arr . iter ( ) . filter_map ( | v | v . as_str ( ) ) . collect ::< Vec < _ > > ( ) )
. unwrap_or_default ( ) ;
let infra_name = arguments . get ( " infra_name " )
. and_then ( | v | v . as_str ( ) )
. unwrap_or ( " ai-cluster " ) ;
info! ( " Creating {} cluster: {} " , cluster_type , cluster_description ) ;
let result = self . engine . create_cluster ( cluster_description , cluster_type , & services , infra_name ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🚢 Cluster creation result: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle status checks
fn handle_status ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let infra_name = arguments . get ( " infra_name " )
. and_then ( | v | v . as_str ( ) ) ;
let detailed = arguments . get ( " detailed " )
. and_then ( | v | v . as_bool ( ) )
. unwrap_or ( false ) ;
info! ( " Getting status for infrastructure: {:?} " , infra_name ) ;
let result = self . engine . get_status ( infra_name , detailed ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📊 Infrastructure status: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
/// Handle AI configuration
fn handle_ai_config ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let action = arguments . get ( " action " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " action is required " . to_string ( ) ) ) ? ;
let provider = arguments . get ( " provider " )
. and_then ( | v | v . as_str ( ) ) ;
info! ( " AI config action: {} " , action ) ;
let result = match action {
" status " = > self . tools . get_ai_status ( ) ? ,
" configure " = > {
let provider = provider . ok_or_else ( | |
ProvisioningError ::InvalidInput ( " provider is required for configure action " . to_string ( ) )
) ? ;
self . tools . configure_ai ( provider ) ?
} ,
" test " = > self . tools . test_ai_connection ( ) ? ,
_ = > return Err ( ProvisioningError ::InvalidInput ( format! ( " Unknown action: {} " , action ) ) . into ( ) ) ,
} ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🤖 AI configuration result: \n \n {} " , result ) ) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
// Enhanced API tool handlers
fn handle_enhanced_ai_query ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let query = arguments . get ( " query " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " query is required " . to_string ( ) ) ) ? ;
let context = arguments . get ( " context " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Enhanced AI query: {} " , query ) ;
// This would be async in real implementation
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . ai_query ( query , context )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🤖 AI Analysis: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_infrastructure_status ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting infrastructure status via API " ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_infrastructure_status ( )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🏗️ Infrastructure Status: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_system_metrics ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let timerange = arguments . get ( " timerange " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Getting system metrics for timerange: {:?} " , timerange ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_system_metrics ( timerange )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📊 System Metrics: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_logs ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let level = arguments . get ( " level " ) . and_then ( | v | v . as_str ( ) ) ;
let since = arguments . get ( " since " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Getting logs - level: {:?}, since: {:?} " , level , since ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_logs ( level , since )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📋 System Logs: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_start_api_server ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let port = arguments . get ( " port " ) . and_then ( | v | v . as_u64 ( ) ) . map ( | p | p as u16 ) ;
info! ( " Starting API server on port: {:?} " , port ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . start_api_server ( port )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🚀 API Server: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_create_dashboard ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let template = arguments . get ( " template " ) . and_then ( | v | v . as_str ( ) ) ;
let name = arguments . get ( " name " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Creating dashboard - template: {:?}, name: {:?} " , template , name ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . create_dashboard ( template , name )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📊 Dashboard Creation: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_start_dashboard ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let name = arguments . get ( " name " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " name is required " . to_string ( ) ) ) ? ;
let port = arguments . get ( " port " ) . and_then ( | v | v . as_u64 ( ) ) . map ( | p | p as u16 ) ;
info! ( " Starting dashboard: {} on port: {:?} " , name , port ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . start_dashboard ( name , port )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🌐 Dashboard Started: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_start_ai_agents ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let agents = arguments . get ( " agents " )
. and_then ( | v | v . as_array ( ) )
. map ( | arr | arr . iter ( ) . filter_map ( | v | v . as_str ( ) ) . collect ::< Vec < _ > > ( ) ) ;
info! ( " Starting AI agents: {:?} " , agents ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . start_ai_agents ( agents )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🤖 AI Agents Started: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_agents_status ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting AI agents status " ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_agents_status ( )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🤖 Agents Status: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_create_servers ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let config = arguments . get ( " config " )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " config is required " . to_string ( ) ) ) ? ;
info! ( " Creating servers with config: {:?} " , config ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . create_servers ( config )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🖥️ Servers Created: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_list_servers ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let provider = arguments . get ( " provider " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Listing servers for provider: {:?} " , provider ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . list_servers ( provider )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📋 Server List: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_delete_servers ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let server_names = arguments . get ( " server_names " )
. and_then ( | v | v . as_array ( ) )
. map ( | arr | arr . iter ( ) . filter_map ( | v | v . as_str ( ) ) . collect ::< Vec < _ > > ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " server_names is required " . to_string ( ) ) ) ? ;
info! ( " Deleting servers: {:?} " , server_names ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . delete_servers ( & server_names )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🗑️ Servers Deleted: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_create_cluster_enhanced ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let config = arguments . get ( " config " )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " config is required " . to_string ( ) ) ) ? ;
info! ( " Creating cluster with config: {:?} " , config ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . create_cluster ( config )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🚢 Cluster Created: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_generate_infrastructure ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let description = arguments . get ( " description " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " description is required " . to_string ( ) ) ) ? ;
let output_type = arguments . get ( " output_type " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Generating infrastructure from description: {} " , description ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . generate_infrastructure ( description , output_type )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🏗️ Generated Infrastructure: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_cost_optimization ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting cost optimization recommendations " ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_cost_optimization ( )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 💰 Cost Optimization: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_security_analysis ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting security analysis " ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_security_analysis ( )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🛡️ Security Analysis: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_performance_analysis ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting performance analysis " ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . get_performance_analysis ( )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " ⚡ Performance Analysis: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_predict_issues ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let timeframe = arguments . get ( " timeframe " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Predicting issues for timeframe: {:?} " , timeframe ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on (
self . api_tools . predict_issues ( timeframe )
) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🔮 Issue Predictions: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
// Installer Settings Tool Handlers
fn handle_get_settings ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let query = arguments . get ( " query " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Getting installer settings - query: {:?} " , query ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let mut tools = settings_tools . lock ( ) . await ;
tools . get_settings ( query ) . await
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " ⚙️ Installer Settings: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_complete_config ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let partial_config = arguments . get ( " config " )
. cloned ( )
. unwrap_or ( json! ( { } ) ) ;
info! ( " Completing partial configuration " ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let mut tools = settings_tools . lock ( ) . await ;
tools . complete_config ( partial_config ) . await
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " ✅ Completed Configuration: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_validate_config ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let config = arguments . get ( " config " )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " config is required " . to_string ( ) ) ) ?
. clone ( ) ;
info! ( " Validating installer configuration " ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let tools = settings_tools . lock ( ) . await ;
tools . validate_config ( config )
} ) ? ;
let is_valid = result . get ( " valid " ) . and_then ( | v | v . as_bool ( ) ) . unwrap_or ( false ) ;
let icon = if is_valid { " ✅ " } else { " ❌ " } ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " {} Configuration Validation: \n \n {} " , icon , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( ! is_valid ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_get_defaults ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let mode = arguments . get ( " mode " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " mode is required " . to_string ( ) ) ) ? ;
info! ( " Getting defaults for mode: {} " , mode ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let tools = settings_tools . lock ( ) . await ;
tools . get_mode_defaults ( mode )
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 📋 Mode Defaults: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_platform_recommendations ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Getting platform recommendations " ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let mut tools = settings_tools . lock ( ) . await ;
tools . get_platform_recommendations ( ) . await
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🎯 Platform Recommendations: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_service_recommendations ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let mode_str = arguments . get ( " mode " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " mode is required " . to_string ( ) ) ) ? ;
info! ( " Getting service recommendations for mode: {} " , mode_str ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let tools = settings_tools . lock ( ) . await ;
let mode = tools ::settings ::DeploymentMode ::from_str ( mode_str )
. ok_or_else ( | | ProvisioningError ::invalid_input ( format! ( " Invalid mode: {} " , mode_str ) ) ) ? ;
Ok ::< _ , ProvisioningError > ( tools . get_service_recommendations ( & mode ) )
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 🔧 Service Recommendations: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
fn handle_resource_recommendations ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let mode_str = arguments . get ( " mode " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " mode is required " . to_string ( ) ) ) ? ;
info! ( " Getting resource recommendations for mode: {} " , mode_str ) ;
let settings_tools = self . settings_tools . clone ( ) ;
let result = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let tools = settings_tools . lock ( ) . await ;
let mode = tools ::settings ::DeploymentMode ::from_str ( mode_str )
. ok_or_else ( | | ProvisioningError ::invalid_input ( format! ( " Invalid mode: {} " , mode_str ) ) ) ? ;
Ok ::< _ , ProvisioningError > ( tools . get_resource_recommendations ( & mode ) )
} ) ? ;
Ok ( CallToolResult {
2026-01-08 21:32:59 +00:00
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent ( rust_mcp_sdk ::schema ::TextContent ::from ( format! ( " 💾 Resource Recommendations: \n \n {} " , serde_json ::to_string_pretty ( & result ) ? ) ,
) ) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
} )
}
}
// ============================================================================
// Guidance Tool Handlers
// ============================================================================
fn handle_check_system_status ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| _request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Checking system status " ) ;
let status = self . system_status_tool . check_system ( ) ? ;
Ok ( CallToolResult {
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent (
rust_mcp_sdk ::schema ::TextContent ::from ( format! (
" 🔍 System Status: \n \n {} " ,
serde_json ::to_string_pretty ( & status ) ?
) ) ,
) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
} )
}
}
fn handle_suggest_next_action ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| _request : CallToolRequest | -> Result < CallToolResult > {
info! ( " Suggesting next action " ) ;
// Get current system status
let status = self . system_status_tool . check_system ( ) ? ;
// Suggest next action based on status
let next_action = self . next_action_tool . suggest_next_action ( & status ) ? ;
Ok ( CallToolResult {
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent (
rust_mcp_sdk ::schema ::TextContent ::from ( format! (
" 💡 Next Action: \n \n **Command:** `{}` \n \n **Description:** {} \n \n **Expected Outcome:** {} \n \n **Documentation:** {} \n \n **Priority:** {} " ,
next_action . command ,
next_action . description ,
next_action . expected_outcome ,
next_action . docs_link ,
next_action . priority
) ) ,
) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
} )
}
}
fn handle_find_docs ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let query = arguments
. get ( " query " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " query is required " . to_string ( ) ) ) ? ;
let context = arguments . get ( " context " ) . and_then ( | v | v . as_str ( ) ) ;
info! ( " Finding documentation for query: {} " , query ) ;
let doc_finder = self . doc_finder_tool . clone ( ) ;
let results = tokio ::runtime ::Handle ::current ( ) . block_on ( async move {
let mut finder = doc_finder . lock ( ) . await ;
finder . find_docs ( query , context )
} ) ? ;
let mut output = String ::from ( " 📚 Documentation Results: \n \n " ) ;
for ( idx , doc ) in results . iter ( ) . enumerate ( ) {
output . push_str ( & format! (
" {}. **{}** (relevance: {:.1}%) \n Path: `{}` \n {} \n \n " ,
idx + 1 ,
doc . title ,
doc . relevance * 100.0 ,
doc . path ,
doc . snippet . trim ( )
) ) ;
}
if results . is_empty ( ) {
output . push_str ( " No documentation found matching your query. \n " ) ;
}
Ok ( CallToolResult {
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent (
rust_mcp_sdk ::schema ::TextContent ::from ( output ) ,
) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
} )
}
}
fn handle_diagnose_issue ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let error = arguments
. get ( " error " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " error is required " . to_string ( ) ) ) ? ;
info! ( " Diagnosing issue: {} " , error ) ;
// Get current system status for context
let status = self . system_status_tool . check_system ( ) ? ;
// Diagnose the issue
let diagnosis = self . troubleshooter_tool . diagnose_issue ( error , & status ) ? ;
let mut output = String ::from ( " 🔧 Issue Diagnosis: \n \n " ) ;
output . push_str ( & format! ( " **Error:** {} \n \n " , diagnosis . error ) ) ;
output . push_str ( & format! ( " **Root Cause:** {} \n \n " , diagnosis . root_cause ) ) ;
output . push_str ( & format! ( " **Confidence:** {:.1} % \n \n " , diagnosis . confidence * 100.0 ) ) ;
output . push_str ( " **Suggested Fixes:** \n \n " ) ;
for ( idx , fix ) in diagnosis . fixes . iter ( ) . enumerate ( ) {
output . push_str ( & format! ( " {} . {} (Risk: {:?} ) \n " , idx + 1 , fix . description , fix . risk ) ) ;
output . push_str ( " Commands: \n " ) ;
for cmd in & fix . commands {
output . push_str ( & format! ( " ``` \n {} \n ``` \n " , cmd ) ) ;
}
output . push_str ( & format! ( " Expected outcome: {} \n \n " , fix . expected_outcome ) ) ;
}
if ! diagnosis . related_docs . is_empty ( ) {
output . push_str ( " \n **Related Documentation:** \n " ) ;
for doc in & diagnosis . related_docs {
output . push_str ( & format! ( " - [ {} ]( {} ) \n " , doc . title , doc . path ) ) ;
}
}
Ok ( CallToolResult {
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent (
rust_mcp_sdk ::schema ::TextContent ::from ( output ) ,
) ] ,
is_error : Some ( false ) ,
meta : None ,
structured_content : None ,
} )
}
}
fn handle_validate_config_file ( & self ) -> impl Fn ( CallToolRequest ) -> Result < CallToolResult > + '_ {
| request : CallToolRequest | -> Result < CallToolResult > {
let arguments = request . params . arguments . unwrap_or_default ( ) ;
let config_path = arguments
. get ( " config_path " )
. and_then ( | v | v . as_str ( ) )
. ok_or_else ( | | ProvisioningError ::InvalidInput ( " config_path is required " . to_string ( ) ) ) ? ;
info! ( " Validating configuration file: {} " , config_path ) ;
let result = self . config_validator_tool . validate_config ( config_path ) ? ;
let mut output = String ::new ( ) ;
if result . valid {
output . push_str ( " ✅ Configuration Valid \n \n " ) ;
} else {
output . push_str ( " ❌ Configuration Invalid \n \n " ) ;
}
if ! result . errors . is_empty ( ) {
output . push_str ( " **Errors:** \n " ) ;
for error in & result . errors {
output . push_str ( & format! ( " - {} \n " , error . message ) ) ;
if let Some ( fix ) = & error . fix {
output . push_str ( & format! ( " Fix: {} \n " , fix ) ) ;
}
}
output . push ( '\n' ) ;
}
if ! result . warnings . is_empty ( ) {
output . push_str ( " **Warnings:** \n " ) ;
for warning in & result . warnings {
output . push_str ( & format! ( " - {} \n " , warning . message ) ) ;
output . push_str ( & format! ( " Recommendation: {} \n " , warning . recommendation ) ) ;
}
output . push ( '\n' ) ;
}
if ! result . suggestions . is_empty ( ) {
output . push_str ( " **Suggestions:** \n " ) ;
for suggestion in & result . suggestions {
output . push_str ( & format! ( " - {} \n " , suggestion ) ) ;
}
output . push ( '\n' ) ;
}
if ! result . docs . is_empty ( ) {
output . push_str ( " **Related Documentation:** \n " ) ;
for doc in & result . docs {
output . push_str ( & format! ( " - [ {} ]( {} ) \n " , doc . title , doc . path ) ) ;
}
}
Ok ( CallToolResult {
content : vec ! [ rust_mcp_sdk ::schema ::ContentBlock ::TextContent (
rust_mcp_sdk ::schema ::TextContent ::from ( output ) ,
) ] ,
is_error : Some ( ! result . valid ) ,
meta : None ,
structured_content : None ,
2025-10-07 10:59:52 +01:00
} )
}
}
}
#[ tokio::main ]
async fn main ( ) -> Result < ( ) > {
let args = Args ::parse ( ) ;
// Initialize tracing
let log_level = args . log_level . parse ( ) . unwrap_or ( tracing ::Level ::INFO ) ;
tracing_subscriber ::fmt ( )
. with_max_level ( log_level )
. with_target ( false )
. init ( ) ;
// Load configuration
let config = Config ::load ( args . config , args . provisioning_path , args . debug ) ? ;
info! ( " Starting Provisioning MCP Server (Rust-native) " ) ;
info! ( " Provisioning path: {} " , config . provisioning_path . display ( ) ) ;
// Create and run server
let server = ProvisioningMCPServer ::new ( config ) ? ;
server . run ( ) . await ? ;
Ok ( ( ) )
}