@@ -208,14 +208,14 @@ impl Agent {
208208 /// This function mutates the agent to a state that is usable for runtime.
209209 /// Practically this means to convert some of the fields value to their usable counterpart.
210210 /// 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 > {
212212 let Self { mcp_servers, .. } = self ;
213213
214214 self . path = Some ( path. to_path_buf ( ) ) ;
215215
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 ) {
217217 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 {
219219 if mcp_servers. mcp_servers . contains_key ( name) {
220220 let _ = queue ! (
221221 stderr,
@@ -269,16 +269,13 @@ impl Agent {
269269 Ok ( config_path) => {
270270 let content = os. fs . read ( & config_path) . await ?;
271271 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
280276 } ;
281- agent. thaw ( & config_path, global_mcp_config. as_ref ( ) ) ?;
277+
278+ agent. thaw ( & config_path, legacy_mcp_config. as_ref ( ) ) ?;
282279 Ok ( ( agent, config_path) )
283280 } ,
284281 _ => bail ! ( "Agent {agent_name} does not exist" ) ,
@@ -288,27 +285,22 @@ impl Agent {
288285 pub async fn load (
289286 os : & Os ,
290287 agent_path : impl AsRef < Path > ,
291- global_mcp_config : & mut Option < McpServerConfig > ,
288+ legacy_mcp_config : & mut Option < McpServerConfig > ,
292289 ) -> Result < Agent , AgentConfigError > {
293290 let content = os. fs . read ( & agent_path) . await ?;
294291 let mut agent = serde_json:: from_slice :: < Agent > ( & content) . map_err ( |e| AgentConfigError :: InvalidJson {
295292 error : e,
296293 path : agent_path. as_ref ( ) . to_path_buf ( ) ,
297294 } ) ?;
298295
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+ }
309301 }
310302
311- agent. thaw ( agent_path. as_ref ( ) , global_mcp_config . as_ref ( ) ) ?;
303+ agent. thaw ( agent_path. as_ref ( ) , legacy_mcp_config . as_ref ( ) ) ?;
312304 Ok ( agent)
313305 }
314306}
@@ -611,7 +603,7 @@ impl Agents {
611603 let mut agent = Agent :: default ( ) ;
612604 ' load_legacy_mcp_json: {
613605 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 {
615607 tracing:: error!( "Error obtaining legacy mcp json path. Skipping" ) ;
616608 break ' load_legacy_mcp_json;
617609 } ;
@@ -769,6 +761,42 @@ async fn load_agents_from_entries(
769761 res
770762}
771763
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+
772800fn default_schema ( ) -> String {
773801 "https://raw.githubusercontent.com/aws/amazon-q-developer-cli/refs/heads/main/schemas/agent-v1.json" . into ( )
774802}
0 commit comments