# Unity MCP WebSocket Hub Session Management Explained

> Unlock Unity MCP WebSocket hub session management. Learn how this CoplayDev repository ensures stable AI assistant connections with registration, keep-alive, and auto-reconnect.

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

---

**Unity MCP WebSocket hub session management establishes persistent connections between AI assistants and the Unity editor through a resilient transport layer that handles registration, keep-alive pings, and automatic reconnection with exponential backoff.**

The Model Context Protocol (MCP) bridge in the [CoplayDev/unity-mcp](https://github.com/CoplayDev/unity-mcp) repository enables AI assistants to communicate with the Unity editor via a WebSocket transport connected to the MCP server's plugin hub (`/hub/plugin`). Understanding how this WebSocket hub manages session lifecycles—from initial connection establishment through error recovery—is essential for building reliable AI-powered Unity workflows.

## WebSocket Connection Establishment

The session lifecycle begins in [`WebSocketTransportClient.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/WebSocketTransportClient.cs) where the transport builds connection candidates and resolves the correct URI for the MCP hub.

The `BuildWebSocketUri` method (lines 22‑48) constructs the WebSocket endpoint, while `BuildConnectionCandidateUris` (lines 61‑72) handles edge cases with bind-only hosts. When the server binds to `0.0.0.0`, the client translates this to `127.0.0.1`; similarly, `::` becomes `::1` for local connections. If the user selects "localhost," the transport falls back to explicit loopback addresses to ensure reliable connectivity.

## Client Registration and Session ID Assignment

Once the socket opens, the client initiates the registration protocol. The `SendRegisterAsync` method (lines 92‑104) transmits a `register` message containing project metadata including the project name, hash, Unity version, and file path.

The server responds with a `registered` message processed by `HandleRegisteredAsync` (lines 110‑118). This response contains the critical **session ID** that uniquely identifies this editor instance to the MCP hub. The client immediately stores this identifier in `ProjectIdentityUtility` for reuse across reconnects and includes it in every subsequent ping/pong exchange.

## Persistent Session State with ProjectIdentityUtility

Session persistence relies on [`ProjectIdentityUtility.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/ProjectIdentityUtility.cs) (lines 13‑20), which stores the session ID in `EditorPrefs` keyed to the specific project. This per-project storage enables:

- **Session restoration** after network interruptions or editor domain reloads
- **Cross-transport recognition** allowing HTTP local transports to detect active WebSocket sessions
- **UI state synchronization** ensuring the connection interface reflects the actual hub registration status

The `SetSessionId` helper persists the identifier, while companion methods retrieve project hashes and names required during re-registration.

## Keep-Alive Mechanism and Ping/Pong Protocol

Active sessions require periodic health checks. The `KeepAliveLoopAsync` method (lines 66‑76) manages the heartbeat interval, which is negotiated from the server's welcome message (`keepAliveInterval`).

The transport sends `pong` payloads via `SendPongAsync` (lines 108‑115) containing the current session ID. This allows the MCP server to detect stale connections and maintain accurate session rosters. If the server fails to receive these pongs within the negotiated window, it marks the session as disconnected.

## Error Handling and Auto-Reconnection Strategy

When network failures occur, `HandleSocketClosureAsync` (lines 145‑164) captures the error, logs the failure, and transitions the transport to a disconnected state. Control then passes to `AttemptReconnectAsync` (lines 166‑208), which implements a sophisticated retry schedule.

The reconnection algorithm follows this delay pattern:

- Immediate first attempt
- 1 second delay
- 3 second delay  
- 5 second delay
- 10 second delay
- 30 second delay
- Perpetual 30‑second retries thereafter

Upon successful reconnection, the client automatically re-registers tools via `SendRegisterToolsAsync` and restores the previous session ID from `ProjectIdentityUtility`, maintaining continuity for AI assistant interactions.

## UI Integration and Session Visualization

The [`McpConnectionSection.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/McpConnectionSection.cs) component (lines 21‑38) provides the visual interface for session management. The `UpdateConnectionStatus` method reflects the transport state by:

- Disabling the connection toggle when a session is already active
- Updating button labels to show current status
- Automatically terminating orphaned sessions when the server disappears unexpectedly

This ensures users always have accurate visibility into the WebSocket hub connection state without manual verification.

## Practical Implementation Examples

### Starting a WebSocket Session

```csharp
var transport = new WebSocketTransportClient();
await transport.StartAsync();          // triggers connection, registration, keep‑alive
Debug.Log($"Session ID: {transport.State.SessionId}");

```

### Sending Diagnostic Pings

```csharp
await transport.SendPongAsync(CancellationToken.None);

```

### Force-Stopping a Session

Useful during domain reloads or when switching transports:

```csharp
transport.ForceStop();    // aborts socket, cancels reconnection loops

```

### Re-registering After Hot-Reload

```csharp
await transport.ReregisterToolsAsync();

```

## Summary

- **Connection establishment** handles localhost binding edge cases through `BuildWebSocketUri` and `BuildConnectionCandidateUris` in [`WebSocketTransportClient.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/WebSocketTransportClient.cs)
- **Session registration** exchanges project metadata for a unique session ID stored in `ProjectIdentityUtility`
- **State persistence** uses `EditorPrefs` to maintain session continuity across editor restarts and domain reloads
- **Keep-alive protocol** sends periodic `pong` messages with session IDs to prevent server-side timeout
- **Auto-reconnection** implements exponential backoff (1s, 3s, 5s, 10s, 30s) via `AttemptReconnectAsync`
- **UI synchronization** through `McpConnectionSection` ensures users have real-time visibility into session status

## Frequently Asked Questions

### How does Unity MCP handle session persistence between editor restarts?

The transport persists session IDs using `EditorPrefs` through the `ProjectIdentityUtility.SetSessionId` method (lines 13‑20). When Unity restarts, the client retrieves the previous session identifier from [`MCPForUnity/Editor/Helpers/ProjectIdentityUtility.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/MCPForUnity/Editor/Helpers/ProjectIdentityUtility.cs) and attempts to reclaim the existing session during registration, ensuring AI assistants maintain context across editor sessions.

### What happens when the WebSocket connection drops unexpectedly?

The `HandleSocketClosureAsync` method (lines 145‑164) detects the closure and triggers `AttemptReconnectAsync` (lines 166‑208), which follows a progressive retry schedule (immediate, 1s, 3s, 5s, 10s, 30s, then perpetual 30s). During successful reconnection, the client automatically re-registers tools and restores the session ID without user intervention.

### How does the transport resolve localhost binding issues?

In [`WebSocketTransportClient.cs`](https://github.com/CoplayDev/unity-mcp/blob/main/WebSocketTransportClient.cs), the `BuildConnectionCandidateUris` method (lines 61‑72) translates bind-all addresses to loopback equivalents—converting `0.0.0.0` to `127.0.0.1` and `::` to `::1`—ensuring the client connects correctly regardless of whether the server binds to specific interfaces or wildcard addresses.

### Can multiple Unity projects maintain simultaneous MCP sessions?

Yes. Because `ProjectIdentityUtility` stores session data in `EditorPrefs` using project-specific keys (combining project hash and name), each Unity project maintains its own independent session ID. The WebSocket transport connects to `/hub/plugin` with unique identifiers, allowing the MCP server to distinguish between multiple concurrent Unity editor instances.