use crate::mcp::tools::agent_context_tools::IndexManager;
use crate::mcp_pmcp::agent_context_handlers::{
PmatFindSimilarHandler, PmatGetFunctionHandler, PmatIndexStatsHandler, PmatQueryCodeHandler,
};
use crate::mcp_pmcp::analyze_handlers::{
AnalyzeBigOTool, AnalyzeComplexityTool, AnalyzeDagTool, AnalyzeDeadCodeTool,
AnalyzeDeepContextTool, AnalyzeSatdTool,
};
use crate::mcp_pmcp::context_handlers::{GenerateContextTool, GitTool, ScaffoldProjectTool};
use crate::mcp_pmcp::handlers::{
RefactorGetStateTool, RefactorNextIterationTool, RefactorStartTool, RefactorStopTool,
};
use crate::mcp_pmcp::pdmt_handler::PdmtTool;
use crate::mcp_pmcp::quality_handlers::QualityGateTool;
use crate::mcp_pmcp::quality_proxy_handler::QualityProxyTool;
use crate::mcp_server::state_manager::StateManager;
use pmcp::{Server, ServerCapabilities, ToolCapabilities};
use std::path::PathBuf;
use std::sync::Arc;
use tokio::sync::Mutex;
use tracing::info;
pub struct SimpleUnifiedServer {
state_manager: Arc<Mutex<StateManager>>,
}
impl SimpleUnifiedServer {
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
Ok(Self {
state_manager: Arc::new(Mutex::new(StateManager::new())),
})
}
#[provable_contracts_macros::contract("pmat-core.yaml", equation = "check_compliance")]
pub async fn run(&self) -> Result<(), Box<dyn std::error::Error>> {
info!("Starting PMAT Simple Unified MCP server (pmcp SDK)");
let index_manager = Arc::new(IndexManager::new(
std::env::current_dir().unwrap_or_else(|_| PathBuf::from(".")),
));
let server = Server::builder()
.name("paiml-mcp-agent-toolkit")
.version(env!("CARGO_PKG_VERSION"))
.capabilities(ServerCapabilities {
tools: Some(ToolCapabilities { list_changed: None }),
..Default::default()
})
.tool("analyze_complexity", AnalyzeComplexityTool)
.tool("analyze_satd", AnalyzeSatdTool)
.tool("analyze_dead_code", AnalyzeDeadCodeTool)
.tool("analyze_dag", AnalyzeDagTool)
.tool("analyze_deep_context", AnalyzeDeepContextTool)
.tool("analyze_big_o", AnalyzeBigOTool)
.tool(
"refactor.start",
RefactorStartTool::new(self.state_manager.clone()),
)
.tool(
"refactor.nextIteration",
RefactorNextIterationTool::new(self.state_manager.clone()),
)
.tool(
"refactor.getState",
RefactorGetStateTool::new(self.state_manager.clone()),
)
.tool(
"refactor.stop",
RefactorStopTool::new(self.state_manager.clone()),
)
.tool("quality_gate", QualityGateTool)
.tool("quality_proxy", QualityProxyTool)
.tool("pdmt_deterministic_todos", PdmtTool::new())
.tool("git_operation", GitTool)
.tool("generate_context", GenerateContextTool)
.tool("scaffold_project", ScaffoldProjectTool)
.tool(
"pmat_query_code",
PmatQueryCodeHandler::new(index_manager.clone()),
)
.tool(
"pmat_get_function",
PmatGetFunctionHandler::new(index_manager.clone()),
)
.tool(
"pmat_find_similar",
PmatFindSimilarHandler::new(index_manager.clone()),
)
.tool(
"pmat_index_stats",
PmatIndexStatsHandler::new(index_manager.clone()),
)
.build()?;
info!("PMAT Simple Unified MCP server ready with 20 tools (16 core + 4 agent_context), listening on stdio");
server.run_stdio().await?;
info!("PMAT Simple Unified MCP server shutting down");
Ok(())
}
}
impl Default for SimpleUnifiedServer {
fn default() -> Self {
Self::new().expect("Failed to create simple unified server")
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod property_tests {
use proptest::prelude::*;
proptest! {
#[test]
fn basic_property_stability(_input in ".*") {
prop_assert!(true);
}
#[test]
fn module_consistency_check(_x in 0u32..1000) {
prop_assert!(_x < 1001);
}
}
}
#[cfg_attr(coverage_nightly, coverage(off))]
#[cfg(test)]
mod active_tests {
use super::*;
#[test]
fn test_simple_unified_server_new() {
let result = SimpleUnifiedServer::new();
assert!(result.is_ok());
}
#[test]
fn test_simple_unified_server_default() {
let server = SimpleUnifiedServer::default();
let _ = server;
}
#[test]
fn test_server_is_send() {
fn assert_send<T: Send>() {}
assert_send::<SimpleUnifiedServer>();
}
#[test]
fn test_server_is_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<SimpleUnifiedServer>();
}
#[test]
fn test_server_size() {
let size = std::mem::size_of::<SimpleUnifiedServer>();
assert!(
size <= 16,
"Server struct is larger than expected: {} bytes",
size
);
}
#[test]
fn test_new_does_not_panic() {
let _ = std::panic::catch_unwind(|| {
let _ = SimpleUnifiedServer::new();
});
}
#[tokio::test]
async fn test_state_manager_accessible() {
let server = SimpleUnifiedServer::new().unwrap();
let state = server.state_manager.lock().await;
drop(state);
}
#[tokio::test]
async fn test_state_manager_thread_safety() {
let server = SimpleUnifiedServer::new().unwrap();
let state_clone = server.state_manager.clone();
{
let _state1 = server.state_manager.lock().await;
}
{
let _state2 = state_clone.lock().await;
}
}
}
#[cfg(all(test, feature = "broken-tests"))]
mod coverage_tests {
use super::*;
#[test]
fn test_simple_unified_server_new() {
let result = SimpleUnifiedServer::new();
assert!(result.is_ok());
let server = result.unwrap();
let _ = server;
}
#[test]
fn test_simple_unified_server_default() {
let server = SimpleUnifiedServer::default();
let _ = server;
}
#[test]
fn test_simple_unified_server_state_manager_initialized() {
let server = SimpleUnifiedServer::new().unwrap();
assert!(std::mem::size_of_val(&server) > 0);
}
#[test]
fn test_server_has_state_manager() {
let server = SimpleUnifiedServer::new().unwrap();
let _ = &server.state_manager;
}
#[test]
fn test_multiple_server_instances() {
let server1 = SimpleUnifiedServer::new().unwrap();
let server2 = SimpleUnifiedServer::new().unwrap();
let _ = server1;
let _ = server2;
}
#[test]
fn test_analyze_tools_importable() {
let _ = AnalyzeComplexityTool::new();
let _ = AnalyzeSatdTool::new();
let _ = AnalyzeDeadCodeTool::new();
let _ = AnalyzeDagTool::new();
let _ = AnalyzeDeepContextTool::new();
let _ = AnalyzeBigOTool::new();
}
#[test]
fn test_refactor_tools_require_state_manager() {
let state_manager = Arc::new(Mutex::new(StateManager::new()));
let _ = RefactorStartTool::new(state_manager.clone());
let _ = RefactorNextIterationTool::new(state_manager.clone());
let _ = RefactorGetStateTool::new(state_manager.clone());
let _ = RefactorStopTool::new(state_manager.clone());
}
#[test]
fn test_quality_tools_importable() {
let _ = QualityGateTool::new();
let _ = QualityProxyTool::new();
let _ = PdmtTool::new();
}
#[test]
fn test_context_tools_importable() {
let _ = GitTool::new();
let _ = GenerateContextTool::new();
let _ = ScaffoldProjectTool::new();
}
#[test]
fn test_server_builder_pattern_accessible() {
let builder = Server::builder()
.name("test-server")
.version("0.1.0")
.capabilities(ServerCapabilities {
tools: Some(ToolCapabilities { list_changed: None }),
..Default::default()
});
let _ = builder;
}
#[tokio::test]
async fn test_server_run_requires_stdio() {
let server = SimpleUnifiedServer::new().unwrap();
let _ = server;
}
#[tokio::test]
async fn test_state_manager_accessible() {
let server = SimpleUnifiedServer::new().unwrap();
let state = server.state_manager.lock().await;
drop(state);
}
#[tokio::test]
async fn test_state_manager_thread_safety() {
let server = SimpleUnifiedServer::new().unwrap();
let state_clone = server.state_manager.clone();
{
let _state1 = server.state_manager.lock().await;
}
{
let _state2 = state_clone.lock().await;
}
}
#[test]
fn test_all_tool_types_accessible() {
assert!(std::any::type_name::<AnalyzeComplexityTool>().contains("ComplexityTool"));
assert!(std::any::type_name::<AnalyzeSatdTool>().contains("SatdTool"));
assert!(std::any::type_name::<AnalyzeDeadCodeTool>().contains("DeadCodeTool"));
assert!(std::any::type_name::<AnalyzeDagTool>().contains("AnalyzeDagTool"));
assert!(std::any::type_name::<AnalyzeDeepContextTool>().contains("AnalyzeDeepContextTool"));
assert!(std::any::type_name::<AnalyzeBigOTool>().contains("AnalyzeBigOTool"));
assert!(std::any::type_name::<QualityGateTool>().contains("QualityGateTool"));
assert!(std::any::type_name::<QualityProxyTool>().contains("QualityProxyTool"));
assert!(std::any::type_name::<GenerateContextTool>().contains("ContextGenerateTool"));
assert!(std::any::type_name::<ScaffoldProjectTool>().contains("ContextSummaryTool"));
assert!(std::any::type_name::<GitTool>().contains("GitStatusTool"));
}
#[test]
fn test_server_capabilities_structure() {
let capabilities = ServerCapabilities {
tools: Some(ToolCapabilities { list_changed: None }),
..Default::default()
};
assert!(capabilities.tools.is_some());
assert!(capabilities.tools.as_ref().unwrap().list_changed.is_none());
}
#[test]
fn test_server_is_send() {
fn assert_send<T: Send>() {}
assert_send::<SimpleUnifiedServer>();
}
#[test]
fn test_server_is_sync() {
fn assert_sync<T: Sync>() {}
assert_sync::<SimpleUnifiedServer>();
}
#[test]
fn test_server_size() {
let size = std::mem::size_of::<SimpleUnifiedServer>();
assert!(
size <= 16,
"Server struct is larger than expected: {} bytes",
size
);
}
#[test]
fn test_new_does_not_panic() {
let _ = std::panic::catch_unwind(|| {
let _ = SimpleUnifiedServer::new();
});
}
#[test]
fn test_default_does_not_panic() {
let result = std::panic::catch_unwind(|| {
let _ = SimpleUnifiedServer::default();
});
assert!(result.is_ok());
}
}