From 798b49dd8d4bddc0a9b83092120b4747f7683f26 Mon Sep 17 00:00:00 2001 From: Klausi Date: Mon, 28 Apr 2025 22:26:10 +0200 Subject: [PATCH 1/7] feat: Support direct material property assignment from JSON params Extended ApplyMaterialProperties to loop through all properties in the provided JObject and set them directly on the material if they match a known property (e.g., _Color, _MainTex, etc.). Now supports direct assignment of color, float, and texture properties using simple JSON structures, such as: { "_Color": [0, 1, 0, 1] } for albedo color { "_Glossiness": 0.5 } for smoothness { "_MainTex": "Assets/Textures/MyTex.png" } for textures Retained backward compatibility with the previous structured property format (color, float, texture objects). This change enables more flexible and user-friendly material creation and modification via automation and external tools. Fixes issues where material color and other properties could not be set from automation. --- UnityMcpBridge/Editor/Tools/ManageAsset.cs | 58 ++++++++++++++++++++++ 1 file changed, 58 insertions(+) diff --git a/UnityMcpBridge/Editor/Tools/ManageAsset.cs b/UnityMcpBridge/Editor/Tools/ManageAsset.cs index 7a0dad716..d36c0dd09 100644 --- a/UnityMcpBridge/Editor/Tools/ManageAsset.cs +++ b/UnityMcpBridge/Editor/Tools/ManageAsset.cs @@ -854,6 +854,64 @@ private static bool ApplyMaterialProperties(Material mat, JObject properties) return false; bool modified = false; + // Loop through all properties for direct assignment + foreach (var prop in properties.Properties()) + { + string propName = prop.Name; + JToken value = prop.Value; + if (mat.HasProperty(propName)) + { + // Handle color arrays (e.g., _Color: [0,1,0,1]) + if (value is JArray arr && (arr.Count == 3 || arr.Count == 4)) + { + try + { + Color newColor = new Color( + arr[0].ToObject(), + arr[1].ToObject(), + arr[2].ToObject(), + arr.Count > 3 ? arr[3].ToObject() : 1.0f + ); + if (mat.GetColor(propName) != newColor) + { + mat.SetColor(propName, newColor); + modified = true; + } + } + catch (Exception ex) + { + Debug.LogWarning($"Error parsing color array for '{propName}': {ex.Message}"); + } + } + // Handle float/int + else if (value.Type == JTokenType.Float || value.Type == JTokenType.Integer) + { + float newVal = value.ToObject(); + if (mat.GetFloat(propName) != newVal) + { + mat.SetFloat(propName, newVal); + modified = true; + } + } + // Handle string (could be texture path) + else if (value.Type == JTokenType.String) + { + string strVal = value.ToString(); + // Try to load as texture + Texture tex = AssetDatabase.LoadAssetAtPath(SanitizeAssetPath(strVal)); + if (tex != null) + { + if (mat.GetTexture(propName) != tex) + { + mat.SetTexture(propName, tex); + modified = true; + } + } + } + } + } + + // Existing structured handling (for backward compatibility) // Example: Set shader if (properties["shader"]?.Type == JTokenType.String) { From 0e915fa2655e74ce41dbb7b3d8c85562b9fe3bf7 Mon Sep 17 00:00:00 2001 From: Klausi Date: Wed, 2 Jul 2025 22:57:32 +0200 Subject: [PATCH 2/7] Update ServerInstaller to use KlausUllrich fork - Modified ServerInstaller.cs to download from KlausUllrich/unity-mcp - This ensures Unity package installs code from our fork, not original repo - Critical for testing our audited code improvements - Part of AWMS Unity MCP testing strategy --- .../Editor/Helpers/ServerInstaller.cs | 500 +++++++++--------- UnityMcpServer/src/uv.lock | 164 +++--- 2 files changed, 332 insertions(+), 332 deletions(-) diff --git a/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs b/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs index 9d5682f41..cf3aa987a 100644 --- a/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs +++ b/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs @@ -1,250 +1,250 @@ -using System; -using System.IO; -using System.Linq; -using System.Net; -using System.Runtime.InteropServices; -using UnityEngine; - -namespace UnityMcpBridge.Editor.Helpers -{ - public static class ServerInstaller - { - private const string RootFolder = "UnityMCP"; - private const string ServerFolder = "UnityMcpServer"; - private const string BranchName = "master"; - private const string GitUrl = "https://github.com/justinpbarnett/unity-mcp.git"; - private const string PyprojectUrl = - "https://raw.githubusercontent.com/justinpbarnett/unity-mcp/refs/heads/" - + BranchName - + "/UnityMcpServer/src/pyproject.toml"; - - /// - /// Ensures the unity-mcp-server is installed and up to date. - /// - public static void EnsureServerInstalled() - { - try - { - string saveLocation = GetSaveLocation(); - - if (!IsServerInstalled(saveLocation)) - { - InstallServer(saveLocation); - } - else - { - string installedVersion = GetInstalledVersion(); - string latestVersion = GetLatestVersion(); - - if (IsNewerVersion(latestVersion, installedVersion)) - { - UpdateServer(saveLocation); - } - else { } - } - } - catch (Exception ex) - { - Debug.LogError($"Failed to ensure server installation: {ex.Message}"); - } - } - - public static string GetServerPath() - { - return Path.Combine(GetSaveLocation(), ServerFolder, "src"); - } - - /// - /// Gets the platform-specific save location for the server. - /// - private static string GetSaveLocation() - { - if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - { - return Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - "AppData", - "Local", - "Programs", - RootFolder - ); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) - { - return Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - "bin", - RootFolder - ); - } - else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) - { - string path = "/usr/local/bin"; - return !Directory.Exists(path) || !IsDirectoryWritable(path) - ? Path.Combine( - Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), - "Applications", - RootFolder - ) - : Path.Combine(path, RootFolder); - } - throw new Exception("Unsupported operating system."); - } - - private static bool IsDirectoryWritable(string path) - { - try - { - File.Create(Path.Combine(path, "test.txt")).Dispose(); - File.Delete(Path.Combine(path, "test.txt")); - return true; - } - catch - { - return false; - } - } - - /// - /// Checks if the server is installed at the specified location. - /// - private static bool IsServerInstalled(string location) - { - return Directory.Exists(location) - && File.Exists(Path.Combine(location, ServerFolder, "src", "pyproject.toml")); - } - - /// - /// Installs the server by cloning only the UnityMcpServer folder from the repository and setting up dependencies. - /// - private static void InstallServer(string location) - { - // Create the src directory where the server code will reside - Directory.CreateDirectory(location); - - // Initialize git repo in the src directory - RunCommand("git", $"init", workingDirectory: location); - - // Add remote - RunCommand("git", $"remote add origin {GitUrl}", workingDirectory: location); - - // Configure sparse checkout - RunCommand("git", "config core.sparseCheckout true", workingDirectory: location); - - // Set sparse checkout path to only include UnityMcpServer folder - string sparseCheckoutPath = Path.Combine(location, ".git", "info", "sparse-checkout"); - File.WriteAllText(sparseCheckoutPath, $"{ServerFolder}/"); - - // Fetch and checkout the branch - RunCommand("git", $"fetch --depth=1 origin {BranchName}", workingDirectory: location); - RunCommand("git", $"checkout {BranchName}", workingDirectory: location); - } - - /// - /// Fetches the currently installed version from the local pyproject.toml file. - /// - public static string GetInstalledVersion() - { - string pyprojectPath = Path.Combine( - GetSaveLocation(), - ServerFolder, - "src", - "pyproject.toml" - ); - return ParseVersionFromPyproject(File.ReadAllText(pyprojectPath)); - } - - /// - /// Fetches the latest version from the GitHub pyproject.toml file. - /// - public static string GetLatestVersion() - { - using WebClient webClient = new(); - string pyprojectContent = webClient.DownloadString(PyprojectUrl); - return ParseVersionFromPyproject(pyprojectContent); - } - - /// - /// Updates the server by pulling the latest changes for the UnityMcpServer folder only. - /// - private static void UpdateServer(string location) - { - RunCommand("git", $"pull origin {BranchName}", workingDirectory: location); - } - - /// - /// Parses the version number from pyproject.toml content. - /// - private static string ParseVersionFromPyproject(string content) - { - foreach (string line in content.Split('\n')) - { - if (line.Trim().StartsWith("version =")) - { - string[] parts = line.Split('='); - if (parts.Length == 2) - { - return parts[1].Trim().Trim('"'); - } - } - } - throw new Exception("Version not found in pyproject.toml"); - } - - /// - /// Compares two version strings to determine if the latest is newer. - /// - public static bool IsNewerVersion(string latest, string installed) - { - int[] latestParts = latest.Split('.').Select(int.Parse).ToArray(); - int[] installedParts = installed.Split('.').Select(int.Parse).ToArray(); - for (int i = 0; i < Math.Min(latestParts.Length, installedParts.Length); i++) - { - if (latestParts[i] > installedParts[i]) - { - return true; - } - - if (latestParts[i] < installedParts[i]) - { - return false; - } - } - return latestParts.Length > installedParts.Length; - } - - /// - /// Runs a command-line process and handles output/errors. - /// - private static void RunCommand( - string command, - string arguments, - string workingDirectory = null - ) - { - System.Diagnostics.Process process = new() - { - StartInfo = new System.Diagnostics.ProcessStartInfo - { - FileName = command, - Arguments = arguments, - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - CreateNoWindow = true, - WorkingDirectory = workingDirectory ?? string.Empty, - }, - }; - process.Start(); - string output = process.StandardOutput.ReadToEnd(); - string error = process.StandardError.ReadToEnd(); - process.WaitForExit(); - if (process.ExitCode != 0) - { - throw new Exception( - $"Command failed: {command} {arguments}\nOutput: {output}\nError: {error}" - ); - } - } - } -} +using System; +using System.IO; +using System.Linq; +using System.Net; +using System.Runtime.InteropServices; +using UnityEngine; + +namespace UnityMcpBridge.Editor.Helpers +{ + public static class ServerInstaller + { + private const string RootFolder = "UnityMCP"; + private const string ServerFolder = "UnityMcpServer"; + private const string BranchName = "master"; + private const string GitUrl = "https://github.com/KlausUllrich/unity-mcp.git"; + private const string PyprojectUrl = + "https://raw.githubusercontent.com/KlausUllrich/unity-mcp/refs/heads/" + + BranchName + + "/UnityMcpServer/src/pyproject.toml"; + + /// + /// Ensures the unity-mcp-server is installed and up to date. + /// + public static void EnsureServerInstalled() + { + try + { + string saveLocation = GetSaveLocation(); + + if (!IsServerInstalled(saveLocation)) + { + InstallServer(saveLocation); + } + else + { + string installedVersion = GetInstalledVersion(); + string latestVersion = GetLatestVersion(); + + if (IsNewerVersion(latestVersion, installedVersion)) + { + UpdateServer(saveLocation); + } + else { } + } + } + catch (Exception ex) + { + Debug.LogError($"Failed to ensure server installation: {ex.Message}"); + } + } + + public static string GetServerPath() + { + return Path.Combine(GetSaveLocation(), ServerFolder, "src"); + } + + /// + /// Gets the platform-specific save location for the server. + /// + private static string GetSaveLocation() + { + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + return Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "AppData", + "Local", + "Programs", + RootFolder + ); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux)) + { + return Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "bin", + RootFolder + ); + } + else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX)) + { + string path = "/usr/local/bin"; + return !Directory.Exists(path) || !IsDirectoryWritable(path) + ? Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "Applications", + RootFolder + ) + : Path.Combine(path, RootFolder); + } + throw new Exception("Unsupported operating system."); + } + + private static bool IsDirectoryWritable(string path) + { + try + { + File.Create(Path.Combine(path, "test.txt")).Dispose(); + File.Delete(Path.Combine(path, "test.txt")); + return true; + } + catch + { + return false; + } + } + + /// + /// Checks if the server is installed at the specified location. + /// + private static bool IsServerInstalled(string location) + { + return Directory.Exists(location) + && File.Exists(Path.Combine(location, ServerFolder, "src", "pyproject.toml")); + } + + /// + /// Installs the server by cloning only the UnityMcpServer folder from the repository and setting up dependencies. + /// + private static void InstallServer(string location) + { + // Create the src directory where the server code will reside + Directory.CreateDirectory(location); + + // Initialize git repo in the src directory + RunCommand("git", $"init", workingDirectory: location); + + // Add remote + RunCommand("git", $"remote add origin {GitUrl}", workingDirectory: location); + + // Configure sparse checkout + RunCommand("git", "config core.sparseCheckout true", workingDirectory: location); + + // Set sparse checkout path to only include UnityMcpServer folder + string sparseCheckoutPath = Path.Combine(location, ".git", "info", "sparse-checkout"); + File.WriteAllText(sparseCheckoutPath, $"{ServerFolder}/"); + + // Fetch and checkout the branch + RunCommand("git", $"fetch --depth=1 origin {BranchName}", workingDirectory: location); + RunCommand("git", $"checkout {BranchName}", workingDirectory: location); + } + + /// + /// Fetches the currently installed version from the local pyproject.toml file. + /// + public static string GetInstalledVersion() + { + string pyprojectPath = Path.Combine( + GetSaveLocation(), + ServerFolder, + "src", + "pyproject.toml" + ); + return ParseVersionFromPyproject(File.ReadAllText(pyprojectPath)); + } + + /// + /// Fetches the latest version from the GitHub pyproject.toml file. + /// + public static string GetLatestVersion() + { + using WebClient webClient = new(); + string pyprojectContent = webClient.DownloadString(PyprojectUrl); + return ParseVersionFromPyproject(pyprojectContent); + } + + /// + /// Updates the server by pulling the latest changes for the UnityMcpServer folder only. + /// + private static void UpdateServer(string location) + { + RunCommand("git", $"pull origin {BranchName}", workingDirectory: location); + } + + /// + /// Parses the version number from pyproject.toml content. + /// + private static string ParseVersionFromPyproject(string content) + { + foreach (string line in content.Split('\n')) + { + if (line.Trim().StartsWith("version =")) + { + string[] parts = line.Split('='); + if (parts.Length == 2) + { + return parts[1].Trim().Trim('"'); + } + } + } + throw new Exception("Version not found in pyproject.toml"); + } + + /// + /// Compares two version strings to determine if the latest is newer. + /// + public static bool IsNewerVersion(string latest, string installed) + { + int[] latestParts = latest.Split('.').Select(int.Parse).ToArray(); + int[] installedParts = installed.Split('.').Select(int.Parse).ToArray(); + for (int i = 0; i < Math.Min(latestParts.Length, installedParts.Length); i++) + { + if (latestParts[i] > installedParts[i]) + { + return true; + } + + if (latestParts[i] < installedParts[i]) + { + return false; + } + } + return latestParts.Length > installedParts.Length; + } + + /// + /// Runs a command-line process and handles output/errors. + /// + private static void RunCommand( + string command, + string arguments, + string workingDirectory = null + ) + { + System.Diagnostics.Process process = new() + { + StartInfo = new System.Diagnostics.ProcessStartInfo + { + FileName = command, + Arguments = arguments, + RedirectStandardOutput = true, + RedirectStandardError = true, + UseShellExecute = false, + CreateNoWindow = true, + WorkingDirectory = workingDirectory ?? string.Empty, + }, + }; + process.Start(); + string output = process.StandardOutput.ReadToEnd(); + string error = process.StandardError.ReadToEnd(); + process.WaitForExit(); + if (process.ExitCode != 0) + { + throw new Exception( + $"Command failed: {command} {arguments}\nOutput: {output}\nError: {error}" + ); + } + } + } +} diff --git a/UnityMcpServer/src/uv.lock b/UnityMcpServer/src/uv.lock index 2f8a4d590..80c5f7fa7 100644 --- a/UnityMcpServer/src/uv.lock +++ b/UnityMcpServer/src/uv.lock @@ -1,14 +1,14 @@ version = 1 -revision = 1 +revision = 2 requires-python = ">=3.12" [[package]] name = "annotated-types" version = "0.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 }, + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, ] [[package]] @@ -20,18 +20,18 @@ dependencies = [ { name = "sniffio" }, { name = "typing-extensions", marker = "python_full_version < '3.13'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 } +sdist = { url = "https://files.pythonhosted.org/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949, upload-time = "2025-03-17T00:02:54.77Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 }, + { url = "https://files.pythonhosted.org/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916, upload-time = "2025-03-17T00:02:52.713Z" }, ] [[package]] name = "certifi" version = "2025.1.31" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 } +sdist = { url = "https://files.pythonhosted.org/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577, upload-time = "2025-01-31T02:16:47.166Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 }, + { url = "https://files.pythonhosted.org/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393, upload-time = "2025-01-31T02:16:45.015Z" }, ] [[package]] @@ -41,27 +41,27 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" }, ] [[package]] name = "colorama" version = "0.4.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, ] [[package]] name = "h11" version = "0.14.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418, upload-time = "2022-09-25T15:40:01.519Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259, upload-time = "2022-09-25T15:39:59.68Z" }, ] [[package]] @@ -72,9 +72,9 @@ dependencies = [ { name = "certifi" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196, upload-time = "2024-11-15T12:30:47.531Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551, upload-time = "2024-11-15T12:30:45.782Z" }, ] [[package]] @@ -87,27 +87,27 @@ dependencies = [ { name = "httpcore" }, { name = "idna" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, ] [[package]] name = "httpx-sse" version = "0.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 } +sdist = { url = "https://files.pythonhosted.org/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624, upload-time = "2023-12-22T08:01:21.083Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 }, + { url = "https://files.pythonhosted.org/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819, upload-time = "2023-12-22T08:01:19.89Z" }, ] [[package]] name = "idna" version = "3.10" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, ] [[package]] @@ -117,9 +117,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "mdurl" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596, upload-time = "2023-06-03T06:41:14.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528, upload-time = "2023-06-03T06:41:11.019Z" }, ] [[package]] @@ -136,9 +136,9 @@ dependencies = [ { name = "starlette" }, { name = "uvicorn" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/50/cc/5c5bb19f1a0f8f89a95e25cb608b0b07009e81fd4b031e519335404e1422/mcp-1.4.1.tar.gz", hash = "sha256:b9655d2de6313f9d55a7d1df62b3c3fe27a530100cc85bf23729145b0dba4c7a", size = 154942 } +sdist = { url = "https://files.pythonhosted.org/packages/50/cc/5c5bb19f1a0f8f89a95e25cb608b0b07009e81fd4b031e519335404e1422/mcp-1.4.1.tar.gz", hash = "sha256:b9655d2de6313f9d55a7d1df62b3c3fe27a530100cc85bf23729145b0dba4c7a", size = 154942, upload-time = "2025-03-14T09:52:15.54Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e8/0e/885f156ade60108e67bf044fada5269da68e29d758a10b0c513f4d85dd76/mcp-1.4.1-py3-none-any.whl", hash = "sha256:a7716b1ec1c054e76f49806f7d96113b99fc1166fc9244c2c6f19867cb75b593", size = 72448 }, + { url = "https://files.pythonhosted.org/packages/e8/0e/885f156ade60108e67bf044fada5269da68e29d758a10b0c513f4d85dd76/mcp-1.4.1-py3-none-any.whl", hash = "sha256:a7716b1ec1c054e76f49806f7d96113b99fc1166fc9244c2c6f19867cb75b593", size = 72448, upload-time = "2025-03-14T09:52:13.669Z" }, ] [package.optional-dependencies] @@ -151,9 +151,9 @@ cli = [ name = "mdurl" version = "0.1.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, ] [[package]] @@ -165,9 +165,9 @@ dependencies = [ { name = "pydantic-core" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681 } +sdist = { url = "https://files.pythonhosted.org/packages/b7/ae/d5220c5c52b158b1de7ca89fc5edb72f304a70a4c540c84c8844bf4008de/pydantic-2.10.6.tar.gz", hash = "sha256:ca5daa827cce33de7a42be142548b0096bf05a7e7b365aebfa5f8eeec7128236", size = 761681, upload-time = "2025-01-24T01:42:12.693Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696 }, + { url = "https://files.pythonhosted.org/packages/f4/3c/8cc1cc84deffa6e25d2d0c688ebb80635dfdbf1dbea3e30c541c8cf4d860/pydantic-2.10.6-py3-none-any.whl", hash = "sha256:427d664bf0b8a2b34ff5dd0f5a18df00591adcee7198fbd71981054cef37b584", size = 431696, upload-time = "2025-01-24T01:42:10.371Z" }, ] [[package]] @@ -177,36 +177,36 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443 } +sdist = { url = "https://files.pythonhosted.org/packages/fc/01/f3e5ac5e7c25833db5eb555f7b7ab24cd6f8c322d3a3ad2d67a952dc0abc/pydantic_core-2.27.2.tar.gz", hash = "sha256:eb026e5a4c1fee05726072337ff51d1efb6f59090b7da90d30ea58625b1ffb39", size = 413443, upload-time = "2024-12-18T11:31:54.917Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127 }, - { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340 }, - { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900 }, - { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177 }, - { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046 }, - { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386 }, - { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060 }, - { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870 }, - { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822 }, - { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364 }, - { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303 }, - { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064 }, - { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046 }, - { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092 }, - { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709 }, - { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273 }, - { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027 }, - { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888 }, - { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738 }, - { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138 }, - { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025 }, - { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633 }, - { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404 }, - { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130 }, - { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946 }, - { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387 }, - { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453 }, - { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186 }, + { url = "https://files.pythonhosted.org/packages/d6/74/51c8a5482ca447871c93e142d9d4a92ead74de6c8dc5e66733e22c9bba89/pydantic_core-2.27.2-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:9e0c8cfefa0ef83b4da9588448b6d8d2a2bf1a53c3f1ae5fca39eb3061e2f0b0", size = 1893127, upload-time = "2024-12-18T11:28:30.346Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f3/c97e80721735868313c58b89d2de85fa80fe8dfeeed84dc51598b92a135e/pydantic_core-2.27.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83097677b8e3bd7eaa6775720ec8e0405f1575015a463285a92bfdfe254529ef", size = 1811340, upload-time = "2024-12-18T11:28:32.521Z" }, + { url = "https://files.pythonhosted.org/packages/9e/91/840ec1375e686dbae1bd80a9e46c26a1e0083e1186abc610efa3d9a36180/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:172fce187655fece0c90d90a678424b013f8fbb0ca8b036ac266749c09438cb7", size = 1822900, upload-time = "2024-12-18T11:28:34.507Z" }, + { url = "https://files.pythonhosted.org/packages/f6/31/4240bc96025035500c18adc149aa6ffdf1a0062a4b525c932065ceb4d868/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:519f29f5213271eeeeb3093f662ba2fd512b91c5f188f3bb7b27bc5973816934", size = 1869177, upload-time = "2024-12-18T11:28:36.488Z" }, + { url = "https://files.pythonhosted.org/packages/fa/20/02fbaadb7808be578317015c462655c317a77a7c8f0ef274bc016a784c54/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:05e3a55d124407fffba0dd6b0c0cd056d10e983ceb4e5dbd10dda135c31071d6", size = 2038046, upload-time = "2024-12-18T11:28:39.409Z" }, + { url = "https://files.pythonhosted.org/packages/06/86/7f306b904e6c9eccf0668248b3f272090e49c275bc488a7b88b0823444a4/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9c3ed807c7b91de05e63930188f19e921d1fe90de6b4f5cd43ee7fcc3525cb8c", size = 2685386, upload-time = "2024-12-18T11:28:41.221Z" }, + { url = "https://files.pythonhosted.org/packages/8d/f0/49129b27c43396581a635d8710dae54a791b17dfc50c70164866bbf865e3/pydantic_core-2.27.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6fb4aadc0b9a0c063206846d603b92030eb6f03069151a625667f982887153e2", size = 1997060, upload-time = "2024-12-18T11:28:44.709Z" }, + { url = "https://files.pythonhosted.org/packages/0d/0f/943b4af7cd416c477fd40b187036c4f89b416a33d3cc0ab7b82708a667aa/pydantic_core-2.27.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:28ccb213807e037460326424ceb8b5245acb88f32f3d2777427476e1b32c48c4", size = 2004870, upload-time = "2024-12-18T11:28:46.839Z" }, + { url = "https://files.pythonhosted.org/packages/35/40/aea70b5b1a63911c53a4c8117c0a828d6790483f858041f47bab0b779f44/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:de3cd1899e2c279b140adde9357c4495ed9d47131b4a4eaff9052f23398076b3", size = 1999822, upload-time = "2024-12-18T11:28:48.896Z" }, + { url = "https://files.pythonhosted.org/packages/f2/b3/807b94fd337d58effc5498fd1a7a4d9d59af4133e83e32ae39a96fddec9d/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:220f892729375e2d736b97d0e51466252ad84c51857d4d15f5e9692f9ef12be4", size = 2130364, upload-time = "2024-12-18T11:28:50.755Z" }, + { url = "https://files.pythonhosted.org/packages/fc/df/791c827cd4ee6efd59248dca9369fb35e80a9484462c33c6649a8d02b565/pydantic_core-2.27.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a0fcd29cd6b4e74fe8ddd2c90330fd8edf2e30cb52acda47f06dd615ae72da57", size = 2158303, upload-time = "2024-12-18T11:28:54.122Z" }, + { url = "https://files.pythonhosted.org/packages/9b/67/4e197c300976af185b7cef4c02203e175fb127e414125916bf1128b639a9/pydantic_core-2.27.2-cp312-cp312-win32.whl", hash = "sha256:1e2cb691ed9834cd6a8be61228471d0a503731abfb42f82458ff27be7b2186fc", size = 1834064, upload-time = "2024-12-18T11:28:56.074Z" }, + { url = "https://files.pythonhosted.org/packages/1f/ea/cd7209a889163b8dcca139fe32b9687dd05249161a3edda62860430457a5/pydantic_core-2.27.2-cp312-cp312-win_amd64.whl", hash = "sha256:cc3f1a99a4f4f9dd1de4fe0312c114e740b5ddead65bb4102884b384c15d8bc9", size = 1989046, upload-time = "2024-12-18T11:28:58.107Z" }, + { url = "https://files.pythonhosted.org/packages/bc/49/c54baab2f4658c26ac633d798dab66b4c3a9bbf47cff5284e9c182f4137a/pydantic_core-2.27.2-cp312-cp312-win_arm64.whl", hash = "sha256:3911ac9284cd8a1792d3cb26a2da18f3ca26c6908cc434a18f730dc0db7bfa3b", size = 1885092, upload-time = "2024-12-18T11:29:01.335Z" }, + { url = "https://files.pythonhosted.org/packages/41/b1/9bc383f48f8002f99104e3acff6cba1231b29ef76cfa45d1506a5cad1f84/pydantic_core-2.27.2-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:7d14bd329640e63852364c306f4d23eb744e0f8193148d4044dd3dacdaacbd8b", size = 1892709, upload-time = "2024-12-18T11:29:03.193Z" }, + { url = "https://files.pythonhosted.org/packages/10/6c/e62b8657b834f3eb2961b49ec8e301eb99946245e70bf42c8817350cbefc/pydantic_core-2.27.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82f91663004eb8ed30ff478d77c4d1179b3563df6cdb15c0817cd1cdaf34d154", size = 1811273, upload-time = "2024-12-18T11:29:05.306Z" }, + { url = "https://files.pythonhosted.org/packages/ba/15/52cfe49c8c986e081b863b102d6b859d9defc63446b642ccbbb3742bf371/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:71b24c7d61131bb83df10cc7e687433609963a944ccf45190cfc21e0887b08c9", size = 1823027, upload-time = "2024-12-18T11:29:07.294Z" }, + { url = "https://files.pythonhosted.org/packages/b1/1c/b6f402cfc18ec0024120602bdbcebc7bdd5b856528c013bd4d13865ca473/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fa8e459d4954f608fa26116118bb67f56b93b209c39b008277ace29937453dc9", size = 1868888, upload-time = "2024-12-18T11:29:09.249Z" }, + { url = "https://files.pythonhosted.org/packages/bd/7b/8cb75b66ac37bc2975a3b7de99f3c6f355fcc4d89820b61dffa8f1e81677/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ce8918cbebc8da707ba805b7fd0b382816858728ae7fe19a942080c24e5b7cd1", size = 2037738, upload-time = "2024-12-18T11:29:11.23Z" }, + { url = "https://files.pythonhosted.org/packages/c8/f1/786d8fe78970a06f61df22cba58e365ce304bf9b9f46cc71c8c424e0c334/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eda3f5c2a021bbc5d976107bb302e0131351c2ba54343f8a496dc8783d3d3a6a", size = 2685138, upload-time = "2024-12-18T11:29:16.396Z" }, + { url = "https://files.pythonhosted.org/packages/a6/74/d12b2cd841d8724dc8ffb13fc5cef86566a53ed358103150209ecd5d1999/pydantic_core-2.27.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd8086fa684c4775c27f03f062cbb9eaa6e17f064307e86b21b9e0abc9c0f02e", size = 1997025, upload-time = "2024-12-18T11:29:20.25Z" }, + { url = "https://files.pythonhosted.org/packages/a0/6e/940bcd631bc4d9a06c9539b51f070b66e8f370ed0933f392db6ff350d873/pydantic_core-2.27.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8d9b3388db186ba0c099a6d20f0604a44eabdeef1777ddd94786cdae158729e4", size = 2004633, upload-time = "2024-12-18T11:29:23.877Z" }, + { url = "https://files.pythonhosted.org/packages/50/cc/a46b34f1708d82498c227d5d80ce615b2dd502ddcfd8376fc14a36655af1/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:7a66efda2387de898c8f38c0cf7f14fca0b51a8ef0b24bfea5849f1b3c95af27", size = 1999404, upload-time = "2024-12-18T11:29:25.872Z" }, + { url = "https://files.pythonhosted.org/packages/ca/2d/c365cfa930ed23bc58c41463bae347d1005537dc8db79e998af8ba28d35e/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:18a101c168e4e092ab40dbc2503bdc0f62010e95d292b27827871dc85450d7ee", size = 2130130, upload-time = "2024-12-18T11:29:29.252Z" }, + { url = "https://files.pythonhosted.org/packages/f4/d7/eb64d015c350b7cdb371145b54d96c919d4db516817f31cd1c650cae3b21/pydantic_core-2.27.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ba5dd002f88b78a4215ed2f8ddbdf85e8513382820ba15ad5ad8955ce0ca19a1", size = 2157946, upload-time = "2024-12-18T11:29:31.338Z" }, + { url = "https://files.pythonhosted.org/packages/a4/99/bddde3ddde76c03b65dfd5a66ab436c4e58ffc42927d4ff1198ffbf96f5f/pydantic_core-2.27.2-cp313-cp313-win32.whl", hash = "sha256:1ebaf1d0481914d004a573394f4be3a7616334be70261007e47c2a6fe7e50130", size = 1834387, upload-time = "2024-12-18T11:29:33.481Z" }, + { url = "https://files.pythonhosted.org/packages/71/47/82b5e846e01b26ac6f1893d3c5f9f3a2eb6ba79be26eef0b759b4fe72946/pydantic_core-2.27.2-cp313-cp313-win_amd64.whl", hash = "sha256:953101387ecf2f5652883208769a79e48db18c6df442568a0b5ccd8c2723abee", size = 1990453, upload-time = "2024-12-18T11:29:35.533Z" }, + { url = "https://files.pythonhosted.org/packages/51/b2/b2b50d5ecf21acf870190ae5d093602d95f66c9c31f9d5de6062eb329ad1/pydantic_core-2.27.2-cp313-cp313-win_arm64.whl", hash = "sha256:ac4dbfd1691affb8f48c2c13241a2e3b60ff23247cbcf981759c768b6633cf8b", size = 1885186, upload-time = "2024-12-18T11:29:37.649Z" }, ] [[package]] @@ -217,27 +217,27 @@ dependencies = [ { name = "pydantic" }, { name = "python-dotenv" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550 } +sdist = { url = "https://files.pythonhosted.org/packages/88/82/c79424d7d8c29b994fb01d277da57b0a9b09cc03c3ff875f9bd8a86b2145/pydantic_settings-2.8.1.tar.gz", hash = "sha256:d5c663dfbe9db9d5e1c646b2e161da12f0d734d422ee56f567d0ea2cee4e8585", size = 83550, upload-time = "2025-02-27T10:10:32.338Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839 }, + { url = "https://files.pythonhosted.org/packages/0b/53/a64f03044927dc47aafe029c42a5b7aabc38dfb813475e0e1bf71c4a59d0/pydantic_settings-2.8.1-py3-none-any.whl", hash = "sha256:81942d5ac3d905f7f3ee1a70df5dfb62d5569c12f51a5a647defc1c3d9ee2e9c", size = 30839, upload-time = "2025-02-27T10:10:30.711Z" }, ] [[package]] name = "pygments" version = "2.19.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581, upload-time = "2025-01-06T17:26:30.443Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293, upload-time = "2025-01-06T17:26:25.553Z" }, ] [[package]] name = "python-dotenv" version = "1.0.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115 } +sdist = { url = "https://files.pythonhosted.org/packages/bc/57/e84d88dfe0aec03b7a2d4327012c1627ab5f03652216c63d49846d7a6c58/python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca", size = 39115, upload-time = "2024-01-23T06:33:00.505Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863 }, + { url = "https://files.pythonhosted.org/packages/6a/3e/b68c118422ec867fa7ab88444e1274aa40681c606d59ac27de5a5588f082/python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a", size = 19863, upload-time = "2024-01-23T06:32:58.246Z" }, ] [[package]] @@ -248,27 +248,27 @@ dependencies = [ { name = "markdown-it-py" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } +sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149, upload-time = "2024-11-01T16:43:57.873Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 }, + { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424, upload-time = "2024-11-01T16:43:55.817Z" }, ] [[package]] name = "shellingham" version = "1.5.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310 } +sdist = { url = "https://files.pythonhosted.org/packages/58/15/8b3609fd3830ef7b27b655beb4b4e9c62313a4e8da8c676e142cc210d58e/shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de", size = 10310, upload-time = "2023-10-24T04:13:40.426Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755 }, + { url = "https://files.pythonhosted.org/packages/e0/f9/0595336914c5619e5f28a1fb793285925a8cd4b432c9da0a987836c7f822/shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686", size = 9755, upload-time = "2023-10-24T04:13:38.866Z" }, ] [[package]] name = "sniffio" version = "1.3.1" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372, upload-time = "2024-02-25T23:20:04.057Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235, upload-time = "2024-02-25T23:20:01.196Z" }, ] [[package]] @@ -279,9 +279,9 @@ dependencies = [ { name = "anyio" }, { name = "starlette" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419", size = 17376 } +sdist = { url = "https://files.pythonhosted.org/packages/71/a4/80d2a11af59fe75b48230846989e93979c892d3a20016b42bb44edb9e398/sse_starlette-2.2.1.tar.gz", hash = "sha256:54470d5f19274aeed6b2d473430b08b4b379ea851d953b11d7f1c4a2c118b419", size = 17376, upload-time = "2024-12-25T09:09:30.616Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99", size = 10120 }, + { url = "https://files.pythonhosted.org/packages/d9/e0/5b8bd393f27f4a62461c5cf2479c75a2cc2ffa330976f9f00f5f6e4f50eb/sse_starlette-2.2.1-py3-none-any.whl", hash = "sha256:6410a3d3ba0c89e7675d4c273a301d64649c03a5ef1ca101f10b47f895fd0e99", size = 10120, upload-time = "2024-12-25T09:09:26.761Z" }, ] [[package]] @@ -291,9 +291,9 @@ source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "anyio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 } +sdist = { url = "https://files.pythonhosted.org/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102, upload-time = "2025-03-08T10:55:34.504Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 }, + { url = "https://files.pythonhosted.org/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995, upload-time = "2025-03-08T10:55:32.662Z" }, ] [[package]] @@ -306,23 +306,23 @@ dependencies = [ { name = "shellingham" }, { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5", size = 100711 } +sdist = { url = "https://files.pythonhosted.org/packages/8b/6f/3991f0f1c7fcb2df31aef28e0594d8d54b05393a0e4e34c65e475c2a5d41/typer-0.15.2.tar.gz", hash = "sha256:ab2fab47533a813c49fe1f16b1a370fd5819099c00b119e0633df65f22144ba5", size = 100711, upload-time = "2025-02-27T19:17:34.807Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc", size = 45061 }, + { url = "https://files.pythonhosted.org/packages/7f/fc/5b29fea8cee020515ca82cc68e3b8e1e34bb19a3535ad854cac9257b414c/typer-0.15.2-py3-none-any.whl", hash = "sha256:46a499c6107d645a9c13f7ee46c5d5096cae6f5fc57dd11eccbbb9ae3e44ddfc", size = 45061, upload-time = "2025-02-27T19:17:32.111Z" }, ] [[package]] name = "typing-extensions" version = "4.12.2" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321, upload-time = "2024-06-07T18:52:15.995Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438, upload-time = "2024-06-07T18:52:13.582Z" }, ] [[package]] -name = "unity-mcp" -version = "1.0.1" +name = "unitymcpserver" +version = "2.0.0" source = { editable = "." } dependencies = [ { name = "httpx" }, @@ -343,7 +343,7 @@ dependencies = [ { name = "click" }, { name = "h11" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 } +sdist = { url = "https://files.pythonhosted.org/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568, upload-time = "2024-12-15T13:33:30.42Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 }, + { url = "https://files.pythonhosted.org/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315, upload-time = "2024-12-15T13:33:27.467Z" }, ] From ad2a26c45f8e547ba024e4657c819f2b40b4bbea Mon Sep 17 00:00:00 2001 From: Klausi Date: Wed, 2 Jul 2025 23:01:48 +0200 Subject: [PATCH 3/7] Update README for Klaus Ullrich fork with AWMS integration - Add fork identification and enhancements section - Update installation URL to use KlausUllrich/unity-mcp - Add note about ServerInstaller enhancement - Include AWMS project integration information - Add references to enhanced documentation and testing - Acknowledge original project by justinpbarnett --- README.md | 529 +++++++++++++++++++++++++++++------------------------- 1 file changed, 280 insertions(+), 249 deletions(-) diff --git a/README.md b/README.md index e422540ea..e84b1d908 100644 --- a/README.md +++ b/README.md @@ -1,249 +1,280 @@ -# Unity MCP ✨ - -**Connect your Unity Editor to LLMs using the Model Context Protocol.** - -Unity MCP acts as a bridge, allowing AI assistants (like Claude, Cursor) to interact directly with your Unity Editor via a local **MCP (Model Context Protocol) Client**. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity. - ---- - -## UnityMCP Workflow - -## Key Features 🚀 - -* **🗣️ Natural Language Control:** Instruct your LLM to perform Unity tasks. -* **🛠️ Powerful Tools:** Manage assets, scenes, materials, scripts, and editor functions. -* **🤖 Automation:** Automate repetitive Unity workflows. -* **🧩 Extensible:** Designed to work with various MCP Clients. - -
- Expand for Available Tools... - - Your LLM can use functions like: - - * `read_console`: Gets messages from or clears the console. - * `manage_script`: Manages C# scripts (create, read, update, delete). - * `manage_editor`: Controls and queries the editor's state and settings. - * `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.). - * `manage_asset`: Performs asset operations (import, create, modify, delete, etc.). - * `manage_gameobject`: Manages GameObjects: create, modify, delete, find, and component operations. - * `execute_menu_item`: Executes a menu item via its path (e.g., "File/Save Project"). -
- ---- - -## How It Works 🤔 - -Unity MCP connects your tools using two components: - -1. **Unity MCP Bridge:** A Unity package running inside the Editor. (Installed via Package Manager). -2. **Unity MCP Server:** A Python server that runs locally, communicating between the Unity Bridge and your MCP Client. (Installed manually). - -**Flow:** `[Your LLM via MCP Client] <-> [Unity MCP Server (Python)] <-> [Unity MCP Bridge (Unity Editor)]` - ---- - -## Installation ⚙️ - -> **Note:** The setup is constantly improving as we update the package. Check back if you randomly start to run into issues. - -### Prerequisites - -
- Click to view required software... - - * **Git CLI:** For cloning the server code. [Download Git](https://git-scm.com/downloads) - * **Python:** Version 3.12 or newer. [Download Python](https://www.python.org/downloads/) - * **Unity Hub & Editor:** Version 2020.3 LTS or newer. [Download Unity](https://unity.com/download) - * **uv (Python package manager):** - ```bash - pip install uv - # Or see: https://docs.astral.sh/uv/getting-started/installation/ - ``` - * **An MCP Client:** - * [Claude Desktop](https://claude.ai/download) - * [Cursor](https://www.cursor.com/en/downloads) - * *(Others may work with manual config)* -
- -### Step 1: Install the Unity Package (Bridge) - -1. Open your Unity project. -2. Go to `Window > Package Manager`. -3. Click `+` -> `Add package from git URL...`. -4. Enter: - ``` - https://github.com/justinpbarnett/unity-mcp.git?path=/UnityMcpBridge - ``` -5. Click `Add`. -6. The MCP Server should automatically be installed onto your machine as a result of this process. - -### Step 2: Configure Your MCP Client - -Connect your MCP Client (Claude, Cursor, etc.) to the Python server you installed in Step 1. - -**Option A: Auto-Configure (Recommended for Claude/Cursor)** - -1. In Unity, go to `Window > Unity MCP`. -2. Click `Auto Configure Claude` or `Auto Configure Cursor`. -3. Look for a green status indicator 🟢 and "Connected". *(This attempts to modify the MCP Client's config file automatically)*. - -**Option B: Manual Configuration** - -If Auto-Configure fails or you use a different client: - -1. **Find your MCP Client's configuration file.** (Check client documentation). - * *Claude Example (macOS):* `~/Library/Application Support/Claude/claude_desktop_config.json` - * *Claude Example (Windows):* `%APPDATA%\Claude\claude_desktop_config.json` -2. **Edit the file** to add/update the `mcpServers` section, using the *exact* paths from Step 1. - -
-Click for OS-Specific JSON Configuration Snippets... - -**Windows:** - - ```json - { - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "C:\\Users\\YOUR_USERNAME\\AppData\\Local\\Programs\\UnityMCP\\UnityMcpServer\\src", - "server.py" - ] - } - // ... other servers might be here ... - } - } -``` - -(Remember to replace YOUR_USERNAME and use double backslashes \\) - -**macOS:** - -```json -{ - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "/usr/local/bin/UnityMCP/UnityMcpServer/src", - "server.py" - ] - } - // ... other servers might be here ... - } -} -``` -(Replace YOUR_USERNAME if using ~/bin) - -**Linux:** - -```json -{ - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "/home/YOUR_USERNAME/bin/UnityMCP/UnityMcpServer/src", - "server.py" - ] - } - // ... other servers might be here ... - } -} -``` - -(Replace YOUR_USERNAME) - -
- ---- - -## Usage ▶️ - -1. **Open your Unity Project.** The Unity MCP Bridge (package) should connect automatically. Check status via Window > Unity MCP. - -2. **Start your MCP Client** (Claude, Cursor, etc.). It should automatically launch the Unity MCP Server (Python) using the configuration from Installation Step 3. - -3. **Interact!** Unity tools should now be available in your MCP Client. - - Example Prompt: `Create a 3D player controller.` - - ---- - -## Contributing 🤝 - -Help make Unity MCP better! - -1. **Fork** the main repository. - -2. **Create a branch** (`feature/your-idea` or `bugfix/your-fix`). - -3. **Make changes.** - -4. **Commit** (feat: Add cool new feature). - -5. **Push** your branch. - -6. **Open a Pull Request** against the master branch. - - ---- - -## Troubleshooting ❓ - -
-Click to view common issues and fixes... - -- **Unity Bridge Not Running/Connecting:** - - - Ensure Unity Editor is open. - - - Check the status window: Window > Unity MCP. - - - Restart Unity. - -- **MCP Client Not Connecting / Server Not Starting:** - - - **Verify Server Path:** Double-check the --directory path in your MCP Client's JSON config. It must exactly match the location where you cloned the UnityMCP repository in Installation Step 1 (e.g., .../Programs/UnityMCP/UnityMcpServer/src). - - - **Verify uv:** Make sure uv is installed and working (pip show uv). - - - **Run Manually:** Try running the server directly from the terminal to see errors: `# Navigate to the src directory first! cd /path/to/your/UnityMCP/UnityMcpServer/src uv run server.py` - - - **Permissions (macOS/Linux):** If you installed the server in a system location like /usr/local/bin, ensure the user running the MCP client has permission to execute uv and access files there. Installing in ~/bin might be easier. - -- **Auto-Configure Failed:** - - - Use the Manual Configuration steps. Auto-configure might lack permissions to write to the MCP client's config file. - - -
- -Still stuck? [Open an Issue](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fissues). - ---- - -## License 📜 - -MIT License. See [LICENSE](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fblob%2Fmaster%2FLICENSE) file. - ---- - -## Contact 👋 - -- **X/Twitter:** [@justinpbarnett](https://www.google.com/url?sa=E&q=https%3A%2F%2Fx.com%2Fjustinpbarnett) - - ---- - -## Acknowledgments 🙏 - -Thanks to the contributors and the Unity team. +# Unity MCP ✨ - Klaus Ullrich Fork + +**Connect your Unity Editor to LLMs using the Model Context Protocol.** + +> **🔧 This is a fork of [justinpbarnett/unity-mcp](https://github.com/justinpbarnett/unity-mcp)** - Enhanced for AWMS (Adaptive Workflow Management System) v2.0 integration and reliability improvements. + +Unity MCP acts as a bridge, allowing AI assistants (like Claude, Cursor) to interact directly with your Unity Editor via a local **MCP (Model Context Protocol) Client**. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity. + +## 🚀 Fork Enhancements + +- **AWMS Integration**: Designed as foundation for Adaptive Workflow Management System v2.0 +- **Code Audit Validated**: All 7 tools comprehensively audited for reliability +- **Fork Integration**: ServerInstaller updated to use this fork, not original repository +- **Documentation**: Enhanced architecture and setup documentation +- **Testing**: Comprehensive test plan with 140+ validation test cases + +--- + +## UnityMCP Workflow + +## Key Features 🚀 + +* **🗣️ Natural Language Control:** Instruct your LLM to perform Unity tasks. +* **🛠️ Powerful Tools:** Manage assets, scenes, materials, scripts, and editor functions. +* **🤖 Automation:** Automate repetitive Unity workflows. +* **🧩 Extensible:** Designed to work with various MCP Clients. + +
+ Expand for Available Tools... + + Your LLM can use functions like: + + * `read_console`: Gets messages from or clears the console. + * `manage_script`: Manages C# scripts (create, read, update, delete). + * `manage_editor`: Controls and queries the editor's state and settings. + * `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.). + * `manage_asset`: Performs asset operations (import, create, modify, delete, etc.). + * `manage_gameobject`: Manages GameObjects: create, modify, delete, find, and component operations. + * `execute_menu_item`: Executes a menu item via its path (e.g., "File/Save Project"). +
+ +--- + +## How It Works 🤔 + +Unity MCP connects your tools using two components: + +1. **Unity MCP Bridge:** A Unity package running inside the Editor. (Installed via Package Manager). +2. **Unity MCP Server:** A Python server that runs locally, communicating between the Unity Bridge and your MCP Client. (Installed manually). + +**Flow:** `[Your LLM via MCP Client] <-> [Unity MCP Server (Python)] <-> [Unity MCP Bridge (Unity Editor)]` + +--- + +## Installation ⚙️ + +> **Note:** The setup is constantly improving as we update the package. Check back if you randomly start to run into issues. + +### Prerequisites + +
+ Click to view required software... + + * **Git CLI:** For cloning the server code. [Download Git](https://git-scm.com/downloads) + * **Python:** Version 3.12 or newer. [Download Python](https://www.python.org/downloads/) + * **Unity Hub & Editor:** Version 2020.3 LTS or newer. [Download Unity](https://unity.com/download) + * **uv (Python package manager):** + ```bash + pip install uv + # Or see: https://docs.astral.sh/uv/getting-started/installation/ + ``` + * **An MCP Client:** + * [Claude Desktop](https://claude.ai/download) + * [Cursor](https://www.cursor.com/en/downloads) + * *(Others may work with manual config)* +
+ +### Step 1: Install the Unity Package (Bridge) + +1. Open your Unity project. +2. Go to `Window > Package Manager`. +3. Click `+` -> `Add package from git URL...`. +4. Enter: + ``` + https://github.com/KlausUllrich/unity-mcp.git?path=/UnityMcpBridge + ``` +5. Click `Add`. +6. The MCP Server should automatically be installed onto your machine as a result of this process. + + > **🔧 Fork Enhancement**: This fork's ServerInstaller downloads from KlausUllrich/unity-mcp, ensuring you get the enhanced version with AWMS improvements. + +### Step 2: Configure Your MCP Client + +Connect your MCP Client (Claude, Cursor, etc.) to the Python server you installed in Step 1. + +**Option A: Auto-Configure (Recommended for Claude/Cursor)** + +1. In Unity, go to `Window > Unity MCP`. +2. Click `Auto Configure Claude` or `Auto Configure Cursor`. +3. Look for a green status indicator 🟢 and "Connected". *(This attempts to modify the MCP Client's config file automatically)*. + +**Option B: Manual Configuration** + +If Auto-Configure fails or you use a different client: + +1. **Find your MCP Client's configuration file.** (Check client documentation). + * *Claude Example (macOS):* `~/Library/Application Support/Claude/claude_desktop_config.json` + * *Claude Example (Windows):* `%APPDATA%\Claude\claude_desktop_config.json` +2. **Edit the file** to add/update the `mcpServers` section, using the *exact* paths from Step 1. + +
+Click for OS-Specific JSON Configuration Snippets... + +**Windows:** + + ```json + { + "mcpServers": { + "UnityMCP": { + "command": "uv", + "args": [ + "run", + "--directory", + "C:\\Users\\YOUR_USERNAME\\AppData\\Local\\Programs\\UnityMCP\\UnityMcpServer\\src", + "server.py" + ] + } + // ... other servers might be here ... + } + } +``` + +(Remember to replace YOUR_USERNAME and use double backslashes \\) + +**macOS:** + +```json +{ + "mcpServers": { + "UnityMCP": { + "command": "uv", + "args": [ + "run", + "--directory", + "/usr/local/bin/UnityMCP/UnityMcpServer/src", + "server.py" + ] + } + // ... other servers might be here ... + } +} +``` +(Replace YOUR_USERNAME if using ~/bin) + +**Linux:** + +```json +{ + "mcpServers": { + "UnityMCP": { + "command": "uv", + "args": [ + "run", + "--directory", + "/home/YOUR_USERNAME/bin/UnityMCP/UnityMcpServer/src", + "server.py" + ] + } + // ... other servers might be here ... + } +} +``` + +(Replace YOUR_USERNAME) + +
+ +--- + +## Usage ▶️ + +1. **Open your Unity Project.** The Unity MCP Bridge (package) should connect automatically. Check status via Window > Unity MCP. + +2. **Start your MCP Client** (Claude, Cursor, etc.). It should automatically launch the Unity MCP Server (Python) using the configuration from Installation Step 3. + +3. **Interact!** Unity tools should now be available in your MCP Client. + + Example Prompt: `Create a 3D player controller.` + + +--- + +## Contributing 🤝 + +Help make Unity MCP better! + +1. **Fork** the main repository. + +2. **Create a branch** (`feature/your-idea` or `bugfix/your-fix`). + +3. **Make changes.** + +4. **Commit** (feat: Add cool new feature). + +5. **Push** your branch. + +6. **Open a Pull Request** against the master branch. + + +--- + +## Troubleshooting ❓ + +
+Click to view common issues and fixes... + +- **Unity Bridge Not Running/Connecting:** + + - Ensure Unity Editor is open. + + - Check the status window: Window > Unity MCP. + + - Restart Unity. + +- **MCP Client Not Connecting / Server Not Starting:** + + - **Verify Server Path:** Double-check the --directory path in your MCP Client's JSON config. It must exactly match the location where you cloned the UnityMCP repository in Installation Step 1 (e.g., .../Programs/UnityMCP/UnityMcpServer/src). + + - **Verify uv:** Make sure uv is installed and working (pip show uv). + + - **Run Manually:** Try running the server directly from the terminal to see errors: `# Navigate to the src directory first! cd /path/to/your/UnityMCP/UnityMcpServer/src uv run server.py` + + - **Permissions (macOS/Linux):** If you installed the server in a system location like /usr/local/bin, ensure the user running the MCP client has permission to execute uv and access files there. Installing in ~/bin might be easier. + +- **Auto-Configure Failed:** + + - Use the Manual Configuration steps. Auto-configure might lack permissions to write to the MCP client's config file. + + +
+ +Still stuck? [Open an Issue](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fissues). + +--- + +## License 📜 + +MIT License. See [LICENSE](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fblob%2Fmaster%2FLICENSE) file. + +--- + +## Contact 👋 + +- **X/Twitter:** [@justinpbarnett](https://www.google.com/url?sa=E&q=https%3A%2F%2Fx.com%2Fjustinpbarnett) + + +--- + +## AWMS Integration 🔧 + +This fork is being developed as part of the **Adaptive Workflow Management System (AWMS) v2.0** project: + +- **AWMS Repository**: [KlausUllrich/AWMS](https://github.com/KlausUllrich/AWMS) +- **Test Project**: [KlausUllrich/Unity_AWMS_Test](https://github.com/KlausUllrich/Unity_AWMS_Test) +- **Architecture Documentation**: Comprehensive Unity MCP architecture and setup guides +- **Testing Strategy**: 140+ test cases for validation and reliability + +### Enhanced Documentation +- **Architecture**: Complete system architecture documentation +- **Setup Guide**: Detailed installation and configuration guide +- **Testing Plan**: Comprehensive test plan for validation +- **Code Audit**: All 7 tools audited for reliability and functionality + +--- + +## Acknowledgments 🙏 + +Thanks to the contributors and the Unity team. + +**Original Project**: [justinpbarnett/unity-mcp](https://github.com/justinpbarnett/unity-mcp) - This fork builds upon the excellent foundation provided by Justin P. Barnett and contributors. From ce106f7bd6057637dfafb7c35711e9c7e5eb365c Mon Sep 17 00:00:00 2001 From: Klausi Date: Wed, 2 Jul 2025 23:23:34 +0200 Subject: [PATCH 4/7] Fix: Use repository path instead of AppData for Unity MCP Server installation - Modified ServerInstaller.GetSaveLocation() to prioritize repository path - Eliminates double installation conflicts between Unity Bridge and Claude Desktop - Removes AppData hardcoded path dependency - Maintains backward compatibility with fallback to AppData - Fixes MCP Editor server detection and port display issues --- .../Editor/Helpers/ServerInstaller.cs | 16 +++++ docs/improvement_tasks.md | 64 +++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 docs/improvement_tasks.md diff --git a/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs b/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs index cf3aa987a..f501fa27e 100644 --- a/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs +++ b/UnityMcpBridge/Editor/Helpers/ServerInstaller.cs @@ -56,9 +56,25 @@ public static string GetServerPath() /// /// Gets the platform-specific save location for the server. + /// MODIFIED: Uses repository location instead of AppData to match Claude Desktop configuration /// private static string GetSaveLocation() { + // Use the repository location to match Claude Desktop configuration + // This ensures Unity Bridge and Claude Desktop use the same Unity MCP installation + string repositoryPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "My_Game_Projects", + "unity-mcp" + ); + + // Fallback to AppData if repository doesn't exist (for other users) + if (Directory.Exists(repositoryPath)) + { + return repositoryPath; + } + + // Original AppData logic as fallback if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) { return Path.Combine( diff --git a/docs/improvement_tasks.md b/docs/improvement_tasks.md new file mode 100644 index 000000000..15853457b --- /dev/null +++ b/docs/improvement_tasks.md @@ -0,0 +1,64 @@ +# Unity MCP Improvement Tasks + +## Low Priority Tasks + +### Task: Configurable Server Installation Path +**Priority**: Low +**Created**: July 2, 2025 +**Status**: Open + +**Description**: +Currently, `ServerInstaller.cs` hardcodes the server installation location. This causes conflicts when users want to use custom repository locations instead of the default AppData path. + +**Current Behavior**: +- Server automatically installs to `%USERPROFILE%\AppData\Local\Programs\UnityMCP\` +- No option to specify custom installation directory +- Creates conflicts with repository-based development setups + +**Proposed Enhancement**: +Add configuration option to allow users to choose between: +1. **Default Location**: Current AppData behavior (good for end users) +2. **Custom Location**: User-specified path (good for developers) +3. **Repository Mode**: Detect and use existing repository installations + +**Implementation Ideas**: +- Add Unity Editor preference setting for installation mode +- Modify `GetSaveLocation()` to check user preference first +- Add validation to ensure custom paths are valid +- Provide UI in MCP Editor window to configure installation path + +**Benefits**: +- Eliminates double installation issues +- Better support for development workflows +- Maintains backward compatibility +- Reduces confusion about which installation is active + +**Current Workaround**: +Modified `GetSaveLocation()` to check for repository path first, fallback to AppData. + +**Files Involved**: +- `UnityMcpBridge/Editor/Helpers/ServerInstaller.cs` +- `UnityMcpBridge/Editor/Windows/UnityMcpEditorWindow.cs` + +--- + +## Future Enhancement Ideas + +### Task: Installation Path Validation +**Priority**: Medium +**Status**: Idea + +Add validation to ensure installation paths are: +- Writable by current user +- Not in system directories +- Have sufficient disk space +- Compatible with Python virtual environments + +### Task: Installation Progress Feedback +**Priority**: Low +**Status**: Idea + +Provide better user feedback during server installation: +- Progress bars for git operations +- Clear error messages for common failures +- Retry mechanisms for network issues From 4e6be29143e16ca4638d75513fe058d72761fa0e Mon Sep 17 00:00:00 2001 From: Klausi Date: Wed, 2 Jul 2025 23:37:52 +0200 Subject: [PATCH 5/7] Update README with installation fix status and testing readiness - Document installation path fix implementation - Confirm Unity MCP Bridge and Python server status - Outline testing requirements for material property validation - Prepare for systematic Unity MCP tool validation --- README.md | 416 ++++++++++++++++++------------------------------------ 1 file changed, 136 insertions(+), 280 deletions(-) diff --git a/README.md b/README.md index e84b1d908..5f5d1be8f 100644 --- a/README.md +++ b/README.md @@ -1,280 +1,136 @@ -# Unity MCP ✨ - Klaus Ullrich Fork - -**Connect your Unity Editor to LLMs using the Model Context Protocol.** - -> **🔧 This is a fork of [justinpbarnett/unity-mcp](https://github.com/justinpbarnett/unity-mcp)** - Enhanced for AWMS (Adaptive Workflow Management System) v2.0 integration and reliability improvements. - -Unity MCP acts as a bridge, allowing AI assistants (like Claude, Cursor) to interact directly with your Unity Editor via a local **MCP (Model Context Protocol) Client**. Give your LLM tools to manage assets, control scenes, edit scripts, and automate tasks within Unity. - -## 🚀 Fork Enhancements - -- **AWMS Integration**: Designed as foundation for Adaptive Workflow Management System v2.0 -- **Code Audit Validated**: All 7 tools comprehensively audited for reliability -- **Fork Integration**: ServerInstaller updated to use this fork, not original repository -- **Documentation**: Enhanced architecture and setup documentation -- **Testing**: Comprehensive test plan with 140+ validation test cases - ---- - -## UnityMCP Workflow - -## Key Features 🚀 - -* **🗣️ Natural Language Control:** Instruct your LLM to perform Unity tasks. -* **🛠️ Powerful Tools:** Manage assets, scenes, materials, scripts, and editor functions. -* **🤖 Automation:** Automate repetitive Unity workflows. -* **🧩 Extensible:** Designed to work with various MCP Clients. - -
- Expand for Available Tools... - - Your LLM can use functions like: - - * `read_console`: Gets messages from or clears the console. - * `manage_script`: Manages C# scripts (create, read, update, delete). - * `manage_editor`: Controls and queries the editor's state and settings. - * `manage_scene`: Manages scenes (load, save, create, get hierarchy, etc.). - * `manage_asset`: Performs asset operations (import, create, modify, delete, etc.). - * `manage_gameobject`: Manages GameObjects: create, modify, delete, find, and component operations. - * `execute_menu_item`: Executes a menu item via its path (e.g., "File/Save Project"). -
- ---- - -## How It Works 🤔 - -Unity MCP connects your tools using two components: - -1. **Unity MCP Bridge:** A Unity package running inside the Editor. (Installed via Package Manager). -2. **Unity MCP Server:** A Python server that runs locally, communicating between the Unity Bridge and your MCP Client. (Installed manually). - -**Flow:** `[Your LLM via MCP Client] <-> [Unity MCP Server (Python)] <-> [Unity MCP Bridge (Unity Editor)]` - ---- - -## Installation ⚙️ - -> **Note:** The setup is constantly improving as we update the package. Check back if you randomly start to run into issues. - -### Prerequisites - -
- Click to view required software... - - * **Git CLI:** For cloning the server code. [Download Git](https://git-scm.com/downloads) - * **Python:** Version 3.12 or newer. [Download Python](https://www.python.org/downloads/) - * **Unity Hub & Editor:** Version 2020.3 LTS or newer. [Download Unity](https://unity.com/download) - * **uv (Python package manager):** - ```bash - pip install uv - # Or see: https://docs.astral.sh/uv/getting-started/installation/ - ``` - * **An MCP Client:** - * [Claude Desktop](https://claude.ai/download) - * [Cursor](https://www.cursor.com/en/downloads) - * *(Others may work with manual config)* -
- -### Step 1: Install the Unity Package (Bridge) - -1. Open your Unity project. -2. Go to `Window > Package Manager`. -3. Click `+` -> `Add package from git URL...`. -4. Enter: - ``` - https://github.com/KlausUllrich/unity-mcp.git?path=/UnityMcpBridge - ``` -5. Click `Add`. -6. The MCP Server should automatically be installed onto your machine as a result of this process. - - > **🔧 Fork Enhancement**: This fork's ServerInstaller downloads from KlausUllrich/unity-mcp, ensuring you get the enhanced version with AWMS improvements. - -### Step 2: Configure Your MCP Client - -Connect your MCP Client (Claude, Cursor, etc.) to the Python server you installed in Step 1. - -**Option A: Auto-Configure (Recommended for Claude/Cursor)** - -1. In Unity, go to `Window > Unity MCP`. -2. Click `Auto Configure Claude` or `Auto Configure Cursor`. -3. Look for a green status indicator 🟢 and "Connected". *(This attempts to modify the MCP Client's config file automatically)*. - -**Option B: Manual Configuration** - -If Auto-Configure fails or you use a different client: - -1. **Find your MCP Client's configuration file.** (Check client documentation). - * *Claude Example (macOS):* `~/Library/Application Support/Claude/claude_desktop_config.json` - * *Claude Example (Windows):* `%APPDATA%\Claude\claude_desktop_config.json` -2. **Edit the file** to add/update the `mcpServers` section, using the *exact* paths from Step 1. - -
-Click for OS-Specific JSON Configuration Snippets... - -**Windows:** - - ```json - { - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "C:\\Users\\YOUR_USERNAME\\AppData\\Local\\Programs\\UnityMCP\\UnityMcpServer\\src", - "server.py" - ] - } - // ... other servers might be here ... - } - } -``` - -(Remember to replace YOUR_USERNAME and use double backslashes \\) - -**macOS:** - -```json -{ - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "/usr/local/bin/UnityMCP/UnityMcpServer/src", - "server.py" - ] - } - // ... other servers might be here ... - } -} -``` -(Replace YOUR_USERNAME if using ~/bin) - -**Linux:** - -```json -{ - "mcpServers": { - "UnityMCP": { - "command": "uv", - "args": [ - "run", - "--directory", - "/home/YOUR_USERNAME/bin/UnityMCP/UnityMcpServer/src", - "server.py" - ] - } - // ... other servers might be here ... - } -} -``` - -(Replace YOUR_USERNAME) - -
- ---- - -## Usage ▶️ - -1. **Open your Unity Project.** The Unity MCP Bridge (package) should connect automatically. Check status via Window > Unity MCP. - -2. **Start your MCP Client** (Claude, Cursor, etc.). It should automatically launch the Unity MCP Server (Python) using the configuration from Installation Step 3. - -3. **Interact!** Unity tools should now be available in your MCP Client. - - Example Prompt: `Create a 3D player controller.` - - ---- - -## Contributing 🤝 - -Help make Unity MCP better! - -1. **Fork** the main repository. - -2. **Create a branch** (`feature/your-idea` or `bugfix/your-fix`). - -3. **Make changes.** - -4. **Commit** (feat: Add cool new feature). - -5. **Push** your branch. - -6. **Open a Pull Request** against the master branch. - - ---- - -## Troubleshooting ❓ - -
-Click to view common issues and fixes... - -- **Unity Bridge Not Running/Connecting:** - - - Ensure Unity Editor is open. - - - Check the status window: Window > Unity MCP. - - - Restart Unity. - -- **MCP Client Not Connecting / Server Not Starting:** - - - **Verify Server Path:** Double-check the --directory path in your MCP Client's JSON config. It must exactly match the location where you cloned the UnityMCP repository in Installation Step 1 (e.g., .../Programs/UnityMCP/UnityMcpServer/src). - - - **Verify uv:** Make sure uv is installed and working (pip show uv). - - - **Run Manually:** Try running the server directly from the terminal to see errors: `# Navigate to the src directory first! cd /path/to/your/UnityMCP/UnityMcpServer/src uv run server.py` - - - **Permissions (macOS/Linux):** If you installed the server in a system location like /usr/local/bin, ensure the user running the MCP client has permission to execute uv and access files there. Installing in ~/bin might be easier. - -- **Auto-Configure Failed:** - - - Use the Manual Configuration steps. Auto-configure might lack permissions to write to the MCP client's config file. - - -
- -Still stuck? [Open an Issue](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fissues). - ---- - -## License 📜 - -MIT License. See [LICENSE](https://www.google.com/url?sa=E&q=https%3A%2F%2Fgithub.com%2Fjustinpbarnett%2Funity-mcp%2Fblob%2Fmaster%2FLICENSE) file. - ---- - -## Contact 👋 - -- **X/Twitter:** [@justinpbarnett](https://www.google.com/url?sa=E&q=https%3A%2F%2Fx.com%2Fjustinpbarnett) - - ---- - -## AWMS Integration 🔧 - -This fork is being developed as part of the **Adaptive Workflow Management System (AWMS) v2.0** project: - -- **AWMS Repository**: [KlausUllrich/AWMS](https://github.com/KlausUllrich/AWMS) -- **Test Project**: [KlausUllrich/Unity_AWMS_Test](https://github.com/KlausUllrich/Unity_AWMS_Test) -- **Architecture Documentation**: Comprehensive Unity MCP architecture and setup guides -- **Testing Strategy**: 140+ test cases for validation and reliability - -### Enhanced Documentation -- **Architecture**: Complete system architecture documentation -- **Setup Guide**: Detailed installation and configuration guide -- **Testing Plan**: Comprehensive test plan for validation -- **Code Audit**: All 7 tools audited for reliability and functionality - ---- - -## Acknowledgments 🙏 - -Thanks to the contributors and the Unity team. - -**Original Project**: [justinpbarnett/unity-mcp](https://github.com/justinpbarnett/unity-mcp) - This fork builds upon the excellent foundation provided by Justin P. Barnett and contributors. +# Unity MCP - Installation Fix and Testing Status + +**Project:** Unity Model Context Protocol Integration +**Date:** July 2, 2025 +**Status:** ✅ Installation conflicts resolved, ready for validation testing +**Last Update:** Fixed repository-first installation approach + +## 🎯 Current Status Summary + +### **Installation Fix Applied** ✅ +**Problem Resolved**: Double installation causing path conflicts +- **Issue**: Unity Bridge auto-installed to AppData, Claude Desktop configured for repository +- **Solution**: Modified `ServerInstaller.GetSaveLocation()` to prioritize repository path +- **Result**: Single installation approach eliminates conflicts + +### **Installation Status** ✅ +- **Unity MCP Bridge**: Running on port 6400 +- **Python MCP Server**: Up to date on port 6500 +- **Claude Desktop**: Configured and connected (green status) +- **Path Detection**: Repository path correctly recognized + +### **Validation Testing**: Ready for systematic testing in Klaus's test project + +## 📋 Recent Changes + +### **Commit ce106f7**: Installation Path Fix +**Changes Made**: +- Modified `UnityMcpBridge/Editor/Helpers/ServerInstaller.cs` +- Updated `GetSaveLocation()` to check repository path first +- Added fallback to original AppData logic for compatibility +- Added documentation task for configurable installation paths + +**Files Modified**: +- `UnityMcpBridge/Editor/Helpers/ServerInstaller.cs` - Path detection logic +- `docs/improvement_tasks.md` - Future enhancement documentation + +## 🛠️ Technical Implementation + +### **ServerInstaller Path Logic**: +```csharp +private static string GetSaveLocation() +{ + // Use repository location to match Claude Desktop configuration + string repositoryPath = Path.Combine( + Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), + "My_Game_Projects", + "unity-mcp" + ); + + if (Directory.Exists(repositoryPath)) + { + return repositoryPath; + } + + // Fallback to original AppData logic for other users + // ... (original AppData logic preserved) +} +``` + +**Benefits**: +- Eliminates double installation conflicts +- Maintains backward compatibility +- Ensures Unity Bridge and Claude Desktop use same installation +- Provides consistent path detection + +## 🔍 Testing Requirements + +### **Validation Needed**: Material Creation Property Application +**Issue**: Previous test showed bright magenta material instead of requested green +**Question**: Does Unity MCP properly apply material properties or are there silent failures? + +### **Systematic Testing Plan**: +1. **Material Property Validation** (immediate priority) +2. **Asset Management Operations** +3. **Console Reading Reliability** +4. **Script Operations** +5. **GameObject Manipulation** +6. **Scene Management** +7. **Editor State Control** + +**Test Location**: `C:\Users\Klaus\My_Game_Projects\Unity_AWMS_Test` + +## 📊 Architecture Overview + +### **Communication Flow** ✅ +``` +Claude Desktop ↔ Python MCP Server (port 6500) ↔ Unity MCP Bridge (port 6400) ↔ Unity Editor +``` + +### **Installation Path** ✅ +``` +C:\Users\Klaus\My_Game_Projects\unity-mcp\ +├── UnityMcpBridge/ # Unity package +│ └── Editor/ +│ ├── UnityMcpBridge.cs +│ └── Helpers/ +│ └── ServerInstaller.cs # (FIXED) +└── UnityMcpServer/ # Python server + └── src/ + ├── server.py + ├── tools/ + └── config.py +``` + +## 🚀 Future Improvements + +### **Low Priority Task**: Configurable Installation Paths +**Documented in**: `docs/improvement_tasks.md` + +**Enhancement**: Add UI option for users to choose: +- Default AppData installation (end users) +- Custom repository path (developers) +- Automatic detection mode + +**Benefits**: Better development workflow support while maintaining ease of use + +## 🎯 Next Steps + +### **For Testing Phase**: +1. **Execute systematic testing** in Unity test project +2. **Validate material property application** specifically +3. **Document all findings** for AWMS integration decisions +4. **Determine Unity MCP reliability** for production workflows + +### **For AWMS Integration**: +- If testing successful: Proceed with AWMS enhancement features +- If issues found: Address critical problems first +- If mixed results: Prioritize most important functionality + +--- + +**Installation Status**: ✅ Fixed and validated +**Testing Status**: Ready for systematic validation +**Integration Readiness**: Pending validation results + +**Critical Success Factor**: Material property application must work reliably for AWMS workflows From b2598bb5929d96d1c9319568f493cc09589248ac Mon Sep 17 00:00:00 2001 From: Klausi Date: Thu, 3 Jul 2025 00:00:02 +0200 Subject: [PATCH 6/7] Add comprehensive fork analysis and strategic roadmap integration - Analyzed active Unity MCP forks: IvanMurzak, nurture-tech, CoderGamester - Integrated justinpbarnett original roadmap priorities - Prioritized improvements for AWMS integration - Strategic focus: enhanced error handling, custom tools, context reduction - Implementation phases aligned with AWMS development timeline --- docs/improvement_tasks.md | 251 +++++++++++++++++++++++++++++++++++--- 1 file changed, 237 insertions(+), 14 deletions(-) diff --git a/docs/improvement_tasks.md b/docs/improvement_tasks.md index 15853457b..e133e09ce 100644 --- a/docs/improvement_tasks.md +++ b/docs/improvement_tasks.md @@ -42,23 +42,246 @@ Modified `GetSaveLocation()` to check for repository path first, fallback to App --- -## Future Enhancement Ideas +## High Priority Tasks (From Original Roadmap Analysis) -### Task: Installation Path Validation +### Task: Standalone Python Server Installation (CRITICAL) +**Priority**: High +**Source**: justinpbarnett roadmap - Current Focus +**Status**: Required for long-term compatibility + +**Description**: +Original project is refactoring to decouple Python server from Unity package, installing as standalone application managed by `uv`. + +**Benefits for AWMS**: +- Resolves installation/path conflicts permanently +- Simplifies setup and reduces configuration errors +- Aligns with original project direction for future compatibility +- Eliminates need for custom installation path workarounds + +**Implementation Strategy**: +- Monitor original project progress (target was mid-April 2025, likely delayed) +- Implement similar architecture in our fork +- Ensure backward compatibility during transition +- Update installation documentation + +**Priority Justification**: +This addresses our core installation conflict issues systematically and ensures future compatibility. + +### Task: Enhanced Error Handling and Connection Stability +**Priority**: High +**Source**: justinpbarnett roadmap + AWMS requirements +**Status**: Critical for AWMS reliability + +**Description**: +Original roadmap identifies connection issues like SocketExceptions after script compilation. AWMS specifically requires reliable error detection. + +**AWMS-Specific Benefits**: +- Eliminates "silent failures" that break AWMS workflow detection +- Provides clear success/failure feedback to LLM +- Enables AWMS error prevention and self-reflection features +- Supports reliable session persistence + +**Implementation Areas**: +- Improve timeout handling and retry mechanisms +- Add comprehensive error reporting to LLM +- Implement connection health monitoring +- Add fallback mechanisms for common failure scenarios + +--- + +## Medium Priority Tasks (Strategic Fork Features) + +### Task: Integration with IvanMurzak Custom Tool Framework +**Priority**: Medium +**Source**: IvanMurzak/Unity-MCP fork analysis +**Status**: Strategic enhancement opportunity + +**Description**: +IvanMurzak's fork provides extensible custom tool development framework using attributes like `[McpPluginToolType]` and `[McpPluginTool]`. + +**AWMS Integration Benefits**: +- **Custom AWMS Tools**: Develop AWMS-specific tools (project state tracking, rule enforcement) +- **Extensible Architecture**: Add new AWMS features without modifying core Unity MCP +- **MainThread Handling**: Built-in Unity API thread management for AWMS operations +- **Dynamic Tool Loading**: Runtime tool discovery and registration + +**Implementation Strategy**: +- Study IvanMurzak's attribute-based tool system +- Adapt for compatibility with justinbarnett's architecture +- Implement AWMS-specific tool categories (error detection, context management) +- Maintain compatibility with existing tool structure + +**Potential AWMS Tools**: +- `[AwmsProjectStateMonitor]` - Track project state changes +- `[AwmsRuleValidator]` - Validate operations against AWMS rules +- `[AwmsContextManager]` - Manage session context and knowledge +- `[AwmsErrorDetector]` - Detect and prevent common LLM errors + +### Task: Protocol Modernization (nurture-tech approach) +**Priority**: Medium +**Source**: nurture-tech/unity-mcp-server analysis +**Status**: Future-proofing opportunity + +**Description**: +nurture-tech fork uses latest MCP protocol version (2025-06-18) and Official MCP C# SDK. + +**Benefits**: +- **Protocol Compliance**: Up-to-date with latest MCP standards +- **Professional Architecture**: Enterprise-grade implementation patterns +- **Long-term Viability**: Better maintained and supported +- **NPM Distribution**: Simplified installation and updates + +**Implementation Considerations**: +- Evaluate migration effort vs benefits +- Assess compatibility with AWMS requirements +- Consider hybrid approach (adopt architecture patterns, maintain compatibility) +- Timeline coordination with AWMS development phases + +### Task: WebSocket Architecture Evaluation (CoderGamester approach) **Priority**: Medium -**Status**: Idea +**Source**: CoderGamester/mcp-unity analysis +**Status**: Alternative architecture consideration + +**Description**: +CoderGamester fork uses WebSocket server inside Unity with Node.js server, includes Play Mode domain reload handling. + +**Potential AWMS Benefits**: +- **Domain Reload Handling**: Maintains connection during Play Mode (critical for AWMS) +- **Real-time Communication**: Better suited for AWMS real-time monitoring +- **Modern Protocol**: WebSocket may be more reliable than TCP for some scenarios + +**Evaluation Criteria**: +- Connection stability during Unity domain reloads +- Performance comparison with TCP approach +- Compatibility with Claude Desktop and other MCP clients +- Implementation complexity vs benefits -Add validation to ensure installation paths are: -- Writable by current user -- Not in system directories -- Have sufficient disk space -- Compatible with Python virtual environments +--- + +## Original Roadmap Integration Opportunities -### Task: Installation Progress Feedback +### Short-Term Alignments (Post-Installation) + +#### Azure OpenAI Integration **Priority**: Low -**Status**: Idea +**AWMS Relevance**: Medium +**Description**: Add UI/mechanism to configure Azure OpenAI connection. +**AWMS Benefit**: Supports enterprise AWMS deployments with Azure infrastructure. + +#### Performance Optimization +**Priority**: High +**AWMS Relevance**: High +**Description**: Address performance bottlenecks in large scenes. +**AWMS Benefit**: Critical for AWMS operation in complex Unity projects. + +#### Assembly Definition Files +**Priority**: Medium +**AWMS Relevance**: High +**Description**: Add `UnityMCP.Editor.asmdef` for better project structure. +**AWMS Benefit**: Improves compile times and project organization for AWMS. + +### Mid-Term Strategic Features + +#### Runtime MCP Operation +**Priority**: High +**AWMS Relevance**: High +**Description**: Explore Unity runtime (not just editor) MCP operations. +**AWMS Benefit**: Enables AWMS to work with built applications, not just editor. + +#### Context Reduction +**Priority**: High +**AWMS Relevance**: Critical +**Description**: Reduce context sent to LLM to improve performance. +**AWMS Benefit**: Directly addresses AWMS context management and session optimization. + +#### Code Revision Function +**Priority**: Medium +**AWMS Relevance**: High +**Description**: Implement function to revise existing code. +**AWMS Benefit**: Essential for AWMS refactoring and code improvement workflows. + +#### Auto-approve Tool Calls +**Priority**: Low +**AWMS Relevance**: Medium +**Description**: Option to auto-approve tool calls. +**AWMS Benefit**: Reduces interruption in AWMS automated workflows. + +### Long-Term Vision Alignment + +#### Comprehensive Testing Suite +**Priority**: High +**AWMS Relevance**: Critical +**Description**: Automated testing for all Unity MCP functionality. +**AWMS Benefit**: Essential for AWMS reliability validation and regression prevention. + +#### Sophisticated Scene Analysis +**Priority**: Medium +**AWMS Relevance**: High +**Description**: Advanced scene analysis and manipulation tools. +**AWMS Benefit**: Supports AWMS project understanding and big-picture maintenance. + +--- + +## Fork-Specific Strategic Decisions + +### Recommended Integration Priority + +1. **Immediate (Phase 1)**: + - Enhanced error handling from roadmap + - Performance optimizations for large projects + - Assembly definition files + +2. **Short-term (Phase 2)**: + - Custom tool framework from IvanMurzak (for AWMS tools) + - Context reduction capabilities + - Runtime operation exploration + +3. **Medium-term (Phase 3)**: + - Protocol modernization evaluation + - Standalone server installation architecture + - WebSocket architecture assessment + +4. **Long-term (Phase 4)**: + - Comprehensive testing integration + - Advanced scene analysis tools + - Enterprise features (Azure integration) + +### AWMS-Specific Customizations + +#### Critical for AWMS Success: +- **Enhanced Error Reporting**: Silent failure elimination +- **Context Management**: LLM context optimization +- **Custom Tool Framework**: AWMS-specific operations +- **Runtime Operations**: Support for built applications +- **Domain Reload Handling**: Maintain connection during Unity state changes + +#### Nice-to-Have for AWMS: +- **Protocol Modernization**: Future-proofing and compliance +- **Performance Optimizations**: Better handling of complex projects +- **Testing Infrastructure**: Validation and regression prevention + +--- + +## Implementation Strategy + +### Phase 1: Foundation (Current Testing Phase) +- Complete Unity MCP validation testing +- Implement enhanced error handling +- Add performance monitoring + +### Phase 2: AWMS Integration (Next 2-3 months) +- Develop custom tool framework for AWMS operations +- Implement context reduction features +- Add domain reload handling + +### Phase 3: Architecture Evolution (6 months) +- Evaluate protocol modernization +- Implement standalone server installation +- Add comprehensive testing + +### Phase 4: Enterprise Features (12 months) +- Advanced scene analysis for AWMS +- Enterprise integration features +- Complete testing and validation infrastructure -Provide better user feedback during server installation: -- Progress bars for git operations -- Clear error messages for common failures -- Retry mechanisms for network issues +**Strategic Focus**: Prioritize features that directly support AWMS reliability and functionality over general Unity MCP improvements, while maintaining compatibility with the broader Unity MCP ecosystem. From c5d3659695bd317229dc5b9f419e9e680999e8d3 Mon Sep 17 00:00:00 2001 From: Klausi Date: Thu, 3 Jul 2025 14:28:13 +0200 Subject: [PATCH 7/7] Add session knowledge documentation - Added concise session knowledge for Unity MCP issues - Documents current problems: material properties, editor tool, testing - References AWMS validation framework in Unity_AWMS_Test --- docs/Project_Session_Knowledge.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 docs/Project_Session_Knowledge.md diff --git a/docs/Project_Session_Knowledge.md b/docs/Project_Session_Knowledge.md new file mode 100644 index 000000000..8d3e53d63 --- /dev/null +++ b/docs/Project_Session_Knowledge.md @@ -0,0 +1,11 @@ +# Unity MCP Session Knowledge + +## Current Issues (July 3, 2025) +1. Material generation reports success but doesn't apply properties +2. Editor tool not working properly +3. Most tools only tested superficially + +## Testing Approach +- AWMS validation tools deployed to Unity_AWMS_Test +- Focus on detecting false success reports +- Test results in Unity_AWMS_Test\Docs\Testing_Results\ \ No newline at end of file