Skip to main content
Glama
UnityMCPEditorWindow.cs10.2 kB
using System; using System.Diagnostics; using System.IO; using UnityEditor; using UnityEngine; namespace UnityMCP { public class UnityMCPEditorWindow : EditorWindow { // UI State private bool showDebugLogs = false; private ValidationLevel validationLevel = ValidationLevel.Standard; private bool showAdvancedSettings = false; private bool showManualConfig = false; private TransportType transportType = TransportType.WebSocket; private string serverUrl = "ws://localhost:8080"; private ClientType selectedClient = ClientType.Cursor; private enum ValidationLevel { Basic, Standard, Strict } private enum TransportType { HTTP, WebSocket } private enum ClientType { Cursor, VSCode, ClaudeDesktop } private string ProjectRoot => Directory.GetParent(Application.dataPath).FullName; private string TargetServerPath => Path.Combine(ProjectRoot, "MCPServer"); [MenuItem("MCP/Dashboard")] public static void ShowWindow() { GetWindow<UnityMCPEditorWindow>("MCP For Unity"); } private void OnGUI() { DrawHeader(); DrawSettings(); DrawConnection(); DrawClientConfig(); } private void DrawHeader() { EditorGUILayout.Space(); GUILayout.Label("MCP For Unity", new GUIStyle(EditorStyles.largeLabel) { fontSize = 20, fontStyle = FontStyle.Bold }); EditorGUILayout.Space(); } private void DrawSettings() { GUILayout.Label("Settings", EditorStyles.boldLabel); using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.LabelField("Version:", GUILayout.Width(150)); EditorGUILayout.LabelField("v1.0.0", EditorStyles.miniLabel); } showDebugLogs = EditorGUILayout.Toggle("Show Debug Logs:", showDebugLogs); validationLevel = (ValidationLevel)EditorGUILayout.EnumPopup("Script Validation Level:", validationLevel); EditorGUILayout.HelpBox("Syntax checks + Unity best practices and warnings", MessageType.None); showAdvancedSettings = EditorGUILayout.Foldout(showAdvancedSettings, "Advanced Settings"); if (showAdvancedSettings) { if (GUILayout.Button("Install Server Files to Project Root")) InstallServerFiles(); if (GUILayout.Button("Install 'uv' and Requirements")) InstallUVAndRequirements(); } } EditorGUILayout.Space(); } private void DrawConnection() { GUILayout.Label("Connection", EditorStyles.boldLabel); using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { transportType = (TransportType)EditorGUILayout.EnumPopup("Transport:", transportType); serverUrl = EditorGUILayout.TextField("URL:", serverUrl); EditorGUILayout.LabelField("Use this command to launch the server manually:"); string cmd = $"uv run --directory \"{TargetServerPath}\" server.py"; using (new EditorGUILayout.HorizontalScope()) { EditorGUILayout.TextArea(cmd, GUILayout.Height(40)); if (GUILayout.Button("Copy", GUILayout.Width(50), GUILayout.Height(40))) { GUIUtility.systemCopyBuffer = cmd; UnityEngine.Debug.Log("Command copied to clipboard!"); } } EditorGUILayout.HelpBox("Run this command in your shell if you prefer to start the server manually.", MessageType.None); using (new EditorGUILayout.HorizontalScope()) { if (GUILayout.Button("Start Internal Server")) UnityMCPServer.StartServer(); if (GUILayout.Button("Stop Internal Server")) UnityMCPServer.StopServer(); } // Status Indicators EditorGUILayout.Space(); using (new EditorGUILayout.HorizontalScope()) { Color statusColor = UnityMCPServer.IsRunning ? Color.green : Color.red; string statusText = UnityMCPServer.IsRunning ? "Running" : "Stopped"; var style = new GUIStyle(EditorStyles.label); style.normal.textColor = statusColor; GUILayout.Label("●", style, GUILayout.Width(20)); GUILayout.Label($"Internal Server: {statusText}"); GUILayout.FlexibleSpace(); if (GUILayout.Button("Restart Session")) UnityMCPServer.RestartServer(); } using (new EditorGUILayout.HorizontalScope()) { GUILayout.Label("Health:"); GUILayout.Label(UnityMCPServer.IsRunning ? "Healthy" : "Unknown"); GUILayout.FlexibleSpace(); if (GUILayout.Button("Test")) UnityEngine.Debug.Log("Test Ping..."); } } EditorGUILayout.Space(); } private void DrawClientConfig() { GUILayout.Label("Client Configuration", EditorStyles.boldLabel); using (new EditorGUILayout.VerticalScope(EditorStyles.helpBox)) { selectedClient = (ClientType)EditorGUILayout.EnumPopup("Client:", selectedClient); if (GUILayout.Button("Configure All Detected Clients")) { GenerateVSCodeConfig(); } using (new EditorGUILayout.HorizontalScope()) { bool configured = File.Exists(Path.Combine(ProjectRoot, ".vscode/mcp.json")); Color statusColor = configured ? Color.green : Color.red; string statusText = configured ? "Configured" : "Not Configured"; var style = new GUIStyle(EditorStyles.label); style.normal.textColor = statusColor; GUILayout.Label("●", style, GUILayout.Width(20)); GUILayout.Label(statusText); GUILayout.FlexibleSpace(); if (GUILayout.Button("Configure")) GenerateVSCodeConfig(); } showManualConfig = EditorGUILayout.Foldout(showManualConfig, "Manual Configuration"); if (showManualConfig) { EditorGUILayout.TextArea(GetMCPConfigJson(), GUILayout.Height(100)); if (GUILayout.Button("Copy Config")) { GUIUtility.systemCopyBuffer = GetMCPConfigJson(); } } } } // --- Helpers --- private void InstallServerFiles() { string packagePath = Path.GetFullPath("Packages/com.yunuscan.unitymcp"); if (!Directory.Exists(packagePath)) packagePath = ProjectRoot; string sourceServer = Path.Combine(packagePath, "Server"); if (!Directory.Exists(sourceServer)) { // Try Assets/MCP/Server if package not found (dev mode) sourceServer = Path.Combine(ProjectRoot, "Assets/MCP/Server"); if(!Directory.Exists(sourceServer)) { UnityEngine.Debug.LogError($"Could not find source Server folder."); return; } } if (!Directory.Exists(TargetServerPath)) Directory.CreateDirectory(TargetServerPath); foreach (string file in Directory.GetFiles(sourceServer)) { if (file.EndsWith(".meta")) continue; string dest = Path.Combine(TargetServerPath, Path.GetFileName(file)); File.Copy(file, dest, true); } UnityEngine.Debug.Log($"Server files installed to {TargetServerPath}"); } private void InstallUVAndRequirements() { string requirementsPath = Path.Combine(TargetServerPath, "requirements.txt"); RunCommand($"pip install uv && uv pip install -r \"{requirementsPath}\" --system"); } private void GenerateVSCodeConfig() { string vscodeDir = Path.Combine(ProjectRoot, ".vscode"); if (!Directory.Exists(vscodeDir)) Directory.CreateDirectory(vscodeDir); string mcpJson = GetMCPConfigJson(); File.WriteAllText(Path.Combine(vscodeDir, "mcp.json"), mcpJson); UnityEngine.Debug.Log($"VS Code configuration generated in {vscodeDir}"); EditorUtility.RevealInFinder(vscodeDir); } private string GetMCPConfigJson() { // SSE Configuration return @"{ ""mcpServers"": { ""unity"": { ""url"": ""http://localhost:8000/sse"" } } }"; } private void RunCommand(string command, bool waitForExit = true) { ProcessStartInfo startInfo = new ProcessStartInfo { FileName = "cmd.exe", Arguments = $"/c {command}", UseShellExecute = true, CreateNoWindow = waitForExit }; if (!waitForExit) startInfo.WindowStyle = ProcessWindowStyle.Normal; try { Process process = Process.Start(startInfo); if (waitForExit) process.WaitForExit(); } catch (System.Exception e) { UnityEngine.Debug.LogError($"Failed to run command: {e.Message}"); } } } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/yunuscan/MCPForUnity'

If you have feedback or need assistance with the MCP directory API, please join our Discord server