Skip to main content
Glama
McpSetupWindow.cs13.8 kB
using System; using System.IO; using UnityEditor; using UnityEngine; namespace LocalMcp.UnityServer { /// <summary> /// Unity MCP Setup Window - Provides one-click setup for Claude Code connection /// </summary> public class McpSetupWindow : EditorWindow { private string _serverPath; private string _projectPath; private string _configPath; private string _runtimeConfigPath; private bool _isServerPathValid; private bool _isConfigGenerated; private Vector2 _scrollPosition; private GUIStyle _headerStyle; private GUIStyle _successStyle; private GUIStyle _errorStyle; private GUIStyle _codeStyle; private bool _stylesInitialized; [MenuItem("Window/Unity MCP/Setup Claude Code", false, 100)] public static void ShowWindow() { var window = GetWindow<McpSetupWindow>("MCP Setup"); window.minSize = new Vector2(500, 400); window.Show(); } private void OnEnable() { RefreshPaths(); } private void InitStyles() { if (_stylesInitialized) return; _headerStyle = new GUIStyle(EditorStyles.boldLabel) { fontSize = 14, margin = new RectOffset(0, 0, 10, 10) }; _successStyle = new GUIStyle(EditorStyles.label) { normal = { textColor = new Color(0.2f, 0.8f, 0.2f) } }; _errorStyle = new GUIStyle(EditorStyles.label) { normal = { textColor = new Color(0.9f, 0.3f, 0.3f) } }; _codeStyle = new GUIStyle(EditorStyles.textArea) { wordWrap = true, padding = new RectOffset(8, 8, 8, 8) }; _stylesInitialized = true; } private void RefreshPaths() { // Find Server~ path in package _serverPath = FindServerPath(); _isServerPathValid = !string.IsNullOrEmpty(_serverPath) && Directory.Exists(_serverPath); // Project paths _projectPath = Path.GetDirectoryName(Application.dataPath); _configPath = Path.Combine(_projectPath, ".mcp.json"); _runtimeConfigPath = Path.Combine(_projectPath, ".unity-mcp-runtime.json"); // Check if config exists _isConfigGenerated = File.Exists(_configPath); } private string FindServerPath() { // Try to find Server~/mcp-bridge in package cache var packagePath = GetPackagePath(); if (!string.IsNullOrEmpty(packagePath)) { var serverPath = Path.Combine(packagePath, "Server~", "mcp-bridge"); if (Directory.Exists(serverPath)) { return serverPath; } } // Fallback: check common locations var possiblePaths = new[] { Path.Combine(Application.dataPath, "..", "Packages", "com.local.mcp.unityserver", "Server~", "mcp-bridge"), Path.Combine(Application.dataPath, "..", "Library", "PackageCache") }; foreach (var basePath in possiblePaths) { if (Directory.Exists(basePath)) { // Search for Server~/mcp-bridge try { var dirs = Directory.GetDirectories(basePath, "com.local.mcp.unityserver*", SearchOption.TopDirectoryOnly); foreach (var dir in dirs) { var serverPath = Path.Combine(dir, "Server~", "mcp-bridge"); if (Directory.Exists(serverPath)) { return serverPath; } } } catch { } } } return null; } private string GetPackagePath() { // Use PackageInfo to find our package var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(McpSetupWindow).Assembly); return packageInfo?.resolvedPath; } private void OnGUI() { InitStyles(); _scrollPosition = EditorGUILayout.BeginScrollView(_scrollPosition); // Header EditorGUILayout.LabelField("Unity MCP - Claude Code Setup", _headerStyle); EditorGUILayout.Space(5); // Status Section DrawStatusSection(); EditorGUILayout.Space(10); // Setup Actions DrawSetupSection(); EditorGUILayout.Space(10); // Configuration Preview DrawConfigSection(); EditorGUILayout.Space(10); // Help Section DrawHelpSection(); EditorGUILayout.EndScrollView(); } private void DrawStatusSection() { EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField("Status", EditorStyles.boldLabel); // Server Path EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("MCP Bridge:", GUILayout.Width(100)); if (_isServerPathValid) { EditorGUILayout.LabelField("Found", _successStyle); } else { EditorGUILayout.LabelField("Not Found", _errorStyle); } EditorGUILayout.EndHorizontal(); // Config File EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Config File:", GUILayout.Width(100)); if (_isConfigGenerated) { EditorGUILayout.LabelField(".mcp.json exists", _successStyle); } else { EditorGUILayout.LabelField("Not generated", _errorStyle); } EditorGUILayout.EndHorizontal(); // Runtime Config var hasRuntimeConfig = File.Exists(_runtimeConfigPath); EditorGUILayout.BeginHorizontal(); EditorGUILayout.LabelField("Runtime:", GUILayout.Width(100)); if (hasRuntimeConfig) { EditorGUILayout.LabelField("Server running", _successStyle); } else { EditorGUILayout.LabelField("Server not started", _errorStyle); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } private void DrawSetupSection() { EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField("Setup Actions", EditorStyles.boldLabel); EditorGUILayout.Space(5); // Main setup button GUI.enabled = _isServerPathValid; if (GUILayout.Button("Generate Configuration", GUILayout.Height(30))) { GenerateConfiguration(); } GUI.enabled = true; EditorGUILayout.Space(5); // Additional actions EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Refresh Status")) { RefreshPaths(); } if (GUILayout.Button("Open Config Folder")) { EditorUtility.RevealInFinder(_projectPath); } if (GUILayout.Button("Install npm packages")) { InstallNpmPackages(); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } private void DrawConfigSection() { EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField("Configuration Preview", EditorStyles.boldLabel); EditorGUILayout.Space(5); var config = GenerateConfigJson(); EditorGUILayout.TextArea(config, _codeStyle, GUILayout.Height(120)); EditorGUILayout.Space(5); EditorGUILayout.BeginHorizontal(); if (GUILayout.Button("Copy to Clipboard")) { GUIUtility.systemCopyBuffer = config; Debug.Log("[MCP Setup] Configuration copied to clipboard"); } if (_isConfigGenerated && GUILayout.Button("View .mcp.json")) { EditorUtility.RevealInFinder(_configPath); } EditorGUILayout.EndHorizontal(); EditorGUILayout.EndVertical(); } private void DrawHelpSection() { EditorGUILayout.BeginVertical(EditorStyles.helpBox); EditorGUILayout.LabelField("Setup Instructions", EditorStyles.boldLabel); EditorGUILayout.HelpBox( "1. Click 'Generate Configuration' to create .mcp.json\n" + "2. Run 'npm install' in the mcp-bridge folder (or click Install npm packages)\n" + "3. Restart Claude Code\n" + "4. Claude Code will automatically detect the Unity MCP server", MessageType.Info ); EditorGUILayout.Space(5); if (!string.IsNullOrEmpty(_serverPath)) { EditorGUILayout.LabelField("Server Path:", EditorStyles.miniLabel); EditorGUILayout.SelectableLabel(_serverPath, EditorStyles.textField, GUILayout.Height(18)); } EditorGUILayout.EndVertical(); } private string GenerateConfigJson() { var indexPath = _isServerPathValid ? Path.Combine(_serverPath, "index.js").Replace("\\", "/") : "<path-to-package>/Server~/mcp-bridge/index.js"; var projectPathEscaped = _projectPath.Replace("\\", "/"); return "{\n" + " \"mcpServers\": {\n" + " \"unity\": {\n" + " \"command\": \"node\",\n" + " \"args\": [\"" + indexPath + "\"],\n" + " \"cwd\": \"" + projectPathEscaped + "\"\n" + " }\n" + " }\n" + "}"; } private void GenerateConfiguration() { try { var config = GenerateConfigJson(); File.WriteAllText(_configPath, config); _isConfigGenerated = true; Debug.Log("[MCP Setup] Configuration generated: " + _configPath); EditorUtility.DisplayDialog( "MCP Setup Complete", "Configuration file generated at:\n" + _configPath + "\n\n" + "Next steps:\n" + "1. Run 'npm install' in Server~/mcp-bridge (or click 'Install npm packages')\n" + "2. Restart Claude Code\n" + "3. The Unity MCP server will be available", "OK" ); } catch (Exception e) { Debug.LogError("[MCP Setup] Failed to generate configuration: " + e.Message); EditorUtility.DisplayDialog( "MCP Setup Error", "Failed to generate configuration:\n" + e.Message, "OK" ); } } private void InstallNpmPackages() { if (!_isServerPathValid) { EditorUtility.DisplayDialog("Error", "Server path not found", "OK"); return; } try { var startInfo = new System.Diagnostics.ProcessStartInfo { FileName = "npm", Arguments = "install", WorkingDirectory = _serverPath, UseShellExecute = false, RedirectStandardOutput = true, RedirectStandardError = true, CreateNoWindow = true }; var process = System.Diagnostics.Process.Start(startInfo); var output = process.StandardOutput.ReadToEnd(); var error = process.StandardError.ReadToEnd(); process.WaitForExit(); if (process.ExitCode == 0) { Debug.Log("[MCP Setup] npm install completed:\n" + output); EditorUtility.DisplayDialog( "npm install Complete", "Dependencies installed successfully.\n\nYou can now restart Claude Code.", "OK" ); } else { Debug.LogError("[MCP Setup] npm install failed:\n" + error); EditorUtility.DisplayDialog( "npm install Failed", "Error:\n" + error + "\n\nTry running manually:\ncd \"" + _serverPath + "\"\nnpm install", "OK" ); } } catch (Exception e) { Debug.LogError("[MCP Setup] Failed to run npm: " + e.Message); EditorUtility.DisplayDialog( "Error", "Failed to run npm:\n" + e.Message + "\n\nMake sure Node.js is installed.", "OK" ); } } } }

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/dsgarage/UniMCP4CC'

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