From 06940c8d522f85c696643079790074bba7597c6b Mon Sep 17 00:00:00 2001 From: Nori Date: Sat, 18 Apr 2026 01:32:26 +0000 Subject: [PATCH 1/2] fix(mcp): sync in-memory config after persisting MCP servers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit persist_mcp_servers wrote to disk but never updated the in-memory Config.mcp_servers, so ComputeMcpAuthStatuses read stale config and the auto-OAuth trigger never fired for newly added servers. 🤖 Generated with [Nori](https://noriagentic.com) Co-Authored-By: Nori --- nori-rs/tui/src/app/config_persistence.rs | 9 +++++ nori-rs/tui/src/chatwidget/helpers.rs | 9 +++++ nori-rs/tui/src/chatwidget/tests/part7.rs | 46 +++++++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/nori-rs/tui/src/app/config_persistence.rs b/nori-rs/tui/src/app/config_persistence.rs index 46ef3ba51..066f56eb8 100644 --- a/nori-rs/tui/src/app/config_persistence.rs +++ b/nori-rs/tui/src/app/config_persistence.rs @@ -345,6 +345,15 @@ impl App { return; } + // Sync in-memory state so that ComputeMcpAuthStatuses (which reads + // chat_widget.config_ref().mcp_servers) sees the newly added servers. + let hash_map: std::collections::HashMap< + String, + codex_core::config::types::McpServerConfig, + > = servers.into_iter().collect(); + self.config.mcp_servers = hash_map.clone(); + self.chat_widget.set_mcp_servers(hash_map); + self.chat_widget.add_info_message( "MCP servers updated. Restart to apply changes.".to_string(), None, diff --git a/nori-rs/tui/src/chatwidget/helpers.rs b/nori-rs/tui/src/chatwidget/helpers.rs index f34017068..5db8be0d8 100644 --- a/nori-rs/tui/src/chatwidget/helpers.rs +++ b/nori-rs/tui/src/chatwidget/helpers.rs @@ -203,6 +203,15 @@ impl ChatWidget { &self.config } + /// Update the in-memory MCP server map so that subsequent reads via + /// `config_ref().mcp_servers` reflect the latest persisted state. + pub(crate) fn set_mcp_servers( + &mut self, + servers: std::collections::HashMap, + ) { + self.config.mcp_servers = servers; + } + /// Forward MCP auth statuses to the active bottom pane view. pub(crate) fn update_mcp_auth_statuses( &mut self, diff --git a/nori-rs/tui/src/chatwidget/tests/part7.rs b/nori-rs/tui/src/chatwidget/tests/part7.rs index ff35fa883..5c8762dec 100644 --- a/nori-rs/tui/src/chatwidget/tests/part7.rs +++ b/nori-rs/tui/src/chatwidget/tests/part7.rs @@ -1,4 +1,50 @@ use super::*; +use codex_core::config::types::McpServerConfig; +use codex_core::config::types::McpServerTransportConfig; + +#[test] +fn set_mcp_servers_updates_config_ref() { + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(); + + // Initially empty + assert!( + chat.config_ref().mcp_servers.is_empty(), + "mcp_servers should start empty" + ); + + // Set servers + let mut servers = std::collections::HashMap::new(); + servers.insert( + "test-server".to_string(), + McpServerConfig { + transport: McpServerTransportConfig::StreamableHttp { + url: "https://example.com/mcp".to_string(), + bearer_token_env_var: None, + http_headers: None, + env_http_headers: None, + client_id: None, + client_secret_env_var: None, + }, + enabled: true, + startup_timeout_sec: None, + tool_timeout_sec: None, + enabled_tools: None, + disabled_tools: None, + }, + ); + chat.set_mcp_servers(servers.clone()); + + // config_ref should now reflect the updated servers + assert_eq!( + chat.config_ref().mcp_servers.len(), + 1, + "config_ref should show 1 server after set_mcp_servers" + ); + assert!( + chat.config_ref().mcp_servers.contains_key("test-server"), + "config_ref should contain 'test-server'" + ); +} #[test] fn cancelling_phase_keeps_task_running_until_prompt_completed() { From 2873cb62abcebef300e4a7470705cad3f4359ace Mon Sep 17 00:00:00 2001 From: Nori Date: Sat, 18 Apr 2026 01:41:59 +0000 Subject: [PATCH 2/2] =?UTF-8?q?refactor:=20avoid=20unnecessary=20HashMap?= =?UTF-8?q?=20clone=20in=20persist=5Fmcp=5Fservers=20=F0=9F=A4=96=20Genera?= =?UTF-8?q?ted=20with=20[Nori](https://noriagentic.com)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Nori --- nori-rs/tui/src/app/config_persistence.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/nori-rs/tui/src/app/config_persistence.rs b/nori-rs/tui/src/app/config_persistence.rs index 066f56eb8..c0728e55b 100644 --- a/nori-rs/tui/src/app/config_persistence.rs +++ b/nori-rs/tui/src/app/config_persistence.rs @@ -347,12 +347,9 @@ impl App { // Sync in-memory state so that ComputeMcpAuthStatuses (which reads // chat_widget.config_ref().mcp_servers) sees the newly added servers. - let hash_map: std::collections::HashMap< - String, - codex_core::config::types::McpServerConfig, - > = servers.into_iter().collect(); - self.config.mcp_servers = hash_map.clone(); - self.chat_widget.set_mcp_servers(hash_map); + self.config.mcp_servers = servers.into_iter().collect(); + self.chat_widget + .set_mcp_servers(self.config.mcp_servers.clone()); self.chat_widget.add_info_message( "MCP servers updated. Restart to apply changes.".to_string(),