use pforge_config::{ForgeConfig, ForgeMetadata, OptimizationLevel, ParamSchema, TransportType};
use pforge_runtime::{HandlerRegistry, McpServer};
use super::handlers::*;
use super::handlers_ops::*;
pub fn export_schema() -> serde_json::Value {
let tools: Vec<serde_json::Value> = crate::verb::verbs()
.iter()
.map(|v| {
serde_json::json!({
"name": v.mcp_name(),
"description": v.description,
"input_schema": (v.input_schema)(),
"output_schema": (v.output_schema)(),
"annotations": { "readOnlyHint": v.effects.read_only() },
})
})
.collect();
serde_json::json!({
"schema_version": "1.0",
"server": "forjar-mcp",
"version": env!("CARGO_PKG_VERSION"),
"tool_count": tools.len(),
"tools": tools,
})
}
fn register_all(reg: &mut HandlerRegistry) {
reg.register("forjar_validate", ValidateHandler);
reg.register("forjar_plan", PlanHandler);
reg.register("forjar_drift", DriftHandler);
reg.register("forjar_lint", LintHandler);
reg.register("forjar_graph", GraphHandler);
reg.register("forjar_show", ShowHandler);
reg.register("forjar_status", StatusHandler);
reg.register("forjar_trace", TraceHandler);
reg.register("forjar_anomaly", AnomalyHandler);
reg.register("forjar_remediate", RemediateHandler);
reg.register("forjar_audit", AuditHandler);
reg.register("forjar_workspace", WorkspaceHandler);
}
pub fn build_registry() -> HandlerRegistry {
let mut registry = HandlerRegistry::new();
register_all(&mut registry);
registry
}
#[cfg(test)]
pub(super) fn build_forge_config_for_test() -> ForgeConfig {
build_forge_config()
}
fn build_forge_config() -> ForgeConfig {
use pforge_config::{HandlerRef, ToolDef};
use rustc_hash::FxHashMap;
let empty_params = ParamSchema {
fields: FxHashMap::default(),
};
ForgeConfig {
forge: ForgeMetadata {
name: "forjar-mcp".to_string(),
version: env!("CARGO_PKG_VERSION").to_string(),
transport: TransportType::Stdio,
optimization: OptimizationLevel::Release,
},
tools: crate::verb::verbs()
.iter()
.map(|v| ToolDef::Native {
name: v.mcp_name(),
description: v.description.to_string(),
handler: HandlerRef {
path: format!("handlers::{}", v.name),
inline: None,
},
params: empty_params.clone(),
timeout_ms: Some(v.timeout_ms),
})
.collect(),
resources: vec![],
prompts: vec![],
state: None,
}
}
pub async fn serve() -> Result<(), String> {
let config = build_forge_config();
let server = McpServer::new(config);
let registry = server.registry();
{
let mut reg = registry.write().await;
register_all(&mut reg);
}
server
.run()
.await
.map_err(|e| format!("MCP server error: {e}"))
}