diff --git a/src-tauri/src/cmd.rs b/src-tauri/src/cmd.rs
index 87feab95055e6bc397f4c7038f414920ac20c995..421c724ece06f596953ae506a721d9f6311ecb4d 100644
--- a/src-tauri/src/cmd.rs
+++ b/src-tauri/src/cmd.rs
@@ -8,6 +8,7 @@ use crate::{
     app_home_dir,
     clash::{self, put_clash_profile},
     fetch::fetch_profile,
+    sysopt::{set_proxy_config, SysProxyConfig},
   },
 };
 use std::fs::File;
@@ -171,3 +172,44 @@ pub async fn put_profiles(
   save_profiles(&profiles);
   put_clash_profile(&clash_info).await
 }
+
+#[tauri::command]
+/// set system proxy
+pub fn set_sys_proxy(enable: bool, clash_info: State<'_, ClashInfoState>) -> Result<(), String> {
+  let clash_info = match clash_info.0.lock() {
+    Ok(arc) => arc.clone(),
+    _ => return Err(format!("can not get clash info")),
+  };
+
+  let port = match clash_info.controller {
+    Some(ctrl) => ctrl.port,
+    None => None,
+  };
+
+  if port.is_none() {
+    return Err(format!("can not get clash core's port"));
+  }
+
+  let config = if enable {
+    let server = format!("127.0.0.1:{}", port.unwrap());
+    // todo
+    let bypass = String::from("localhost;127.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;192.168.*");
+
+    SysProxyConfig {
+      enable,
+      server,
+      bypass,
+    }
+  } else {
+    SysProxyConfig {
+      enable,
+      server: String::from(""),
+      bypass: String::from(""),
+    }
+  };
+
+  match set_proxy_config(&config) {
+    Ok(_) => Ok(()),
+    Err(_) => Err(format!("can not set proxy")),
+  }
+}
diff --git a/src-tauri/src/config/clash.rs b/src-tauri/src/config/clash.rs
index 4c8760dc05c9f88191cca7563b12cb6202a69f68..245b8461736987fbfeac2a421e2e14b380089cc0 100644
--- a/src-tauri/src/config/clash.rs
+++ b/src-tauri/src/config/clash.rs
@@ -21,6 +21,9 @@ pub struct ClashConfig {
 
 #[derive(Default, Debug, Clone, Deserialize, Serialize)]
 pub struct ClashController {
+  /// clash core port
+  pub port: Option<String>,
+
   /// same as `external-controller`
   pub server: Option<String>,
   pub secret: Option<String>,
diff --git a/src-tauri/src/config/operate.rs b/src-tauri/src/config/operate.rs
index b5c944f2c7847ce62f3dca0a77e62da4d0e5d945..388ed7406946e04f075307967f7b699ce3961efe 100644
--- a/src-tauri/src/config/operate.rs
+++ b/src-tauri/src/config/operate.rs
@@ -44,9 +44,31 @@ pub fn read_clash() -> Mapping {
 pub fn read_clash_controller() -> ClashController {
   let config = read_clash();
 
+  let key_port_1 = Value::String("port".to_string());
+  let key_port_2 = Value::String("mixed-port".to_string());
   let key_server = Value::String("external-controller".to_string());
   let key_secret = Value::String("secret".to_string());
 
+  let port = match config.get(&key_port_1) {
+    Some(value) => match value {
+      Value::String(val_str) => Some(val_str.clone()),
+      Value::Number(val_num) => Some(val_num.to_string()),
+      _ => None,
+    },
+    _ => None,
+  };
+  let port = match port {
+    Some(_) => port,
+    None => match config.get(&key_port_2) {
+      Some(value) => match value {
+        Value::String(val_str) => Some(val_str.clone()),
+        Value::Number(val_num) => Some(val_num.to_string()),
+        _ => None,
+      },
+      _ => None,
+    },
+  };
+
   let server = match config.get(&key_server) {
     Some(value) => match value {
       Value::String(val_str) => Some(val_str.clone()),
@@ -64,7 +86,11 @@ pub fn read_clash_controller() -> ClashController {
     _ => None,
   };
 
-  ClashController { server, secret }
+  ClashController {
+    port,
+    server,
+    secret,
+  }
 }
 
 /// Get Profiles Config
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index 920ce8230ca83e6252787a05baabcb55a6297f6c..3177d69c4d60e90364a303e934f248e69fa6e429 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -63,6 +63,7 @@ fn main() -> std::io::Result<()> {
       cmd::get_profiles,
       cmd::set_profiles,
       cmd::put_profiles,
+      cmd::set_sys_proxy,
     ])
     .build(tauri::generate_context!())
     .expect("error while running tauri application");
diff --git a/src-tauri/src/utils/sysopt.rs b/src-tauri/src/utils/sysopt.rs
index 4e42154fed11b6b6ecfa17edc7bf5dfbc0fb8016..6e487cb8b28e8dd5ce6b07da1652a0bace4aec4d 100644
--- a/src-tauri/src/utils/sysopt.rs
+++ b/src-tauri/src/utils/sysopt.rs
@@ -3,9 +3,9 @@ use std::io;
 
 #[derive(Debug, Deserialize, Serialize)]
 pub struct SysProxyConfig {
-  enable: bool,
-  server: String,
-  bypass: String,
+  pub enable: bool,
+  pub server: String,
+  pub bypass: String,
 }
 
 #[cfg(target_os = "windows")]