# Unity MCP setup — Claude (WSL) driving the Unity Editor (Windows) **Goal:** let Claude Code (running in WSL) control the Unity Editor (running on the Windows host) via MCP — the same pattern our UE projects already use (nwiro / ChiR24): the MCP server runs **host-side over HTTP**, and Claude in WSL connects across the WSL↔Windows boundary by its host IP. **Server:** [CoplayDev/unity-mcp](https://github.com/CoplayDev/unity-mcp) ("MCP for Unity", MIT, ~12k★). Chosen because it's the most popular/maintained and — critically — supports an **HTTP transport** (`url: http://host:8080/mcp`), which bridges the WSL boundary cleanly instead of a same-machine stdio assumption. > The in-editor **"Configure All Detected Clients"** button will *not* find WSL's `claude` (it looks on Windows), so we configure Claude manually via the committed `.mcp.json` (already in this repo) pointed at the Windows host IP. ## Current values (this machine) **✅ WORKING CONFIG (verified 2026-07-10, mcp-for-unity-server v3.4.4):** - **Windows host IP as seen from WSL:** `172.27.208.1` (the WSL default gateway; confirm with `ip route show default`). Can change across WSL restarts — if MCP stops connecting, re-check it and update `.mcp.json`. - **MCP server:** binds `127.0.0.1:8067` (set the port in the *MCP for Unity* window; HTTP transport). **Do NOT use 8080** — see gotcha below. - **WSL bridge:** Windows `netsh portproxy` `0.0.0.0:8068 → 127.0.0.1:8067` (+ firewall allow on 8068). A **distinct** listen port (8068) is required — a proxy on `0.0.0.0:8067` would collide with the server's `127.0.0.1:8067` bind. - **`.mcp.json`** (committed) → `{"unity": {"type":"http","url":"http://172.27.208.1:8068/mcp"}}` - **`.claude/settings.local.json`** (local) pre-enables the `unity` server. - **Verify from WSL:** `curl -s -X POST http://172.27.208.1:8068/mcp -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"0"}}}'` → should return an `initialize` result naming `mcp-for-unity-server`. **⚠️ Gotcha — the port 8080 trap (why this took a few tries):** binding `8080` failed with Windows `[Errno 13] ... forbidden by its access permissions` (WSAEACCES). That's because **WSL2 runs on Hyper-V/WinNAT, which reserves large TCP port ranges**, and 8080 fell inside one. The server silently started then shut down; the "open 8080" was only the dead portproxy accepting + resetting. Fix = pick a port **outside** the reserved ranges (check `netsh interface ipv4 show excludedportrange protocol=tcp`) — we used `8067`. Bridge with a *different* proxy port (`8068`) to avoid the loopback/all-interfaces bind collision. **Bridge commands (admin PowerShell), for reference / re-setup:** ```powershell netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8068 connectaddress=127.0.0.1 connectport=8067 New-NetFirewallRule -DisplayName "Unity MCP 8068" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8068 netsh interface portproxy show all ``` ## One-time setup (do on Windows, in the Unity Editor) 1. **Create/open the Unity project** at `F:\jankenstein` (Unity LTS). This repo already lives there — Unity will add `Assets/`, `Packages/`, `ProjectSettings/` alongside the existing files. 2. **Install the package:** `Window → Package Manager → + → Add package from git URL…` ``` https://github.com/CoplayDev/unity-mcp.git?path=/MCPForUnity#main ``` 3. **Open** `Window → MCP for Unity`. Switch the transport to **HTTP** and **Start** the server (listens on `:8080`). Note the exact port shown. 4. **Make it reachable from WSL.** The HTTP server binds loopback by default, so pick one: - **(a)** If the panel exposes a non-loopback / `0.0.0.0` / "listen on all interfaces" option, enable it. Then WSL reaches it directly at `http://172.27.208.1:8080/mcp`. - **(b)** Otherwise add a Windows port-proxy + firewall rule (admin PowerShell) — same trick pair-o-dox uses for nwiro: ```powershell netsh interface portproxy add v4tov4 listenaddress=0.0.0.0 listenport=8080 connectaddress=127.0.0.1 connectport=8080 New-NetFirewallRule -DisplayName "Unity MCP 8080" -Direction Inbound -Action Allow -Protocol TCP -LocalPort 8080 ``` Remove later with `netsh interface portproxy delete v4tov4 listenaddress=0.0.0.0 listenport=8080`. ## Connect from WSL (Claude Code) 1. Make sure the Unity Editor is **running with the project open** and the MCP server is **Started** (step 3 above) — the tools only work while the editor is live. 2. Run Claude from this folder (`/mnt/f/jankenstein`, or the symlink `~/claude/projects/jankenstein`). The committed `.mcp.json` + `.claude/settings.local.json` register/enable the `unity` server. 3. **Restart the Claude session** after any transport or `.mcp.json` change so it re-reads the config. 4. **Verify:** Claude should see `mcp__unity__*` tools. Quick smoke test: ask it to read the open scene / list GameObjects. If it fails: - `curl -s http://172.27.208.1:8080/mcp` from WSL — no response ⇒ the bridge (step 4) isn't up or the IP changed. - Confirm the editor is open and the server Started. - Re-check the gateway IP (`ip route show default`). ## Gotchas - **Editor must be open** with the project loaded — MCP drives the live editor, it doesn't launch it. - **IP drift:** the WSL gateway IP (`172.27.208.1`) can change on WSL restart; update `.mcp.json` if so. - **HTTP↔stdio toggling** in the Unity panel requires a Claude restart to pick up. - This is **editor tooling**, unrelated to the game's own netcode (NGO + Relay) — different layer entirely.