diff --git a/.github/workflows/docs-deploy.yml b/.github/workflows/docs-deploy.yml index 2ee53f24f..367f8b011 100644 --- a/.github/workflows/docs-deploy.yml +++ b/.github/workflows/docs-deploy.yml @@ -70,6 +70,11 @@ jobs: - name: Build working-directory: website + env: + # Inject the cookieless GoatCounter beacon when provisioned. The site + # gates on process.env.GOATCOUNTER_CODE, which Actions does NOT + # auto-expose — the Actions variable must be mapped in explicitly. + GOATCOUNTER_CODE: ${{ vars.GOATCOUNTER_CODE }} run: npm run build - name: Upload Pages artifact diff --git a/.github/workflows/stats.yml b/.github/workflows/stats.yml new file mode 100644 index 000000000..4120a30b3 --- /dev/null +++ b/.github/workflows/stats.yml @@ -0,0 +1,25 @@ +name: Adoption stats (maintainer-only) +# Posts unified PyPI install + docs-traffic numbers to the workflow run summary, +# which is visible ONLY to repo collaborators. Nothing is published publicly. +on: + schedule: + - cron: '0 6 * * *' + workflow_dispatch: {} +permissions: + contents: read +jobs: + stats: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: { node-version: 20 } + - name: Fetch + summarize stats (private to collaborators) + env: + # public stars/forks work with the default token; unique cloners/viewers + # need a maintainer PAT with Administration: read (STATS_GITHUB_TOKEN). + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + STATS_GITHUB_TOKEN: ${{ secrets.STATS_GITHUB_TOKEN }} + GOATCOUNTER_TOKEN: ${{ secrets.GOATCOUNTER_TOKEN }} + GOATCOUNTER_SITE: ${{ secrets.GOATCOUNTER_SITE }} + run: node website/scripts/fetch-stats.mjs >> "$GITHUB_STEP_SUMMARY" diff --git a/.gitignore b/.gitignore index 834d504ff..d75b5fae0 100644 --- a/.gitignore +++ b/.gitignore @@ -69,3 +69,7 @@ tools/.unity-check-logs/ # Ignore the .claude directory, since it might contain local/project-level setting such as deny and allowlist. /.claude .mcp.json + +# Superpowers skill working artifacts (specs, plans, SDD ledger) +docs/superpowers/ +.superpowers/ diff --git a/MCPForUnity/Editor/Constants/ProductInfo.cs b/MCPForUnity/Editor/Constants/ProductInfo.cs new file mode 100644 index 000000000..969cba1e2 --- /dev/null +++ b/MCPForUnity/Editor/Constants/ProductInfo.cs @@ -0,0 +1,9 @@ +namespace MCPForUnity.Editor.Constants +{ + /// Canonical user-facing product identity strings. + public static class ProductInfo + { + public const string ProductName = "MCP for Unity"; + public const string MenuRoot = "Window/MCP for Unity"; + } +} diff --git a/MCPForUnity/Editor/Constants/ProductInfo.cs.meta b/MCPForUnity/Editor/Constants/ProductInfo.cs.meta new file mode 100644 index 000000000..c5a677aed --- /dev/null +++ b/MCPForUnity/Editor/Constants/ProductInfo.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 1df5e80156ac4f1ebe343e537eaa9da4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Helpers/McpLogRecord.cs.meta b/MCPForUnity/Editor/Helpers/McpLogRecord.cs.meta index f862b96ad..262ddc827 100644 --- a/MCPForUnity/Editor/Helpers/McpLogRecord.cs.meta +++ b/MCPForUnity/Editor/Helpers/McpLogRecord.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 925ef3d40ecf53649a6af9e94df6114b \ No newline at end of file +guid: 925ef3d40ecf53649a6af9e94df6114b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/MenuItems/MCPForUnityMenu.cs b/MCPForUnity/Editor/MenuItems/MCPForUnityMenu.cs index c0df247c0..57fed915e 100644 --- a/MCPForUnity/Editor/MenuItems/MCPForUnityMenu.cs +++ b/MCPForUnity/Editor/MenuItems/MCPForUnityMenu.cs @@ -1,3 +1,4 @@ +using MCPForUnity.Editor.Constants; using MCPForUnity.Editor.Setup; using MCPForUnity.Editor.Windows; using UnityEditor; @@ -7,20 +8,20 @@ namespace MCPForUnity.Editor.MenuItems { public static class MCPForUnityMenu { - [MenuItem("Window/MCP For Unity/Toggle MCP Window %#m", priority = 1)] + [MenuItem(ProductInfo.MenuRoot + "/Toggle MCP Window %#m", priority = 1)] public static void ToggleMCPWindow() { MCPForUnityEditorWindow.ShowWindow(); } - [MenuItem("Window/MCP For Unity/Local Setup Window", priority = 2)] + [MenuItem(ProductInfo.MenuRoot + "/Local Setup Window", priority = 2)] public static void ShowSetupWindow() { SetupWindowService.ShowSetupWindow(); } - [MenuItem("Window/MCP For Unity/Edit EditorPrefs", priority = 3)] + [MenuItem(ProductInfo.MenuRoot + "/Edit EditorPrefs", priority = 3)] public static void ShowEditorPrefsWindow() { EditorPrefsWindow.ShowWindow(); diff --git a/MCPForUnity/Editor/Services/HttpAutoStartHandler.cs.meta b/MCPForUnity/Editor/Services/HttpAutoStartHandler.cs.meta index 29a8a5f9e..d42fc7968 100644 --- a/MCPForUnity/Editor/Services/HttpAutoStartHandler.cs.meta +++ b/MCPForUnity/Editor/Services/HttpAutoStartHandler.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 3d8f1790992fe0742938d8a879056ee6 \ No newline at end of file +guid: 3d8f1790992fe0742938d8a879056ee6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Services/PackageJobManager.cs.meta b/MCPForUnity/Editor/Services/PackageJobManager.cs.meta index f70a01b5e..140a6946f 100644 --- a/MCPForUnity/Editor/Services/PackageJobManager.cs.meta +++ b/MCPForUnity/Editor/Services/PackageJobManager.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 0c8e16aa625e01544beb2468fda53613 \ No newline at end of file +guid: 0c8e16aa625e01544beb2468fda53613 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Services/Server/ServerCommandBuilder.cs b/MCPForUnity/Editor/Services/Server/ServerCommandBuilder.cs index 3e505634a..3c3207d5e 100644 --- a/MCPForUnity/Editor/Services/Server/ServerCommandBuilder.cs +++ b/MCPForUnity/Editor/Services/Server/ServerCommandBuilder.cs @@ -26,7 +26,7 @@ public bool TryBuildCommand(out string fileName, out string arguments, out strin bool useHttpTransport = EditorConfigurationCache.Instance.UseHttpTransport; if (!useHttpTransport) { - error = "HTTP transport is disabled. Enable it in the MCP For Unity window first."; + error = $"HTTP transport is disabled. Enable it in the {ProductInfo.ProductName} window first."; return false; } diff --git a/MCPForUnity/Editor/Services/ServerManagementService.cs b/MCPForUnity/Editor/Services/ServerManagementService.cs index 6c667afa1..1d943265d 100644 --- a/MCPForUnity/Editor/Services/ServerManagementService.cs +++ b/MCPForUnity/Editor/Services/ServerManagementService.cs @@ -271,7 +271,7 @@ public bool StartLocalHttpServer(bool quiet = false) "Port In Use", $"Cannot start the local HTTP server because port {uri.Port} is already in use by PID(s): " + $"{string.Join(", ", remaining)}\n\n" + - "MCP For Unity will not terminate unrelated processes. Stop the owning process manually or change the HTTP URL.", + $"{ProductInfo.ProductName} will not terminate unrelated processes. Stop the owning process manually or change the HTTP URL.", "OK"); } return false; diff --git a/MCPForUnity/Editor/Tools/ExecuteCode.cs.meta b/MCPForUnity/Editor/Tools/ExecuteCode.cs.meta index b5d099adc..62bff5dc5 100644 --- a/MCPForUnity/Editor/Tools/ExecuteCode.cs.meta +++ b/MCPForUnity/Editor/Tools/ExecuteCode.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 8ebfb8c53994b4750ad9c4f284e7126e \ No newline at end of file +guid: 8ebfb8c53994b4750ad9c4f284e7126e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/ManagePackages.cs.meta b/MCPForUnity/Editor/Tools/ManagePackages.cs.meta index 2ff4b16a0..8edee704f 100644 --- a/MCPForUnity/Editor/Tools/ManagePackages.cs.meta +++ b/MCPForUnity/Editor/Tools/ManagePackages.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 1a51e052ae3ba4242bd69448578405e1 \ No newline at end of file +guid: 1a51e052ae3ba4242bd69448578405e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs.meta b/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs.meta index 8bddd351e..b55503918 100644 --- a/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/ManageProfiler.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 369d21351c8c6c744a5775783d4957c9 \ No newline at end of file +guid: 369d21351c8c6c744a5775783d4957c9 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/CounterOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/CounterOps.cs.meta index edcf0f885..c5f35e113 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/CounterOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/CounterOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: d082e7102c501e14084295fdd363f2e4 \ No newline at end of file +guid: d082e7102c501e14084295fdd363f2e4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/FrameDebuggerOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/FrameDebuggerOps.cs.meta index 1b5df5c73..80ac698ab 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/FrameDebuggerOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/FrameDebuggerOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 6c99fe029dffcb945a39beda3acf304e \ No newline at end of file +guid: 6c99fe029dffcb945a39beda3acf304e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/FrameTimingOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/FrameTimingOps.cs.meta index ae1cccfda..5b3a1f1b4 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/FrameTimingOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/FrameTimingOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: aace6e3da2222164298de24af50cab3b \ No newline at end of file +guid: aace6e3da2222164298de24af50cab3b +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/MemorySnapshotOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/MemorySnapshotOps.cs.meta index 826eb6e63..3ee44a576 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/MemorySnapshotOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/MemorySnapshotOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: cb63d9b6a47327b40883452637eeb075 \ No newline at end of file +guid: cb63d9b6a47327b40883452637eeb075 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/ObjectMemoryOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/ObjectMemoryOps.cs.meta index b3bfc58f0..ec03b31b2 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/ObjectMemoryOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/ObjectMemoryOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: d57a224350157834083a7aabc86dc4e1 \ No newline at end of file +guid: d57a224350157834083a7aabc86dc4e1 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Tools/Profiler/Operations/SessionOps.cs.meta b/MCPForUnity/Editor/Tools/Profiler/Operations/SessionOps.cs.meta index 082dbcbb2..a2939726c 100644 --- a/MCPForUnity/Editor/Tools/Profiler/Operations/SessionOps.cs.meta +++ b/MCPForUnity/Editor/Tools/Profiler/Operations/SessionOps.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 4470c7a41470fb841b1d7e75d990eafd \ No newline at end of file +guid: 4470c7a41470fb841b1d7e75d990eafd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs b/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs index 23e4d5e55..6f2001c53 100644 --- a/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs +++ b/MCPForUnity/Editor/Windows/Components/ClientConfig/McpClientConfigSection.cs @@ -18,7 +18,7 @@ namespace MCPForUnity.Editor.Windows.Components.ClientConfig { /// - /// Controller for the Client Configuration section of the MCP For Unity editor window. + /// Controller for the Client Configuration section of the MCP for Unity editor window. /// Handles client selection, configuration, status display, and manual configuration details. /// public class McpClientConfigSection diff --git a/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs b/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs index df75a2201..64a0c0212 100644 --- a/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs +++ b/MCPForUnity/Editor/Windows/Components/Connection/McpConnectionSection.cs @@ -14,7 +14,7 @@ namespace MCPForUnity.Editor.Windows.Components.Connection { /// - /// Controller for the Connection section of the MCP For Unity editor window. + /// Controller for the Connection section of the MCP for Unity editor window. /// Handles transport protocol, HTTP/stdio configuration, connection status, and health checks. /// public class McpConnectionSection diff --git a/MCPForUnity/Editor/Windows/Components/Resources/McpResourcesSection.cs b/MCPForUnity/Editor/Windows/Components/Resources/McpResourcesSection.cs index 2682d4a5b..3b83b21af 100644 --- a/MCPForUnity/Editor/Windows/Components/Resources/McpResourcesSection.cs +++ b/MCPForUnity/Editor/Windows/Components/Resources/McpResourcesSection.cs @@ -10,7 +10,7 @@ namespace MCPForUnity.Editor.Windows.Components.Resources { /// - /// Controller for the Resources section inside the MCP For Unity editor window. + /// Controller for the Resources section inside the MCP for Unity editor window. /// Provides discovery, filtering, and per-resource enablement toggles. /// public class McpResourcesSection diff --git a/MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs b/MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs index bb8980023..723ec5eed 100644 --- a/MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs +++ b/MCPForUnity/Editor/Windows/Components/Tools/McpToolsSection.cs @@ -16,7 +16,7 @@ namespace MCPForUnity.Editor.Windows.Components.Tools { /// - /// Controller for the Tools section inside the MCP For Unity editor window. + /// Controller for the Tools section inside the MCP for Unity editor window. /// Provides discovery, filtering, and per-tool enablement toggles. /// Tools are grouped by their Group property (core first, then alphabetical). /// diff --git a/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs b/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs index b683a21a5..0d858bdba 100644 --- a/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs +++ b/MCPForUnity/Editor/Windows/EditorPrefs/EditorPrefsWindow.cs @@ -12,7 +12,7 @@ namespace MCPForUnity.Editor.Windows { /// - /// Editor window for managing Unity EditorPrefs, specifically for MCP For Unity development + /// Editor window for managing Unity EditorPrefs, specifically for MCP for Unity development /// public class EditorPrefsWindow : EditorWindow { diff --git a/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs b/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs index 9f06833fb..bd1e05844 100644 --- a/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs +++ b/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs @@ -100,10 +100,10 @@ public static void ShowWindow() } else { - window = GetWindow("MCP For Unity"); + window = GetWindow(ProductInfo.ProductName); } - window.titleContent = new GUIContent("MCP For Unity"); + window.titleContent = new GUIContent(ProductInfo.ProductName); window.minSize = new Vector2(500, 340); if (window.position.width < 100 || window.position.height < 100) @@ -409,8 +409,8 @@ private void UpdateVersionLabel() string version = AssetPathUtility.GetPackageVersion(); versionLabel.text = $"v{version}"; versionLabel.tooltip = AssetPathUtility.IsPreReleaseVersion() - ? $"MCP For Unity v{version} (pre-release package, using prerelease server channel)" - : $"MCP For Unity v{version}"; + ? $"{ProductInfo.ProductName} v{version} (pre-release package, using prerelease server channel)" + : $"{ProductInfo.ProductName} v{version}"; } private void QueueUpdateCheck() diff --git a/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml b/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml index bda651a64..a98ff2a4b 100644 --- a/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml +++ b/MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.uxml @@ -1,7 +1,7 @@ - + diff --git a/MCPForUnity/Runtime/Helpers/UnityFindObjectsCompat.cs.meta b/MCPForUnity/Runtime/Helpers/UnityFindObjectsCompat.cs.meta index 195437795..f72eb3e0e 100644 --- a/MCPForUnity/Runtime/Helpers/UnityFindObjectsCompat.cs.meta +++ b/MCPForUnity/Runtime/Helpers/UnityFindObjectsCompat.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: 7c3a9f12e4b60438d9a1c52ef8d07b3e \ No newline at end of file +guid: 7c3a9f12e4b60438d9a1c52ef8d07b3e +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/README.md b/README.md index cff6d256d..77358a498 100644 --- a/README.md +++ b/README.md @@ -1,46 +1,24 @@ -MCP for Unity +

+ + + MCP for Unity + +

-| [English](README.md) | [简体中文](docs/i18n/README-zh.md) | -|----------------------|---------------------------------| +
-#### Proudly sponsored and maintained by [Aura](https://www.tryaura.dev/) — the AI assistant for Unreal & Unity. -##### And don't miss [Godot AI](https://github.com/hi-godot/godot-ai), the new open source MCP/AI project from the makers of MCP for Unity. - -[![Docs](https://img.shields.io/badge/Docs-unity--mcp-4f46e5)](https://coplaydev.github.io/unity-mcp/) -[![Discord](https://img.shields.io/badge/discord-join-red.svg?logo=discord&logoColor=white)](https://discord.gg/y4p8KfzrN4) -[![](https://img.shields.io/badge/Website-Visit-purple)](https://www.coplay.dev/?ref=unity-mcp) -[![](https://img.shields.io/badge/Unity-000000?style=flat&logo=unity&logoColor=blue 'Unity')](https://unity.com/releases/editor/archive) -[![python](https://img.shields.io/badge/Python-3.10+-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) -[![](https://badge.mcpx.dev?status=on 'MCP Enabled')](https://modelcontextprotocol.io/introduction) -[![](https://img.shields.io/badge/License-MIT-red.svg 'MIT License')](https://opensource.org/licenses/MIT) - -**Create your Unity apps with LLMs.** MCP for Unity bridges AI assistants — Claude, Codex, VS Code, local LLMs, and more — with your Unity Editor via the [Model Context Protocol](https://modelcontextprotocol.io/introduction). Give your LLM the tools to manage assets, control scenes, edit scripts, run tests, and automate workflows. - -MCP for Unity building a scene - ---- - -## Read the Docs - -### **→ [coplaydev.github.io/unity-mcp](https://coplaydev.github.io/unity-mcp/)** - ---- - -## Install - -In Unity: **Window → Package Manager → + → Add package from git URL**, paste: - -```text -https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main -``` +[English](README.md) ↔ [简体中文](docs/i18n/README-zh.md)    |    [Discord](https://discord.gg/y4p8KfzrN4) ↔ [Wiki](https://coplaydev.github.io/unity-mcp/) -Beta channel uses `#beta`. Asset Store and OpenUPM paths are documented in the [Install guide](https://coplaydev.github.io/unity-mcp/getting-started/install). +#### Proudly sponsored and maintained by [Aura](https://www.tryaura.dev/) — the AI assistant for Unreal & Unity. +##### And don't miss [Godot AI](https://github.com/hi-godot/godot-ai), the new open source project from the makers of MCP for Unity. -Then **Window → MCP for Unity → Configure All Detected Clients**. That's it — try a prompt: +
-> Create a red, blue, and yellow cube in the current scene. +

Create your Unity apps with LLMs. MCP for Unity bridges AI assistants — Claude, Codex, VS Code, local LLMs, and more — with your Unity Editor via Model Context Protocol. Give your LLM the tools to manage assets, control scenes, edit scripts, run tests, and automate your game dev workflows.

-Full walkthrough: [Your First Prompt](https://coplaydev.github.io/unity-mcp/getting-started/first-prompt). +

+ MCP for Unity building a scene +

--- @@ -61,6 +39,25 @@ Full history: [Release Notes](https://coplaydev.github.io/unity-mcp/releases). --- +## What it does + +Control the Unity Editor in natural language from any MCP client — create scenes & GameObjects, edit C# scripts, manage assets, run tests, profile, and build. 40+ focused tools, any client, free & MIT. + +**[Browse the full tool catalog →](https://coplaydev.github.io/unity-mcp/reference/tools/)** + +--- + +## Quickstart + +**Requirements:** Unity **2021.3 LTS → 6.x** · Python **3.10+** (via [`uv`](https://docs.astral.sh/uv/)). Works with **any MCP client** — Claude Desktop & Code, Cursor, VS Code, Windsurf, Cline, Gemini CLI, and more. + +1. **Install** — Unity → Package Manager → Add from git URL: + `https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#beta`  _(or `openupm add com.coplaydev.unity-mcp`)_ +2. **Configure** — `Window → MCP for Unity → Configure All Detected Clients`. +3. **Prompt** — *"Create a cube at the origin and add a Rigidbody."* The cube appears in seconds. + +--- + ## AI Asset Generation Bring-your-own-key generation of **3D models** (text→3D and image→3D), **2D images**, and **Sketchfab** model import — straight into your project. Generated assets land under `Assets/Generated/`. diff --git a/Server/README.md b/Server/README.md index 581380a9f..470d09758 100644 --- a/Server/README.md +++ b/Server/README.md @@ -4,6 +4,8 @@ [![python](https://img.shields.io/badge/Python-3.10+-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) [![License](https://img.shields.io/badge/License-MIT-red.svg 'MIT License')](https://opensource.org/licenses/MIT) [![Discord](https://img.shields.io/badge/discord-join-red.svg?logo=discord&logoColor=white)](https://discord.gg/y4p8KfzrN4) +[![PyPI version](https://img.shields.io/pypi/v/mcpforunityserver?label=PyPI)](https://pypi.org/project/mcpforunityserver/) +[![Downloads](https://static.pepy.tech/badge/mcpforunityserver)](https://pepy.tech/project/mcpforunityserver) Model Context Protocol server for Unity Editor integration. Control Unity through natural language using AI assistants like Claude, Cursor, and more. @@ -271,7 +273,7 @@ Once connected, try these commands in your AI assistant: For complete documentation, troubleshooting, and advanced usage: -📖 **[Full Documentation](https://github.com/CoplayDev/unity-mcp#readme)** +📖 **[Full Documentation](https://coplaydev.github.io/unity-mcp/)** --- diff --git a/Server/pyproject.toml b/Server/pyproject.toml index 569ec6dd6..1b7889450 100644 --- a/Server/pyproject.toml +++ b/Server/pyproject.toml @@ -47,8 +47,11 @@ dev = [ ] [project.urls] +Homepage = "https://coplaydev.github.io/unity-mcp/" +Documentation = "https://coplaydev.github.io/unity-mcp/" Repository = "https://github.com/CoplayDev/unity-mcp.git" Issues = "https://github.com/CoplayDev/unity-mcp/issues" +Changelog = "https://github.com/CoplayDev/unity-mcp/releases" [project.scripts] mcp-for-unity = "main:main" diff --git a/Server/uv.lock b/Server/uv.lock index 585a83c2b..3eaa003ee 100644 --- a/Server/uv.lock +++ b/Server/uv.lock @@ -858,7 +858,7 @@ wheels = [ [[package]] name = "mcpforunityserver" -version = "9.7.1" +version = "9.7.3" source = { editable = "." } dependencies = [ { name = "click" }, diff --git a/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/TestJobManagerInitTimeoutTests.cs.meta b/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/TestJobManagerInitTimeoutTests.cs.meta index 663e2f94c..12d1c8c5f 100644 --- a/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/TestJobManagerInitTimeoutTests.cs.meta +++ b/TestProjects/UnityMCPTests/Assets/Tests/EditMode/Services/TestJobManagerInitTimeoutTests.cs.meta @@ -1,2 +1,11 @@ fileFormatVersion: 2 -guid: e0b6718bcbe94429595354c108865f67 \ No newline at end of file +guid: e0b6718bcbe94429595354c108865f67 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/docs/i18n/README-zh.md b/docs/i18n/README-zh.md index 420d4fb98..fddee9959 100644 --- a/docs/i18n/README-zh.md +++ b/docs/i18n/README-zh.md @@ -1,116 +1,65 @@ -MCP for Unity +

+ + + MCP for Unity + +

-| [English](../../README.md) | [简体中文](README-zh.md) | -|----------------------|---------------------------------| +
+ +[English](../../README.md) ↔ [简体中文](README-zh.md)    |    [Discord](https://discord.gg/y4p8KfzrN4) ↔ [Wiki](https://coplaydev.github.io/unity-mcp/) #### 由 [Aura](https://www.tryaura.dev/) 荣誉赞助并维护 —— 面向 Unreal 与 Unity 的 AI 助手。 -##### 别错过 [Godot A](https://github.com/hi-godot/godot-ai)I 🤖,MCP for Unity 团队推出的全新开源 MCP/AI 项目! +##### 别错过 [Godot AI](https://github.com/hi-godot/godot-ai) 🤖,MCP for Unity 团队推出的全新开源项目! + +
-[![Discord](https://img.shields.io/badge/discord-join-red.svg?logo=discord&logoColor=white)](https://discord.gg/y4p8KfzrN4) -[![](https://img.shields.io/badge/Website-Visit-purple)](https://www.coplay.dev/?ref=unity-mcp) -[![](https://img.shields.io/badge/Unity-000000?style=flat&logo=unity&logoColor=blue 'Unity')](https://unity.com/releases/editor/archive) -[![python](https://img.shields.io/badge/Python-3.10+-3776AB.svg?style=flat&logo=python&logoColor=white)](https://www.python.org) -[![](https://badge.mcpx.dev?status=on 'MCP Enabled')](https://modelcontextprotocol.io/introduction) -[![](https://img.shields.io/badge/License-MIT-red.svg 'MIT License')](https://opensource.org/licenses/MIT) +

MCP for Unity 通过 Model Context Protocol 把 Claude、Cursor、VS Code、本地大模型等 AI 助手接入 Unity 编辑器,让它们直接帮你管理资源、搭场景、写脚本、跑测试,把开发流程里的重复活儿都包了。

-**用大语言模型创建你的 Unity 应用!** MCP for Unity 通过 [Model Context Protocol](https://modelcontextprotocol.io/introduction) 将 AI 助手(Claude、Cursor、VS Code 等)与你的 Unity Editor 连接起来。为你的大语言模型提供管理资源、控制场景、编辑脚本和自动化任务的工具。 +

+ MCP for Unity building a scene +

-MCP for Unity building a scene +---
最近更新 -* **v9.6.3 (beta)** — 新增 `manage_profiler` 工具(14个操作):Profiler 会话控制(启动/停止/状态/设置区域)、帧时间与计数器读取、对象内存查询、内存快照(通过 com.unity.memoryprofiler 进行拍摄/列表/比较)、帧调试器(启用/禁用/获取事件)。分组:`profiling`。 -* **v9.6.2** — 新增 `manage_physics` 工具(21个操作):物理设置、层碰撞矩阵、物理材质、关节(5种3D + 9种2D类型)、查询(raycast、raycast_all、linecast、shapecast、overlap)、力施加(AddForce/AddTorque/AddExplosionForce)、刚体配置、场景物理验证与编辑器模式模拟。全面支持3D和2D物理。 -* **v9.6.1** — QoL 扩展:`manage_editor` 新增撤销/重做操作。`manage_scene` 新增多场景编辑(叠加加载、关闭、设置活动场景、跨场景移动物体)、场景模板(3d_basic、2d_basic 等)、场景验证与自动修复。新增 `manage_build` 工具:触发玩家构建、切换平台、配置玩家设置、管理构建场景和配置文件(Unity 6+)、跨多平台批量构建、异步任务跟踪与轮询。新增 `MaxPollSeconds` 基础设施,支持长时间运行的工具操作。 -* **v9.5.4** — 新增 `unity_reflect` 和 `unity_docs` 工具用于 API 验证:通过反射检查实时 C# API,获取官方 Unity 文档(ScriptReference、Manual、包文档)。新增 `manage_packages` 工具:安装、移除、搜索和管理 Unity 包及作用域注册表。包含输入验证、移除时依赖检查和 git URL 警告。 -* **v9.5.3** — 新增 `manage_graphics` 工具(33个操作):体积/后处理、光照烘焙、渲染统计、管线设置、URP渲染器特性。3个新资源:`volumes`、`rendering_stats`、`renderer_features`。 -* **v9.5.2** — 新增 `manage_camera` 工具,支持 Cinemachine(预设、优先级、噪声、混合、扩展)、`cameras` 资源、通过 SerializedProperty 修复优先级持久化问题。 +* **[v9.7.0](https://github.com/CoplayDev/unity-mcp/releases/tag/v9.7.0)**(2026-05-22) +* **[v9.6.8](https://github.com/CoplayDev/unity-mcp/releases/tag/v9.6.8)**(2026-04-27) +* **[v9.6.6](https://github.com/CoplayDev/unity-mcp/releases/tag/v9.6.6)**(2026-04-07) +* **[v9.6.5](https://github.com/CoplayDev/unity-mcp/releases/tag/v9.6.5)**(2026-04-03) +* **[v9.6.4](https://github.com/CoplayDev/unity-mcp/releases/tag/v9.6.4)**(2026-03-31) -
-更早的版本 +完整更新历史见 [发布说明](https://coplaydev.github.io/unity-mcp/releases)。 -* **v9.4.8** — 新编辑器 UI、通过 `manage_tools` 实时切换工具、技能同步窗口、多视图截图、一键 Roslyn 安装器、支持 Qwen Code 与 Gemini CLI 客户端、通过 `manage_probuilder` 进行 ProBuilder 网格编辑。 -* **v9.4.7** — 支持按调用路由 Unity 实例、修复 macOS pyenv PATH 问题、脚本工具的域重载稳定性提升。 -* **v9.4.6** — 新增 `manage_animation` 工具、支持 Cline 客户端、失效连接检测、工具状态跨重载持久化。 -* **v9.4.4** — 可配置 `batch_execute` 限制、按会话状态过滤工具、修复 IPv6/IPv4 回环问题。 - -
--- -## 快速开始 - -### 前置要求 - -* **Unity 2021.3 LTS+** — [下载 Unity](https://unity.com/download) -* **Python 3.10+** 和 **uv** — [安装 uv](https://docs.astral.sh/uv/getting-started/installation/) -* **一个 MCP 客户端** — [Claude Desktop](https://claude.ai/download) | [Cursor](https://www.cursor.com/en/downloads) | [VS Code Copilot](https://code.visualstudio.com/docs/copilot/overview) | [GitHub Copilot CLI](https://docs.github.com/en/copilot/concepts/agents/about-copilot-cli) | [OpenClaw](https://openclaw.ai) - -### 1. 安装 Unity 包 - -在 Unity 中:`Window > Package Manager > + > Add package from git URL...` - -> [!TIP] -> ```text -> https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main -> ``` - -**想要最新的 beta 版本?** 使用 beta 分支: -```text -https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#beta -``` - -
-其他安装方式(Asset Store、OpenUPM) - -**Unity Asset Store:** -1. 访问 [Asset Store 上的 MCP for Unity](https://assetstore.unity.com/packages/tools/generative-ai/mcp-for-unity-ai-driven-development-329908) -2. 点击 `Add to My Assets`,然后通过 `Window > Package Manager` 导入 - -**OpenUPM:** -```bash -openupm add com.coplaydev.unity-mcp -``` -
- -### 2. 启动服务器并连接 +## 它能做什么 -1. 在 Unity 中:`Window > MCP for Unity` -2. 点击 **Start Server**(会在 `localhost:8080` 启动 HTTP 服务器) -3. 从下拉菜单选择你的 MCP Client,然后点击 **Configure** -4. 查找 🟢 "Connected ✓" -5. **连接你的客户端:** 一些客户端(Cursor、Antigravity 2.0、Antigravity IDE、OpenClaw)需要在设置里启用 MCP 开关或插件。Antigravity 2.0 与 Antigravity IDE 是分开列出的:Antigravity 2.0 已迁移到 `~/.gemini/config/`,而 Antigravity IDE 仍使用 `~/.gemini/antigravity-ide/`;如果两者都在使用,请分别配置。OpenClaw 还需要启用 `openclaw-mcp-bridge` 插件,并会跟随 MCP for Unity 当前选择的传输方式(HTTP 或 stdio);另一些(Claude Desktop、Claude Code)在配置后会自动连接。 +用自然语言从任意 MCP 客户端操作 Unity 编辑器:搭场景、建 GameObject、写改 C# 脚本、调材质和着色器、跑测试、看性能、出包。40+ 个工具,任意客户端可用,免费、MIT 开源。 -**就这些!** 试试这样的提示词:*"Create a red, blue and yellow cube"* 或 *"Build a simple player controller"* +**[查看完整工具目录 →](https://coplaydev.github.io/unity-mcp/reference/tools/)** --- -
-功能与工具 - -### 关键功能 -* **自然语言控制** — 指示你的大语言模型执行 Unity 任务 -* **强大工具** — 管理资源、场景、材质、脚本和编辑器功能 -* **自动化** — 自动化重复的 Unity 工作流程 -* **可扩展** — 可与多种 MCP Client 配合使用 +## 快速开始 -### 可用工具 -`apply_text_edits` • `batch_execute` • `create_script` • `debug_request_context` • `delete_script` • `execute_custom_tool` • `execute_menu_item` • `find_gameobjects` • `find_in_file` • `get_sha` • `get_test_job` • `manage_animation` • `manage_asset` • `manage_build` • `manage_camera` • `manage_components` • `manage_editor` • `manage_gameobject` • `manage_graphics` • `manage_material` • `manage_packages` • `manage_physics` • `manage_prefabs` • `manage_probuilder` • `manage_profiler` • `manage_scene` • `manage_script` • `manage_script_capabilities` • `manage_scriptable_object` • `manage_shader` • `manage_texture` • `manage_tools` • `manage_ui` • `manage_vfx` • `read_console` • `refresh_unity` • `run_tests` • `script_apply_edits` • `set_active_instance` • `unity_docs` • `unity_reflect` • `validate_script` +**环境要求:** Unity **2021.3 LTS → 6.x** · Python **3.10+**(用 [`uv`](https://docs.astral.sh/uv/) 管理)。兼容**任意 MCP 客户端**——Claude Desktop 与 Claude Code、Cursor、VS Code、Windsurf、Cline、Gemini CLI 等等。 -### 可用资源 -`cameras` • `custom_tools` • `renderer_features` • `rendering_stats` • `volumes` • `editor_active_tool` • `editor_prefab_stage` • `editor_selection` • `editor_state` • `editor_windows` • `gameobject` • `gameobject_api` • `gameobject_component` • `gameobject_components` • `get_tests` • `get_tests_for_mode` • `menu_items` • `prefab_api` • `prefab_hierarchy` • `prefab_info` • `project_info` • `project_layers` • `project_tags` • `tool_groups` • `unity_instances` - -**性能提示:** 多个操作请使用 `batch_execute` — 比逐个调用快 10-100 倍! -
+1. **安装** —— 在 Unity 里打开 Package Manager,从 git URL 添加: + `https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#beta`  _(也可以用 `openupm add com.coplaydev.unity-mcp`)_ +2. **配置客户端** —— `Window → MCP for Unity → Configure All Detected Clients`,一键搞定所有检测到的客户端。 +3. **发个提示试试** —— *"在原点放一个立方体,加个 Rigidbody。"* 立方体几秒就出现在场景里了。
手动配置 -如果自动设置不生效,请把下面内容添加到你的 MCP Client 配置文件中: +如果自动配置不生效,把下面的内容加到你的 MCP 客户端配置文件里: -**HTTP(默认 — 适用于 Claude Desktop、Cursor、Windsurf):** +**HTTP(默认 —— 适用于 Claude Desktop、Cursor、Windsurf):** ```json { "mcpServers": { @@ -162,34 +111,36 @@ openupm add com.coplaydev.unity-mcp
+--- +
多个 Unity 实例 -MCP for Unity 支持多个 Unity Editor 实例。要将操作定向到某个特定实例: +MCP for Unity 支持同时开多个 Unity 编辑器实例。想把操作定向到某个实例: -1. 让你的大语言模型检查 `unity_instances` 资源 -2. 使用 `set_active_instance` 并传入 `Name@hash`(例如 `MyProject@abc123`) -3. 后续所有工具都会路由到该实例 +1. 让大模型读一下 `unity_instances` 资源 +2. 用 `set_active_instance` 传入 `Name@hash`(比如 `MyProject@abc123`) +3. 之后所有工具调用都会走这个实例
-Roslyn 脚本验证(高级) +Roslyn 脚本验证(进阶) -要使用能捕获未定义命名空间、类型和方法的 **Strict** 验证: +想用能查出未定义命名空间、类型和方法的 **Strict** 验证: -1. 安装 [NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity) +1. 装 [NuGetForUnity](https://github.com/GlitchEnzo/NuGetForUnity) 2. `Window > NuGet Package Manager` → 安装 `Microsoft.CodeAnalysis` v5.0 -3. 同时安装 `SQLitePCLRaw.core` 和 `SQLitePCLRaw.bundle_e_sqlite3` v3.0.2 -4. 在 `Player Settings > Scripting Define Symbols` 中添加 `USE_ROSLYN` +3. 再装 `SQLitePCLRaw.core` 和 `SQLitePCLRaw.bundle_e_sqlite3` v3.0.2 +4. 在 `Player Settings > Scripting Define Symbols` 里加上 `USE_ROSLYN` 5. 重启 Unity
- 手动 DLL 安装(如果 NuGetForUnity 不可用) + 手动安装 DLL(NuGetForUnity 用不了时) - 1. 从 [NuGet](https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp/) 下载 `Microsoft.CodeAnalysis.CSharp.dll` 及其依赖项 - 2. 将 DLL 放到 `Assets/Plugins/` 目录 - 3. 确保 .NET 兼容性设置正确 - 4. 在 Scripting Define Symbols 中添加 `USE_ROSLYN` + 1. 从 [NuGet](https://www.nuget.org/packages/Microsoft.CodeAnalysis.CSharp/) 下载 `Microsoft.CodeAnalysis.CSharp.dll` 及其依赖 + 2. 把 DLL 放进 `Assets/Plugins/` + 3. 确认 .NET 兼容性设置正确 + 4. 在 Scripting Define Symbols 里加上 `USE_ROSLYN` 5. 重启 Unity
@@ -197,35 +148,35 @@ MCP for Unity 支持多个 Unity Editor 实例。要将操作定向到某个特
故障排除 -* **Unity Bridge 无法连接:** 检查 `Window > MCP for Unity` 状态,重启 Unity -* **Server 无法启动:** 确认 `uv --version` 可用,并检查终端错误 -* **Client 无法连接:** 确认 HTTP server 正在运行,并且 URL 与你的配置一致 +* **Unity Bridge 连不上:** 看一下 `Window > MCP for Unity` 的状态,重启 Unity +* **服务器起不来:** 确认 `uv --version` 能跑,并看看终端报错 +* **客户端连不上:** 确认 HTTP 服务在运行,且 URL 和你的配置一致 -**详细的设置指南:** -* [Fix Unity MCP and Cursor, VSCode & Windsurf](https://github.com/CoplayDev/unity-mcp/wiki/1.-Fix-Unity-MCP-and-Cursor,-VSCode-&-Windsurf) — uv/Python 安装、PATH 问题 -* [Fix Unity MCP and Claude Code](https://github.com/CoplayDev/unity-mcp/wiki/2.-Fix-Unity-MCP-and-Claude-Code) — Claude CLI 安装 -* [Common Setup Problems](https://github.com/CoplayDev/unity-mcp/wiki/3.-Common-Setup-Problems) — macOS dyld 错误、FAQ +**详细配置指南:** +* [Fix Unity MCP and Cursor, VSCode & Windsurf](https://github.com/CoplayDev/unity-mcp/wiki/1.-Fix-Unity-MCP-and-Cursor,-VSCode-&-Windsurf) —— uv/Python 安装、PATH 问题 +* [Fix Unity MCP and Claude Code](https://github.com/CoplayDev/unity-mcp/wiki/2.-Fix-Unity-MCP-and-Claude-Code) —— Claude CLI 安装 +* [Common Setup Problems](https://github.com/CoplayDev/unity-mcp/wiki/3.-Common-Setup-Problems) —— macOS dyld 错误、常见问题 -还是卡住?[开一个 Issue](https://github.com/CoplayDev/unity-mcp/issues) 或 [加入 Discord](https://discord.gg/y4p8KfzrN4) +还是搞不定?[提个 Issue](https://github.com/CoplayDev/unity-mcp/issues) 或者 [来 Discord 问](https://discord.gg/y4p8KfzrN4)
-贡献 +参与贡献 -开发环境设置见 [README-DEV.md](../development/README-DEV.md)。自定义工具见 [CUSTOM_TOOLS.md](../reference/CUSTOM_TOOLS.md)。 +开发环境配置见 [README-DEV.md](../development/README-DEV.md),自定义工具见 [CUSTOM_TOOLS.md](../reference/CUSTOM_TOOLS.md)。 -1. Fork → 创建 issue → 新建分支(`feature/your-idea`)→ 修改 → 提 PR +1. Fork → 开 issue → 建分支(`feature/your-idea`)→ 改 → 提 PR
遥测与隐私 -匿名、注重隐私的遥测(不包含代码、项目名或个人数据)。可通过 `DISABLE_TELEMETRY=true` 关闭。详见 [TELEMETRY.md](../reference/TELEMETRY.md)。 +匿名、注重隐私的遥测(不收集代码、项目名或任何个人数据),用 `DISABLE_TELEMETRY=true` 就能关掉。详见 [TELEMETRY.md](../reference/TELEMETRY.md)。
--- -**许可证:** MIT — 查看 [LICENSE](../../LICENSE) | **需要帮助?** [Discord](https://discord.gg/y4p8KfzrN4) | [Issues](https://github.com/CoplayDev/unity-mcp/issues) +**许可证:** MIT —— 见 [LICENSE](../../LICENSE) | **需要帮助?** [Discord](https://discord.gg/y4p8KfzrN4) | [Issues](https://github.com/CoplayDev/unity-mcp/issues) --- @@ -234,8 +185,8 @@ MCP for Unity 支持多个 Unity Editor 实例。要将操作定向到某个特 [![Star History Chart](https://api.star-history.com/svg?repos=CoplayDev/unity-mcp&type=Date)](https://www.star-history.com/#CoplayDev/unity-mcp&Date)
-研究引用 -如果你正在进行与 Unity-MCP 相关的研究,请引用我们! +论文引用 +如果 MCP for Unity 对你的研究有帮助,欢迎引用我们! ```bibtex @inproceedings{10.1145/3757376.3771417, @@ -254,10 +205,10 @@ series = {SA Technical Communications '25} ## Aura 的 Unity AI 工具 -Aura 提供 2 个 Unity AI 工具: -- **MCP for Unity** 在 MIT 许可证下免费提供。 -- **Aura for Unity** 是一款面向游戏开发者打造的高级 Unity/Unreal AI 助手。 +Aura 出品两款 Unity AI 工具: +- **MCP for Unity** —— MIT 许可证,免费开源。 +- **Aura for Unity** —— 面向游戏开发者的高级 Unity/Unreal AI 助手。 ## 免责声明 -本项目是一个免费开源的 Unity Editor 工具,与 Unity Technologies 无关。 +本项目是一个免费开源的 Unity 编辑器工具,与 Unity Technologies 无关。 diff --git a/docs/images/connector.svg b/docs/images/connector.svg new file mode 100644 index 000000000..884ace1fd --- /dev/null +++ b/docs/images/connector.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/docs/images/logo-header-dark.png b/docs/images/logo-header-dark.png new file mode 100644 index 000000000..74ae94b69 Binary files /dev/null and b/docs/images/logo-header-dark.png differ diff --git a/docs/images/logo-header-light.png b/docs/images/logo-header-light.png new file mode 100644 index 000000000..19641d9db Binary files /dev/null and b/docs/images/logo-header-light.png differ diff --git a/docs/images/logo.png b/docs/images/logo.png deleted file mode 100644 index 142983992..000000000 Binary files a/docs/images/logo.png and /dev/null differ diff --git a/docs/wiki/V10.md b/docs/wiki/V10.md new file mode 100644 index 000000000..8dd68aba4 --- /dev/null +++ b/docs/wiki/V10.md @@ -0,0 +1,233 @@ +# MCP for Unity v10 Release Candidate Notes + +These notes cover the v10 release candidate: the full major-version change from +v9.0.0, the new AI asset generation/import surface, secure provider-key storage, +Blender/local-file handoff, and the README/docs/brand refresh. + +For this comparison, **v9 means `v9.0.0`**, not the last v9 patch. The `v9.7.3` +tag is still useful for the release-to-release changelog, but it already +contains much of the v9 tool expansion. + +## What changed since v9.0.0 + +At `v9.0.0`, MCP for Unity exposed 29 MCP tool entrypoints around the core Unity +Editor loop: scenes, GameObjects, components, scripts, prefabs, assets, +materials, shaders, VFX, console reads, editor refresh, async tests, custom +tools, and batch execution. + +The v10 release candidate exposes 47 MCP tool entrypoints across 10 groups: +`core`, `animation`, `asset_gen`, `docs`, `probuilder`, `profiling`, +`scripting_ext`, `testing`, `ui`, and `vfx`. + +| Area | `v9.0.0` baseline | v10 release candidate | +| --- | --- | --- | +| Tool catalog | 29 MCP tool entrypoints, with most tools registered directly into one visible surface. | 47 MCP tool entrypoints across grouped domains. | +| Tool visibility | No decorator-level group metadata and no `manage_tools` workflow for user-controlled visibility. | Tool registry has named groups; `core` is enabled by default and non-core groups are opt-in. | +| Editor automation domains | Core scene/object/component/script/asset/prefab/material/shader/VFX/test/editor operations. | Adds build orchestration, camera/Cinemachine control, render pipeline and graphics operations, package management, physics, animation, UI Toolkit, profiling, ProBuilder, and procedural texture generation. | +| Asset creation/import | Existing asset management and VFX/shader/script tools could create or modify project content, but external generation providers were not part of the product surface. | Adds the `asset_gen` group for Tripo/Meshy model generation, fal.ai/OpenRouter image generation, Sketchfab import, and local FBX/OBJ/glTF handoff from tools such as Blender. | +| API lookup and docs | API discovery depended on external docs or local project inspection. | Adds `unity_docs` and `unity_reflect`, plus generated tool/resource reference docs. | +| Safety model | Core tool execution, custom tools, async test polling, and instance routing were present. | Adds group-gated high-power tools, secure provider-key storage in Unity, project-scoped import hardening, archive/path validation, and more test coverage around transport, tool registry, provider adapters, and Unity compatibility. | +| Editor UI and docs | The window focused on connection/client setup and the docs grew around accumulated features. | Adds tool/resource visibility flows, Asset Gen setup, glTFast dependency guidance, refreshed README/docs navigation, icons/social assets, and consistent "MCP for Unity" product naming. | + +Added MCP tool entrypoints since `v9.0.0`: `execute_code`, +`generate_image`, `generate_model`, `import_model`, `import_model_file`, +`manage_animation`, `manage_build`, `manage_camera`, `manage_graphics`, +`manage_packages`, `manage_physics`, `manage_probuilder`, `manage_profiler`, +`manage_texture`, `manage_tools`, `manage_ui`, `unity_docs`, and +`unity_reflect`. + +## What v10 is about + +1. **A larger grouped tool surface** - the catalog grows from 29 to 47 MCP tool + entrypoints, with high-power domains split into opt-in groups. +2. **Asset generation and import** - first-class MCP tools for generating 3D + models, generating 2D images, importing marketplace models, and handing off + local files from tools like Blender. +3. **Safer agent operations** - provider keys stay in the Unity Editor, tools + are opt-in by group, long-running jobs are explicit and pollable, and file + writes are constrained to project assets. +4. **Clearer product surface** - refreshed README, docs site, branding, and + distribution metadata. +5. **Release confidence** - Python tests, Unity compile checks, docs builds, and + compatibility shims for the wide Unity support window. + +## AI Asset Generation + +The headline v10 feature is the new `asset_gen` tool group. It is disabled by +default like other non-core tool groups, and can be enabled with `manage_tools`. + +| Tool | Purpose | +| --- | --- | +| `generate_model` | Generate 3D models from text or image prompts through providers such as Tripo and Meshy. | +| `generate_image` | Generate 2D images through providers such as fal.ai and OpenRouter. | +| `import_model` | Search and import downloadable Sketchfab models. | +| `import_model_file` | Import a local model file already on disk, such as an FBX/OBJ/glTF exported from Blender. | + +Generation and import jobs are asynchronous. A request returns a `job_id`, and +the client polls `action="status"` until the job completes or fails. + +## Provider keys + +Asset providers are bring-your-own-key. Keys are entered in the Unity Editor's +Asset Gen tab and stored in the operating system secure store: + +- macOS: Keychain +- Windows: Credential Manager +- Linux: libsecret / Secret Service compatible tooling + +Keys are not written to project assets, `EditorPrefs`, generated docs, or MCP +tool parameters. The MCP client can request a generation job, but it does not +receive provider credentials. + +## Local image inputs + +v10 distinguishes hosted image inputs from local project images: + +- `image_url` points at an externally hosted image. +- `image_path` points at a local file, commonly under `Assets/`. + +Meshy image-to-3D and fal/OpenRouter image-to-image can accept local image files +by sending the image data inline as a base64 data URI. Tripo image-to-3D still +requires a hosted `image_url` until an upload flow is wired. + +## Blender handoff + +The `import_model_file` tool creates a clean boundary between DCC generation and +Unity import: + +1. The modeling tool creates or exports the asset. +2. MCP for Unity imports the file with `import_model_file`. +3. The Unity agent uses existing scene, material, prefab, and build tools to wire + the asset into the project. + +This is a handoff, not MCP for Unity controlling Blender directly. + +## Safety model + +### Opt-in tool group + +`asset_gen` is not part of the default core tool set. Users must explicitly +enable it with `manage_tools`. + +### Project-scoped imports + +Generated and imported assets resolve into the Unity project's `Assets/` folder, +with traversal and unsafe paths rejected. Archives are extracted through +allowlisted import paths and extensions rather than blindly writing every file +a provider returns. + +### No hidden spend + +Generation calls go to third-party providers using the user's own API keys. + +- MCP for Unity does not bundle provider credits. +- Provider pricing, rate limits, and content policies are controlled by the + provider. +- Enable the tool group only when you intend to call generation or import + providers. + +## Docs and brand refresh + +v10 also updates the project front door: + +- README trimmed into a clearer front door. +- Docs site reorganized around Getting Started, Guides, Reference, + Architecture, Contributing, Migrations, and Releases. +- Tool reference pages are generated from the tool registry. +- Distribution and analytics docs are explicit about what is measured and what + is not. +- Branding now consistently uses **MCP for Unity** in user-facing UI and docs. + +## Compatibility posture + +v10 continues the existing compatibility promise: + +- Unity 2021.3 LTS remains the package floor. +- Unity 6.x stays in the supported matrix. +- Known Unity API changes route through compatibility helpers under + `MCPForUnity/Runtime/Helpers/`. +- Contributors touching shims or version-gated APIs run + `tools/check-unity-versions.sh` against installed Unity Hub editors. + +## Upgrade notes from v9 + +1. Update the Unity package to v10. During RC testing, use the `beta` branch. +2. Reconfigure MCP clients if the package prompts you to. +3. Install optional dependencies only when needed. GLB import uses glTFast; FBX + import does not require that package. +4. Enable `asset_gen` explicitly with `manage_tools` before calling asset + generation tools. +5. Add provider keys in Unity, not in MCP client config files. +6. Keep generated assets under review before committing them. + +## What is intentionally not in v10 + +- No hosted MCP for Unity asset-generation credits. +- No guarantee that every provider supports every input mode. +- No automatic BlenderMCP configuration from Unity. +- No promise that provider-generated assets are production-ready without artist + review. +- No change to the rule that non-core tool groups start disabled. + +## Final comparison + +**Major-version comparison**: https://github.com/CoplayDev/unity-mcp/compare/v9.0.0...v10.0.0 + +**v9.7.3 patch comparison**: https://github.com/CoplayDev/unity-mcp/compare/v9.7.3...v10.0.0 + +## Troubleshooting + +### `asset_gen` tools do not appear + +The `asset_gen` group is disabled by default. Enable it with `manage_tools`: + +```text +manage_tools action=activate group=asset_gen +``` + +If the tools still do not appear, refresh/reconnect the MCP server in the client. +Some clients cache tool lists until the server is restarted or refreshed. + +### Provider key missing + +Generation providers are bring-your-own-key. Add keys in Unity's **Asset Gen** +tab. Do not place provider keys in MCP client config files, prompts, project +assets, or generated docs. + +### GLB import fails or has missing geometry/materials + +GLB/glTF import depends on **glTFast**. Install it from the Dependencies tab or +via Package Manager before importing GLB assets. FBX imports do not require +glTFast. + +### Tripo image-to-3D rejects `image_path` + +Tripo image-to-3D currently needs a hosted `image_url`. Local `image_path` inputs +are supported by Meshy image-to-3D and fal/OpenRouter image-to-image, where the +image can be sent inline as a base64 data URI. + +### Generated or imported files are larger than expected + +Provider output can include large binary assets. Review generated files before +committing them, keep generated output under `Assets/Generated/` when possible, +and avoid committing experimental provider output that is not needed by the +project. + +### Archive import is rejected + +Archive extraction is intentionally constrained. Provider archives may be +rejected when they contain unsupported extensions, traversal paths, scripts, or +files outside the import allowlist. Import the model again with a supported +format or inspect the archive before bringing it into the Unity project. + +## Related docs + +- Tool groups: https://coplaydev.github.io/unity-mcp/guides/tool-groups +- Asset generation tools: https://coplaydev.github.io/unity-mcp/reference/tools/asset_gen/ +- generate_model: https://coplaydev.github.io/unity-mcp/reference/tools/asset_gen/generate_model +- generate_image: https://coplaydev.github.io/unity-mcp/reference/tools/asset_gen/generate_image +- import_model: https://coplaydev.github.io/unity-mcp/reference/tools/asset_gen/import_model +- import_model_file: https://coplaydev.github.io/unity-mcp/reference/tools/asset_gen/import_model_file +- Tool reference: https://coplaydev.github.io/unity-mcp/reference/tools/ +- Unity compatibility shims: https://coplaydev.github.io/unity-mcp/architecture/unity-compat +- Project roadmap: https://coplaydev.github.io/unity-mcp/architecture/project-roadmap diff --git a/website/docs/architecture/external-analytics.md b/website/docs/architecture/external-analytics.md new file mode 100644 index 000000000..c24d88f70 --- /dev/null +++ b/website/docs/architecture/external-analytics.md @@ -0,0 +1,57 @@ +--- +description: How MCP for Unity tracks adoption with cookieless, aggregate-only analytics — a public PyPI downloads badge plus a private, maintainer-only dashboard. +--- + +# External analytics + +## What is tracked and why + +MCP for Unity tracks adoption with several aggregate signals, ordered from most to least honest about *real users*: + +- **In-product DAU / WAU** — the true active-user count, deduplicated per anonymous install UUID by the in-product telemetry (`Server/src/core/telemetry.py`). Surfacing it on this dashboard needs a read API on the Coplay telemetry backend. +- **Unique repo cloners / viewers (14-day)** — from the GitHub repository traffic API; a strong proxy for developers actually pulling the code. Only collaborators can read it (needs a token), so it is private by nature. +- **GitHub stars / forks** — real accounts that starred or forked; public, an interest (not usage) signal. +- **PyPI installs** — daily/weekly/monthly download counts for `mcpforunityserver` from the public [pypistats.org](https://pypistats.org/packages/mcpforunityserver) API. **Heavily inflated** by CI, mirrors, `uvx` re-fetches, and Docker rebuilds — an install-event *reach* number, not a user count. A downloads badge appears in the README. +- **Docs traffic** — aggregate pageview totals from [GoatCounter](https://www.goatcounter.com/) when provisioned. + +All sources are **cookieless, store no personal data, and expose only aggregates**. The DAU/WAU source is the [in-product telemetry](./telemetry) that runs inside the Unity Editor and is controlled by the user from the MCP for Unity settings window. + +## What is public vs private + +- **Public:** the PyPI **downloads badge** in the README (download counts are public on PyPI regardless of what we do). +- **Private (maintainer-only):** the unified install + docs-traffic **dashboard**. It is posted to the GitHub Actions run summary, which only repo collaborators can see. There is **no public stats page and no stats file published to the site**. + +## Privacy stance + +- No cookies, no fingerprinting, no user IDs. +- No PII is transmitted or stored. +- GoatCounter is a privacy-first analytics service; its [privacy policy](https://www.goatcounter.com/help/privacy) commits to not selling data. The GoatCounter dashboard should be kept **private** so traffic numbers stay maintainer-only. +- The maintainer summary contains only counts and a timestamp. + +## How data flows + +1. A GitHub Actions workflow (`.github/workflows/stats.yml`) runs daily at 06:00 UTC, and on demand via **Run workflow**. +2. `website/scripts/fetch-stats.mjs` fetches PyPI recent-download counts and, when GoatCounter secrets are present, the total pageview count. +3. The script renders a Markdown table that the workflow appends to `$GITHUB_STEP_SUMMARY`. +4. Collaborators read the numbers on the **Actions → Adoption stats** run page. Nothing is committed to the repo or published to the docs site. + +## Maintainer provisioning + +Stars, forks, and PyPI numbers work out of the box. The two highest-signal rows need setup: + +**Unique repo cloners / viewers (GitHub traffic):** + +1. Create a fine-grained PAT scoped to `CoplayDev/unity-mcp` with **Repository permissions → Administration: read** (the traffic API requires it; the default `GITHUB_TOKEN` returns 401/403). +2. Add it as the repository **secret** `STATS_GITHUB_TOKEN`. + +**In-product DAU / WAU (the true active-user count):** + +- The data is already collected by `Server/src/core/telemetry.py` (deduplicated per anonymous install UUID) and POSTed to the Coplay telemetry backend. Surfacing it here needs a **read / aggregate API** on that backend plus a token — back-end work owned by Coplay. Once available, add a `COPLAY_STATS_TOKEN` secret and a fetch in `fetch-stats.mjs`. + +**Docs traffic (GoatCounter):** + +1. Create a free [goatcounter.com](https://www.goatcounter.com/) site (e.g. code `mcp-for-unity`); keep its dashboard **private**. +2. Generate an API token with read access to stats. +3. Add secrets `GOATCOUNTER_TOKEN` (token) and `GOATCOUNTER_SITE` (site code), and an **Actions variable** `GOATCOUNTER_CODE` (same site code) so the docs build injects the cookieless beacon — collection happens on the public site, the numbers stay private. + +Then run **Actions → Adoption stats → Run workflow**. The `stats` workflow needs only `contents: read` — it posts to the run summary and never commits. diff --git a/website/docs/guides/roslyn.md b/website/docs/guides/roslyn.md index 3f27a1a6e..be35cf51f 100644 --- a/website/docs/guides/roslyn.md +++ b/website/docs/guides/roslyn.md @@ -24,7 +24,7 @@ Most users don't need this. Enable it when: The installer downloads the required NuGet packages, places the DLLs in `Assets/Plugins/Roslyn/`, and adds `USE_ROSLYN` to Scripting Define Symbols. -You can also trigger it from the menu: **Window → MCP For Unity → Install Roslyn DLLs**. +You can also trigger it from the menu: **Window → MCP for Unity → Install Roslyn DLLs**. ## Manual install (if the installer isn't available) diff --git a/website/docs/migrations/v10.md b/website/docs/migrations/v10.md new file mode 100644 index 000000000..80bd1f505 --- /dev/null +++ b/website/docs/migrations/v10.md @@ -0,0 +1,263 @@ +--- +title: v10 - Asset Generation and Docs Refresh +author: MCP for Unity Maintainers +date: 2026-06-30 +--- + +# MCP for Unity v10 Release Candidate Notes + +These notes cover the v10 release candidate: the full major-version change from +v9.0.0, the new AI asset generation/import surface, secure provider-key storage, +Blender/local-file handoff, and the README/docs/brand refresh. + +For this comparison, **v9 means `v9.0.0`**, not the last v9 patch. The `v9.7.3` +tag is still useful for the release-to-release changelog, but it already +contains much of the v9 tool expansion. + +## What changed since v9.0.0 + +At `v9.0.0`, MCP for Unity exposed 29 MCP tool entrypoints around the core Unity +Editor loop: scenes, GameObjects, components, scripts, prefabs, assets, +materials, shaders, VFX, console reads, editor refresh, async tests, custom +tools, and batch execution. + +The v10 release candidate exposes 47 MCP tool entrypoints across 10 groups: +`core`, `animation`, `asset_gen`, `docs`, `probuilder`, `profiling`, +`scripting_ext`, `testing`, `ui`, and `vfx`. + +| Area | `v9.0.0` baseline | v10 release candidate | +| --- | --- | --- | +| Tool catalog | 29 MCP tool entrypoints, with most tools registered directly into one visible surface. | 47 MCP tool entrypoints across grouped domains. | +| Tool visibility | No decorator-level group metadata and no `manage_tools` workflow for user-controlled visibility. | Tool registry has named groups; `core` is enabled by default and non-core groups are opt-in. | +| Editor automation domains | Core scene/object/component/script/asset/prefab/material/shader/VFX/test/editor operations. | Adds build orchestration, camera/Cinemachine control, render pipeline and graphics operations, package management, physics, animation, UI Toolkit, profiling, ProBuilder, and procedural texture generation. | +| Asset creation/import | Existing asset management and VFX/shader/script tools could create or modify project content, but external generation providers were not part of the product surface. | Adds the `asset_gen` group for Tripo/Meshy model generation, fal.ai/OpenRouter image generation, Sketchfab import, and local FBX/OBJ/glTF handoff from tools such as Blender. | +| API lookup and docs | API discovery depended on external docs or local project inspection. | Adds `unity_docs` and `unity_reflect`, plus generated tool/resource reference docs. | +| Safety model | Core tool execution, custom tools, async test polling, and instance routing were present. | Adds group-gated high-power tools, secure provider-key storage in Unity, project-scoped import hardening, archive/path validation, and more test coverage around transport, tool registry, provider adapters, and Unity compatibility. | +| Editor UI and docs | The window focused on connection/client setup and the docs grew around accumulated features. | Adds tool/resource visibility flows, Asset Gen setup, glTFast dependency guidance, refreshed README/docs navigation, icons/social assets, and consistent "MCP for Unity" product naming. | + +Added MCP tool entrypoints since `v9.0.0`: `execute_code`, +`generate_image`, `generate_model`, `import_model`, `import_model_file`, +`manage_animation`, `manage_build`, `manage_camera`, `manage_graphics`, +`manage_packages`, `manage_physics`, `manage_probuilder`, `manage_profiler`, +`manage_texture`, `manage_tools`, `manage_ui`, `unity_docs`, and +`unity_reflect`. + +## What v10 is about + +v10 is organized around five concrete changes: + +1. **A larger grouped tool surface** - the catalog grows from 29 to 47 MCP tool + entrypoints, with high-power domains split into opt-in groups. +2. **Asset generation and import** - first-class MCP tools for generating 3D + models, generating 2D images, importing marketplace models, and handing off + local files from tools like Blender. +3. **Safer agent operations** - provider keys stay in the Unity Editor, tools + are opt-in by group, long-running jobs are explicit and pollable, and file + writes are constrained to project assets. +4. **Clearer product surface** - refreshed README, docs site, branding, and + distribution metadata make it easier to understand what the project does and + where to start. +5. **Release confidence** - Python tests, Unity compile checks, docs builds, and + compatibility shims keep the wide Unity support window practical. + +## AI Asset Generation + +The headline v10 feature is the new `asset_gen` tool group. It is disabled by +default like other non-core tool groups, and can be enabled with `manage_tools`. + +The group contains: + +| Tool | Purpose | +| --- | --- | +| `generate_model` | Generate 3D models from text or image prompts through providers such as Tripo and Meshy. | +| `generate_image` | Generate 2D images through providers such as fal.ai and OpenRouter. | +| `import_model` | Search and import downloadable Sketchfab models. | +| `import_model_file` | Import a local model file already on disk, such as an FBX/OBJ/glTF exported from Blender. | + +The tools use asynchronous job semantics for long-running work. A generation or +import request returns a `job_id`; clients then call the corresponding +`action="status"` operation until the job completes or fails. This keeps MCP +calls responsive and gives agents a predictable pattern for progress reporting. + +### Provider keys + +Asset providers are bring-your-own-key. Keys are entered in the Unity Editor's +Asset Gen tab and stored in the operating system secure store: + +- macOS: Keychain +- Windows: Credential Manager +- Linux: libsecret / Secret Service compatible tooling + +Keys are not written to project assets, `EditorPrefs`, generated docs, or MCP +tool parameters. The MCP client can request a generation job, but it does not +receive provider credentials. + +### Local image inputs + +v10 distinguishes hosted image inputs from local project images: + +- `image_url` points at an externally hosted image. +- `image_path` points at a local file, commonly under `Assets/`. + +Meshy image-to-3D and fal/OpenRouter image-to-image can accept local image files +by sending the image data inline as a base64 data URI. Tripo image-to-3D still +requires a hosted `image_url` until an upload flow is wired. + +### Blender handoff + +The `import_model_file` tool creates a clean boundary between DCC generation and +Unity import. BlenderMCP or another modeling workflow can create/export a model, +then MCP for Unity imports that local file into the Unity project and can place +it in the scene. + +This is a handoff, not MCP for Unity controlling Blender directly: + +1. The modeling tool creates or exports the asset. +2. MCP for Unity imports the file with `import_model_file`. +3. The Unity agent uses existing scene, material, prefab, and build tools to wire + the asset into the project. + +## Safety model + +Asset generation makes the bridge more powerful, so v10 calls out the guardrails +around provider calls and file import. + +### Opt-in tool group + +`asset_gen` is not part of the default core tool set. Users must explicitly +enable it with `manage_tools`, which keeps routine MCP sessions focused and +limits accidental provider calls. + +### Project-scoped imports + +Generated and imported assets resolve into the Unity project's `Assets/` folder, +with traversal and unsafe paths rejected. Archives are extracted through +allowlisted import paths and extensions rather than blindly writing every file +a provider returns. + +### No hidden spend + +Generation calls go to third-party providers using the user's own API keys: + +- MCP for Unity does not bundle provider credits. +- Provider pricing, rate limits, and content policies are controlled by the + provider. +- Enable the tool group only when you intend to call generation or import + providers. + +## Docs and brand refresh + +v10 also updates the project front door: + +- README trimmed into a clearer front door: what the project does, quickstart, + community, advanced links, and citation. +- Docs site reorganized around Getting Started, Guides, Reference, + Architecture, Contributing, Migrations, and Releases. +- Tool reference pages are generated from the tool registry so the docs match + the Python MCP layer. +- Distribution and analytics docs are explicit about what is measured and what + is not. +- Branding now consistently uses **MCP for Unity** in user-facing UI and docs. + +## Compatibility posture + +v10 continues the existing compatibility promise: + +- Unity 2021.3 LTS remains the package floor. +- Unity 6.x stays in the supported matrix. +- Known Unity API changes route through compatibility helpers under + `MCPForUnity/Runtime/Helpers/` instead of scattering `#if UNITY_*` gates + across tool code. +- When touching shims or version-gated APIs, run `tools/check-unity-versions.sh` + against installed Unity Hub editors. + +The CoreCLR 6.8 path matters here. Deprecation fixes belong in one shim layer, +not at every call site. + +## Upgrade notes from v9 + +1. **Update the Unity package** to v10. During RC testing, use the `beta` branch. +2. **Reconfigure MCP clients** if the package prompts you to, especially after + transport or server URL changes. +3. **Install optional dependencies** only when needed. For example, GLB import + uses glTFast; FBX import does not require that package. +4. **Enable `asset_gen` explicitly** with `manage_tools` before calling asset + generation tools. +5. **Add provider keys in Unity**, not in MCP client config files. +6. **Keep generated assets under review** before committing them. Provider + output can be large and belongs in the same review path as other binary + project assets. + +## What is intentionally not in v10 + +Call these out to avoid confusing expectations: + +- No hosted MCP for Unity asset-generation credits. +- No guarantee that every provider supports every input mode. +- No automatic BlenderMCP configuration from Unity. +- No promise that provider-generated assets are production-ready without artist + review. +- No change to the rule that non-core tool groups start disabled. + +## Final comparison + +**Major-version comparison**: https://github.com/CoplayDev/unity-mcp/compare/v9.0.0...v10.0.0 + +**v9.7.3 patch comparison**: https://github.com/CoplayDev/unity-mcp/compare/v9.7.3...v10.0.0 + +## Troubleshooting + +### `asset_gen` tools do not appear + +The `asset_gen` group is disabled by default. Enable it with `manage_tools`: + +```text +manage_tools action=activate group=asset_gen +``` + +If the tools still do not appear, refresh/reconnect the MCP server in the client. +Some clients cache tool lists until the server is restarted or refreshed. + +### Provider key missing + +Generation providers are bring-your-own-key. Add keys in Unity's **Asset Gen** +tab. Do not place provider keys in MCP client config files, prompts, project +assets, or generated docs. + +### GLB import fails or has missing geometry/materials + +GLB/glTF import depends on **glTFast**. Install it from the Dependencies tab or +via Package Manager before importing GLB assets. FBX imports do not require +glTFast. + +### Tripo image-to-3D rejects `image_path` + +Tripo image-to-3D currently needs a hosted `image_url`. Local `image_path` inputs +are supported by Meshy image-to-3D and fal/OpenRouter image-to-image, where the +image can be sent inline as a base64 data URI. + +### Generated or imported files are larger than expected + +Provider output can include large binary assets. Review generated files before +committing them, keep generated output under `Assets/Generated/` when possible, +and avoid committing experimental provider output that is not needed by the +project. + +### Archive import is rejected + +Archive extraction is intentionally constrained. Provider archives may be +rejected when they contain unsupported extensions, traversal paths, scripts, or +files outside the import allowlist. Import the model again with a supported +format or inspect the archive before bringing it into the Unity project. + +## Related docs + +- [Tool groups](/guides/tool-groups) +- [Asset generation tools](/reference/tools/asset_gen/) +- [`generate_model`](/reference/tools/asset_gen/generate_model) +- [`generate_image`](/reference/tools/asset_gen/generate_image) +- [`import_model`](/reference/tools/asset_gen/import_model) +- [`import_model_file`](/reference/tools/asset_gen/import_model_file) +- [Generated tool reference](/reference/tools/) +- [Unity compatibility shims](/architecture/unity-compat) +- [Project roadmap](/architecture/project-roadmap) diff --git a/website/docs/migrations/v6.md b/website/docs/migrations/v6.md index b33ad19ec..02effe11c 100644 --- a/website/docs/migrations/v6.md +++ b/website/docs/migrations/v6.md @@ -14,7 +14,7 @@ The new MCP Editor Window is a complete rebuild using **UI Toolkit (UXML/USS)** with a **service-oriented architecture**. The design philosophy emphasizes **explicit over implicit** behavior, making the system more predictable, testable, and maintainable. -**Quick Access:** `Cmd/Ctrl+Shift+M` or `Window > MCP For Unity > Open MCP Window` +**Quick Access:** `Cmd/Ctrl+Shift+M` or `Window > MCP for Unity > Open MCP Window` **Key Improvements:** - 🎨 Modern UI that doesn't hide info as the window size changes @@ -73,7 +73,7 @@ The new window intentionally removes implicit behaviors and complex edge-case ha ### ❌ Python Detection Warning - **Old:** Warning banner if Python not detected on system - **Why Removed:** Setup Wizard handles dependency checks, we also can't flood a bunch of error and warning logs when submitting to the Asset Store -- **Alternative:** Run Setup Wizard via `Window > MCP For Unity > Setup Wizard` +- **Alternative:** Run Setup Wizard via `Window > MCP for Unity > Setup Wizard` ### ❌ Separate Manual Setup Windows - **Old:** `VSCodeManualSetupWindow`, `ManualConfigEditorWindow` popup dialogs diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 2f0ba06f8..66ec89d04 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -20,6 +20,8 @@ function countConfigurators() { } const supportedClientCount = countConfigurators(); +const baseUrl = '/unity-mcp/'; + /** @type {import('@docusaurus/types').Config} */ const config = { title: 'MCP for Unity', @@ -29,7 +31,7 @@ const config = { // Hosted on GitHub Pages under the CoplayDev org. // Custom domain (CNAME) deferred — see plan Phase 2. url: 'https://coplaydev.github.io', - baseUrl: '/unity-mcp/', + baseUrl, organizationName: 'CoplayDev', projectName: 'unity-mcp', @@ -59,6 +61,22 @@ const config = { crossorigin: 'anonymous', }, }, + { + tagName: 'link', + attributes: { rel: 'icon', type: 'image/png', sizes: '32x32', href: `${baseUrl}img/favicon-32.png` }, + }, + { + tagName: 'link', + attributes: { rel: 'apple-touch-icon', sizes: '180x180', href: `${baseUrl}img/apple-touch-icon.png` }, + }, + { + tagName: 'link', + attributes: { rel: 'icon', type: 'image/png', sizes: '192x192', href: `${baseUrl}img/android-chrome-192.png` }, + }, + { + tagName: 'link', + attributes: { rel: 'icon', type: 'image/png', sizes: '512x512', href: `${baseUrl}img/android-chrome-512.png` }, + }, ], stylesheets: [ 'https://api.fontshare.com/v2/css?f[]=satoshi@300,400,500,700,900&display=swap', @@ -124,18 +142,20 @@ const config = { ], }, ], + ...(process.env.GOATCOUNTER_CODE ? ['docusaurus-plugin-goatcounter'] : []), ], themeConfig: /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ ({ image: 'img/social-card.png', + metadata: [{ name: 'theme-color', content: '#4f46e5' }], navbar: { title: 'MCP for Unity', logo: { alt: 'MCP for Unity logo', src: 'img/logo-mark.svg', - srcDark: 'img/logo-mark-dark.svg', + srcDark: 'img/logo-mark.svg', }, items: [ { @@ -205,6 +225,7 @@ const config = { defaultMode: 'light', respectPrefersColorScheme: true, }, + ...(process.env.GOATCOUNTER_CODE ? { goatcounter: { code: process.env.GOATCOUNTER_CODE } } : {}), }), }; diff --git a/website/package-lock.json b/website/package-lock.json index bce930311..59a305bca 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -20,10 +20,12 @@ }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.6.3", - "@docusaurus/types": "^3.6.3" + "@docusaurus/types": "^3.6.3", + "docusaurus-plugin-goatcounter": "^4.0.0", + "sharp": "^0.35.2" }, "engines": { - "node": ">=18.0" + "node": ">=20.9.0" } }, "node_modules/@algolia/abtesting": { @@ -4259,9 +4261,9 @@ } }, "node_modules/@emnapi/runtime": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", - "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.1.tgz", + "integrity": "sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==", "license": "MIT", "optional": true, "dependencies": { @@ -4293,6 +4295,533 @@ "@hapi/hoek": "^9.0.0" } }, + "node_modules/@img/colour": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", + "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.2.tgz", + "integrity": "sha512-eEieHsMksAW4IiO5NzauESRl2D2qz3J/kwUxUrSfV06A93eEaRfMpHXyUb1mAqrR7i8U9A0GRqE9pjn6u1Jjpg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.2.tgz", + "integrity": "sha512-BaktuGPCeHJMARpodR8jK4uKiZrPAy9WrfQW0sdI37clracq8Bp01AYS3SZgi5FS/y5twa9t4+LIuuxQjqRrWw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-freebsd-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.2.tgz", + "integrity": "sha512-YoAxdnd8hPUkvLHd3bWY+YA8nw3xM/RyRopYucNsWHVSan8NLVM3X2volsfoRDcXdUJPg6tXahSd7HXPK7lRnw==", + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "freebsd" + ], + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.1.tgz", + "integrity": "sha512-4V/M3roRMTYjiwZY9IOVQOE8OyeCxFAkYmyZDrZl51uOKjibm3oeEJ4WAmLxutAfzFbC9jqUiPs2gbnGflH+7g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.1.tgz", + "integrity": "sha512-c0/DxItpJv2+dGhgycJBBgotdqruGYDvA79drdh0MD1dFpy7JzJ/PlXwi1H4rFf0eTy8tgbI91aHDnZIceY3jQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.1.tgz", + "integrity": "sha512-aGGy9aWzXgHBG7HNyQPWorZthlp7+x6fDRoPAQbGO3ThcttuTyKIx3NuSHb6zb4gBNq6/yNn9f1cy9nFKS/Vmg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.1.tgz", + "integrity": "sha512-JznefmcK9j1JKPz8AkQDh89kjojubyfOasWBPKfzMIhPwsgDy9evpE/naJTXXXmghS1iFwR8u/kTwh/I2/+GCw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-ppc64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.1.tgz", + "integrity": "sha512-1EkwGNCZk6iWNCMWqrvdJ+r1j0PT1zIz60CNPhYnJlK/zyeWqlsPZIe+ocBVqPF8k/Ssee/NCk+tE9Ryrko6ng==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-riscv64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.1.tgz", + "integrity": "sha512-Ilays+w2bXdnxzxtQdmXR62u8o8GYa3eL4+Gr+1KiE4xperMZUslRaVPJwwPkzlHEjGfXAfRVAa/7CYCtSqsBw==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.1.tgz", + "integrity": "sha512-VfBwVHQTbRoj4XlpA/KLZ7ltgMpz+4WSejFzQ+GnoImjo1PtEJ59QB2qR1xQEeRPYIkNrPIm2L4cICMvz4C2ew==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.1.tgz", + "integrity": "sha512-+c8ukgwU62DS54nCAjw7keOfHUkmr0B5QHEdcOqRnodF/MNXJbVI8Eopoj4B/0H8Asr65I+A4Amrn7a85/md6A==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.1.tgz", + "integrity": "sha512-qlKb/pwbkAi1WMsJrYHk7CuDrd12s27U2QnRhFYUoJNrRCmkosMTttuRFat/DDB3IlDm5qE1TJgZ4JDnHX8Ldw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.1.tgz", + "integrity": "sha512-yO21HwoUVLN8Qa+/SBjQLMYwBWAVJjeGPNe+hc0OUeMeifEtJqu5a1c4HayE1nNpDih9y3/KkoltfkDodmKAlg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.2.tgz", + "integrity": "sha512-SE4kzF2mepn6z+6E7L6lsV8FzuLL6IPQdyX8ZiwROAG/G8td+hP/m7FsFPwidtrF19gvajuC9l6TxAVcsA4S7A==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.2.tgz", + "integrity": "sha512-af12Pnd0ZGu2HfP8NayB0kk6eC/lrfbQE6HlR4jD+34wdJ1Vw9TF6TMn6ZvffT+WgqVsl0hRbmNvz2u/23VmwA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-ppc64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.2.tgz", + "integrity": "sha512-hYSBm7zcNtDCozCxQHYZJiu63b/bXsgRZuOxCIBZsStMM9Vap47iFHdbX4kCvQsblPB/k+clhELpdQJHQLSHvg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-ppc64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-riscv64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.2.tgz", + "integrity": "sha512-qQt0Kc13+Hoan/Awq/qMSQw3L+RI1NCRPgD5cUJ/1WSSmIoysLOc72jlRM3E0OHN9Yr313jgeQ2T+zW+F03QFA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-riscv64": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.2.tgz", + "integrity": "sha512-E4fLLfRPzDLlEeDaTzI98OFLcv++WL5ChLLMwPoVd0CIoZQqupBSNbOisPL5am9XsbQ9T84+iiMpUvbFtkunbA==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.3.1" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.2.tgz", + "integrity": "sha512-gi0zFJJRLswfCZmHtJdikXPOc5u7qamSOS3NHedLqLd4W8Q0NqjdBr6TTRIgsfFjqfTsHFgdfvJ9LwqSgcHiAA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.2.tgz", + "integrity": "sha512-siWbOW1u6HFnFLrp0waKyW7VEf7jYvcDWdrXEFa8AkdAQgEvuu5Fz8/Y70w9EeqAdwDtfU012BhEHHaDqvQNzg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.2.tgz", + "integrity": "sha512-YBqMMcjDi4QGYiSn4vNOYBhmlC4z5AXqkOUUqI2e0AFA4urNv4ESgOgwNl3K+4etQhha0twXlzeF20bbULm9Yg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.3.1" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.2.tgz", + "integrity": "sha512-Mrv4JQNYVQ94xH+jzZ9r+gowleN8mv2FTgKT+PI6bx5C0G8TdNYndu161pg2i7uoBwxy2ImPMHrJOM2LZef7Bw==", + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.11.1" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-webcontainers-wasm32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.2.tgz", + "integrity": "sha512-QNV27pxs9wpApEiCfvHM1RDoP1w1+2KrUWWDPEhEwg+latvOrfuhWrHWZKwdSFwU6jh3myjw/yOCRsUIuOft3g==", + "cpu": [ + "wasm32" + ], + "dev": true, + "license": "Apache-2.0", + "optional": true, + "dependencies": { + "@img/sharp-wasm32": "0.35.2" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-arm64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.2.tgz", + "integrity": "sha512-BiVRYc/t6/Vl3e1hBx0hugG4oN9Pydf4fgMSpxTQJmwGUg/YoXTWHiFeRymHfCZzifxu4F4rpk/I67D0LQ20wQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.2.tgz", + "integrity": "sha512-YYEhx9PImCC7T0tI8JDMi4DB9LwLCXCU5OWNYEXAxh5Q1ShKkyC6byxzoBJ3gEFDnH2lQckWuDe70G7mB2XJog==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.2.tgz", + "integrity": "sha512-imoOyBcoM/iiUr4J6VPpCNjPnjvP/Gks95898yB8YqoGGYmHYbOyCuNv9FMhFgtaiHFGbHW8bxKqRV6VjtXThQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@jest/schemas": { "version": "29.6.3", "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", @@ -8303,6 +8832,16 @@ "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", @@ -8363,6 +8902,16 @@ "node": ">=6" } }, + "node_modules/docusaurus-plugin-goatcounter": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/docusaurus-plugin-goatcounter/-/docusaurus-plugin-goatcounter-4.0.0.tgz", + "integrity": "sha512-YJgbriYdruis4N0xutIv1qzoBi7/pe3RwExVvTyRAYLwNyd4oYA119pFSQ92pn6fUUxsffTanDvCT4cT1whSAA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=20" + } + }, "node_modules/dom-converter": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", @@ -16743,9 +17292,9 @@ } }, "node_modules/semver": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.1.tgz", - "integrity": "sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -16995,6 +17544,51 @@ "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==", "license": "MIT" }, + "node_modules/sharp": { + "version": "0.35.2", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.2.tgz", + "integrity": "sha512-FVtFjtBCMiJS6yb5CX7Sop45WFMpeGw6oRKuJnXYgf/f1ms/D7LE/ZUSNxnW7rZ/dbslQWYkoqFHGPaDBtaK4w==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "@img/colour": "^1.1.0", + "detect-libc": "^2.1.2", + "semver": "^7.8.4" + }, + "engines": { + "node": ">=20.9.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.35.2", + "@img/sharp-darwin-x64": "0.35.2", + "@img/sharp-freebsd-wasm32": "0.35.2", + "@img/sharp-libvips-darwin-arm64": "1.3.1", + "@img/sharp-libvips-darwin-x64": "1.3.1", + "@img/sharp-libvips-linux-arm": "1.3.1", + "@img/sharp-libvips-linux-arm64": "1.3.1", + "@img/sharp-libvips-linux-ppc64": "1.3.1", + "@img/sharp-libvips-linux-riscv64": "1.3.1", + "@img/sharp-libvips-linux-s390x": "1.3.1", + "@img/sharp-libvips-linux-x64": "1.3.1", + "@img/sharp-libvips-linuxmusl-arm64": "1.3.1", + "@img/sharp-libvips-linuxmusl-x64": "1.3.1", + "@img/sharp-linux-arm": "0.35.2", + "@img/sharp-linux-arm64": "0.35.2", + "@img/sharp-linux-ppc64": "0.35.2", + "@img/sharp-linux-riscv64": "0.35.2", + "@img/sharp-linux-s390x": "0.35.2", + "@img/sharp-linux-x64": "0.35.2", + "@img/sharp-linuxmusl-arm64": "0.35.2", + "@img/sharp-linuxmusl-x64": "0.35.2", + "@img/sharp-webcontainers-wasm32": "0.35.2", + "@img/sharp-win32-arm64": "0.35.2", + "@img/sharp-win32-ia32": "0.35.2", + "@img/sharp-win32-x64": "0.35.2" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", diff --git a/website/package.json b/website/package.json index 2b50ff7b4..265265f34 100644 --- a/website/package.json +++ b/website/package.json @@ -11,12 +11,13 @@ "clear": "docusaurus clear", "serve": "docusaurus serve", "write-translations": "docusaurus write-translations", - "write-heading-ids": "docusaurus write-heading-ids" + "write-heading-ids": "docusaurus write-heading-ids", + "gen:brand": "node scripts/gen-brand-assets.mjs" }, "dependencies": { "@docusaurus/core": "^3.6.3", - "@docusaurus/preset-classic": "^3.6.3", "@docusaurus/plugin-client-redirects": "^3.6.3", + "@docusaurus/preset-classic": "^3.6.3", "@easyops-cn/docusaurus-search-local": "^0.46.1", "@mdx-js/react": "^3.0.0", "clsx": "^2.0.0", @@ -26,10 +27,16 @@ }, "devDependencies": { "@docusaurus/module-type-aliases": "^3.6.3", - "@docusaurus/types": "^3.6.3" + "@docusaurus/types": "^3.6.3", + "docusaurus-plugin-goatcounter": "^4.0.0", + "sharp": "^0.35.2" }, "browserslist": { - "production": [">0.5%", "not dead", "not op_mini all"], + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], "development": [ "last 3 chrome version", "last 3 firefox version", @@ -37,6 +44,6 @@ ] }, "engines": { - "node": ">=18.0" + "node": ">=20.9.0" } } diff --git a/website/scripts/fetch-stats.mjs b/website/scripts/fetch-stats.mjs new file mode 100644 index 000000000..448d4ab19 --- /dev/null +++ b/website/scripts/fetch-stats.mjs @@ -0,0 +1,101 @@ +const PKG = 'mcpforunityserver'; +const REPO = 'CoplayDev/unity-mcp'; +const GH = 'https://api.github.com'; + +export function normalizePypiRecent(recent) { + if (recent == null) { + return { lastDay: null, lastWeek: null, lastMonth: null, unavailable: true }; + } + const d = (recent && recent.data) || {}; + return { lastDay: d.last_day ?? 0, lastWeek: d.last_week ?? 0, lastMonth: d.last_month ?? 0 }; +} + +// Builds the unified stats object. Honest user signals (GitHub clones/stars, +// and the in-product DAU/WAU surfaced elsewhere) sit alongside the noisy PyPI +// download proxy, which renderSummary clearly labels as inflated. +export function buildStats({ recent, repo = null, clones = null, views = null, webPageviews = null, generatedAt }) { + return { + generatedAt, + github: { + stars: repo?.stargazers_count ?? null, + forks: repo?.forks_count ?? null, + uniqueCloners14d: clones?.uniques ?? null, + uniqueViewers14d: views?.uniques ?? null, + }, + pypi: normalizePypiRecent(recent), + web: webPageviews, + }; +} + +export function renderSummary(stats) { + const g = stats.github, p = stats.pypi; + const n = (x) => (x == null ? '—' : Number(x).toLocaleString('en-US')); + const web = stats.web && stats.web.total != null + ? `${n(stats.web.total)} total pageviews` + : '_pending GoatCounter provisioning_'; + const trafficMissing = g.uniqueCloners14d == null && g.uniqueViewers14d == null; + return [ + '## MCP for Unity — adoption (maintainer-only)', + `_generated ${stats.generatedAt}_`, + '', + '### Real-user signals (the honest ones)', + '| Signal | Value | Reads as |', + '| --- | ---: | --- |', + `| In-product DAU / WAU | _pending_ | **true active users** — already collected by the in-product telemetry; needs a Coplay read API |`, + `| Unique repo cloners (14d) | ${n(g.uniqueCloners14d)} | developers actually pulling the code |`, + `| Unique repo viewers (14d) | ${n(g.uniqueViewers14d)} | distinct repo visitors |`, + `| GitHub stars | ${n(g.stars)} | real accounts interested |`, + `| GitHub forks | ${n(g.forks)} | |`, + ...(trafficMissing + ? ['', '> Cloners/viewers are blank: the workflow needs a maintainer PAT with **Administration: read** (`STATS_GITHUB_TOKEN`). See the external-analytics doc.'] + : []), + '', + '### Reach proxy (inflated — NOT a user count)', + '| Window | PyPI downloads |', + '| --- | ---: |', + `| Last day | ${n(p.lastDay)} |`, + `| Last week | ${n(p.lastWeek)} |`, + `| Last month | ${n(p.lastMonth)} |`, + '', + ...(p.unavailable + ? ['> PyPI stats are unavailable: the pypistats.org request failed. Do not treat these dashes as zero downloads.', ''] + : []), + '> PyPI counts are install events — CI, mirrors, `uvx` re-fetches, and Docker rebuilds inflate them heavily. Treat as a trend line, not people.', + '', + '### Docs traffic', + web, + '', + ].join('\n'); +} + +async function main() { + const get = async (url, headers) => { + try { const r = await fetch(url, { headers }); return r.ok ? await r.json() : null; } catch { return null; } + }; + const ghToken = process.env.STATS_GITHUB_TOKEN || process.env.GITHUB_TOKEN; + const ghHeaders = { + 'User-Agent': 'mcp-for-unity-stats', + Accept: 'application/vnd.github+json', + ...(ghToken ? { Authorization: `Bearer ${ghToken}` } : {}), + }; + + const recent = await get(`https://pypistats.org/api/packages/${PKG}/recent`, { Accept: 'application/json' }); + const repo = await get(`${GH}/repos/${REPO}`, ghHeaders); + const clones = await get(`${GH}/repos/${REPO}/traffic/clones`, ghHeaders); + const views = await get(`${GH}/repos/${REPO}/traffic/views`, ghHeaders); + + let web = null; + const gcToken = process.env.GOATCOUNTER_TOKEN, gcSite = process.env.GOATCOUNTER_SITE; + if (gcToken && gcSite) { + const j = await get(`https://${gcSite}.goatcounter.com/api/v0/stats/total`, { Authorization: `Bearer ${gcToken}` }); + if (j) web = { total: j.total ?? null }; + } + + const stats = buildStats({ recent, repo, clones, views, webPageviews: web, generatedAt: new Date().toISOString() }); + process.stdout.write(renderSummary(stats)); +} + +import { fileURLToPath } from 'node:url'; +if (process.argv[1] === fileURLToPath(import.meta.url)) { + main().catch((e) => { console.error(e); process.exit(1); }); +} diff --git a/website/scripts/fetch-stats.test.mjs b/website/scripts/fetch-stats.test.mjs new file mode 100644 index 000000000..b27f073fe --- /dev/null +++ b/website/scripts/fetch-stats.test.mjs @@ -0,0 +1,71 @@ +import { test } from 'node:test'; +import assert from 'node:assert/strict'; +import { normalizePypiRecent, buildStats, renderSummary } from './fetch-stats.mjs'; + +test('normalizePypiRecent extracts day/week/month', () => { + assert.deepEqual( + normalizePypiRecent({ data: { last_day: 100, last_week: 700, last_month: 3000 } }), + { lastDay: 100, lastWeek: 700, lastMonth: 3000 }, + ); +}); + +test('normalizePypiRecent handles missing data', () => { + assert.deepEqual(normalizePypiRecent({}), { lastDay: 0, lastWeek: 0, lastMonth: 0 }); +}); + +test('normalizePypiRecent marks failed requests as unavailable', () => { + assert.deepEqual( + normalizePypiRecent(null), + { lastDay: null, lastWeek: null, lastMonth: null, unavailable: true }, + ); +}); + +test('buildStats maps github + pypi + web', () => { + const stats = buildStats({ + recent: { data: { last_day: 1, last_week: 2, last_month: 3 } }, + repo: { stargazers_count: 11102, forks_count: 1229 }, + clones: { uniques: 84 }, + views: { uniques: 530 }, + webPageviews: { total: 42 }, + generatedAt: 't', + }); + assert.deepEqual(stats.github, { stars: 11102, forks: 1229, uniqueCloners14d: 84, uniqueViewers14d: 530 }); + assert.deepEqual(stats.pypi, { lastDay: 1, lastWeek: 2, lastMonth: 3 }); + assert.deepEqual(stats.web, { total: 42 }); +}); + +test('buildStats nulls github fields when sources unavailable', () => { + const stats = buildStats({ recent: { data: {} }, generatedAt: 't' }); + assert.deepEqual(stats.github, { stars: null, forks: null, uniqueCloners14d: null, uniqueViewers14d: null }); + assert.equal(stats.web, null); +}); + +test('renderSummary leads with real-user signals and labels PyPI as inflated', () => { + const stats = buildStats({ + recent: { data: { last_day: 4912, last_week: 38270, last_month: 192776 } }, + repo: { stargazers_count: 11102, forks_count: 1229 }, + clones: { uniques: 84 }, + views: { uniques: 530 }, + generatedAt: 't', + }); + const md = renderSummary(stats); + assert.match(md, /Real-user signals/); + assert.match(md, /GitHub stars \| 11,102/); + assert.match(md, /Unique repo cloners \(14d\) \| 84/); + assert.match(md, /true active users/); // DAU/WAU flagged first + assert.match(md, /inflated — NOT a user count/); + assert.match(md, /Last month \| 192,776/); +}); + +test('renderSummary notes when the traffic token is missing', () => { + const stats = buildStats({ recent: { data: {} }, repo: { stargazers_count: 1, forks_count: 0 }, generatedAt: 't' }); + assert.match(renderSummary(stats), /Administration: read/); +}); + +test('renderSummary distinguishes unavailable PyPI stats from zero downloads', () => { + const stats = buildStats({ recent: null, repo: { stargazers_count: 1, forks_count: 0 }, generatedAt: 't' }); + const md = renderSummary(stats); + assert.match(md, /Last day \| —/); + assert.match(md, /PyPI stats are unavailable/); + assert.match(md, /Do not treat these dashes as zero downloads/); +}); diff --git a/website/scripts/gen-brand-assets.mjs b/website/scripts/gen-brand-assets.mjs new file mode 100644 index 000000000..98e4c5350 --- /dev/null +++ b/website/scripts/gen-brand-assets.mjs @@ -0,0 +1,34 @@ +// Rasterizes the brand SVG marks into the favicon/icon PNG set. +// Run from the website/ directory: `npm run gen:brand` +// Text-bearing assets (hero banner, social card) are produced separately via +// an HTML render so the Satoshi wordmark uses the real font. +import sharp from 'sharp'; +import { readFile, mkdir } from 'node:fs/promises'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const HERE = path.dirname(fileURLToPath(import.meta.url)); // website/scripts +const ROOT = path.resolve(HERE, '..', '..'); +const IMG = path.join(ROOT, 'website', 'static', 'img'); + +const full = path.join(IMG, 'logo-mark.svg'); + +async function rasterize(src, size, out) { + const svg = await readFile(src); + await sharp(svg, { density: 512 }) + .resize(size, size, { fit: 'contain', background: { r: 0, g: 0, b: 0, alpha: 0 } }) + .png() + .toFile(out); + console.log(' wrote', path.relative(ROOT, out), `(${size}px)`); +} + +await mkdir(IMG, { recursive: true }); +await rasterize(full, 48, path.join(IMG, 'favicon.png')); +await rasterize(full, 32, path.join(IMG, 'favicon-32.png')); +await rasterize(full, 180, path.join(IMG, 'apple-touch-icon.png')); +await rasterize(full, 192, path.join(IMG, 'android-chrome-192.png')); +await rasterize(full, 512, path.join(IMG, 'android-chrome-512.png')); +// 128px source for the UPM package icon — wiring it into MCPForUnity needs the +// Unity Editor to generate the .meta, so it lives here as a source asset. +await rasterize(full, 128, path.join(IMG, 'package-icon.png')); +console.log('Brand icon set generated.'); diff --git a/website/sidebars.js b/website/sidebars.js index 1aee6cea5..dd158e28f 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -75,6 +75,7 @@ const sidebars = { 'architecture/manage-physics', 'architecture/project-roadmap', 'architecture/roadmap', + 'architecture/external-analytics', ], }, { @@ -96,6 +97,7 @@ const sidebars = { 'migrations/v5', 'migrations/v6', 'migrations/v8', + 'migrations/v10', ], }, 'releases', diff --git a/website/static/img/android-chrome-192.png b/website/static/img/android-chrome-192.png new file mode 100644 index 000000000..288a3cabe Binary files /dev/null and b/website/static/img/android-chrome-192.png differ diff --git a/website/static/img/android-chrome-512.png b/website/static/img/android-chrome-512.png new file mode 100644 index 000000000..a379e4e87 Binary files /dev/null and b/website/static/img/android-chrome-512.png differ diff --git a/website/static/img/apple-touch-icon.png b/website/static/img/apple-touch-icon.png new file mode 100644 index 000000000..8ba35c20d Binary files /dev/null and b/website/static/img/apple-touch-icon.png differ diff --git a/website/static/img/favicon-32.png b/website/static/img/favicon-32.png new file mode 100644 index 000000000..e31b79e68 Binary files /dev/null and b/website/static/img/favicon-32.png differ diff --git a/website/static/img/favicon.png b/website/static/img/favicon.png index 142983992..05bdfc00f 100644 Binary files a/website/static/img/favicon.png and b/website/static/img/favicon.png differ diff --git a/website/static/img/github-social-preview.png b/website/static/img/github-social-preview.png new file mode 100644 index 000000000..a02f51ff2 Binary files /dev/null and b/website/static/img/github-social-preview.png differ diff --git a/website/static/img/logo-mark-dark.svg b/website/static/img/logo-mark-dark.svg deleted file mode 100644 index 0195f0e1d..000000000 --- a/website/static/img/logo-mark-dark.svg +++ /dev/null @@ -1,6 +0,0 @@ - diff --git a/website/static/img/logo-mark.svg b/website/static/img/logo-mark.svg index 28d489cda..728afeca3 100644 --- a/website/static/img/logo-mark.svg +++ b/website/static/img/logo-mark.svg @@ -1,6 +1,23 @@ -