@@ -48,6 +48,7 @@ use codex_protocol::protocol::TurnAbortReason;
4848use codex_protocol:: protocol:: TurnContextItem ;
4949use codex_protocol:: protocol:: TurnStartedEvent ;
5050use codex_rmcp_client:: ElicitationResponse ;
51+ use codex_rmcp_client:: OAuthCredentialsStoreMode ;
5152use futures:: future:: BoxFuture ;
5253use futures:: prelude:: * ;
5354use futures:: stream:: FuturesOrdered ;
@@ -84,6 +85,7 @@ use crate::config::Config;
8485use crate :: config:: Constrained ;
8586use crate :: config:: ConstraintResult ;
8687use crate :: config:: GhostSnapshotConfig ;
88+ use crate :: config:: types:: McpServerConfig ;
8789use crate :: config:: types:: ShellEnvironmentPolicy ;
8890use crate :: context_manager:: ContextManager ;
8991use crate :: environment_context:: EnvironmentContext ;
@@ -107,6 +109,7 @@ use crate::protocol::ErrorEvent;
107109use crate :: protocol:: Event ;
108110use crate :: protocol:: EventMsg ;
109111use crate :: protocol:: ExecApprovalRequestEvent ;
112+ use crate :: protocol:: McpServerRefreshConfig ;
110113use crate :: protocol:: Op ;
111114use crate :: protocol:: RateLimitSnapshot ;
112115use crate :: protocol:: ReasoningContentDeltaEvent ;
@@ -361,7 +364,7 @@ pub(crate) struct Session {
361364 /// The set of enabled features should be invariant for the lifetime of the
362365 /// session.
363366 features : Features ,
364- should_refresh_mcp_servers : AtomicBool ,
367+ pending_mcp_server_refresh_config : Mutex < Option < McpServerRefreshConfig > > ,
365368 pub ( crate ) active_turn : Mutex < Option < ActiveTurn > > ,
366369 pub ( crate ) services : SessionServices ,
367370 next_internal_sub_id : AtomicU64 ,
@@ -707,7 +710,7 @@ impl Session {
707710 agent_status : Arc :: clone ( & agent_status) ,
708711 state : Mutex :: new ( state) ,
709712 features : config. features . clone ( ) ,
710- should_refresh_mcp_servers : AtomicBool :: new ( false ) ,
713+ pending_mcp_server_refresh_config : Mutex :: new ( None ) ,
711714 active_turn : Mutex :: new ( None ) ,
712715 services,
713716 next_internal_sub_id : AtomicU64 :: new ( 0 ) ,
@@ -1635,25 +1638,41 @@ impl Session {
16351638 Arc :: clone ( & self . services . user_shell )
16361639 }
16371640
1638- fn request_mcp_server_refresh ( & self ) {
1639- self . should_refresh_mcp_servers
1640- . store ( true , Ordering :: SeqCst ) ;
1641+ async fn request_mcp_server_refresh ( & self , refresh_config : McpServerRefreshConfig ) {
1642+ let mut guard = self . pending_mcp_server_refresh_config . lock ( ) . await ;
1643+ * guard = Some ( refresh_config ) ;
16411644 }
16421645
16431646 async fn refresh_mcp_servers_if_requested ( & self , turn_context : & TurnContext ) {
1644- if !self
1645- . should_refresh_mcp_servers
1646- . swap ( false , Ordering :: SeqCst )
1647- {
1647+ let refresh_config = { self . pending_mcp_server_refresh_config . lock ( ) . await . take ( ) } ;
1648+ let Some ( refresh_config) = refresh_config else {
16481649 return ;
1649- }
1650+ } ;
16501651
1651- let config = turn_context. client . config ( ) ;
1652- let auth_statuses = compute_auth_statuses (
1653- config. mcp_servers . iter ( ) ,
1654- config. mcp_oauth_credentials_store_mode ,
1655- )
1656- . await ;
1652+ let McpServerRefreshConfig {
1653+ mcp_servers,
1654+ mcp_oauth_credentials_store_mode,
1655+ } = refresh_config;
1656+
1657+ let mcp_servers =
1658+ match serde_json:: from_value :: < HashMap < String , McpServerConfig > > ( mcp_servers) {
1659+ Ok ( servers) => servers,
1660+ Err ( err) => {
1661+ warn ! ( "failed to parse MCP server refresh config: {err}" ) ;
1662+ return ;
1663+ }
1664+ } ;
1665+ let store_mode = match serde_json:: from_value :: < OAuthCredentialsStoreMode > (
1666+ mcp_oauth_credentials_store_mode,
1667+ ) {
1668+ Ok ( mode) => mode,
1669+ Err ( err) => {
1670+ warn ! ( "failed to parse MCP OAuth refresh config: {err}" ) ;
1671+ return ;
1672+ }
1673+ } ;
1674+
1675+ let auth_statuses = compute_auth_statuses ( mcp_servers. iter ( ) , store_mode) . await ;
16571676 let sandbox_state = SandboxState {
16581677 sandbox_policy : turn_context. sandbox_policy . clone ( ) ,
16591678 codex_linux_sandbox_exe : turn_context. codex_linux_sandbox_exe . clone ( ) ,
@@ -1664,8 +1683,8 @@ impl Session {
16641683 let mut refreshed_manager = McpConnectionManager :: default ( ) ;
16651684 refreshed_manager
16661685 . initialize (
1667- config . mcp_servers . clone ( ) ,
1668- config . mcp_oauth_credentials_store_mode ,
1686+ mcp_servers,
1687+ store_mode ,
16691688 auth_statuses,
16701689 self . get_tx_event ( ) ,
16711690 cancel_token,
@@ -1760,8 +1779,8 @@ async fn submission_loop(sess: Arc<Session>, config: Arc<Config>, rx_sub: Receiv
17601779 Op :: ListMcpTools => {
17611780 handlers:: list_mcp_tools ( & sess, & config, sub. id . clone ( ) ) . await ;
17621781 }
1763- Op :: RefreshMcpServers => {
1764- handlers:: refresh_mcp_servers ( & sess) . await ;
1782+ Op :: RefreshMcpServers { config } => {
1783+ handlers:: refresh_mcp_servers ( & sess, config ) . await ;
17651784 }
17661785 Op :: ListCustomPrompts => {
17671786 handlers:: list_custom_prompts ( & sess, sub. id . clone ( ) ) . await ;
@@ -1831,6 +1850,7 @@ mod handlers {
18311850 use codex_protocol:: protocol:: EventMsg ;
18321851 use codex_protocol:: protocol:: ListCustomPromptsResponseEvent ;
18331852 use codex_protocol:: protocol:: ListSkillsResponseEvent ;
1853+ use codex_protocol:: protocol:: McpServerRefreshConfig ;
18341854 use codex_protocol:: protocol:: Op ;
18351855 use codex_protocol:: protocol:: ReviewDecision ;
18361856 use codex_protocol:: protocol:: ReviewRequest ;
@@ -2062,8 +2082,8 @@ mod handlers {
20622082 } ) ;
20632083 }
20642084
2065- pub async fn refresh_mcp_servers ( sess : & Arc < Session > ) {
2066- sess. request_mcp_server_refresh ( ) ;
2085+ pub async fn refresh_mcp_servers ( sess : & Arc < Session > , refresh_config : McpServerRefreshConfig ) {
2086+ sess. request_mcp_server_refresh ( refresh_config ) . await ;
20672087 }
20682088
20692089 pub async fn list_mcp_tools ( sess : & Session , config : & Arc < Config > , sub_id : String ) {
@@ -3618,7 +3638,7 @@ mod tests {
36183638 agent_status : Arc :: clone ( & agent_status) ,
36193639 state : Mutex :: new ( state) ,
36203640 features : config. features . clone ( ) ,
3621- should_refresh_mcp_servers : AtomicBool :: new ( false ) ,
3641+ pending_mcp_server_refresh_config : Mutex :: new ( None ) ,
36223642 active_turn : Mutex :: new ( None ) ,
36233643 services,
36243644 next_internal_sub_id : AtomicU64 :: new ( 0 ) ,
@@ -3713,7 +3733,7 @@ mod tests {
37133733 agent_status : Arc :: clone ( & agent_status) ,
37143734 state : Mutex :: new ( state) ,
37153735 features : config. features . clone ( ) ,
3716- should_refresh_mcp_servers : AtomicBool :: new ( false ) ,
3736+ pending_mcp_server_refresh_config : Mutex :: new ( None ) ,
37173737 active_turn : Mutex :: new ( None ) ,
37183738 services,
37193739 next_internal_sub_id : AtomicU64 :: new ( 0 ) ,
0 commit comments