@@ -2035,6 +2035,125 @@ pub async fn handle_tools_list(id: Option<Value>, _state: &ServerState) -> Resul
20352035 ) )
20362036}
20372037
2038+ /// Handles the tools/call MCP method to execute a specific tool
2039+ pub async fn handle_tools_call (
2040+ params : Option < Value > ,
2041+ id : Option < Value > ,
2042+ state : Arc < RwLock < ServerState > > ,
2043+ ) -> Result < JsonRpcMessage > {
2044+ log:: info!( "Handling tools/call request" ) ;
2045+
2046+ let params = params. ok_or_else ( || anyhow:: anyhow!( "Missing params" ) ) ?;
2047+
2048+ let tool_name = params
2049+ . get ( "name" )
2050+ . and_then ( |v| v. as_str ( ) )
2051+ . ok_or_else ( || anyhow:: anyhow!( "Missing tool name parameter" ) ) ?;
2052+
2053+ let arguments = params. get ( "arguments" ) . cloned ( ) . unwrap_or ( serde_json:: json!( { } ) ) ;
2054+
2055+ log:: info!( "Executing tool: {}" , tool_name) ;
2056+
2057+ // Execute the specific tool based on the tool name
2058+ let result = match tool_name {
2059+ "getHealth" => {
2060+ let state_guard = state. read ( ) . await ;
2061+ crate :: rpc:: system:: get_health ( & state_guard. rpc_client ) . await
2062+ . map_err ( |e| anyhow:: anyhow!( "Health check failed: {}" , e) )
2063+ }
2064+ "getVersion" => {
2065+ let state_guard = state. read ( ) . await ;
2066+ crate :: rpc:: system:: get_version ( & state_guard. rpc_client ) . await
2067+ . map_err ( |e| anyhow:: anyhow!( "Version check failed: {}" , e) )
2068+ }
2069+ "getBalance" => {
2070+ let pubkey_str = arguments
2071+ . get ( "pubkey" )
2072+ . and_then ( |v| v. as_str ( ) )
2073+ . ok_or_else ( || anyhow:: anyhow!( "Missing pubkey parameter" ) ) ?;
2074+ let pubkey = Pubkey :: try_from ( pubkey_str) ?;
2075+
2076+ let state_guard = state. read ( ) . await ;
2077+ crate :: rpc:: accounts:: get_balance ( & state_guard. rpc_client , & pubkey) . await
2078+ . map_err ( |e| anyhow:: anyhow!( "Get balance failed: {}" , e) )
2079+ }
2080+ "getAccountInfo" => {
2081+ let pubkey_str = arguments
2082+ . get ( "pubkey" )
2083+ . and_then ( |v| v. as_str ( ) )
2084+ . ok_or_else ( || anyhow:: anyhow!( "Missing pubkey parameter" ) ) ?;
2085+ let pubkey = Pubkey :: try_from ( pubkey_str) ?;
2086+
2087+ let state_guard = state. read ( ) . await ;
2088+ crate :: rpc:: accounts:: get_account_info ( & state_guard. rpc_client , & pubkey) . await
2089+ . map_err ( |e| anyhow:: anyhow!( "Get account info failed: {}" , e) )
2090+ }
2091+ "getMultipleAccounts" => {
2092+ let pubkeys_array = arguments
2093+ . get ( "pubkeys" )
2094+ . and_then ( |v| v. as_array ( ) )
2095+ . ok_or_else ( || anyhow:: anyhow!( "Missing pubkeys parameter" ) ) ?;
2096+
2097+ let mut pubkeys = Vec :: new ( ) ;
2098+ for pubkey_val in pubkeys_array {
2099+ let pubkey_str = pubkey_val
2100+ . as_str ( )
2101+ . ok_or_else ( || anyhow:: anyhow!( "Invalid pubkey in array" ) ) ?;
2102+ pubkeys. push ( Pubkey :: try_from ( pubkey_str) ?) ;
2103+ }
2104+
2105+ let state_guard = state. read ( ) . await ;
2106+ crate :: rpc:: accounts:: get_multiple_accounts ( & state_guard. rpc_client , & pubkeys) . await
2107+ . map_err ( |e| anyhow:: anyhow!( "Get multiple accounts failed: {}" , e) )
2108+ }
2109+ "getSlot" => {
2110+ let state_guard = state. read ( ) . await ;
2111+ crate :: rpc:: blocks:: get_slot ( & state_guard. rpc_client ) . await
2112+ }
2113+ "getTransactionCount" => {
2114+ let state_guard = state. read ( ) . await ;
2115+ crate :: rpc:: system:: get_transaction_count ( & state_guard. rpc_client ) . await
2116+ . map_err ( |e| anyhow:: anyhow!( "Get transaction count failed: {}" , e) )
2117+ }
2118+ "getLatestBlockhash" => {
2119+ let state_guard = state. read ( ) . await ;
2120+ crate :: rpc:: system:: get_latest_blockhash ( & state_guard. rpc_client ) . await
2121+ . map_err ( |e| anyhow:: anyhow!( "Get latest blockhash failed: {}" , e) )
2122+ }
2123+ "getEpochInfo" => {
2124+ let state_guard = state. read ( ) . await ;
2125+ crate :: rpc:: system:: get_epoch_info ( & state_guard. rpc_client ) . await
2126+ . map_err ( |e| anyhow:: anyhow!( "Get epoch info failed: {}" , e) )
2127+ }
2128+ "getClusterNodes" => {
2129+ let state_guard = state. read ( ) . await ;
2130+ crate :: rpc:: system:: get_cluster_nodes ( & state_guard. rpc_client ) . await
2131+ . map_err ( |e| anyhow:: anyhow!( "Get cluster nodes failed: {}" , e) )
2132+ }
2133+ _ => {
2134+ return Ok ( create_error_response (
2135+ -32601 ,
2136+ format ! ( "Tool not found: {}" , tool_name) ,
2137+ id. unwrap_or ( Value :: Null ) ,
2138+ None ,
2139+ ) ) ;
2140+ }
2141+ } ;
2142+
2143+ match result {
2144+ Ok ( result_value) => Ok ( create_success_response ( result_value, id. unwrap_or ( Value :: Null ) ) ) ,
2145+ Err ( e) => {
2146+ log:: error!( "Tool execution failed: {}" , e) ;
2147+ Ok ( create_error_response (
2148+ -32603 ,
2149+ format ! ( "Tool execution failed: {}" , e) ,
2150+ id. unwrap_or ( Value :: Null ) ,
2151+ None ,
2152+ ) )
2153+ }
2154+ }
2155+ }
2156+
20382157use solana_sdk:: pubkey:: Pubkey ;
20392158
20402159// SVM Network Management Functions
@@ -2322,6 +2441,10 @@ pub async fn handle_request(
23222441 handle_tools_list ( Some ( req. id . clone ( ) ) , & state_guard)
23232442 . await
23242443 }
2444+ "tools/call" => {
2445+ handle_tools_call ( req. params , Some ( req. id . clone ( ) ) , state. clone ( ) )
2446+ . await
2447+ }
23252448
23262449 // Account methods
23272450 "getAccountInfo" => {
0 commit comments