From 5f0eba8a807b21628724d3386c119838acb60e5d Mon Sep 17 00:00:00 2001 From: Riz Ashraf Date: Tue, 8 Sep 2026 15:32:49 +0100 Subject: [PATCH] fix: Proxy stdout corruption and auto-daemonize --- server/src/main.rs | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/server/src/main.rs b/server/src/main.rs index 49df924..3c46816 100644 --- a/server/src/main.rs +++ b/server/src/main.rs @@ -31,6 +31,8 @@ struct Cli { command: Option, #[arg(long)] target: Option, + #[arg(long)] + daemon: bool, } #[derive(Subcommand)] @@ -185,7 +187,7 @@ fn run_server(state: Arc) -> SdkResult<()> { }), ); - println!("MCP Memory Server running on http://0.0.0.0:3000/sse"); + eprintln!("MCP Memory Server running on http://0.0.0.0:3000/sse"); server.start().await.unwrap(); Ok(()) @@ -199,20 +201,32 @@ fn main() -> SdkResult<()> { #[cfg(target_os = "windows")] { - loop { - if let Err(_) = std::net::TcpListener::bind("0.0.0.0:3000") { - // Port in use, become a stub proxy! - let target_url = cli.target.as_deref().unwrap_or("http://127.0.0.1:3000"); - match proxy::run_proxy(target_url) { - Ok(true) => { - std::thread::sleep(std::time::Duration::from_millis(50)); - continue; // Leader died, race to bind 3000 + use std::os::windows::process::CommandExt; + if !cli.daemon { + loop { + if let Err(_) = std::net::TcpListener::bind("0.0.0.0:3000") { + // Port in use, become a stub proxy! + let target_url = cli.target.as_deref().unwrap_or("http://127.0.0.1:3000"); + match proxy::run_proxy(target_url) { + Ok(true) => { + std::thread::sleep(std::time::Duration::from_millis(50)); + continue; // Leader died, race to bind 3000 + } + Ok(false) => return Ok(()), // Stdin closed, user exited + Err(_) => std::thread::sleep(std::time::Duration::from_millis(1000)), } - Ok(false) => return Ok(()), // Stdin closed, user exited - Err(_) => std::thread::sleep(std::time::Duration::from_millis(1000)), + } else { + // Port is free. We must spawn the daemon, then loop again to become proxy + std::process::Command::new(std::env::current_exe().unwrap()) + .arg("--daemon") + .stdin(std::process::Stdio::null()) + .stdout(std::process::Stdio::null()) + .stderr(std::process::Stdio::null()) + .creation_flags(0x08000000) // CREATE_NO_WINDOW + .spawn() + .expect("Failed to spawn daemon"); + std::thread::sleep(std::time::Duration::from_millis(500)); } - } else { - break; // Proceed as Leader } } }