@@ -90,6 +90,7 @@ use crate::database::settings::Setting;
9090use crate :: mcp_client:: messenger:: Messenger ;
9191use crate :: mcp_client:: {
9292 InitializedMcpClient ,
93+ InnerService ,
9394 McpClientService ,
9495} ;
9596use crate :: os:: Os ;
@@ -137,6 +138,11 @@ enum LoadingMsg {
137138 /// This is sent when all tool initialization is complete or when the application is shutting
138139 /// down.
139140 Terminate { still_loading : Vec < String > } ,
141+ /// Indicates that a server requires user authentication and provides a sign-in link.
142+ /// This message is used to notify the user about authentication requirements for MCP servers
143+ /// that need OAuth or other authentication methods. Contains the server name and the
144+ /// authentication message (typically a URL or instructions).
145+ SignInNotice { name : String } ,
140146}
141147
142148/// Used to denote the loading outcome associated with a server.
@@ -630,19 +636,29 @@ impl ToolManager {
630636 let server_name_clone = server_name. clone ( ) ;
631637 tokio:: spawn ( async move {
632638 match handle. await {
633- Ok ( Ok ( client) ) => match client. cancel ( ) . await {
634- Ok ( _) => info ! ( "Server {server_name_clone} evicted due to agent swap" ) ,
635- Err ( e) => error ! ( "Server {server_name_clone} has failed to cancel: {e}" ) ,
639+ Ok ( Ok ( client) ) => {
640+ let InnerService :: Original ( client) = client. inner_service else {
641+ unreachable ! ( ) ;
642+ } ;
643+ match client. cancel ( ) . await {
644+ Ok ( _) => info ! ( "Server {server_name_clone} evicted due to agent swap" ) ,
645+ Err ( e) => error ! ( "Server {server_name_clone} has failed to cancel: {e}" ) ,
646+ }
636647 } ,
637648 Ok ( Err ( _) ) | Err ( _) => {
638649 error ! ( "Server {server_name_clone} has failed to cancel" ) ;
639650 } ,
640651 }
641652 } ) ;
642653 } ,
643- InitializedMcpClient :: Ready ( running_service) => match running_service. cancel ( ) . await {
644- Ok ( _) => info ! ( "Server {server_name} evicted due to agent swap" ) ,
645- Err ( e) => error ! ( "Server {server_name} has failed to cancel: {e}" ) ,
654+ InitializedMcpClient :: Ready ( running_service) => {
655+ let InnerService :: Original ( client) = running_service. inner_service else {
656+ unreachable ! ( ) ;
657+ } ;
658+ match client. cancel ( ) . await {
659+ Ok ( _) => info ! ( "Server {server_name} evicted due to agent swap" ) ,
660+ Err ( e) => error ! ( "Server {server_name} has failed to cancel: {e}" ) ,
661+ }
646662 } ,
647663 }
648664 }
@@ -869,17 +885,16 @@ impl ToolManager {
869885 } ) ;
870886 } ;
871887
872- let running_service = ( * client. get_running_service ( ) . await . map_err ( |e| ToolResult {
888+ let running_service = client. get_running_service ( ) . await . map_err ( |e| ToolResult {
873889 tool_use_id : value. id . clone ( ) ,
874890 content : vec ! [ ToolResultContentBlock :: Text ( format!( "Mcp tool client not ready: {e}" ) ) ] ,
875891 status : ToolResultStatus :: Error ,
876- } ) ?)
877- . clone ( ) ;
892+ } ) ?;
878893
879894 Tool :: Custom ( CustomTool {
880895 name : tool_name. to_owned ( ) ,
881896 server_name : server_name. to_owned ( ) ,
882- client : running_service,
897+ client : running_service. clone ( ) ,
883898 params : value. args . as_object ( ) . cloned ( ) ,
884899 } )
885900 } ,
@@ -1170,6 +1185,15 @@ fn spawn_display_task(
11701185 execute ! ( output, style:: Print ( "\n " ) , ) ?;
11711186 break ;
11721187 } ,
1188+ LoadingMsg :: SignInNotice { name } => {
1189+ execute ! (
1190+ output,
1191+ cursor:: MoveToColumn ( 0 ) ,
1192+ cursor:: MoveUp ( 1 ) ,
1193+ terminal:: Clear ( terminal:: ClearType :: CurrentLine ) ,
1194+ ) ?;
1195+ queue_oauth_message ( & name, & mut output) ?;
1196+ } ,
11731197 } ,
11741198 Err ( _e) => {
11751199 spinner_logo_idx = ( spinner_logo_idx + 1 ) % SPINNER_CHARS . len ( ) ;
@@ -1595,6 +1619,35 @@ fn spawn_orchestrator_task(
15951619 } ,
15961620 UpdateEventMessage :: ListResourcesResult { .. } => { } ,
15971621 UpdateEventMessage :: ResourceTemplatesListResult { .. } => { } ,
1622+ UpdateEventMessage :: OauthLink { server_name, link } => {
1623+ let mut buf_writer = BufWriter :: new ( & mut * record_temp_buf) ;
1624+ let msg = eyre:: eyre!( link) ;
1625+ let _ = queue_oauth_message_with_link ( server_name. as_str ( ) , & msg, & mut buf_writer) ;
1626+ let _ = buf_writer. flush ( ) ;
1627+ drop ( buf_writer) ;
1628+ let record_str = String :: from_utf8_lossy ( record_temp_buf) . to_string ( ) ;
1629+ let record = LoadingRecord :: Warn ( record_str. clone ( ) ) ;
1630+ load_record
1631+ . lock ( )
1632+ . await
1633+ . entry ( server_name. clone ( ) )
1634+ . and_modify ( |load_record| {
1635+ load_record. push ( record. clone ( ) ) ;
1636+ } )
1637+ . or_insert ( vec ! [ record] ) ;
1638+ if let Some ( sender) = & loading_status_sender {
1639+ let msg = LoadingMsg :: SignInNotice {
1640+ name : server_name. clone ( ) ,
1641+ } ;
1642+ if let Err ( e) = sender. send ( msg) . await {
1643+ warn ! (
1644+ "Error sending update message to display task: {:?}\n Assume display task has completed" ,
1645+ e
1646+ ) ;
1647+ loading_status_sender. take ( ) ;
1648+ }
1649+ }
1650+ } ,
15981651 UpdateEventMessage :: InitStart { server_name, .. } => {
15991652 pending. write ( ) . await . insert ( server_name. clone ( ) ) ;
16001653 loading_servers. insert ( server_name, std:: time:: Instant :: now ( ) ) ;
@@ -1876,6 +1929,34 @@ fn queue_failure_message(
18761929 ) ?)
18771930}
18781931
1932+ fn queue_oauth_message ( name : & str , output : & mut impl Write ) -> eyre:: Result < ( ) > {
1933+ Ok ( queue ! (
1934+ output,
1935+ style:: SetForegroundColor ( style:: Color :: Yellow ) ,
1936+ style:: Print ( "⚠ " ) ,
1937+ style:: SetForegroundColor ( style:: Color :: Blue ) ,
1938+ style:: Print ( name) ,
1939+ style:: ResetColor ,
1940+ style:: Print ( " requires OAuth authentication. Use /mcp to see the auth link\n " ) ,
1941+ ) ?)
1942+ }
1943+
1944+ fn queue_oauth_message_with_link ( name : & str , msg : & eyre:: Report , output : & mut impl Write ) -> eyre:: Result < ( ) > {
1945+ Ok ( queue ! (
1946+ output,
1947+ style:: SetForegroundColor ( style:: Color :: Yellow ) ,
1948+ style:: Print ( "⚠ " ) ,
1949+ style:: SetForegroundColor ( style:: Color :: Blue ) ,
1950+ style:: Print ( name) ,
1951+ style:: ResetColor ,
1952+ style:: Print ( " requires OAuth authentication. Follow this link to proceed: \n " ) ,
1953+ style:: SetForegroundColor ( style:: Color :: Yellow ) ,
1954+ style:: Print ( msg) ,
1955+ style:: ResetColor ,
1956+ style:: Print ( "\n " )
1957+ ) ?)
1958+ }
1959+
18791960fn queue_warn_message ( name : & str , msg : & eyre:: Report , time : & str , output : & mut impl Write ) -> eyre:: Result < ( ) > {
18801961 Ok ( queue ! (
18811962 output,
0 commit comments