@@ -42,6 +42,9 @@ public class WebSocketTransportClient : IMcpTransportClient, IDisposable
4242
4343 private Uri _endpointUri ;
4444 private string _sessionId ;
45+ private string _projectHash ;
46+ private string _projectName ;
47+ private string _unityVersion ;
4548 private TimeSpan _keepAliveInterval = DefaultKeepAliveInterval ;
4649 private TimeSpan _socketKeepAliveInterval = DefaultKeepAliveInterval ;
4750 private volatile bool _isConnected ;
@@ -54,19 +57,25 @@ public class WebSocketTransportClient : IMcpTransportClient, IDisposable
5457
5558 public async Task < bool > StartAsync ( )
5659 {
60+ // Capture identity values on the main thread before any async context switching
61+ _projectName = ProjectIdentityUtility . GetProjectName ( ) ;
62+ _projectHash = ProjectIdentityUtility . GetProjectHash ( ) ;
63+ _unityVersion = Application . unityVersion ;
64+
5765 await StopAsync ( ) ;
5866
5967 _lifecycleCts = new CancellationTokenSource ( ) ;
6068 _endpointUri = BuildWebSocketUri ( HttpEndpointUtility . GetBaseUrl ( ) ) ;
61- _sessionId = ProjectIdentityUtility . GetOrCreateSessionId ( ) ;
69+ _sessionId = null ;
6270
6371 if ( ! await EstablishConnectionAsync ( _lifecycleCts . Token ) )
6472 {
6573 await StopAsync ( ) ;
6674 return false ;
6775 }
6876
69- _state = TransportState . Connected ( TransportDisplayName , sessionId : _sessionId , details : _endpointUri . ToString ( ) ) ;
77+ // State is connected but session ID might be pending until 'registered' message
78+ _state = TransportState . Connected ( TransportDisplayName , sessionId : "pending" , details : _endpointUri . ToString ( ) ) ;
7079 _isConnected = true ;
7180 return true ;
7281 }
@@ -281,6 +290,9 @@ private async Task HandleMessageAsync(string message, CancellationToken token)
281290 case "welcome" :
282291 ApplyWelcome ( payload ) ;
283292 break ;
293+ case "registered" :
294+ HandleRegistered ( payload ) ;
295+ break ;
284296 case "execute" :
285297 await HandleExecuteAsync ( payload , token ) . ConfigureAwait ( false ) ;
286298 break ;
@@ -311,6 +323,18 @@ private void ApplyWelcome(JObject payload)
311323 }
312324 }
313325
326+ private void HandleRegistered ( JObject payload )
327+ {
328+ string newSessionId = payload . Value < string > ( "session_id" ) ;
329+ if ( ! string . IsNullOrEmpty ( newSessionId ) )
330+ {
331+ _sessionId = newSessionId ;
332+ ProjectIdentityUtility . SetSessionId ( _sessionId ) ;
333+ _state = TransportState . Connected ( TransportDisplayName , sessionId : _sessionId , details : _endpointUri . ToString ( ) ) ;
334+ McpLog . Info ( $ "[WebSocket] Registered with session ID: { _sessionId } ") ;
335+ }
336+ }
337+
314338 private async Task HandleExecuteAsync ( JObject payload , CancellationToken token )
315339 {
316340 string commandId = payload . Value < string > ( "id" ) ;
@@ -409,10 +433,10 @@ private async Task SendRegisterAsync(CancellationToken token)
409433 var registerPayload = new JObject
410434 {
411435 [ "type" ] = "register" ,
412- [ " session_id" ] = _sessionId ,
413- [ "project_name" ] = ProjectIdentityUtility . GetProjectName ( ) ,
414- [ "project_hash" ] = ProjectIdentityUtility . GetProjectHash ( ) ,
415- [ "unity_version" ] = Application . unityVersion
436+ // session_id is now server-authoritative; omitted here or sent as null
437+ [ "project_name" ] = _projectName ,
438+ [ "project_hash" ] = _projectHash ,
439+ [ "unity_version" ] = _unityVersion
416440 } ;
417441
418442 await SendJsonAsync ( registerPayload , token ) . ConfigureAwait ( false ) ;
0 commit comments