@@ -90,6 +90,7 @@ use crate::database::settings::Setting;
90
90
use crate :: mcp_client:: messenger:: Messenger ;
91
91
use crate :: mcp_client:: {
92
92
InitializedMcpClient ,
93
+ InnerService ,
93
94
McpClientService ,
94
95
} ;
95
96
use crate :: os:: Os ;
@@ -137,6 +138,11 @@ enum LoadingMsg {
137
138
/// This is sent when all tool initialization is complete or when the application is shutting
138
139
/// down.
139
140
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 } ,
140
146
}
141
147
142
148
/// Used to denote the loading outcome associated with a server.
@@ -630,19 +636,29 @@ impl ToolManager {
630
636
let server_name_clone = server_name. clone ( ) ;
631
637
tokio:: spawn ( async move {
632
638
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
+ }
636
647
} ,
637
648
Ok ( Err ( _) ) | Err ( _) => {
638
649
error ! ( "Server {server_name_clone} has failed to cancel" ) ;
639
650
} ,
640
651
}
641
652
} ) ;
642
653
} ,
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
+ }
646
662
} ,
647
663
}
648
664
}
@@ -869,17 +885,16 @@ impl ToolManager {
869
885
} ) ;
870
886
} ;
871
887
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 {
873
889
tool_use_id : value. id . clone ( ) ,
874
890
content : vec ! [ ToolResultContentBlock :: Text ( format!( "Mcp tool client not ready: {e}" ) ) ] ,
875
891
status : ToolResultStatus :: Error ,
876
- } ) ?)
877
- . clone ( ) ;
892
+ } ) ?;
878
893
879
894
Tool :: Custom ( CustomTool {
880
895
name : tool_name. to_owned ( ) ,
881
896
server_name : server_name. to_owned ( ) ,
882
- client : running_service,
897
+ client : running_service. clone ( ) ,
883
898
params : value. args . as_object ( ) . cloned ( ) ,
884
899
} )
885
900
} ,
@@ -1170,6 +1185,15 @@ fn spawn_display_task(
1170
1185
execute ! ( output, style:: Print ( "\n " ) , ) ?;
1171
1186
break ;
1172
1187
} ,
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
+ } ,
1173
1197
} ,
1174
1198
Err ( _e) => {
1175
1199
spinner_logo_idx = ( spinner_logo_idx + 1 ) % SPINNER_CHARS . len ( ) ;
@@ -1595,6 +1619,35 @@ fn spawn_orchestrator_task(
1595
1619
} ,
1596
1620
UpdateEventMessage :: ListResourcesResult { .. } => { } ,
1597
1621
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
+ } ,
1598
1651
UpdateEventMessage :: InitStart { server_name, .. } => {
1599
1652
pending. write ( ) . await . insert ( server_name. clone ( ) ) ;
1600
1653
loading_servers. insert ( server_name, std:: time:: Instant :: now ( ) ) ;
@@ -1876,6 +1929,34 @@ fn queue_failure_message(
1876
1929
) ?)
1877
1930
}
1878
1931
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
+
1879
1960
fn queue_warn_message ( name : & str , msg : & eyre:: Report , time : & str , output : & mut impl Write ) -> eyre:: Result < ( ) > {
1880
1961
Ok ( queue ! (
1881
1962
output,
0 commit comments