@@ -208,14 +208,14 @@ impl Agent {
208
208
/// This function mutates the agent to a state that is usable for runtime.
209
209
/// Practically this means to convert some of the fields value to their usable counterpart.
210
210
/// For example, converting the mcp array to actual mcp config and populate the agent file path.
211
- fn thaw ( & mut self , path : & Path , global_mcp_config : Option < & McpServerConfig > ) -> Result < ( ) , AgentConfigError > {
211
+ fn thaw ( & mut self , path : & Path , legacy_mcp_config : Option < & McpServerConfig > ) -> Result < ( ) , AgentConfigError > {
212
212
let Self { mcp_servers, .. } = self ;
213
213
214
214
self . path = Some ( path. to_path_buf ( ) ) ;
215
215
216
- if let ( true , Some ( global_mcp_config ) ) = ( self . use_legacy_mcp_json , global_mcp_config ) {
216
+ if let ( true , Some ( legacy_mcp_config ) ) = ( self . use_legacy_mcp_json , legacy_mcp_config ) {
217
217
let mut stderr = std:: io:: stderr ( ) ;
218
- for ( name, legacy_server) in & global_mcp_config . mcp_servers {
218
+ for ( name, legacy_server) in & legacy_mcp_config . mcp_servers {
219
219
if mcp_servers. mcp_servers . contains_key ( name) {
220
220
let _ = queue ! (
221
221
stderr,
@@ -269,16 +269,13 @@ impl Agent {
269
269
Ok ( config_path) => {
270
270
let content = os. fs . read ( & config_path) . await ?;
271
271
let mut agent = serde_json:: from_slice :: < Agent > ( & content) ?;
272
-
273
- let global_mcp_path = directories:: chat_legacy_mcp_config ( os) ?;
274
- let global_mcp_config = match McpServerConfig :: load_from_file ( os, global_mcp_path) . await {
275
- Ok ( config) => Some ( config) ,
276
- Err ( e) => {
277
- tracing:: error!( "Error loading global mcp json path: {e}." ) ;
278
- None
279
- } ,
272
+ let legacy_mcp_config = if agent. use_legacy_mcp_json {
273
+ load_legacy_mcp_config ( os) . await . unwrap_or ( None )
274
+ } else {
275
+ None
280
276
} ;
281
- agent. thaw ( & config_path, global_mcp_config. as_ref ( ) ) ?;
277
+
278
+ agent. thaw ( & config_path, legacy_mcp_config. as_ref ( ) ) ?;
282
279
Ok ( ( agent, config_path) )
283
280
} ,
284
281
_ => bail ! ( "Agent {agent_name} does not exist" ) ,
@@ -288,27 +285,22 @@ impl Agent {
288
285
pub async fn load (
289
286
os : & Os ,
290
287
agent_path : impl AsRef < Path > ,
291
- global_mcp_config : & mut Option < McpServerConfig > ,
288
+ legacy_mcp_config : & mut Option < McpServerConfig > ,
292
289
) -> Result < Agent , AgentConfigError > {
293
290
let content = os. fs . read ( & agent_path) . await ?;
294
291
let mut agent = serde_json:: from_slice :: < Agent > ( & content) . map_err ( |e| AgentConfigError :: InvalidJson {
295
292
error : e,
296
293
path : agent_path. as_ref ( ) . to_path_buf ( ) ,
297
294
} ) ?;
298
295
299
- if agent. use_legacy_mcp_json && global_mcp_config. is_none ( ) {
300
- let global_mcp_path = directories:: chat_legacy_mcp_config ( os) ?;
301
- let legacy_mcp_config = if global_mcp_path. exists ( ) {
302
- McpServerConfig :: load_from_file ( os, global_mcp_path)
303
- . await
304
- . map_err ( AgentConfigError :: BadLegacyMcpConfig ) ?
305
- } else {
306
- McpServerConfig :: default ( )
307
- } ;
308
- global_mcp_config. replace ( legacy_mcp_config) ;
296
+ if agent. use_legacy_mcp_json && legacy_mcp_config. is_none ( ) {
297
+ let config = load_legacy_mcp_config ( os) . await . unwrap_or_default ( ) ;
298
+ if let Some ( config) = config {
299
+ legacy_mcp_config. replace ( config) ;
300
+ }
309
301
}
310
302
311
- agent. thaw ( agent_path. as_ref ( ) , global_mcp_config . as_ref ( ) ) ?;
303
+ agent. thaw ( agent_path. as_ref ( ) , legacy_mcp_config . as_ref ( ) ) ?;
312
304
Ok ( agent)
313
305
}
314
306
}
@@ -611,7 +603,7 @@ impl Agents {
611
603
let mut agent = Agent :: default ( ) ;
612
604
' load_legacy_mcp_json: {
613
605
if global_mcp_config. is_none ( ) {
614
- let Ok ( global_mcp_path) = directories:: chat_legacy_mcp_config ( os) else {
606
+ let Ok ( global_mcp_path) = directories:: chat_legacy_global_mcp_config ( os) else {
615
607
tracing:: error!( "Error obtaining legacy mcp json path. Skipping" ) ;
616
608
break ' load_legacy_mcp_json;
617
609
} ;
@@ -769,6 +761,42 @@ async fn load_agents_from_entries(
769
761
res
770
762
}
771
763
764
+ /// Loads legacy mcp config by combining workspace and global config.
765
+ /// In case of a server naming conflict, the workspace config is prioritized.
766
+ async fn load_legacy_mcp_config ( os : & Os ) -> eyre:: Result < Option < McpServerConfig > > {
767
+ let global_mcp_path = directories:: chat_legacy_global_mcp_config ( os) ?;
768
+ let global_mcp_config = match McpServerConfig :: load_from_file ( os, global_mcp_path) . await {
769
+ Ok ( config) => Some ( config) ,
770
+ Err ( e) => {
771
+ tracing:: error!( "Error loading global mcp json path: {e}." ) ;
772
+ None
773
+ } ,
774
+ } ;
775
+
776
+ let workspace_mcp_path = directories:: chat_legacy_workspace_mcp_config ( os) ?;
777
+ let workspace_mcp_config = match McpServerConfig :: load_from_file ( os, workspace_mcp_path) . await {
778
+ Ok ( config) => Some ( config) ,
779
+ Err ( e) => {
780
+ tracing:: error!( "Error loading global mcp json path: {e}." ) ;
781
+ None
782
+ } ,
783
+ } ;
784
+
785
+ Ok ( match ( workspace_mcp_config, global_mcp_config) {
786
+ ( Some ( mut wc) , Some ( gc) ) => {
787
+ for ( server_name, config) in gc. mcp_servers {
788
+ // We prioritize what is in the workspace
789
+ wc. mcp_servers . entry ( server_name) . or_insert ( config) ;
790
+ }
791
+
792
+ Some ( wc)
793
+ } ,
794
+ ( None , Some ( gc) ) => Some ( gc) ,
795
+ ( Some ( wc) , None ) => Some ( wc) ,
796
+ _ => None ,
797
+ } )
798
+ }
799
+
772
800
fn default_schema ( ) -> String {
773
801
"https://raw.githubusercontent.com/aws/amazon-q-developer-cli/refs/heads/main/schemas/agent-v1.json" . into ( )
774
802
}
0 commit comments