2323import webbrowser
2424from pathlib import Path
2525
26+ # Global flag to prevent duplicate browser opens
27+ _browser_opened = False
28+
2629
2730def get_base_path () -> Path :
2831 """Get the base path for resources (handles both dev and bundled modes)."""
@@ -214,9 +217,21 @@ def is_tauri_sidecar() -> bool:
214217
215218
216219def open_browser_delayed (url : str , delay : float = 1.5 ):
217- """Open browser after a delay to allow server to start."""
220+ """Open browser after a delay to allow server to start.
221+
222+ Uses a global flag to prevent duplicate browser opens which can happen
223+ when Claude SDK or Codex subprocess triggers browser behavior on Windows.
224+ """
225+ global _browser_opened
226+
227+ if _browser_opened :
228+ return
229+
230+ _browser_opened = True
231+
218232 def _open ():
219233 time .sleep (delay )
234+ # Double-check flag in case of race condition
220235 webbrowser .open (url )
221236
222237 thread = threading .Thread (target = _open , daemon = True )
@@ -230,7 +245,7 @@ def run_mcp_server(server_type: str) -> None:
230245 allowing Codex to spawn this exe as an MCP server subprocess.
231246
232247 Args:
233- server_type: Either "action" or "guidelines "
248+ server_type: Either "action", "guidelines", or "etc "
234249 """
235250 import asyncio
236251
@@ -241,9 +256,11 @@ def run_mcp_server(server_type: str) -> None:
241256 from mcp_servers .action_server import main as server_main
242257 elif server_type == "guidelines" :
243258 from mcp_servers .guidelines_server import main as server_main
259+ elif server_type == "etc" :
260+ from mcp_servers .etc_server import main as server_main
244261 else :
245262 print (f"Unknown MCP server type: { server_type } " , file = sys .stderr )
246- print ("Valid types: action, guidelines" , file = sys .stderr )
263+ print ("Valid types: action, guidelines, etc " , file = sys .stderr )
247264 sys .exit (1 )
248265
249266 # Run the MCP server (async main)
0 commit comments