Skip to content

MCP server frequently disconnects and fails to restart when Unity still owns the configured HTTP port #6

@JOY

Description

@JOY

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

  1. The MCP server appears as running in the Unity window.
  2. MCP tool calls from the client may later time out or disconnect.
  3. Toggling the server off/on, restarting Unity, or domain reload can lead to startup failure.
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions