@@ -68,6 +68,17 @@ pub struct GoalIndexInputs {
6868 pub goal_index : Value ,
6969}
7070
71+ #[ derive( Serialize , Deserialize , JsonSchema ) ]
72+ pub struct LspCallInputs {
73+ pub method : String ,
74+ /// Optional params to pass to the LSP method. If omitted, `null` is sent.
75+ pub params : Option < Value > ,
76+ /// If provided, sets the workspace root before making the call.
77+ pub workspace_path : Option < String > ,
78+ /// If true, send as a notification (no response expected). Defaults to false.
79+ pub is_notification : Option < bool > ,
80+ }
81+
7182pub const SERVER_ID : & str = "rust-analyzer" ;
7283
7384pub ( crate ) async fn ensure_bridge ( bridge : & BridgeType , workspace_path : Option < & str > ) -> Result < ( ) > {
@@ -463,6 +474,37 @@ pub async fn build_server(
463474 } ,
464475 sacp:: tool_fn_mut!( ) ,
465476 )
477+ . tool_fn_mut (
478+ "rust_analyzer_lsp_call" ,
479+ "Make an arbitrary LSP method call" ,
480+ {
481+ let bridge = bridge. clone ( ) ;
482+ async move |input : LspCallInputs , _mcp_cx| {
483+ let method = input. method . clone ( ) ;
484+ let params = input. params ;
485+ let is_notification = input. is_notification . unwrap_or ( false ) ;
486+
487+ with_bridge ( & bridge, input. workspace_path . as_deref ( ) , async move |client| {
488+ if is_notification {
489+ client
490+ . notify ( & method, params)
491+ . await
492+ . map_err ( |e| anyhow ! ( "LSP notify failed: {}" , e) ) ?;
493+ Ok ( "Notification sent" . to_string ( ) )
494+ } else {
495+ let params = params. unwrap_or ( Value :: Null ) ;
496+ let result = client
497+ . request ( & method, params)
498+ . await
499+ . map_err ( |e| anyhow ! ( "LSP request failed: {}" , e) ) ?;
500+ Ok ( serde_json:: to_string ( & result) . map_err ( |e| anyhow:: Error :: new ( e) ) ?)
501+ }
502+ } )
503+ . await
504+ }
505+ } ,
506+ sacp:: tool_fn_mut!( ) ,
507+ )
466508 . build ( ) ;
467509
468510 Ok ( server)
0 commit comments