1use std::path::PathBuf;
2
3use async_lsp::ServerSocket as LSPServerSocket;
4use rmcp::model::CallToolResult;
5use rmcp::ServerHandler as MCPServerHandler;
6use rmcp::ErrorData as MCPError;
7use rmcp::handler::server::tool::ToolRouter;
8use rmcp::handler::server::wrapper::Parameters;
9use rmcp::model::{Implementation, ProtocolVersion, ServerCapabilities, ServerInfo};
10use rmcp::{tool_handler, tool_router};
11
12pub use crate::mcp::tools::read::*;
13
14#[derive(Clone)]
15pub struct MCPServerConfig {
16 pub project_root: PathBuf,
17}
18
19#[derive(Clone)]
20pub struct MCPServer {
21 pub(crate) tool_router: ToolRouter<Self>,
22 pub(crate) config: MCPServerConfig,
23 pub(crate) lsp_server: LSPServerSocket,
24}
25
26impl MCPServer {
27 pub fn new(config: MCPServerConfig, lsp_server: LSPServerSocket) -> Self {
28 Self {
29 config,
30 lsp_server,
31 tool_router: Self::tool_router(),
32 }
33 }
34}
35
36#[tool_router]
37impl MCPServer {
38 #[rmcp::tool(
39 description = "Like the 'view' tool, except it returns LSP diagnostics too. Always use this instead of 'view'"
40 )]
41 pub async fn read(
42 &self,
43 Parameters(args): Parameters<ReadToolArgs>,
44 ) -> Result<CallToolResult, MCPError> {
45 crate::mcp::tools::read::call(self, Parameters(args)).await
46 }
47}
48
49#[tool_handler]
50impl MCPServerHandler for MCPServer {
51 fn get_info(&self) -> ServerInfo {
52 ServerInfo {
53 protocol_version: ProtocolVersion::V_2024_11_05,
54 capabilities: ServerCapabilities::builder().enable_tools().build(),
55 server_info: Implementation::from_build_env(),
56 instructions: Some("This server turns standard coding agent tools like `read` and `edit` into LSP clients.".into())
57 }
58 }
59}