#
tokens: 5705/50000 1/29 files (page 2/2)
lines: on (toggle) GitHub
raw markdown copy reset
This is page 2 of 2. Use http://codebase.md/quazaai/unitymcpintegration?lines=true&page={x} to view the full context.

# Directory Structure

```
├── .gitignore
├── CHANGELOG.md
├── CHANGELOG.md.meta
├── CODE_OF_CONDUCT.md
├── CODE_OF_CONDUCT.md.meta
├── Editor
│   ├── GamePilot.UnityMCP.asmdef
│   ├── GamePilot.UnityMCP.asmdef.meta
│   ├── MCPCodeExecutor.cs
│   ├── MCPCodeExecutor.cs.meta
│   ├── MCPConnectionManager.cs
│   ├── MCPConnectionManager.cs.meta
│   ├── MCPDataCollector.cs
│   ├── MCPDataCollector.cs.meta
│   ├── MCPLogger.cs
│   ├── MCPLogger.cs.meta
│   ├── MCPManager.cs
│   ├── MCPManager.cs.meta
│   ├── MCPMessageHandler.cs
│   ├── MCPMessageHandler.cs.meta
│   ├── MCPMessageSender.cs
│   ├── MCPMessageSender.cs.meta
│   ├── Models
│   │   ├── MCPEditorState.cs
│   │   ├── MCPEditorState.cs.meta
│   │   ├── MCPSceneInfo.cs
│   │   └── MCPSceneInfo.cs.meta
│   ├── Models.meta
│   ├── UI
│   │   ├── MCPDebugSettings.json
│   │   ├── MCPDebugSettings.json.meta
│   │   ├── MCPDebugWindow.cs
│   │   ├── MCPDebugWindow.cs.meta
│   │   ├── MCPDebugWindow.uss
│   │   ├── MCPDebugWindow.uss.meta
│   │   ├── MCPDebugWindow.uxml
│   │   └── MCPDebugWindow.uxml.meta
│   └── UI.meta
├── Editor.meta
├── LICENSE
├── LICENSE.meta
├── mcpInspector.png
├── mcpInspector.png.meta
├── mcpServer
│   ├── .dockerignore
│   ├── .env.example
│   ├── build
│   │   ├── filesystemTools.js
│   │   ├── filesystemTools.js.meta
│   │   ├── index.js
│   │   ├── index.js.meta
│   │   ├── toolDefinitions.js
│   │   ├── toolDefinitions.js.meta
│   │   ├── types.js
│   │   ├── types.js.meta
│   │   ├── websocketHandler.js
│   │   └── websocketHandler.js.meta
│   ├── build.meta
│   ├── docker-compose.yml
│   ├── docker-compose.yml.meta
│   ├── Dockerfile
│   ├── Dockerfile.meta
│   ├── MCPSummary.md
│   ├── MCPSummary.md.meta
│   ├── node_modules.meta
│   ├── package-lock.json
│   ├── package-lock.json.meta
│   ├── package.json
│   ├── package.json.meta
│   ├── smithery.yaml
│   ├── src
│   │   ├── filesystemTools.ts
│   │   ├── filesystemTools.ts.meta
│   │   ├── index.ts
│   │   ├── index.ts.meta
│   │   ├── toolDefinitions.ts
│   │   ├── toolDefinitions.ts.meta
│   │   ├── types.ts
│   │   ├── types.ts.meta
│   │   ├── websocketHandler.ts
│   │   └── websocketHandler.ts.meta
│   ├── src.meta
│   ├── tsconfig.json
│   └── tsconfig.json.meta
├── mcpServer.meta
├── package.json
├── package.json.meta
├── README.md
└── README.md.meta
```

# Files

--------------------------------------------------------------------------------
/Editor/UI/MCPDebugWindow.cs:
--------------------------------------------------------------------------------

```csharp
  1 | using UnityEditor;
  2 | using UnityEditor.UIElements;
  3 | using UnityEngine;
  4 | using UnityEngine.UIElements;
  5 | using System;
  6 | using System.Collections.Generic;
  7 | using System.IO;
  8 | using Newtonsoft.Json;
  9 | 
 10 | namespace Plugins.GamePilot.Editor.MCP
 11 | {
 12 |     [Serializable]
 13 |     public class MCPDebugSettings
 14 |     {
 15 |         public int port = 5010;
 16 |         public bool autoReconnect = false;
 17 |         public bool globalLoggingEnabled = false;
 18 |         public Dictionary<string, bool> componentLoggingEnabled = new Dictionary<string, bool>();
 19 |     }
 20 | 
 21 |     public class MCPDebugWindow : EditorWindow
 22 |     {
 23 |         [SerializeField]
 24 |         private VisualTreeAsset uxml;
 25 |         [SerializeField]
 26 |         private StyleSheet uss;
 27 | 
 28 |         [SerializeField]
 29 |         private VisualTreeAsset m_VisualTreeAsset = default;
 30 |         
 31 |         private Label connectionStatusLabel;
 32 |         private Button connectButton;
 33 |         private Button disconnectButton;
 34 |         private Toggle autoReconnectToggle;
 35 |         private TextField serverPortField;
 36 |         
 37 |         // Component logging toggles
 38 |         private Dictionary<string, Toggle> logToggles = new Dictionary<string, Toggle>();
 39 |         
 40 |         // Connection info labels
 41 |         private Label lastErrorLabel;
 42 |         private Label connectionTimeLabel;
 43 |         
 44 |         // Statistics elements
 45 |         private Label messagesSentLabel;
 46 |         private Label messagesReceivedLabel;
 47 |         private Label reconnectAttemptsLabel;
 48 |         
 49 |         // Statistics counters
 50 |         private int messagesSent = 0;
 51 |         private int messagesReceived = 0;
 52 |         private int reconnectAttempts = 0;
 53 |         private DateTime? connectionStartTime = null;
 54 |         
 55 |         // Settings
 56 |         private MCPDebugSettings settings;
 57 |         private string settingsPath;
 58 |         
 59 |         [MenuItem("Window/MCP Debug")]
 60 |         public static void ShowWindow()
 61 |         {
 62 |             MCPDebugWindow wnd = GetWindow<MCPDebugWindow>();
 63 |             wnd.titleContent = new GUIContent("MCP Debug");
 64 |             wnd.minSize = new Vector2(400, 500);
 65 |         }
 66 | 
 67 |         private void OnEnable()
 68 |         {
 69 |             // Get the path to save settings
 70 |             settingsPath = GetSettingsPath();
 71 |             
 72 |             // Load or create settings
 73 |             LoadSettings();
 74 |         }
 75 | 
 76 |         private string GetSettingsPath()
 77 |         {
 78 |             // Get the script location
 79 |             var script = MonoScript.FromScriptableObject(this);
 80 |             var scriptPath = AssetDatabase.GetAssetPath(script);
 81 |             var directoryPath = Path.GetDirectoryName(scriptPath);
 82 |             
 83 |             // Create settings path in the same directory
 84 |             return Path.Combine(directoryPath, "MCPDebugSettings.json");
 85 |         }
 86 | 
 87 |         private void LoadSettings()
 88 |         {
 89 |             settings = new MCPDebugSettings();
 90 |             
 91 |             try
 92 |             {
 93 |                 // Check if settings file exists
 94 |                 if (File.Exists(settingsPath))
 95 |                 {
 96 |                     string json = File.ReadAllText(settingsPath);
 97 |                     settings = JsonConvert.DeserializeObject<MCPDebugSettings>(json);
 98 |                     
 99 |                     Debug.Log($"[MCP] [MCPDebugWindow] Loaded settings from {settingsPath}");
100 |                 }
101 |                 else
102 |                 {
103 |                     // Create default settings
104 |                     settings = new MCPDebugSettings();
105 |                     SaveSettings();
106 |                     Debug.Log($"[MCP] [MCPDebugWindow] Created default settings at {settingsPath}");
107 |                 }
108 |             }
109 |             catch (Exception ex)
110 |             {
111 |                 Debug.LogError($"[MCP] [MCPDebugWindow] Error loading settings: {ex.Message}");
112 |                 settings = new MCPDebugSettings();
113 |             }
114 |             
115 |             // Apply settings to MCPLogger
116 |             MCPLogger.GlobalLoggingEnabled = settings.globalLoggingEnabled;
117 |             
118 |             // Apply component logging settings
119 |             foreach (var pair in settings.componentLoggingEnabled)
120 |             {
121 |                 MCPLogger.SetComponentLoggingEnabled(pair.Key, pair.Value);
122 |             }
123 |         }
124 | 
125 |         private void SaveSettings()
126 |         {
127 |             try
128 |             {
129 |                 // Save settings using Newtonsoft.Json which supports dictionaries directly
130 |                 string json = JsonConvert.SerializeObject(settings, Formatting.Indented);
131 |                 File.WriteAllText(settingsPath, json);
132 |                 
133 |                 Debug.Log($"[MCP] [MCPDebugWindow] Saved settings to {settingsPath}");
134 |             }
135 |             catch (Exception ex)
136 |             {
137 |                 Debug.LogError($"[MCP] [MCPDebugWindow] Error saving settings: {ex.Message}");
138 |             }
139 |         }
140 | 
141 |         public void CreateGUI()
142 |         {
143 |             VisualElement root = rootVisualElement;
144 |             
145 |             if (uxml != null)
146 |             {
147 |                 uxml.CloneTree(root);
148 |             }
149 |             else
150 |             {
151 |                 Debug.LogError("VisualTreeAsset not found. Please check the path.");
152 |             }
153 |             
154 |             if (uss != null)
155 |             {
156 |                 root.styleSheets.Add(uss);
157 |             } else
158 |             {
159 |                 Debug.LogError("StyleSheet not found. Please check the path.");
160 |             }
161 |             
162 |             // Get UI elements
163 |             connectionStatusLabel = root.Q<Label>("connection-status");
164 |             connectButton = root.Q<Button>("connect-button");
165 |             disconnectButton = root.Q<Button>("disconnect-button");
166 |             autoReconnectToggle = root.Q<Toggle>("auto-reconnect-toggle");
167 |             serverPortField = root.Q<TextField>("server-port-field");
168 |             
169 |             lastErrorLabel = root.Q<Label>("last-error-value");
170 |             connectionTimeLabel = root.Q<Label>("connection-time-value");
171 |             
172 |             messagesSentLabel = root.Q<Label>("messages-sent-value");
173 |             messagesReceivedLabel = root.Q<Label>("messages-received-value");
174 |             reconnectAttemptsLabel = root.Q<Label>("reconnect-attempts-value");
175 |             
176 |             // Apply settings to UI
177 |             serverPortField.value = settings.port.ToString();
178 |             autoReconnectToggle.value = settings.autoReconnect;
179 |             
180 |             // Setup UI events
181 |             connectButton.clicked += OnConnectClicked;
182 |             disconnectButton.clicked += OnDisconnectClicked;
183 |             autoReconnectToggle.RegisterValueChangedCallback(OnAutoReconnectChanged);
184 |             serverPortField.RegisterValueChangedCallback(OnPortChanged);
185 |             
186 |             // Setup component logging toggles
187 |             SetupComponentLoggingToggles(root);
188 |             
189 |             // Initialize UI with current state
190 |             UpdateUIFromState();
191 |             
192 |             // Register for updates
193 |             EditorApplication.update += OnEditorUpdate;
194 |         }
195 |         
196 |         private void OnPortChanged(ChangeEvent<string> evt)
197 |         {
198 |             if (int.TryParse(evt.newValue, out int port) && port >= 1 && port <= 65535)
199 |             {
200 |                 settings.port = port;
201 |                 SaveSettings();
202 |             }
203 |         }
204 |         
205 |         private void CreateFallbackUI(VisualElement root)
206 |         {
207 |             // Create a simple fallback UI if UXML fails to load
208 |             root.Add(new Label("MCP Debug Window - UXML not found") { style = { fontSize = 16, marginBottom = 10 } });
209 |             
210 |             // Removed serverUrlField - only using port field as requested
211 |             
212 |             serverPortField = new TextField("Port (Default: 5010)") { value = "5010" };
213 |             root.Add(serverPortField);
214 |             
215 |             var connectButton = new Button(OnConnectClicked) { text = "Connect" };
216 |             root.Add(connectButton);
217 |             
218 |             var disconnectButton = new Button(OnDisconnectClicked) { text = "Disconnect" };
219 |             root.Add(disconnectButton);
220 |             
221 |             var autoReconnectToggle = new Toggle("Auto Reconnect");
222 |             autoReconnectToggle.RegisterValueChangedCallback(OnAutoReconnectChanged);
223 |             root.Add(autoReconnectToggle);
224 |             
225 |             connectionStatusLabel = new Label("Status: Not Connected");
226 |             root.Add(connectionStatusLabel);
227 |         }
228 |         
229 |         private void SetupComponentLoggingToggles(VisualElement root)
230 |         {
231 |             var loggingContainer = root.Q<VisualElement>("logging-container");
232 |             
233 |             // Register MCPDebugWindow as a component for logging
234 |             MCPLogger.InitializeComponent("MCPDebugWindow", settings.componentLoggingEnabled.ContainsKey("MCPDebugWindow") ? 
235 |                 settings.componentLoggingEnabled["MCPDebugWindow"] : false);
236 |             
237 |             // Global logging toggle
238 |             var globalToggle = new Toggle("Enable All Logging");
239 |             globalToggle.value = settings.globalLoggingEnabled;
240 |             globalToggle.RegisterValueChangedCallback(evt => {
241 |                 settings.globalLoggingEnabled = evt.newValue;
242 |                 MCPLogger.GlobalLoggingEnabled = evt.newValue;
243 |                 SaveSettings();
244 |                 
245 |                 // First make sure all components are properly initialized before updating UI
246 |                 EnsureComponentsInitialized();
247 |                 
248 |                 // Update all component toggles to show they're enabled/disabled
249 |                 foreach (var componentName in MCPLogger.GetRegisteredComponents())
250 |                 {
251 |                     if (logToggles.TryGetValue(componentName, out var toggle))
252 |                     {
253 |                         // Don't disable the toggle UI, just update its interactable state
254 |                         toggle.SetEnabled(true);
255 |                     }
256 |                 }
257 |             });
258 |             loggingContainer.Add(globalToggle);
259 |             
260 |             // Add a separator
261 |             var separator = new VisualElement();
262 |             separator.style.height = 1;
263 |             separator.style.marginTop = 5;
264 |             separator.style.marginBottom = 5;
265 |             separator.style.backgroundColor = new Color(0.3f, 0.3f, 0.3f);
266 |             loggingContainer.Add(separator);
267 |             
268 |             // Ensure all components are initialized
269 |             EnsureComponentsInitialized();
270 |             
271 |             // Create toggles for standard components
272 |             string[] standardComponents = {
273 |                 "MCPManager",
274 |                 "MCPConnectionManager",
275 |                 "MCPDataCollector",
276 |                 "MCPMessageHandler",
277 |                 "MCPCodeExecutor",
278 |                 "MCPMessageSender",
279 |                 "MCPDebugWindow"  // Add the debug window itself
280 |             };
281 |             
282 |             foreach (string componentName in standardComponents)
283 |             {
284 |                 bool isEnabled = settings.componentLoggingEnabled.ContainsKey(componentName) ? 
285 |                     settings.componentLoggingEnabled[componentName] : false;
286 |                     
287 |                 CreateLoggingToggle(loggingContainer, componentName, $"Enable {componentName} logging", isEnabled);
288 |             }
289 |             
290 |             // Add any additional registered components not in our standard list
291 |             foreach (var componentName in MCPLogger.GetRegisteredComponents())
292 |             {
293 |                 if (!logToggles.ContainsKey(componentName))
294 |                 {
295 |                     bool isEnabled = settings.componentLoggingEnabled.ContainsKey(componentName) ? 
296 |                         settings.componentLoggingEnabled[componentName] : false;
297 |                         
298 |                     CreateLoggingToggle(loggingContainer, componentName, $"Enable {componentName} logging", isEnabled);
299 |                 }
300 |             }
301 |         }
302 |         
303 |         // Make sure all components are initialized in the logger
304 |         private void EnsureComponentsInitialized()
305 |         {
306 |             string[] standardComponents = {
307 |                 "MCPManager",
308 |                 "MCPConnectionManager",
309 |                 "MCPDataCollector",
310 |                 "MCPMessageHandler",
311 |                 "MCPCodeExecutor",
312 |                 "MCPMessageSender",
313 |                 "MCPDebugWindow"
314 |             };
315 |             
316 |             foreach (string componentName in standardComponents)
317 |             {
318 |                 MCPLogger.InitializeComponent(componentName, false);
319 |             }
320 |         }
321 |         
322 |         private void CreateLoggingToggle(VisualElement container, string componentName, string label, bool initialValue)
323 |         {
324 |             var toggle = new Toggle(label);
325 |             toggle.value = initialValue;
326 |             
327 |             // Make all toggles interactive, they'll work based on global enabled state
328 |             toggle.SetEnabled(true);
329 |             
330 |             toggle.RegisterValueChangedCallback(evt => OnLoggingToggleChanged(componentName, evt.newValue));
331 |             container.Add(toggle);
332 |             logToggles[componentName] = toggle;
333 |         }
334 |         
335 |         private void OnLoggingToggleChanged(string componentName, bool enabled)
336 |         {
337 |             MCPLogger.SetComponentLoggingEnabled(componentName, enabled);
338 |             settings.componentLoggingEnabled[componentName] = enabled;
339 |             SaveSettings();
340 |         }
341 |         
342 |         private void OnConnectClicked()
343 |         {
344 |             // Always use localhost for the WebSocket URL
345 |             string serverUrl = "ws://localhost";
346 |             
347 |             // Get the server port from the text field
348 |             string portText = serverPortField.value;
349 |             
350 |             // If port is empty, default to 5010
351 |             if (string.IsNullOrWhiteSpace(portText))
352 |             {
353 |                 portText = "5010";
354 |                 serverPortField.value = portText;
355 |             }
356 |             
357 |             // Validate port format
358 |             if (!int.TryParse(portText, out int port) || port < 1 || port > 65535)
359 |             {
360 |                 EditorUtility.DisplayDialog("Invalid Port", 
361 |                     "Please enter a valid port number between 1 and 65535.", "OK");
362 |                 return;
363 |             }
364 |             
365 |             // Save the port setting
366 |             settings.port = port;
367 |             SaveSettings();
368 |             
369 |             try {
370 |                 // Create the WebSocket URL with the specified port
371 |                 Uri uri = new Uri($"{serverUrl}:{port}");
372 |                 
373 |                 // If we have access to the ConnectionManager, try to update its server URI
374 |                 var connectionManager = GetConnectionManager();
375 |                 if (connectionManager != null)
376 |                 {
377 |                     // Use reflection to set the serverUri field if it exists
378 |                     var serverUriField = typeof(MCPConnectionManager).GetField("serverUri", 
379 |                         System.Reflection.BindingFlags.NonPublic | 
380 |                         System.Reflection.BindingFlags.Instance);
381 |                         
382 |                     if (serverUriField != null)
383 |                     {
384 |                         serverUriField.SetValue(connectionManager, uri);
385 |                     }
386 |                 }
387 |                 
388 |                 // Initiate manual connection
389 |                 if (MCPManager.IsInitialized)
390 |                 {
391 |                     MCPManager.RetryConnection();
392 |                     connectionStartTime = DateTime.Now;
393 |                     UpdateUIFromState();
394 |                 }
395 |                 else
396 |                 {
397 |                     MCPManager.Initialize();
398 |                     connectionStartTime = DateTime.Now;
399 |                     UpdateUIFromState();
400 |                 }
401 |             }
402 |             catch (UriFormatException)
403 |             {
404 |                 EditorUtility.DisplayDialog("Invalid URL", 
405 |                     "The URL format is invalid.", "OK");
406 |             }
407 |             catch (Exception ex)
408 |             {
409 |                 EditorUtility.DisplayDialog("Connection Error", 
410 |                     $"Error connecting to server: {ex.Message}", "OK");
411 |             }
412 |         }
413 |         
414 |         private void OnDisconnectClicked()
415 |         {
416 |             if (MCPManager.IsInitialized)
417 |             {
418 |                 MCPManager.Shutdown();
419 |                 connectionStartTime = null;
420 |                 UpdateUIFromState();
421 |             }
422 |         }
423 |         
424 |         private void OnAutoReconnectChanged(ChangeEvent<bool> evt)
425 |         {
426 |             settings.autoReconnect = evt.newValue;
427 |             SaveSettings();
428 |             
429 |             if (MCPManager.IsInitialized)
430 |             {
431 |                 MCPManager.EnableAutoReconnect(evt.newValue);
432 |             }
433 |         }
434 |         
435 |         private void OnEditorUpdate()
436 |         {
437 |             // Update connection status and statistics
438 |             UpdateUIFromState();
439 |         }
440 |         
441 |         private void UpdateUIFromState()
442 |         {
443 |             bool isInitialized = MCPManager.IsInitialized;
444 |             bool isConnected = MCPManager.IsConnected;
445 |             
446 |             // Only log status if logging is enabled
447 |             if (MCPLogger.IsLoggingEnabled("MCPDebugWindow"))
448 |             {
449 |                 Debug.Log($"[MCP] [MCPDebugWindow] Status check: IsInitialized={isInitialized}, IsConnected={isConnected}");
450 |             }
451 |             
452 |             // Update status label
453 |             if (!isInitialized)
454 |             {
455 |                 connectionStatusLabel.text = "Not Initialized";
456 |                 connectionStatusLabel.RemoveFromClassList("status-connected");
457 |                 connectionStatusLabel.RemoveFromClassList("status-connecting");
458 |                 connectionStatusLabel.AddToClassList("status-disconnected");
459 |             }
460 |             else if (isConnected)
461 |             {
462 |                 connectionStatusLabel.text = "Connected";
463 |                 connectionStatusLabel.RemoveFromClassList("status-disconnected");
464 |                 connectionStatusLabel.RemoveFromClassList("status-connecting");
465 |                 connectionStatusLabel.AddToClassList("status-connected");
466 |                 
467 |                 // If we're in the connected state, make sure connectionStartTime is set
468 |                 // This ensures the timer works properly
469 |                 if (!connectionStartTime.HasValue)
470 |                 {
471 |                     connectionStartTime = DateTime.Now;
472 |                 }
473 |             }
474 |             else
475 |             {
476 |                 connectionStatusLabel.text = "Disconnected";
477 |                 connectionStatusLabel.RemoveFromClassList("status-connected");
478 |                 connectionStatusLabel.RemoveFromClassList("status-connecting");
479 |                 connectionStatusLabel.AddToClassList("status-disconnected");
480 |                 
481 |                 // Reset connection time when disconnected
482 |                 connectionStartTime = null;
483 |             }
484 |             
485 |             // Update button states
486 |             connectButton.SetEnabled(!isConnected);
487 |             disconnectButton.SetEnabled(isInitialized);
488 |             serverPortField.SetEnabled(!isConnected); // Only allow port changes when disconnected
489 |             
490 |             // Update connection time if connected
491 |             if (connectionStartTime.HasValue && isConnected)
492 |             {
493 |                 TimeSpan duration = DateTime.Now - connectionStartTime.Value;
494 |                 connectionTimeLabel.text = $"{duration.Hours:00}:{duration.Minutes:00}:{duration.Seconds:00}";
495 |             }
496 |             else
497 |             {
498 |                 connectionTimeLabel.text = "00:00:00";
499 |             }
500 |             
501 |             // Update statistics if available
502 |             if (isInitialized)
503 |             {
504 |                 // Get connection statistics
505 |                 var connectionManager = GetConnectionManager();
506 |                 if (connectionManager != null)
507 |                 {
508 |                     messagesSentLabel.text = connectionManager.MessagesSent.ToString();
509 |                     messagesReceivedLabel.text = connectionManager.MessagesReceived.ToString();
510 |                     reconnectAttemptsLabel.text = connectionManager.ReconnectAttempts.ToString();
511 |                     lastErrorLabel.text = !string.IsNullOrEmpty(connectionManager.LastErrorMessage) 
512 |                         ? connectionManager.LastErrorMessage : "None";
513 |                 }
514 |                 else
515 |                 {
516 |                     messagesSentLabel.text = "0";
517 |                     messagesReceivedLabel.text = "0";
518 |                     reconnectAttemptsLabel.text = "0";
519 |                     lastErrorLabel.text = "None";
520 |                 }
521 |             }
522 |         }
523 |         
524 |         // Helper to access connection manager through reflection if needed
525 |         private MCPConnectionManager GetConnectionManager()
526 |         {
527 |             if (!MCPManager.IsInitialized)
528 |                 return null;
529 |                 
530 |             // Try to access the connection manager using reflection
531 |             try
532 |             {
533 |                 var managerType = typeof(MCPManager);
534 |                 var field = managerType.GetField("connectionManager", 
535 |                     System.Reflection.BindingFlags.NonPublic | 
536 |                     System.Reflection.BindingFlags.Static);
537 |                     
538 |                 if (field != null)
539 |                 {
540 |                     return field.GetValue(null) as MCPConnectionManager;
541 |                 }
542 |             }
543 |             catch (Exception ex)
544 |             {
545 |                 Debug.LogError($"Error accessing connection manager: {ex.Message}");
546 |             }
547 |             
548 |             return null;
549 |         }
550 |         
551 |         private void OnDisable()
552 |         {
553 |             // Unregister from editor updates
554 |             EditorApplication.update -= OnEditorUpdate;
555 |             
556 |             // Save settings one last time when window is closed
557 |             SaveSettings();
558 |         }
559 |     }
560 | }
561 | 
```
Page 2/2FirstPrevNextLast