@@ -1142,13 +1142,20 @@ fn nonempty_vec<T: Clone>(v: &[T]) -> Option<Vec<T>> {
11421142 if v. is_empty ( ) { None } else { Some ( v. to_vec ( ) ) }
11431143}
11441144
1145- /// Returns `Some(m.clone())` when `m` is non-empty, otherwise `None`.
1146- fn nonempty_map < K , V > ( m : & HashMap < K , V > ) -> Option < HashMap < K , V > >
1145+ /// Returns `Some(BTreeMap from m)` when `m` is non-empty, otherwise `None`.
1146+ ///
1147+ /// Converts a `HashMap` source to a `BTreeMap` so JSON serialization is
1148+ /// deterministic (keys are emitted in sorted order).
1149+ fn nonempty_map < K , V > ( m : & HashMap < K , V > ) -> Option < std:: collections:: BTreeMap < K , V > >
11471150where
1148- K : Clone + Eq + std:: hash:: Hash ,
1151+ K : Clone + Eq + std:: hash:: Hash + Ord ,
11491152 V : Clone ,
11501153{
1151- if m. is_empty ( ) { None } else { Some ( m. clone ( ) ) }
1154+ if m. is_empty ( ) {
1155+ None
1156+ } else {
1157+ Some ( m. iter ( ) . map ( |( k, v) | ( k. clone ( ) , v. clone ( ) ) ) . collect ( ) )
1158+ }
11521159}
11531160
11541161/// Validate a container-based MCP entry and emit any warnings.
@@ -1200,7 +1207,7 @@ fn build_http_mcpg_server(url: &str, opts: &crate::compile::types::McpOptions) -
12001207fn try_add_user_mcp (
12011208 name : & str ,
12021209 config : & McpConfig ,
1203- servers : & mut HashMap < String , McpgServerConfig > ,
1210+ servers : & mut std :: collections :: BTreeMap < String , McpgServerConfig > ,
12041211) -> Result < ( ) > {
12051212 // Prevent user-defined MCPs from overwriting the reserved safeoutputs backend
12061213 if name. eq_ignore_ascii_case ( "safeoutputs" ) {
@@ -1282,7 +1289,7 @@ pub fn generate_mcpg_config(
12821289 ctx : & CompileContext ,
12831290 extensions : & [ super :: extensions:: Extension ] ,
12841291) -> Result < McpgConfig > {
1285- let mut mcp_servers = HashMap :: new ( ) ;
1292+ let mut mcp_servers = std :: collections :: BTreeMap :: new ( ) ;
12861293
12871294 // Add extension-contributed MCPG server entries (safeoutputs, azure-devops, etc.)
12881295 for ext in extensions {
0 commit comments