|
| 1 | +### Cursor/VSCode/Windsurf: UV path issue on Windows (diagnosis and fix) |
| 2 | + |
| 3 | +#### The issue |
| 4 | +- Some Windows machines have multiple `uv.exe` locations. Our auto-config sometimes picked a less stable path, causing the MCP client to fail to launch the Unity MCP Server or for the path to be auto-rewritten on repaint/restart. |
| 5 | + |
| 6 | +#### Typical symptoms |
| 7 | +- Cursor shows the UnityMCP server but never connects or reports it “can’t start.” |
| 8 | +- Your `%USERPROFILE%\\.cursor\\mcp.json` flips back to a different `command` path when Unity or the Unity MCP window refreshes. |
| 9 | + |
| 10 | +#### Real-world example |
| 11 | +- Wrong/fragile path (auto-picked): |
| 12 | + - `C:\Users\mrken.local\bin\uv.exe` (malformed, not standard) |
| 13 | + - `C:\Users\mrken\AppData\Local\Microsoft\WinGet\Packages\astral-sh.uv_Microsoft.Winget.Source_8wekyb3d8bbwe\uv.exe` |
| 14 | +- Correct/stable path (works with Cursor): |
| 15 | + - `C:\Users\mrken\AppData\Local\Microsoft\WinGet\Links\uv.exe` |
| 16 | + |
| 17 | +#### Quick fix (recommended) |
| 18 | +1) In Unity: `Window > Unity MCP` → select your MCP client (Cursor or Windsurf) |
| 19 | +2) If you see “uv Not Found,” click “Choose UV Install Location” and browse to: |
| 20 | + - `C:\Users\<YOU>\AppData\Local\Microsoft\WinGet\Links\uv.exe` |
| 21 | +3) If uv is already found but wrong, still click “Choose UV Install Location” and select the `Links\uv.exe` path above. This saves a persistent override. |
| 22 | +4) Click “Auto Configure” (or re-open the client) and restart Cursor. |
| 23 | + |
| 24 | +This sets an override stored in the Editor (key: `UnityMCP.UvPath`) so UnityMCP won’t auto-rewrite the config back to a different `uv.exe` later. |
| 25 | + |
| 26 | +#### Verify the fix |
| 27 | +- Confirm global Cursor config is at: `%USERPROFILE%\\.cursor\\mcp.json` |
| 28 | +- You should see something like: |
| 29 | + |
| 30 | +```json |
| 31 | +{ |
| 32 | + "mcpServers": { |
| 33 | + "unityMCP": { |
| 34 | + "command": "C:\\Users\\YOU\\AppData\\Local\\Microsoft\\WinGet\\Links\\uv.exe", |
| 35 | + "args": [ |
| 36 | + "--directory", |
| 37 | + "C:\\Users\\YOU\\AppData\\Local\\Programs\\UnityMCP\\UnityMcpServer\\src", |
| 38 | + "run", |
| 39 | + "server.py" |
| 40 | + ] |
| 41 | + } |
| 42 | + } |
| 43 | +} |
| 44 | +``` |
| 45 | + |
| 46 | +- Manually run the same command in PowerShell to confirm it launches: |
| 47 | + |
| 48 | +```powershell |
| 49 | +"C:\Users\YOU\AppData\Local\Microsoft\WinGet\Links\uv.exe" --directory "C:\Users\YOU\AppData\Local\Programs\UnityMCP\UnityMcpServer\src" run server.py |
| 50 | +``` |
| 51 | + |
| 52 | +If that runs without error, restart Cursor and it should connect. |
| 53 | + |
| 54 | +#### Why this happens |
| 55 | +- On Windows, multiple `uv.exe` can exist (WinGet Packages path, a WinGet Links shim, Python Scripts, etc.). The Links shim is the most stable target for GUI apps to launch. |
| 56 | +- Prior versions of the auto-config could pick the first found path and re-write config on refresh. Choosing a path via the MCP window pins a known‑good absolute path and prevents auto-rewrites. |
| 57 | + |
| 58 | +#### Extra notes |
| 59 | +- Restart Cursor after changing `mcp.json`; it doesn’t always hot-reload that file. |
| 60 | +- If you also have a project-scoped `.cursor\\mcp.json` in your Unity project folder, that file overrides the global one. |
| 61 | + |
| 62 | + |
| 63 | +### Why pin the WinGet Links shim (and not the Packages path) |
| 64 | + |
| 65 | +- Windows often has multiple `uv.exe` installs and GUI clients (Cursor/Windsurf/VSCode) may launch with a reduced `PATH`. Using an absolute path is safer than `"command": "uv"`. |
| 66 | +- WinGet publishes stable launch shims in these locations: |
| 67 | + - User scope: `%LOCALAPPDATA%\Microsoft\WinGet\Links\uv.exe` |
| 68 | + - Machine scope: `C:\Program Files\WinGet\Links\uv.exe` |
| 69 | + These shims survive upgrades and are intended as the portable entrypoints. See the WinGet notes: [discussion](https://github.com/microsoft/winget-pkgs/discussions/184459) • [how to find installs](https://superuser.com/questions/1739292/how-to-know-where-winget-installed-a-program) |
| 70 | +- The `Packages` root is where payloads live and can change across updates, so avoid pointing your config at it. |
| 71 | + |
| 72 | +Recommended practice |
| 73 | + |
| 74 | +- Prefer the WinGet Links shim paths above. If present, select one via “Choose UV Install Location”. |
| 75 | +- If the unity window keeps rewriting to a different `uv.exe`, pick the Links shim again; Unity MCP saves a pinned override and will stop auto-rewrites. |
| 76 | +- If neither Links path exists, a reasonable fallback is `~/.local/bin/uv.exe` (uv tools bin) or a Scoop shim, but Links is preferred for stability. |
| 77 | + |
| 78 | +References |
| 79 | + |
| 80 | +- WinGet portable Links: [GitHub discussion](https://github.com/microsoft/winget-pkgs/discussions/184459) |
| 81 | +- WinGet install locations: [Super User](https://superuser.com/questions/1739292/how-to-know-where-winget-installed-a-program) |
| 82 | +- GUI client PATH caveats (Cursor): [Cursor community thread](https://forum.cursor.com/t/mcp-feature-client-closed-fix/54651?page=4) |
| 83 | +- uv tools install location (`~/.local/bin`): [Astral docs](https://docs.astral.sh/uv/concepts/tools/) |
| 84 | + |
| 85 | + |
0 commit comments