CoplayDev/unity-mcp · error · UnityConnectionError

Connection to Unity timed out after {timeout or cfg.timeout}

Error message

Connection to Unity timed out after {timeout or cfg.timeout}s. Unity may be busy or unresponsive.

What it means

Thrown by send_command() when httpx raises a TimeoutException while posting to /api/command. It reports the effective timeout (the per-call override or cfg.timeout). Timeouts mean the server was reachable but did not respond in time — typically because Unity is busy compiling, importing, or hung.

Source

Thrown at Server/src/cli/utils/connection.py:117

        payload["unity_instance"] = cfg.unity_instance

    try:
        async with httpx.AsyncClient() as client:
            response = await client.post(
                url,
                json=payload,
                timeout=timeout or cfg.timeout,
            )
            response.raise_for_status()
            return response.json()
    except httpx.ConnectError as e:
        raise UnityConnectionError(
            f"Cannot connect to Unity MCP server at {cfg.host}:{cfg.port}. "
            f"Make sure the server is running and Unity is connected.\n"
            f"Error: {e}"
        )
    except httpx.TimeoutException:
        raise UnityConnectionError(
            f"Connection to Unity timed out after {timeout or cfg.timeout}s. "
            f"Unity may be busy or unresponsive."
        )
    except httpx.HTTPStatusError as e:
        raise UnityConnectionError(
            f"HTTP error from server: {e.response.status_code} - {e.response.text}"
        )
    except Exception as e:
        raise UnityConnectionError(f"Unexpected error: {e}")


def run_command(
    command_type: str,
    params: Dict[str, Any],
    config: Optional[CLIConfig] = None,
    timeout: Optional[int] = None,
) -> Dict[str, Any]:
    """Synchronous wrapper for send_command.

View on GitHub (pinned to c21bf496bc)

Solutions

  1. Increase the timeout for heavy operations via the timeout argument or UNITY_MCP_TIMEOUT.
  2. Ensure Unity is not blocked on a modal dialog or compilation during the call.
  3. Split very large operations into smaller batches so each call completes within the timeout.

Example fix

# before
UNITY_MCP_TIMEOUT=10 unity-mcp texture create Assets/Big.png
# after
UNITY_MCP_TIMEOUT=120 unity-mcp texture create Assets/Big.png
Defensive patterns

Strategy: retry

Validate before calling

import socket
# pre-flight: confirm a response is plausible; size timeout to the operation
timeout = 120 if heavy_op else cfg.timeout

Try / catch

for attempt in range(3):
    try:
        return await send_command(cmd, params, timeout=120)
    except UnityConnectionError as e:
        if "timed out" not in str(e) or attempt == 2:
            raise

Prevention

When it happens

Trigger: A command that triggers heavy Unity work (large asset import, script recompile, play-mode) exceeding the configured timeout, or an unresponsive Unity Editor. Reproducible with a low UNITY_MCP_TIMEOUT against a slow operation.

Common situations: Default 30s timeout too short for big texture/asset operations; Unity stuck on a modal dialog; or the Editor main thread blocked so the WebSocket→HTTP path stalls.

Understand the failure class

Related errors


AI-assisted analysis of CoplayDev/unity-mcp@c21bf496bc (2026-08-13). Data as JSON: /api/errors/64c46c5e71a7cd89. Report an issue: GitHub.