read.rs

 1use std::path::PathBuf;
 2
 3use async_lsp::LanguageServer;
 4use async_lsp::lsp_types::{
 5    DocumentDiagnosticParams, DocumentDiagnosticReportResult, PartialResultParams,
 6    TextDocumentIdentifier, Url, WorkDoneProgressParams,
 7};
 8use rmcp::ErrorData as MCPError;
 9use rmcp::{
10    handler::server::wrapper::Parameters, model::CallToolResult, schemars, serde_json, tool_router,
11};
12
13use crate::mcp::*;
14use rmcp::ServerHandler as MCPServerHandler;
15
16#[derive(Debug, serde::Deserialize, schemars::JsonSchema)]
17pub struct ReadToolArgs {
18    pub path: PathBuf,
19    pub range_start: usize,
20    pub range_end: usize,
21}
22
23#[derive(Debug, serde::Serialize)]
24pub struct ReadToolOutput {
25    pub content: Option<String>,
26    pub diagnostics: DocumentDiagnosticReportResult,
27}
28
29pub async fn call(
30    server: &MCPServer,
31    Parameters(args): Parameters<ReadToolArgs>,
32) -> Result<CallToolResult, MCPError> {
33    let file_path = server.config.project_root.join(&args.path);
34    let file_path = tokio::fs::canonicalize(file_path).await.unwrap();
35    let content = tokio::fs::read_to_string(&file_path)
36        .await
37        .map_err(|e| MCPError::invalid_request(format!("Failed to read file: {e}"), None))?;
38
39    let mut lsp_server = server.lsp_server.clone();
40
41    let diagnostic_report = lsp_server
42        .document_diagnostic(DocumentDiagnosticParams {
43            text_document: TextDocumentIdentifier::new(Url::from_file_path(file_path).unwrap()),
44            identifier: None,
45            previous_result_id: None,
46            work_done_progress_params: WorkDoneProgressParams {
47                work_done_token: None,
48            },
49            partial_result_params: PartialResultParams {
50                partial_result_token: None,
51            },
52        })
53        .await
54        .unwrap();
55
56    Ok(CallToolResult {
57        content: vec![],
58        structured_content: Some(serde_json::json!(ReadToolOutput {
59            content: Some(content),
60            diagnostics: diagnostic_report
61        })),
62        is_error: None,
63        meta: None,
64    })
65}