# How to Debug Unity MCP Connection Issues: WebSocket and HTTP Troubleshooting Guide

> Troubleshoot Unity MCP connection issues like WebSocket and HTTP errors. Learn to debug invalid endpoints and WebSocket lifecycle mismatches with our guide.

- Repository: [Coplay/unity-mcp](https://github.com/CoplayDev/unity-mcp)
- Tags: how-to-guide
- Published: 2026-07-06

---

**Unity MCP connection failures most commonly originate from invalid HTTP endpoint configurations, bind-all address resolution errors, or WebSocket lifecycle mismatches that can be isolated by inspecting `TransportState.Error` and validating output from `HttpEndpointUtility.GetBaseUrl()`.**

When AI assistants cannot communicate with the Unity Editor through the Model Context Protocol, the root cause typically lies in the transport layer implementation within the CoplayDev/unity-mcp repository. Understanding how `TransportManager` coordinates `WebSocketTransportClient` and how `HttpEndpointUtility` resolves base URLs allows you to systematically diagnose registration failures, dropped keep-alive pings, and authentication errors.

## Unity MCP Transport Architecture Overview

The Unity MCP SDK implements a pluggable transport layer with distinct components responsible for connection lifecycle management.

### Key Architectural Components

- **TransportManager** ([`MCPForUnity/Editor/Services/Transport/TransportManager.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Services/Transport/TransportManager.cs)): Creates and controls the active client instance, handling start/stop operations and state aggregation for both HTTP and stdio modes.
- **WebSocketTransportClient** ([`MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Services/Transport/Transports/WebSocketTransportClient.cs)): Manages the persistent WebSocket connection, tool registration, keep-alive loops, and exponential backoff reconnection logic.
- **HttpEndpointUtility** ([`MCPForUnity/Editor/Helpers/HttpEndpointUtility.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Helpers/HttpEndpointUtility.cs)): Resolves the base URL for local (`http://127.0.0.1:8080`) or remote scopes and validates security policies including HTTPS requirements.
- **TransportState** ([`MCPForUnity/Editor/Services/Transport/TransportState.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Services/Transport/TransportState.cs)): Provides an immutable snapshot of connection status, exposing `IsConnected`, `SessionId`, and `Error` properties for runtime inspection.

### Connection Initialization Flow

1. **Manager Startup**: `TransportManager.StartAsync(TransportMode.Http)` instantiates `WebSocketTransportClient` through its internal factory.
2. **Endpoint Resolution**: The client queries `HttpEndpointUtility.GetBaseUrl()` to determine the target server address.
3. **URI Construction**: `WebSocketTransportClient.BuildWebSocketUri(baseUrl)` rewrites bind-only hosts (`0.0.0.0` → `127.0.0.1`, `::` → `::1`) and appends `/hub/plugin` to the path.
4. **Socket Establishment**: `EstablishConnectionAsync` iterates candidate URIs, creates `ClientWebSocket`, and applies API key headers from `EditorPrefs.GetString(EditorPrefKeys.ApiKey)`.
5. **Registration**: Upon successful connection, the client transmits a register payload containing `project_name` and `project_hash`, then synchronizes enabled tools.
6. **Keep-Alive**: A background task pings the server every 15 seconds (`keepAliveInterval`); failure triggers `AttemptReconnectAsync` using exponential backoff (0s to 30s) followed by steady 30-second intervals.

## Diagnosing Common Unity MCP Connection Problems

Connection symptoms map directly to specific failure points in the architecture. Use targeted diagnostics for each error pattern.

### "Connection failed. Check that the server URL is correct…"

This error indicates `HttpEndpointUtility` cannot resolve a valid base URL or the server is unreachable.

- Verify the active URL via `HttpEndpointUtility.GetBaseUrl()` in the Unity Console.
- Confirm **Editor > Advanced Settings** matches the server's listening address and port (default: `8080`).
- For remote connections, ensure the scheme is `https` unless **Allow Insecure Remote HTTP** is explicitly enabled.

### Bind-All Address Warnings (0.0.0.0 Resolution)

When the log displays *"Base URL host '0.0.0.0' is bind-only; using '127.0.0.1' for client connection"*, the MCP server was launched with a bind-all flag that clients cannot use directly.

- Reconfigure the server launch arguments to `--bind 127.0.0.1` instead of `0.0.0.0`.
- Alternatively, enable **Allow LAN Bind for HTTP Local** in the Unity MCP settings to permit non-loopback addresses.
- Check `McpLog.Warn` entries to confirm the host rewrite occurred in `BuildWebSocketUri`.

### WebSocket Disconnection During Send Operations

Errors stating *"WebSocket is not open"* or *"SendJsonAsync – WebSocket is not initialised"* occur when the socket closes before a command transmission, often following a failed keep-alive ping.

- Inspect `TransportManager.GetState(TransportMode.Http).Error` via a custom Editor script to retrieve the specific disconnection reason.
- Review logs prefixed with `[WebSocket] Receive loop error` to identify server-side terminations.
- Verify the MCP server process remains active and has not crashed from unhandled exceptions.

### API Key Authentication Failures in Remote Mode

Remote HTTP mode requires a valid API key header injected during `EstablishConnectionAsync` (lines 70-73 of [`WebSocketTransportClient.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/WebSocketTransportClient.cs)).

- Validate that `EditorPrefs.GetString(EditorPrefKeys.ApiKey)` returns a non-empty string matching your server configuration.
- Connection will silently fail or return authorization errors if this preference is unset or expired.

### Command Execution Timeouts

Tools that exceed `DefaultCommandTimeout` (30 seconds) will trigger timeout exceptions.

- Extend the deadline by passing a larger `timeout` value (in seconds) within the `execute` message payload.
- Optimize tool implementations to complete within the default window, or implement progress reporting to prevent keep-alive starvation.

## Debugging Code Examples for Unity MCP

Use these snippets to programmatically inspect connection health and force recovery.

### Manually Starting the HTTP Transport

Call this from an Editor script or test fixture to validate the full startup sequence:

```csharp
using MCPForUnity.Editor.Services;
using MCPForUnity.Editor.Services.Transport;
using System.Threading.Tasks;
using UnityEngine;

public static async Task<bool> ValidateMcpConnectionAsync()
{
    var manager = new TransportManager();
    bool isConnected = await manager.StartAsync(TransportMode.Http);
    
    if (!isConnected)
    {
        var state = manager.GetState(TransportMode.Http);
        Debug.LogError($"MCP HTTP start failed: {state.Error}");
    }
    
    return isConnected;
}

```

### Forcing Reconnection After Network Outage

When the socket enters a stale state, force a clean restart:

```csharp
public static async Task RecoverConnectionAsync()
{
    var manager = new TransportManager();
    
    // Terminates the existing client without graceful close
    manager.ForceStop(TransportMode.Http);
    
    // Re-runs the full connection and registration flow
    await manager.StartAsync(TransportMode.Http);
}

```

### Inspecting Current Endpoint Configuration

Debug endpoint resolution and security scope:

```csharp
using MCPForUnity.Editor.Helpers;
using UnityEngine;

public static void DiagnoseEndpoint()
{
    string baseUrl = HttpEndpointUtility.GetBaseUrl();
    bool isRemote = HttpEndpointUtility.IsRemoteScope();
    
    Debug.Log($"MCP endpoint ({(isRemote ? "remote" : "local")}): {baseUrl}");
    
    if (isRemote && baseUrl.StartsWith("http://"))
    {
        Debug.LogWarning("Insecure remote HTTP detected. Enable 'AllowInsecureRemoteHttp' or switch to HTTPS.");
    }
}

```

### Adjusting Keep-Alive Intervals (Advanced)

Modify the ping frequency before calling `StartAsync()` using reflection:

```csharp
var client = new WebSocketTransportClient();
var field = client.GetType().GetField(
    "_keepAliveInterval", 
    System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance
);

field?.SetValue(client, System.TimeSpan.FromSeconds(30));
await client.StartAsync();

```

## Reading Transport State and Logs

All WebSocket activity logs use the `[WebSocket]` prefix, categorized by severity through `McpLog`. To surface runtime diagnostics:

1. Query `TransportManager.GetState(TransportMode.Http)` to access `TransportState.IsConnected` and `TransportState.Error`.
2. Enable verbose logging in the Unity Console to capture `McpLog.Debug` messages containing raw JSON payloads in `ReceiveLoopAsync`.
3. Monitor `BridgeControlService` ([`MCPForUnity/Editor/Services/BridgeControlService.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Services/BridgeControlService.cs)) for UI-level connection indicators in the Editor toolbar.

## Summary

- **Validate endpoints first**: Use `HttpEndpointUtility.GetBaseUrl()` to confirm the client targets the correct server address and scheme.
- **Handle bind-all addresses**: Replace `0.0.0.0` with `127.0.0.1` in server configuration or enable LAN binding to prevent connection refusals.
- **Inspect TransportState**: `TransportManager.GetState(mode).Error` provides the definitive reason for disconnection.
- **Check authentication**: Remote mode requires `EditorPrefKeys.ApiKey` to be set before `EstablishConnectionAsync` executes.
- **Force recovery**: Use `ForceStop` followed by `StartAsync` to clear stale sockets and trigger fresh registration when automatic reconnection stalls.

## Frequently Asked Questions

### Why does Unity MCP show "Connection failed. Check that the server URL is correct…"?

This error appears when `HttpEndpointUtility` resolves a base URL that is unreachable or malformed. Verify the URL in **Editor > Advanced Settings** matches your MCP server's listening address, ensure the port is correct (default 8080), and confirm remote URLs use HTTPS unless `AllowInsecureRemoteHttp` is enabled.

### How do I fix the "Base URL host '0.0.0.0' is bind-only" warning?

The warning indicates your MCP server launched with `--bind 0.0.0.0`, which accepts connections on all interfaces but cannot be used as a client destination. Configure the server to bind specifically to `127.0.0.1` for local development, or enable **Allow LAN Bind for HTTP Local** in Unity MCP settings to permit the client to connect to non-loopback addresses.

### What does "WebSocket is not open" mean and how do I resolve it?

This error occurs when `WebSocketTransportClient` attempts to send data while the underlying `ClientWebSocket` is closed or null, typically due to a failed keep-alive ping or server termination. Check `TransportState.Error` for the specific failure reason, verify the server process is running, and use `ForceStop` followed by `StartAsync` to reset the connection state if the automatic reconnection loop has stalled.

### How can I check the current connection status programmatically?

Call `TransportManager.GetState(TransportMode.Http)` to retrieve a `TransportState` object containing `IsConnected`, `SessionId`, and `Error` properties. This immutable snapshot reflects the live status of the WebSocket transport and can be polled in Editor scripts or displayed in custom debugging windows to monitor MCP health in real-time.