use {
crate::{
connect::lsp::{
LspClient,
request::{
DocumentSymbolRequest,
WorkspaceSymbolRequest,
},
},
connect::mcp::{
schema,
tool::{
Tool,
ToolError,
ToolRegistry,
},
},
protocol::lsp::{
DocumentSymbolParams,
DocumentSymbolResponse,
WorkspaceSymbolParams,
WorkspaceSymbolResponse,
},
},
serde_json::json,
};
pub fn register(registry: &mut ToolRegistry) {
registry.register::<FindSymbol>();
registry.register::<DocumentSymbols>();
}
pub enum FindSymbol {}
impl Tool for FindSymbol {
type Input = WorkspaceSymbolParams;
type Output = Option<WorkspaceSymbolResponse>;
const NAME: &'static str = "find_symbol";
const DESCRIPTION: &'static str =
"Search the workspace for symbols whose name matches a query string. \
Wraps LSP `workspace/symbol`.";
fn input_schema() -> serde_json::Value {
json!({
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Fuzzy substring matched against symbol names."
}
},
"required": ["query"]
})
}
async fn call(
client: &LspClient,
input: Self::Input,
) -> Result<Self::Output, ToolError> {
Ok(client.send_request::<WorkspaceSymbolRequest>(input).await?)
}
}
pub enum DocumentSymbols {}
impl Tool for DocumentSymbols {
type Input = DocumentSymbolParams;
type Output = Option<DocumentSymbolResponse>;
const NAME: &'static str = "document_symbols";
const DESCRIPTION: &'static str =
"Return the symbol outline (functions, types, etc.) for a single file. \
Wraps LSP `textDocument/documentSymbol`.";
fn input_schema() -> serde_json::Value {
json!({
"type": "object",
"properties": { "textDocument": schema::text_document_identifier() },
"required": ["textDocument"]
})
}
async fn call(
client: &LspClient,
input: Self::Input,
) -> Result<Self::Output, ToolError> {
Ok(client.send_request::<DocumentSymbolRequest>(input).await?)
}
}