11using System ;
2- using System . Collections . Generic ;
32using System . IO ;
4- using System . Net . Sockets ;
53using System . Runtime . InteropServices ;
6- using System . Text ;
7- using System . Threading . Tasks ;
84using Newtonsoft . Json ;
95using UnityEditor ;
106using UnityEngine ;
@@ -18,13 +14,11 @@ public class UnityMcpEditorWindow : EditorWindow
1814 {
1915 private bool isUnityBridgeRunning = false ;
2016 private Vector2 scrollPosition ;
21- private string claudeConfigStatus = "Not configured" ;
22- private string cursorConfigStatus = "Not configured" ;
23- private string pythonServerStatus = "Not Connected" ;
24- private Color pythonServerStatusColor = Color . red ;
17+ private string pythonServerInstallationStatus = "Not Installed" ;
18+ private Color pythonServerInstallationStatusColor = Color . red ;
2519 private const int unityPort = 6400 ; // Hardcoded Unity port
2620 private const int mcpPort = 6500 ; // Hardcoded MCP port
27- private McpClients mcpClients = new ( ) ;
21+ private readonly McpClients mcpClients = new ( ) ;
2822
2923 [ MenuItem ( "Window/Unity MCP" ) ]
3024 public static void ShowWindow ( )
@@ -34,7 +28,8 @@ public static void ShowWindow()
3428
3529 private void OnEnable ( )
3630 {
37- // Check initial states
31+ UpdatePythonServerInstallationStatus ( ) ;
32+
3833 isUnityBridgeRunning = UnityMcpBridge . IsRunning ;
3934 foreach ( McpClient mcpClient in mcpClients . clients )
4035 {
@@ -57,12 +52,39 @@ private Color GetStatusColor(McpStatus status)
5752 } ;
5853 }
5954
55+ private void UpdatePythonServerInstallationStatus ( )
56+ {
57+ string serverPath = ServerInstaller . GetServerPath ( ) ;
58+
59+ if ( File . Exists ( Path . Combine ( serverPath , "server.py" ) ) )
60+ {
61+ string installedVersion = ServerInstaller . GetInstalledVersion ( ) ;
62+ string latestVersion = ServerInstaller . GetLatestVersion ( ) ;
63+
64+ if ( ServerInstaller . IsNewerVersion ( latestVersion , installedVersion ) )
65+ {
66+ pythonServerInstallationStatus = "Newer Version Available" ;
67+ pythonServerInstallationStatusColor = Color . yellow ;
68+ }
69+ else
70+ {
71+ pythonServerInstallationStatus = "Up to Date" ;
72+ pythonServerInstallationStatusColor = Color . green ;
73+ }
74+ }
75+ else
76+ {
77+ pythonServerInstallationStatus = "Not Installed" ;
78+ pythonServerInstallationStatusColor = Color . red ;
79+ }
80+ }
81+
6082 private void ConfigurationSection ( McpClient mcpClient )
6183 {
6284 // Calculate if we should use half-width layout
6385 // Minimum width for half-width layout is 400 pixels
6486 bool useHalfWidth = position . width >= 800 ;
65- float sectionWidth = useHalfWidth ? position . width / 2 - 15 : position . width - 20 ;
87+ float sectionWidth = useHalfWidth ? ( position . width / 2 ) - 15 : position . width - 20 ;
6688
6789 // Begin horizontal layout if using half-width
6890 if ( useHalfWidth && mcpClients . clients . IndexOf ( mcpClient ) % 2 == 0 )
@@ -106,9 +128,11 @@ private void ConfigurationSection(McpClient mcpClient)
106128 EditorGUILayout . Space ( 8 ) ;
107129
108130 // Configure button with improved styling
109- GUIStyle buttonStyle = new ( GUI . skin . button ) ;
110- buttonStyle . padding = new RectOffset ( 15 , 15 , 5 , 5 ) ;
111- buttonStyle . margin = new RectOffset ( 10 , 10 , 5 , 5 ) ;
131+ GUIStyle buttonStyle = new ( GUI . skin . button )
132+ {
133+ padding = new RectOffset ( 15 , 15 , 5 , 5 ) ,
134+ margin = new RectOffset ( 10 , 10 , 5 , 5 ) ,
135+ } ;
112136
113137 // Create muted button style for Manual Setup
114138 GUIStyle mutedButtonStyle = new ( buttonStyle ) ;
@@ -156,7 +180,11 @@ private void ConfigurationSection(McpClient mcpClient)
156180 private void DrawStatusDot ( Rect statusRect , Color statusColor )
157181 {
158182 Rect dotRect = new ( statusRect . x + 6 , statusRect . y + 4 , 12 , 12 ) ;
159- Vector3 center = new ( dotRect . x + dotRect . width / 2 , dotRect . y + dotRect . height / 2 , 0 ) ;
183+ Vector3 center = new (
184+ dotRect . x + ( dotRect . width / 2 ) ,
185+ dotRect . y + ( dotRect . height / 2 ) ,
186+ 0
187+ ) ;
160188 float radius = dotRect . width / 2 ;
161189
162190 // Draw the main dot
@@ -191,14 +219,14 @@ private void OnGUI()
191219 ) ;
192220 EditorGUILayout . Space ( 10 ) ;
193221
194- // Python Server Status Section
222+ // Python Server Installation Status Section
195223 EditorGUILayout . BeginVertical ( EditorStyles . helpBox ) ;
196224 EditorGUILayout . LabelField ( "Python Server Status" , EditorStyles . boldLabel ) ;
197225
198226 // Status indicator with colored dot
199- var statusRect = EditorGUILayout . BeginHorizontal ( GUILayout . Height ( 20 ) ) ;
200- DrawStatusDot ( statusRect , pythonServerStatusColor ) ;
201- EditorGUILayout . LabelField ( " " + pythonServerStatus ) ;
227+ Rect installStatusRect = EditorGUILayout . BeginHorizontal ( GUILayout . Height ( 20 ) ) ;
228+ DrawStatusDot ( installStatusRect , pythonServerInstallationStatusColor ) ;
229+ EditorGUILayout . LabelField ( " " + pythonServerInstallationStatus ) ;
202230 EditorGUILayout . EndHorizontal ( ) ;
203231
204232 EditorGUILayout . LabelField ( $ "Unity Port: { unityPort } ") ;
@@ -249,13 +277,13 @@ private void ToggleUnityBridge()
249277 private string WriteToConfig ( string pythonDir , string configPath )
250278 {
251279 // Create configuration object for unityMCP
252- var unityMCPConfig = new McpConfigServer
280+ McpConfigServer unityMCPConfig = new ( )
253281 {
254282 command = "uv" ,
255283 args = new [ ] { "--directory" , pythonDir , "run" , "server.py" } ,
256284 } ;
257285
258- var jsonSettings = new JsonSerializerSettings { Formatting = Formatting . Indented } ;
286+ JsonSerializerSettings jsonSettings = new ( ) { Formatting = Formatting . Indented } ;
259287
260288 // Read existing config if it exists
261289 string existingJson = "{}" ;
@@ -267,16 +295,13 @@ private string WriteToConfig(string pythonDir, string configPath)
267295 }
268296 catch ( Exception e )
269297 {
270- UnityEngine . Debug . LogWarning ( $ "Error reading existing config: { e . Message } .") ;
298+ Debug . LogWarning ( $ "Error reading existing config: { e . Message } .") ;
271299 }
272300 }
273301
274302 // Parse the existing JSON while preserving all properties
275303 dynamic existingConfig = JsonConvert . DeserializeObject ( existingJson ) ;
276- if ( existingConfig == null )
277- {
278- existingConfig = new Newtonsoft . Json . Linq . JObject ( ) ;
279- }
304+ existingConfig ??= new Newtonsoft . Json . Linq . JObject ( ) ;
280305
281306 // Ensure mcpServers object exists
282307 if ( existingConfig . mcpServers == null )
@@ -311,7 +336,7 @@ private void ShowManualInstructionsWindow(string configPath, McpClient mcpClient
311336 string pythonDir = FindPackagePythonDirectory ( ) ;
312337
313338 // Create the manual configuration message
314- var jsonConfig = new McpConfig
339+ McpConfig jsonConfig = new ( )
315340 {
316341 mcpServers = new McpConfigServers
317342 {
@@ -323,25 +348,26 @@ private void ShowManualInstructionsWindow(string configPath, McpClient mcpClient
323348 } ,
324349 } ;
325350
326- var jsonSettings = new JsonSerializerSettings { Formatting = Formatting . Indented } ;
351+ JsonSerializerSettings jsonSettings = new ( ) { Formatting = Formatting . Indented } ;
327352 string manualConfigJson = JsonConvert . SerializeObject ( jsonConfig , jsonSettings ) ;
328353
329354 ManualConfigEditorWindow . ShowWindow ( configPath , manualConfigJson , mcpClient ) ;
330355 }
331356
332357 private string FindPackagePythonDirectory ( )
333358 {
334- string pythonDir = "/path/to/your/unity-mcp/Python" ;
359+ string pythonDir = ServerInstaller . GetServerPath ( ) ;
335360
336361 try
337362 {
338363 // Try to find the package using Package Manager API
339- var request = UnityEditor . PackageManager . Client . List ( ) ;
364+ UnityEditor . PackageManager . Requests . ListRequest request =
365+ UnityEditor . PackageManager . Client . List ( ) ;
340366 while ( ! request . IsCompleted ) { } // Wait for the request to complete
341367
342368 if ( request . Status == UnityEditor . PackageManager . StatusCode . Success )
343369 {
344- foreach ( var package in request . Result )
370+ foreach ( UnityEditor . PackageManager . PackageInfo package in request . Result )
345371 {
346372 if ( package . name == "com.justinpbarnett.unity-mcp" )
347373 {
@@ -360,7 +386,7 @@ private string FindPackagePythonDirectory()
360386 }
361387 else if ( request . Error != null )
362388 {
363- UnityEngine . Debug . LogError ( "Failed to list packages: " + request . Error . message ) ;
389+ Debug . LogError ( "Failed to list packages: " + request . Error . message ) ;
364390 }
365391
366392 // If not found via Package Manager, try manual approaches
@@ -370,7 +396,7 @@ private string FindPackagePythonDirectory()
370396 Path . GetFullPath ( Path . Combine ( Application . dataPath , "unity-mcp" , "Python" ) ) ,
371397 } ;
372398
373- foreach ( var dir in possibleDirs )
399+ foreach ( string dir in possibleDirs )
374400 {
375401 if ( Directory . Exists ( dir ) && File . Exists ( Path . Combine ( dir , "server.py" ) ) )
376402 {
@@ -379,13 +405,11 @@ private string FindPackagePythonDirectory()
379405 }
380406
381407 // If still not found, return the placeholder path
382- UnityEngine . Debug . LogWarning (
383- "Could not find Python directory, using placeholder path"
384- ) ;
408+ Debug . LogWarning ( "Could not find Python directory, using placeholder path" ) ;
385409 }
386410 catch ( Exception e )
387411 {
388- UnityEngine . Debug . LogError ( $ "Error finding package path: { e . Message } ") ;
412+ Debug . LogError ( $ "Error finding package path: { e . Message } ") ;
389413 }
390414
391415 return pythonDir ;
@@ -453,7 +477,7 @@ private string ConfigureMcpClient(McpClient mcpClient)
453477 }
454478
455479 ShowManualInstructionsWindow ( configPath , mcpClient ) ;
456- UnityEngine . Debug . LogError (
480+ Debug . LogError (
457481 $ "Failed to configure { mcpClient . name } : { e . Message } \n { e . StackTrace } "
458482 ) ;
459483 return $ "Failed to configure { mcpClient . name } ";
@@ -471,7 +495,7 @@ McpClient mcpClient
471495 string pythonDir = FindPackagePythonDirectory ( ) ;
472496
473497 // Create the manual configuration message
474- var jsonConfig = new McpConfig
498+ McpConfig jsonConfig = new ( )
475499 {
476500 mcpServers = new McpConfigServers
477501 {
@@ -483,7 +507,7 @@ McpClient mcpClient
483507 } ,
484508 } ;
485509
486- var jsonSettings = new JsonSerializerSettings { Formatting = Formatting . Indented } ;
510+ JsonSerializerSettings jsonSettings = new ( ) { Formatting = Formatting . Indented } ;
487511 string manualConfigJson = JsonConvert . SerializeObject ( jsonConfig , jsonSettings ) ;
488512
489513 ManualConfigEditorWindow . ShowWindow ( configPath , manualConfigJson , mcpClient ) ;
@@ -518,7 +542,7 @@ private void CheckMcpConfiguration(McpClient mcpClient)
518542 }
519543
520544 string configJson = File . ReadAllText ( configPath ) ;
521- var config = JsonConvert . DeserializeObject < McpConfig > ( configJson ) ;
545+ McpConfig config = JsonConvert . DeserializeObject < McpConfig > ( configJson ) ;
522546
523547 if ( config ? . mcpServers ? . unityMCP != null )
524548 {
0 commit comments