@@ -484,6 +484,16 @@ pub fn write_global_mcp_servers(
484484 entry[ "tool_timeout_sec" ] = toml_edit:: value ( timeout. as_secs_f64 ( ) ) ;
485485 }
486486
487+ if let Some ( enabled_tools) = & config. enabled_tools {
488+ entry[ "enabled_tools" ] =
489+ TomlItem :: Value ( enabled_tools. iter ( ) . collect :: < TomlArray > ( ) . into ( ) ) ;
490+ }
491+
492+ if let Some ( disabled_tools) = & config. disabled_tools {
493+ entry[ "disabled_tools" ] =
494+ TomlItem :: Value ( disabled_tools. iter ( ) . collect :: < TomlArray > ( ) . into ( ) ) ;
495+ }
496+
487497 doc[ "mcp_servers" ] [ name. as_str ( ) ] = TomlItem :: Table ( entry) ;
488498 }
489499 }
@@ -1923,6 +1933,8 @@ approve_all = true
19231933 enabled : true ,
19241934 startup_timeout_sec : Some ( Duration :: from_secs ( 3 ) ) ,
19251935 tool_timeout_sec : Some ( Duration :: from_secs ( 5 ) ) ,
1936+ enabled_tools : None ,
1937+ disabled_tools : None ,
19261938 } ,
19271939 ) ;
19281940
@@ -2059,6 +2071,8 @@ bearer_token = "secret"
20592071 enabled : true ,
20602072 startup_timeout_sec : None ,
20612073 tool_timeout_sec : None ,
2074+ enabled_tools : None ,
2075+ disabled_tools : None ,
20622076 } ,
20632077 ) ] ) ;
20642078
@@ -2121,6 +2135,8 @@ ZIG_VAR = "3"
21212135 enabled : true ,
21222136 startup_timeout_sec : None ,
21232137 tool_timeout_sec : None ,
2138+ enabled_tools : None ,
2139+ disabled_tools : None ,
21242140 } ,
21252141 ) ] ) ;
21262142
@@ -2163,6 +2179,8 @@ ZIG_VAR = "3"
21632179 enabled : true ,
21642180 startup_timeout_sec : None ,
21652181 tool_timeout_sec : None ,
2182+ enabled_tools : None ,
2183+ disabled_tools : None ,
21662184 } ,
21672185 ) ] ) ;
21682186
@@ -2204,6 +2222,8 @@ ZIG_VAR = "3"
22042222 enabled : true ,
22052223 startup_timeout_sec : Some ( Duration :: from_secs ( 2 ) ) ,
22062224 tool_timeout_sec : None ,
2225+ enabled_tools : None ,
2226+ disabled_tools : None ,
22072227 } ,
22082228 ) ] ) ;
22092229
@@ -2261,6 +2281,8 @@ startup_timeout_sec = 2.0
22612281 enabled : true ,
22622282 startup_timeout_sec : Some ( Duration :: from_secs ( 2 ) ) ,
22632283 tool_timeout_sec : None ,
2284+ enabled_tools : None ,
2285+ disabled_tools : None ,
22642286 } ,
22652287 ) ] ) ;
22662288 write_global_mcp_servers ( codex_home. path ( ) , & servers) ?;
@@ -2330,6 +2352,8 @@ X-Auth = "DOCS_AUTH"
23302352 enabled : true ,
23312353 startup_timeout_sec : Some ( Duration :: from_secs ( 2 ) ) ,
23322354 tool_timeout_sec : None ,
2355+ enabled_tools : None ,
2356+ disabled_tools : None ,
23332357 } ,
23342358 ) ] ) ;
23352359
@@ -2351,6 +2375,8 @@ X-Auth = "DOCS_AUTH"
23512375 enabled : true ,
23522376 startup_timeout_sec : None ,
23532377 tool_timeout_sec : None ,
2378+ enabled_tools : None ,
2379+ disabled_tools : None ,
23542380 } ,
23552381 ) ;
23562382 write_global_mcp_servers ( codex_home. path ( ) , & servers) ?;
@@ -2410,6 +2436,8 @@ url = "https://example.com/mcp"
24102436 enabled : true ,
24112437 startup_timeout_sec : Some ( Duration :: from_secs ( 2 ) ) ,
24122438 tool_timeout_sec : None ,
2439+ enabled_tools : None ,
2440+ disabled_tools : None ,
24132441 } ,
24142442 ) ,
24152443 (
@@ -2425,6 +2453,8 @@ url = "https://example.com/mcp"
24252453 enabled : true ,
24262454 startup_timeout_sec : None ,
24272455 tool_timeout_sec : None ,
2456+ enabled_tools : None ,
2457+ disabled_tools : None ,
24282458 } ,
24292459 ) ,
24302460 ] ) ;
@@ -2499,6 +2529,8 @@ url = "https://example.com/mcp"
24992529 enabled : false ,
25002530 startup_timeout_sec : None ,
25012531 tool_timeout_sec : None ,
2532+ enabled_tools : None ,
2533+ disabled_tools : None ,
25022534 } ,
25032535 ) ] ) ;
25042536
@@ -2518,6 +2550,49 @@ url = "https://example.com/mcp"
25182550 Ok ( ( ) )
25192551 }
25202552
2553+ #[ tokio:: test]
2554+ async fn write_global_mcp_servers_serializes_tool_filters ( ) -> anyhow:: Result < ( ) > {
2555+ let codex_home = TempDir :: new ( ) ?;
2556+
2557+ let servers = BTreeMap :: from ( [ (
2558+ "docs" . to_string ( ) ,
2559+ McpServerConfig {
2560+ transport : McpServerTransportConfig :: Stdio {
2561+ command : "docs-server" . to_string ( ) ,
2562+ args : Vec :: new ( ) ,
2563+ env : None ,
2564+ env_vars : Vec :: new ( ) ,
2565+ cwd : None ,
2566+ } ,
2567+ enabled : true ,
2568+ startup_timeout_sec : None ,
2569+ tool_timeout_sec : None ,
2570+ enabled_tools : Some ( vec ! [ "allowed" . to_string( ) ] ) ,
2571+ disabled_tools : Some ( vec ! [ "blocked" . to_string( ) ] ) ,
2572+ } ,
2573+ ) ] ) ;
2574+
2575+ write_global_mcp_servers ( codex_home. path ( ) , & servers) ?;
2576+
2577+ let config_path = codex_home. path ( ) . join ( CONFIG_TOML_FILE ) ;
2578+ let serialized = std:: fs:: read_to_string ( & config_path) ?;
2579+ assert ! ( serialized. contains( r#"enabled_tools = ["allowed"]"# ) ) ;
2580+ assert ! ( serialized. contains( r#"disabled_tools = ["blocked"]"# ) ) ;
2581+
2582+ let loaded = load_global_mcp_servers ( codex_home. path ( ) ) . await ?;
2583+ let docs = loaded. get ( "docs" ) . expect ( "docs entry" ) ;
2584+ assert_eq ! (
2585+ docs. enabled_tools. as_ref( ) ,
2586+ Some ( & vec![ "allowed" . to_string( ) ] )
2587+ ) ;
2588+ assert_eq ! (
2589+ docs. disabled_tools. as_ref( ) ,
2590+ Some ( & vec![ "blocked" . to_string( ) ] )
2591+ ) ;
2592+
2593+ Ok ( ( ) )
2594+ }
2595+
25212596 #[ tokio:: test]
25222597 async fn persist_model_selection_updates_defaults ( ) -> anyhow:: Result < ( ) > {
25232598 let codex_home = TempDir :: new ( ) ?;
0 commit comments