@@ -3,11 +3,19 @@ use std::collections::HashMap;
33use std:: fs;
44use std:: str:: FromStr ;
55use tauri:: command;
6- use toml_edit:: { Document , Item , Table } ;
6+ use toml_edit:: { value , Document , Item , Table } ;
77
88use crate :: config:: { get_config_path, CodexConfig } ;
99use crate :: config:: toml_helpers:: serialize_to_table;
1010
11+ fn default_enabled ( ) -> bool {
12+ true
13+ }
14+
15+ fn is_enabled_true ( enabled : & bool ) -> bool {
16+ * enabled
17+ }
18+
1119#[ derive( Debug , Clone , Serialize ) ]
1220#[ serde( tag = "type" ) ]
1321pub enum McpServerConfig {
@@ -17,11 +25,21 @@ pub enum McpServerConfig {
1725 args : Vec < String > ,
1826 #[ serde( skip_serializing_if = "Option::is_none" ) ]
1927 env : Option < HashMap < String , String > > ,
28+ #[ serde( default = "default_enabled" , skip_serializing_if = "is_enabled_true" ) ]
29+ enabled : bool ,
2030 } ,
2131 #[ serde( rename = "http" ) ]
22- Http { url : String } ,
32+ Http {
33+ url : String ,
34+ #[ serde( default = "default_enabled" , skip_serializing_if = "is_enabled_true" ) ]
35+ enabled : bool ,
36+ } ,
2337 #[ serde( rename = "sse" ) ]
24- Sse { url : String } ,
38+ Sse {
39+ url : String ,
40+ #[ serde( default = "default_enabled" , skip_serializing_if = "is_enabled_true" ) ]
41+ enabled : bool ,
42+ } ,
2543}
2644
2745impl < ' de > Deserialize < ' de > for McpServerConfig {
@@ -38,11 +56,21 @@ impl<'de> Deserialize<'de> for McpServerConfig {
3856 args : Vec < String > ,
3957 #[ serde( default ) ]
4058 env : Option < HashMap < String , String > > ,
59+ #[ serde( default = "default_enabled" ) ]
60+ enabled : bool ,
4161 } ,
4262 #[ serde( rename = "http" ) ]
43- Http { url : String } ,
63+ Http {
64+ url : String ,
65+ #[ serde( default = "default_enabled" ) ]
66+ enabled : bool ,
67+ } ,
4468 #[ serde( rename = "sse" ) ]
45- Sse { url : String } ,
69+ Sse {
70+ url : String ,
71+ #[ serde( default = "default_enabled" ) ]
72+ enabled : bool ,
73+ } ,
4674 }
4775
4876 #[ derive( Deserialize ) ]
@@ -52,6 +80,8 @@ impl<'de> Deserialize<'de> for McpServerConfig {
5280 args : Vec < String > ,
5381 #[ serde( default ) ]
5482 env : Option < HashMap < String , String > > ,
83+ #[ serde( default = "default_enabled" ) ]
84+ enabled : bool ,
5585 }
5686
5787 #[ derive( Deserialize ) ]
@@ -66,16 +96,30 @@ impl<'de> Deserialize<'de> for McpServerConfig {
6696 command,
6797 args,
6898 env,
69- } ) => Ok ( McpServerConfig :: Stdio { command, args, env } ) ,
70- McpServerConfigHelper :: Tagged ( TaggedMcpServerConfig :: Http { url } ) => {
71- Ok ( McpServerConfig :: Http { url } )
72- }
73- McpServerConfigHelper :: Tagged ( TaggedMcpServerConfig :: Sse { url } ) => {
74- Ok ( McpServerConfig :: Sse { url } )
99+ enabled,
100+ } ) => Ok ( McpServerConfig :: Stdio {
101+ command,
102+ args,
103+ env,
104+ enabled,
105+ } ) ,
106+ McpServerConfigHelper :: Tagged ( TaggedMcpServerConfig :: Http { url, enabled } ) => {
107+ Ok ( McpServerConfig :: Http { url, enabled } )
75108 }
76- McpServerConfigHelper :: Legacy ( LegacyStdioConfig { command , args , env } ) => {
77- Ok ( McpServerConfig :: Stdio { command , args , env } )
109+ McpServerConfigHelper :: Tagged ( TaggedMcpServerConfig :: Sse { url , enabled } ) => {
110+ Ok ( McpServerConfig :: Sse { url , enabled } )
78111 }
112+ McpServerConfigHelper :: Legacy ( LegacyStdioConfig {
113+ command,
114+ args,
115+ env,
116+ enabled,
117+ } ) => Ok ( McpServerConfig :: Stdio {
118+ command,
119+ args,
120+ env,
121+ enabled,
122+ } ) ,
79123 }
80124 }
81125}
@@ -176,3 +220,47 @@ pub async fn delete_mcp_server(name: String) -> Result<(), String> {
176220
177221 Ok ( ( ) )
178222}
223+
224+ #[ command]
225+ pub async fn set_mcp_server_enabled ( name : String , enabled : bool ) -> Result < ( ) , String > {
226+ let config_path = get_config_path ( ) ?;
227+
228+ if !config_path. exists ( ) {
229+ return Err ( "Config file does not exist" . to_string ( ) ) ;
230+ }
231+
232+ let content = fs:: read_to_string ( & config_path)
233+ . map_err ( |e| format ! ( "Failed to read config file: {}" , e) ) ?;
234+
235+ let mut doc = Document :: from_str ( & content)
236+ . map_err ( |e| format ! ( "Failed to parse config file: {}" , e) ) ?;
237+
238+ let mcp_servers_entry = doc
239+ . entry ( "mcp_servers" )
240+ . or_insert ( Item :: Table ( Table :: new ( ) ) ) ;
241+
242+ let mcp_servers_table = mcp_servers_entry
243+ . as_table_mut ( )
244+ . ok_or ( "Failed to access mcp_servers table" ) ?;
245+
246+ let server_entry = mcp_servers_table
247+ . get_mut ( & name)
248+ . ok_or ( format ! ( "MCP server '{}' not found" , name) ) ?;
249+
250+ let server_table = server_entry
251+ . as_table_mut ( )
252+ . ok_or ( format ! ( "MCP server '{}' is not a table" , name) ) ?;
253+
254+ if enabled {
255+ server_table. remove ( "enabled" ) ;
256+ } else {
257+ server_table. insert ( "enabled" , value ( enabled) ) ;
258+ }
259+
260+ let toml_content = doc. to_string ( ) ;
261+
262+ fs:: write ( & config_path, toml_content)
263+ . map_err ( |e| format ! ( "Failed to write config file: {}" , e) ) ?;
264+
265+ Ok ( ( ) )
266+ }
0 commit comments