@@ -134,6 +134,22 @@ pub(super) struct DeleteAgentQuery {
134134 agent_id : String ,
135135}
136136
137+ #[ derive( Deserialize ) ]
138+ pub ( super ) struct AgentMcpQuery {
139+ agent_id : String ,
140+ }
141+
142+ #[ derive( Deserialize ) ]
143+ pub ( super ) struct ReconnectMcpRequest {
144+ agent_id : String ,
145+ server_name : String ,
146+ }
147+
148+ #[ derive( Serialize ) ]
149+ pub ( super ) struct AgentMcpResponse {
150+ servers : Vec < crate :: mcp:: McpServerStatus > ,
151+ }
152+
137153/// List all configured agents with their config summaries.
138154pub ( super ) async fn list_agents ( State ( state) : State < Arc < ApiState > > ) -> Json < AgentsResponse > {
139155 let agents = state. agent_configs . load ( ) ;
@@ -142,6 +158,51 @@ pub(super) async fn list_agents(State(state): State<Arc<ApiState>>) -> Json<Agen
142158 } )
143159}
144160
161+ /// List MCP connection status for an agent.
162+ pub ( super ) async fn list_agent_mcp (
163+ State ( state) : State < Arc < ApiState > > ,
164+ Query ( query) : Query < AgentMcpQuery > ,
165+ ) -> Result < Json < AgentMcpResponse > , StatusCode > {
166+ let managers = state. mcp_managers . load ( ) ;
167+ let manager = managers
168+ . get ( & query. agent_id )
169+ . cloned ( )
170+ . ok_or ( StatusCode :: NOT_FOUND ) ?;
171+ let servers = manager. statuses ( ) . await ;
172+ Ok ( Json ( AgentMcpResponse { servers } ) )
173+ }
174+
175+ /// Force reconnect for a single MCP server on an agent.
176+ pub ( super ) async fn reconnect_agent_mcp (
177+ State ( state) : State < Arc < ApiState > > ,
178+ Json ( request) : Json < ReconnectMcpRequest > ,
179+ ) -> Result < Json < serde_json:: Value > , StatusCode > {
180+ let managers = state. mcp_managers . load ( ) ;
181+ let manager = managers
182+ . get ( & request. agent_id )
183+ . cloned ( )
184+ . ok_or ( StatusCode :: NOT_FOUND ) ?;
185+
186+ manager
187+ . reconnect ( & request. server_name )
188+ . await
189+ . map_err ( |error| {
190+ tracing:: warn!(
191+ %error,
192+ agent_id = %request. agent_id,
193+ server_name = %request. server_name,
194+ "failed to reconnect mcp server"
195+ ) ;
196+ StatusCode :: BAD_REQUEST
197+ } ) ?;
198+
199+ Ok ( Json ( serde_json:: json!( {
200+ "success" : true ,
201+ "agent_id" : request. agent_id,
202+ "server_name" : request. server_name
203+ } ) ) )
204+ }
205+
145206/// Create a new agent and initialize it live (directories, databases, memory, identity, cron, cortex).
146207pub ( super ) async fn create_agent (
147208 State ( state) : State < Arc < ApiState > > ,
@@ -233,6 +294,7 @@ pub(super) async fn create_agent(
233294 ingestion : None ,
234295 cortex : None ,
235296 browser : None ,
297+ mcp : None ,
236298 brave_search_key : None ,
237299 cron : Vec :: new ( ) ,
238300 } ;
@@ -354,10 +416,14 @@ pub(super) async fn create_agent(
354416 . clone ( )
355417 } ;
356418
419+ let mcp_manager = std:: sync:: Arc :: new ( crate :: mcp:: McpManager :: new ( agent_config. mcp . clone ( ) ) ) ;
420+ mcp_manager. connect_all ( ) . await ;
421+
357422 let deps = crate :: AgentDeps {
358423 agent_id : arc_agent_id. clone ( ) ,
359424 memory_search : memory_search. clone ( ) ,
360425 llm_manager,
426+ mcp_manager : mcp_manager. clone ( ) ,
361427 cron_tool : None ,
362428 runtime_config : runtime_config. clone ( ) ,
363429 event_tx : event_tx. clone ( ) ,
@@ -455,6 +521,10 @@ pub(super) async fn create_agent(
455521 configs. insert ( agent_id. clone ( ) , runtime_config) ;
456522 state. runtime_configs . store ( std:: sync:: Arc :: new ( configs) ) ;
457523
524+ let mut mcp_managers = ( * * state. mcp_managers . load ( ) ) . clone ( ) ;
525+ mcp_managers. insert ( agent_id. clone ( ) , mcp_manager) ;
526+ state. mcp_managers . store ( std:: sync:: Arc :: new ( mcp_managers) ) ;
527+
458528 let mut agent_infos = ( * * state. agent_configs . load ( ) ) . clone ( ) ;
459529 agent_infos. push ( AgentInfo {
460530 id : agent_config. id . clone ( ) ,
@@ -567,6 +637,12 @@ pub(super) async fn delete_agent(
567637
568638 // Remove from all API state maps
569639 {
640+ let mut mcp_managers = ( * * state. mcp_managers . load ( ) ) . clone ( ) ;
641+ if let Some ( mcp_manager) = mcp_managers. remove ( & agent_id) {
642+ mcp_manager. disconnect_all ( ) . await ;
643+ }
644+ state. mcp_managers . store ( std:: sync:: Arc :: new ( mcp_managers) ) ;
645+
570646 let mut pools = ( * * state. agent_pools . load ( ) ) . clone ( ) ;
571647 pools. remove ( & agent_id) ;
572648 state. agent_pools . store ( std:: sync:: Arc :: new ( pools) ) ;
0 commit comments