main.rs

 1mod config;
 2mod lsp;
 3mod mcp;
 4
 5use clap::Parser;
 6use futures::join;
 7use rmcp::ServiceExt;
 8
 9use config::{CommandLineArgs, Config};
10use lsp::setup_lsp_client;
11use mcp::{MCPServer, MCPServerConfig};
12
13#[tokio::main]
14async fn main() -> Result<(), Box<dyn std::error::Error>> {
15    let args = CommandLineArgs::parse();
16    let config = Config::load(&args.config).await?;
17
18    let (mainloop_fut, lsp_server) = setup_lsp_client(
19        &config.lsp_server_command.command,
20        &config.lsp_server_command.args,
21        &config.project_root,
22    )
23    .await?;
24
25    let project_root_canonicalized = tokio::fs::canonicalize(config.project_root)
26        .await
27        .expect("Failed to canonicalize project root");
28
29    let mcp_service = MCPServer::new(
30        MCPServerConfig {
31            project_root: project_root_canonicalized,
32        },
33        lsp_server,
34    );
35
36    let server = mcp_service
37        .serve(rmcp::transport::stdio())
38        .await
39        .expect("Failed to starting serving MCP");
40    let (r1, r2) = join!(mainloop_fut, server.waiting());
41    r1.expect("R1 failed");
42
43    r2.expect("R2 failed");
44
45    Ok(())
46}