Summary
Funplay MCP for Unity frequently disconnects or becomes unresponsive in a Unity project, then fails to restart with an HTTP transport bind error even though the port is owned by the same Unity Editor process.
This looks like a server lifecycle / idempotent-start issue: an existing listener can remain alive or partially alive, while a later start path attempts to bind the same port again instead of detecting/reusing/stopping the existing transport cleanly.
Environment
- OS: Windows 11
- Unity: 6000.5.0b8
- Funplay MCP for Unity: v0.3.4
- Transport: HTTP
- Tool exposure: full
- Port used: 8766
- Client configured: Codex
Symptoms
- The MCP server appears as running in the Unity window.
- MCP tool calls from the client may later time out or disconnect.
- Toggling the server off/on, restarting Unity, or domain reload can lead to startup failure.
- Unity Console reports:
[Funplay MCP Server] Failed to start HTTP transport: Only one usage of each socket address (protocol/network address/port) is normally permitted.
UnityEngine.Debug:LogError (object)
Funplay.Editor.MCP.Server.HttpMCPTransport/<StartAsync>d__12:MoveNext () (at ./Library/PackageCache/com.gamebooom.unity.mcp@b600f4e2b1d3/Editor/MCP/Server/HttpMCPTransport.cs:79)
Funplay.Editor.MCP.Server.MCPServerService/<StartAsync>d__26:MoveNext () (at ./Library/PackageCache/com.gamebooom.unity.mcp@b600f4e2b1d3/Editor/MCP/Server/MCPServerService.cs:111)
Funplay.Editor.MCP.Server.FunplayMCPWindow/<>c__DisplayClass18_0:<BuildUI>b__0 (at ./Library/PackageCache/com.gamebooom.unity.mcp@b600f4e2b1d3/Editor/MCP/Server/FunplayMCPWindow.cs:124)
[Funplay MCP Server] Failed to start transport
UnityEngine.Debug:LogError (object)
Funplay.Editor.MCP.Server.MCPServerService/<StartAsync>d__26:MoveNext () (at ./Library/PackageCache/com.gamebooom.unity.mcp@b600f4e2b1d3/Editor/MCP/Server/MCPServerService.cs:121)
On the same machine, Windows reports the configured port is owned by Unity itself, not by a stale node/client process:
LocalAddress LocalPort State OwningProcess
::1 8766 Listen 152460
127.0.0.1 8766 Listen 152460
127.0.0.1 8766 CloseWait 152460
127.0.0.1 8766 Established 152460
ProcessName: Unity
Path: D:\Program Files\Unity Hub\Editors\6000.5.0b8\Editor\Unity.exe
Expected behavior
- Starting the MCP server should be idempotent.
- If the transport is already running in the same Unity process, Start should treat it as running or cleanly restart it before binding again.
- Stop/Dispose should tolerate already-disposed listeners without throwing noisy errors.
- Domain reload / assembly reload / Unity restart recovery should not leave the server UI in a running-but-unusable state.
Actual behavior
- The server can show as running but client calls time out.
- A later start path tries to bind the same port again and fails with
Only one usage of each socket address....
- The only reliable recovery is usually changing port or fully restarting Unity, and even then the issue may return.
Related observation
A separate stop/dispose error was also seen earlier:
[Funplay MCP Server] Error stopping HTTP transport: Cannot access a disposed object.
Object name: 'System.Net.HttpListener'.
Funplay.Editor.MCP.Server.HttpMCPTransport:Stop () (at ./Library/PackageCache/com.gamebooom.unity.mcp@.../Editor/MCP/Server/HttpMCPTransport.cs:108)
Funplay.Editor.MCP.Server.HttpMCPTransport:Dispose () (at ./Library/PackageCache/com.gamebooom.unity.mcp@.../Editor/MCP/Server/HttpMCPTransport.cs:373)
Funplay.Editor.MCP.Server.MCPServerService:StopSync () (at ./Library/PackageCache/com.gamebooom.unity.mcp@.../Editor/MCP/Server/MCPServerService.cs:155)
Funplay.Editor.MCP.Server.MCPServerDomainReloadHandler:OnBeforeReload () (at ./Library/PackageCache/com.gamebooom.unity.mcp@.../Editor/MCP/Server/MCPServerDomainReloadHandler.cs:65)
This may be related to listener lifecycle cleanup around reloads.
Suggested fix direction
- Add a guard in
MCPServerService.StartAsync so repeated Start calls do not create a second HTTP transport when one is already running or starting.
- Make
HttpMCPTransport.Stop() and Dispose() idempotent and safe when the underlying HttpListener is already disposed.
- On bind failure, detect whether the current Unity process already owns the port and surface a clearer "already running / stale state" message, or recover by stopping the old listener before retrying.
- Consider cleaning up
CloseWait connections or adding a health probe that reconciles UI state with actual listener state.
Thanks for the project. The embedded Unity-side server approach is very convenient when it stays connected; this lifecycle issue is the main blocker in day-to-day use right now.
Summary
Funplay MCP for Unity frequently disconnects or becomes unresponsive in a Unity project, then fails to restart with an HTTP transport bind error even though the port is owned by the same Unity Editor process.
This looks like a server lifecycle / idempotent-start issue: an existing listener can remain alive or partially alive, while a later start path attempts to bind the same port again instead of detecting/reusing/stopping the existing transport cleanly.
Environment
Symptoms
On the same machine, Windows reports the configured port is owned by Unity itself, not by a stale node/client process:
Expected behavior
Actual behavior
Only one usage of each socket address....Related observation
A separate stop/dispose error was also seen earlier:
This may be related to listener lifecycle cleanup around reloads.
Suggested fix direction
MCPServerService.StartAsyncso repeated Start calls do not create a second HTTP transport when one is already running or starting.HttpMCPTransport.Stop()andDispose()idempotent and safe when the underlyingHttpListeneris already disposed.CloseWaitconnections or adding a health probe that reconciles UI state with actual listener state.Thanks for the project. The embedded Unity-side server approach is very convenient when it stays connected; this lifecycle issue is the main blocker in day-to-day use right now.