@@ -319,5 +319,70 @@ public void UpsertCodexServerBlock_OnNonWindows_ExcludesEnv()
319319 bool hasEnv = unityMcp . TryGetNode ( "env" , out _ ) ;
320320 Assert . IsFalse ( hasEnv , "Non-Windows config should not contain env table" ) ;
321321 }
322+
323+ [ Test ]
324+ public void UpsertCodexServerBlock_OnWindows_PreservesExistingEnvVariables ( )
325+ {
326+ // This test verifies that existing environment variables are preserved when SystemRoot is added
327+ // See: https://github.com/CoplayDev/unity-mcp/issues/315
328+
329+ // Mock Windows platform
330+ MCPServiceLocator . Register < IPlatformService > ( new MockPlatformService ( isWindows : true , systemRoot : "C:\\ Windows" ) ) ;
331+
332+ // Existing TOML with custom environment variables
333+ string existingToml = string . Join ( "\n " , new [ ]
334+ {
335+ "[mcp_servers.unityMCP]" ,
336+ "command = \" uv\" " ,
337+ "args = [\" run\" , \" --directory\" , \" C:\\ \\ old\\ \\ path\" , \" server.py\" ]" ,
338+ "" ,
339+ "[mcp_servers.unityMCP.env]" ,
340+ "CUSTOM_VAR = \" custom_value\" " ,
341+ "ANOTHER_VAR = \" another_value\" "
342+ } ) ;
343+
344+ string uvPath = "C:\\ path\\ to\\ uv.exe" ;
345+ string serverSrc = "C:\\ path\\ to\\ server" ;
346+
347+ string result = CodexConfigHelper . UpsertCodexServerBlock ( existingToml , uvPath , serverSrc ) ;
348+
349+ Assert . IsNotNull ( result , "UpsertCodexServerBlock should return a valid TOML string" ) ;
350+
351+ // Parse the generated TOML to validate structure
352+ TomlTable parsed ;
353+ using ( var reader = new StringReader ( result ) )
354+ {
355+ parsed = TOML . Parse ( reader ) ;
356+ }
357+
358+ // Verify mcp_servers structure
359+ Assert . IsTrue ( parsed . TryGetNode ( "mcp_servers" , out var mcpServersNode ) , "TOML should contain mcp_servers" ) ;
360+ var mcpServers = mcpServersNode as TomlTable ;
361+ Assert . IsTrue ( mcpServers . TryGetNode ( "unityMCP" , out var unityMcpNode ) , "mcp_servers should contain unityMCP" ) ;
362+ var unityMcp = unityMcpNode as TomlTable ;
363+
364+ // Verify env table exists
365+ Assert . IsTrue ( unityMcp . TryGetNode ( "env" , out var envNode ) , "Windows config should contain env table" ) ;
366+ Assert . IsInstanceOf < TomlTable > ( envNode , "env should be a table" ) ;
367+
368+ var env = envNode as TomlTable ;
369+
370+ // Verify SystemRoot was added
371+ Assert . IsTrue ( env . TryGetNode ( "SystemRoot" , out var systemRootNode ) , "env should contain SystemRoot" ) ;
372+ Assert . IsInstanceOf < TomlString > ( systemRootNode , "SystemRoot should be a string" ) ;
373+ var systemRoot = ( systemRootNode as TomlString ) . Value ;
374+ Assert . AreEqual ( "C:\\ Windows" , systemRoot , "SystemRoot should be C:\\ Windows" ) ;
375+
376+ // Verify existing environment variables were preserved
377+ Assert . IsTrue ( env . TryGetNode ( "CUSTOM_VAR" , out var customVarNode ) , "env should preserve CUSTOM_VAR" ) ;
378+ Assert . IsInstanceOf < TomlString > ( customVarNode , "CUSTOM_VAR should be a string" ) ;
379+ var customVar = ( customVarNode as TomlString ) . Value ;
380+ Assert . AreEqual ( "custom_value" , customVar , "CUSTOM_VAR should retain its value" ) ;
381+
382+ Assert . IsTrue ( env . TryGetNode ( "ANOTHER_VAR" , out var anotherVarNode ) , "env should preserve ANOTHER_VAR" ) ;
383+ Assert . IsInstanceOf < TomlString > ( anotherVarNode , "ANOTHER_VAR should be a string" ) ;
384+ var anotherVar = ( anotherVarNode as TomlString ) . Value ;
385+ Assert . AreEqual ( "another_value" , anotherVar , "ANOTHER_VAR should retain its value" ) ;
386+ }
322387 }
323388}
0 commit comments