Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MCPForUnity/Editor/Constants/EditorPrefKeys.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,5 +63,6 @@ internal static class EditorPrefKeys
internal const string CustomerUuid = "MCPForUnity.CustomerUUID";

internal const string ApiKey = "MCPForUnity.ApiKey";
internal const string KeepServerRunning = "MCPForUnity.KeepServerRunning";
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR description mentions a Unity Editor UI toggle and sending a keep_server_running flag during WebSocket registration, but the only Unity-side change in this PR appears to be adding the EditorPrefs key. A repo-wide search shows no other references to EditorPrefKeys.KeepServerRunning or any C# code emitting keep_server_running in a registration message, so the feature looks incomplete or the description is ahead of the code.

Copilot uses AI. Check for mistakes.
}
}
9 changes: 9 additions & 0 deletions MCPForUnity/Editor/Services/McpEditorShutdownCleanup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,17 @@ private static void OnEditorQuitting()
}

// 2) Stop local HTTP server if it was Unity-managed (best-effort).
// Skip shutdown if Keep Server Running is enabled - server should persist for reconnection.
try
{
bool keepServerRunning = EditorPrefs.GetBool(EditorPrefKeys.KeepServerRunning, false);

if (keepServerRunning)
{
McpLog.Info("Keep Server Running is enabled - leaving MCP server running after Unity quits");
return;
}

bool useHttp = EditorConfigurationCache.Instance.UseHttpTransport;
string scope = string.Empty;
try { scope = EditorPrefs.GetString(EditorPrefKeys.HttpTransportScope, string.Empty); } catch { }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ public class WebSocketTransportClient : IMcpTransportClient, IDisposable
private int _isReconnectingFlag;
private TransportState _state = TransportState.Disconnected(TransportDisplayName, "Transport not started");
private string _apiKey;
private bool _keepServerRunning;
private bool _disposed;

public WebSocketTransportClient(IToolDiscoveryService toolDiscoveryService = null)
Expand Down Expand Up @@ -85,6 +86,7 @@ public async Task<bool> StartAsync()
_apiKey = HttpEndpointUtility.IsRemoteScope()
? EditorPrefs.GetString(EditorPrefKeys.ApiKey, string.Empty)
: string.Empty;
_keepServerRunning = EditorPrefs.GetBool(EditorPrefKeys.KeepServerRunning, false);

// Get project root path (strip /Assets from dataPath) for focus nudging
string dataPath = Application.dataPath;
Expand Down Expand Up @@ -608,7 +610,8 @@ private async Task SendRegisterAsync(CancellationToken token)
["project_name"] = _projectName,
["project_hash"] = _projectHash,
["unity_version"] = _unityVersion,
["project_path"] = _projectPath
["project_path"] = _projectPath,
["keep_server_running"] = _keepServerRunning
};

await SendJsonAsync(registerPayload, token).ConfigureAwait(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,14 @@ public class McpAdvancedSection
private VisualElement healthIndicator;
private Label healthStatus;
private Button testConnectionButton;
private Toggle keepServerRunningToggle;

// Events
public event Action OnGitUrlChanged;
public event Action OnHttpServerCommandUpdateRequested;
public event Action OnTestConnectionRequested;
public event Action<bool> OnBetaModeChanged;
public event Action<bool> OnKeepServerRunningChanged;

public VisualElement Root { get; private set; }

Expand Down Expand Up @@ -77,6 +79,7 @@ private void CacheUIElements()
deployStatusLabel = Root.Q<Label>("deploy-status-label");
healthIndicator = Root.Q<VisualElement>("health-indicator");
healthStatus = Root.Q<Label>("health-status");
keepServerRunningToggle = Root.Q<Toggle>("keep-server-running-toggle");
testConnectionButton = Root.Q<Button>("test-connection-button");
}

Expand Down Expand Up @@ -108,6 +111,26 @@ private void InitializeUI()
if (betaServerLabel != null)
betaServerLabel.tooltip = useBetaServerToggle.tooltip;
}
if (keepServerRunningToggle != null)
{
// When enabled, server stays running after Unity disconnects (for auto-reconnect)
keepServerRunningToggle.tooltip = "When enabled, MCP server will stay running even when Unity disconnects. "
+ "Useful during development to avoid manual server restart after Domain Reload, test runs, or entering Play Mode. "
+ "Only works with HTTP transport mode.";
var keepRunningLabel = keepServerRunningToggle?.parent?.Q<Label>();
if (keepRunningLabel != null)
{
keepRunningLabel.tooltip = keepServerRunningToggle.tooltip;
}
// Load current value and register callback
keepServerRunningToggle.value = EditorPrefs.GetBool(EditorPrefKeys.KeepServerRunning, false);
keepServerRunningToggle.RegisterValueChangedCallback(evt =>
{
EditorPrefs.SetBool(EditorPrefKeys.KeepServerRunning, evt.newValue);
OnKeepServerRunningChanged?.Invoke(evt.newValue);
OnHttpServerCommandUpdateRequested?.Invoke();
});
}
Comment on lines +114 to +133
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

rg -n -C5 'keepServerRunning|keep-server-running|KeepServerRunning' --type=cs -g '!*Test*'

Repository: CoplayDev/unity-mcp

Length of output: 9272


🏁 Script executed:

rg -n 'SetEnabled.*keepServerRunning|keepServerRunning.*SetEnabled' --type=cs -g '!*Test*'

Repository: CoplayDev/unity-mcp

Length of output: 45


🏁 Script executed:

rg -n -B5 -A5 'keepServerRunningToggle|KeepServerRunning' --type=cs -g '!*Test*' | grep -i 'enabled\|visible\|transport\|http\|stdio'

Repository: CoplayDev/unity-mcp

Length of output: 2488


🏁 Script executed:

rg -n 'McpAdvancedSection' --type=cs -g '!*Test*'

Repository: CoplayDev/unity-mcp

Length of output: 685


🏁 Script executed:

cat -n MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs | head -100

Repository: CoplayDev/unity-mcp

Length of output: 4234


🏁 Script executed:

rg -n 'advancedSection|SetEnabled|transport.*mode|http.*mode' -A2 -B2 MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs --type=cs

Repository: CoplayDev/unity-mcp

Length of output: 1869


🏁 Script executed:

rg -n 'transport.*mode|TransportMode|HTTP|STDIO' --type=cs -g '!*Test*' | grep -i 'enabled\|visible\|toggle\|advanced' | head -20

Repository: CoplayDev/unity-mcp

Length of output: 1593


🏁 Script executed:

rg -n 'public.*void.*Set|public.*void.*Update|public.*void.*Enable|public.*void.*Disable' MCPForUnity/Editor/Windows/Components/Advanced/McpAdvancedSection.cs --type=cs

Repository: CoplayDev/unity-mcp

Length of output: 186


🏁 Script executed:

rg -n -A10 'OnKeepServerRunningChanged' --type=cs -g '!*Test*'

Repository: CoplayDev/unity-mcp

Length of output: 2525


🏁 Script executed:

rg -n 'transport.*mode\|TransportMode\|IsHttpMode\|IsStdioMode' --type=cs -g '!*Test*' | head -30

Repository: CoplayDev/unity-mcp

Length of output: 45


🏁 Script executed:

rg -n 'TransportMode|transport.*mode|IsHttpMode|HttpMode|StdioMode' --type=cs -g '!*Test*' | head -40

Repository: CoplayDev/unity-mcp

Length of output: 5434


🏁 Script executed:

rg -n 'enum.*Transport|class.*Transport' --type=cs -g '!*Test*' | head -20

Repository: CoplayDev/unity-mcp

Length of output: 1058


🏁 Script executed:

rg -n -B3 -A3 'OnKeepServerRunningChanged' MCPForUnity/Editor/Windows/MCPForUnityEditorWindow.cs --type=cs

Repository: CoplayDev/unity-mcp

Length of output: 45


🏁 Script executed:

wc -l MCPForUnity/Editor/Windows/Components/Advanced/McpAdvancedSection.cs

Repository: CoplayDev/unity-mcp

Length of output: 135


🏁 Script executed:

cat -n MCPForUnity/Editor/Windows/Components/Advanced/McpAdvancedSection.cs | tail -n +240 | head -n 100

Repository: CoplayDev/unity-mcp

Length of output: 4939


🏁 Script executed:

rg -n 'public|private.*void.*Transport|SetEnabled|SetDisplay|style\.display' MCPForUnity/Editor/Windows/Components/Advanced/McpAdvancedSection.cs --type=cs

Repository: CoplayDev/unity-mcp

Length of output: 711


Transport-mode gating is missing for the keep-server-running toggle.

The PR description specifies the toggle should be "enabled only when HTTP transport is active; stdio mode shows an explanation," but McpAdvancedSection has no transport-mode detection or SetEnabled/visibility logic. The toggle will appear and remain functional regardless of the active transport mode. There is no public method to control the toggle's enabled state, and MCPForUnityEditorWindow does not wire up any transport-mode event handlers. Either add transport-mode gating to McpAdvancedSection or confirm this is managed by a parent coordinator.

🤖 Prompt for AI Agents
In `@MCPForUnity/Editor/Windows/Components/Advanced/McpAdvancedSection.cs` around
lines 114 - 133, McpAdvancedSection currently always shows and allows toggling
keepServerRunningToggle without checking transport mode; update
McpAdvancedSection to detect the active transport (e.g., via a TransportMode
property/event or a supplied enum like HTTP vs STDIO) and gate the control: when
transport is HTTP enable and show keepServerRunningToggle (and preserve
tooltip/label), when transport is STDIO disable or hide the toggle and replace
it with an explanatory Label; expose a public method or property on
McpAdvancedSection (e.g., SetTransportMode(TransportMode mode) or
SetKeepServerRunningEnabled(bool)) so the parent MCPForUnityEditorWindow can
call it, and ensure that changes still call existing callbacks
OnKeepServerRunningChanged and OnHttpServerCommandUpdateRequested and respect
EditorPrefKeys.KeepServerRunning when enabled.

if (testConnectionButton != null)
testConnectionButton.tooltip = "Test the connection between Unity and the MCP server.";
if (deploySourcePath != null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<ui:Button name="browse-uv-button" text="Browse" class="icon-button" />
<ui:Button name="clear-uv-button" text="Clear" class="icon-button" />
</ui:VisualElement>

<ui:VisualElement class="override-row" style="margin-top: 8px;">
<ui:Label text="Server Source:" class="override-label" />
</ui:VisualElement>
Expand All @@ -21,12 +20,10 @@
<ui:Button name="browse-git-url-button" text="Select" class="icon-button" />
<ui:Button name="clear-git-url-button" text="Clear" class="icon-button" />
</ui:VisualElement>

<ui:VisualElement class="setting-row" style="margin-top: 8px;">
<ui:Label text="Debug Logging:" class="setting-label" />
<ui:Toggle name="debug-logs-toggle" class="setting-toggle" />
</ui:VisualElement>

<ui:VisualElement class="setting-row">
<ui:Label text="Server Health:" class="setting-label" />
<ui:VisualElement class="status-container">
Expand All @@ -35,17 +32,18 @@
</ui:VisualElement>
<ui:Button name="test-connection-button" text="Test" class="action-button" />
</ui:VisualElement>

<ui:VisualElement class="setting-row">
<ui:Label text="Force Fresh Install:" class="setting-label" />
<ui:Toggle name="dev-mode-force-refresh-toggle" class="setting-toggle" />
</ui:VisualElement>

<ui:VisualElement class="setting-row">
<ui:Label text="Use Beta Server:" class="setting-label" />
<ui:Toggle name="use-beta-server-toggle" class="setting-toggle" />
</ui:VisualElement>

<ui:VisualElement class="setting-row" style="margin-top: 4px;">
<ui:Label text="Keep Server Running:" class="setting-label" />
<ui:Toggle name="keep-server-running-toggle" class="setting-toggle" />
</ui:VisualElement>
<ui:VisualElement class="override-row" style="margin-top: 8px;">
<ui:Label text="Package Source:" class="override-label" />
</ui:VisualElement>
Expand All @@ -63,4 +61,4 @@
<ui:Label name="deploy-status-label" class="help-text" />
</ui:VisualElement>
</ui:VisualElement>
</ui:UXML>
</ui:UXML>
38 changes: 32 additions & 6 deletions Server/src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,11 +133,15 @@ def doRollover(self):
# In-memory custom tool service initialized after MCP construction
custom_tool_service: CustomToolService | None = None

# Per-session keep_server_running flag, indexed by session_id
# Set by middleware when Unity registers with the flag enabled
keep_server_running: dict[str, bool] = {}
Comment on lines +136 to +138
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

keep_server_running dict is never populated — shutdown keep-alive logic is inert.

The global keep_server_running: dict[str, bool] is declared here and checked during shutdown (line 259), but no code in this PR ever writes to it. The PluginHub._handle_register stores the flag on PluginSession in the registry, but never updates main.keep_server_running. Similarly, the unity_instance_middleware.py imports main but doesn't write to this dict.

As a result, has_keep_running (line 259) is always False, and the keep-server-running feature has no effect on shutdown behavior. You need to bridge the registration path to this global state — either by having _handle_register (or the registry) update this dict, or by querying PluginRegistry sessions during shutdown instead of maintaining a separate dict.

🔧 Option: query the registry directly at shutdown instead of maintaining a separate dict
-# Per-session keep_server_running flag, indexed by session_id
-# Set by middleware when Unity registers with the flag enabled
-keep_server_running: dict[str, bool] = {}

Then at shutdown (lines 256-271), query the registry:

-        has_keep_running = any(keep_server_running.values()) if keep_server_running else False
+        has_keep_running = False
+        if _plugin_registry is not None:
+            try:
+                sessions = await _plugin_registry.list_sessions()
+                has_keep_running = any(s.keep_server_running for s in sessions.values())
+            except Exception:
+                pass
 
         if _unity_connection_pool and not has_keep_running:
             _unity_connection_pool.disconnect_all()
 
         shutdown_msg = "MCP for Unity Server shut down"
         if has_keep_running:
             shutdown_msg += " (Keep-Running mode: maintaining server for Unity reconnection)"
         logger.info(shutdown_msg)
-
-        # Note: keep_server_running state is per-session, not server-global.
-        # Cleared when sessions expire, used by middleware to pass state.
-        keep_server_running.clear()
🤖 Prompt for AI Agents
In `@Server/src/main.py` around lines 136 - 138, The global keep_server_running
dict is never written to, so shutdown logic never sees per-session keep-alive
flags; fix by either updating this dict when sessions register or by querying
the registry at shutdown: add code in PluginHub._handle_register to set
main.keep_server_running[session.session_id] = session.keep_server_running
(using the PluginSession/PluginHub path that creates the session), and ensure
you clear the key on unregister, OR change the shutdown routine that computes
has_keep_running to iterate PluginRegistry (or call
PluginRegistry.get_session(sid)) and check PluginSession.keep_server_running for
any active sessions instead of reading the unused keep_server_running dict.



@asynccontextmanager
async def server_lifespan(server: FastMCP) -> AsyncIterator[dict[str, Any]]:
"""Handle server startup and shutdown."""
global _unity_connection_pool, _server_version
global _unity_connection_pool, _server_version, keep_server_running
_server_version = get_package_version()
logger.info(f"MCP for Unity Server v{_server_version} starting up")

Expand Down Expand Up @@ -183,9 +187,17 @@ def _emit_startup():
logger.info(
"Skipping Unity connection on startup (UNITY_MCP_SKIP_STARTUP_CONNECT=1)")
else:
# Initialize connection pool and discover instances
_unity_connection_pool = get_unity_connection_pool()
instances = _unity_connection_pool.discover_all_instances()
# Initialize connection pool and discover instances (stdio mode only)
# In HTTP mode, PluginHub handles connections directly
instances = [] # Initialize to avoid UnboundLocalError in HTTP mode
if enable_http_server:
_unity_connection_pool = None # No legacy pool in HTTP mode
logger.info("HTTP mode enabled - PluginHub will manage Unity connections")
# Skip stdio-specific connection logic in HTTP mode.
# Lifespan must still continue to reach the context yield.
else:
_unity_connection_pool = get_unity_connection_pool()
instances = _unity_connection_pool.discover_all_instances()

if instances:
logger.info(
Expand Down Expand Up @@ -244,9 +256,23 @@ def _emit_startup():
"plugin_registry": _plugin_registry,
}
finally:
if _unity_connection_pool:
# In HTTP mode, PluginHub manages connections independently.
# Only disconnect legacy pool if it was initialized (stdio mode).
Comment on lines 258 to +260
Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

keep_server_running is referenced as a global dict (keep_server_running.values(), keep_server_running.clear()), but there is no module-level definition in main.py, so this will raise NameError during shutdown. Also, the new state is stored on PluginSession.keep_server_running, so this shutdown logic should derive the flag from the registry’s sessions (or define/populate the intended global state consistently).

Copilot uses AI. Check for mistakes.
# Check if any session has keep_server_running enabled.
has_keep_running = any(keep_server_running.values()) if keep_server_running else False

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Initialize keep_server_running before lifespan cleanup

The shutdown path now evaluates any(keep_server_running.values()), but keep_server_running is never initialized at module scope or assigned in this function. This causes a NameError during lifespan teardown, so server shutdown errors out regardless of whether any sessions were active.

Useful? React with 👍 / 👎.


if _unity_connection_pool and not has_keep_running:
_unity_connection_pool.disconnect_all()
logger.info("MCP for Unity Server shut down")

shutdown_msg = "MCP for Unity Server shut down"
if has_keep_running:
shutdown_msg += " (Keep-Running mode: maintaining server for Unity reconnection)"
logger.info(shutdown_msg)

# Note: keep_server_running state is per-session, not server-global.
# Cleared when sessions expire, used by middleware to pass state.
keep_server_running.clear()



def _build_instructions(project_scoped_tools: bool) -> str:
Expand Down
1 change: 1 addition & 0 deletions Server/src/transport/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ class RegisterMessage(BaseModel):
project_hash: str
unity_version: str = "Unknown"
project_path: str | None = None # Full path to project root (for focus nudging)
keep_server_running: bool = False # When True, server stays running after Unity disconnects


class RegisterToolsMessage(BaseModel):
Expand Down
18 changes: 17 additions & 1 deletion Server/src/transport/plugin_hub.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,13 @@ async def on_disconnect(self, websocket: WebSocket, close_code: int) -> None:
ping_task.cancel()
# Clean up last pong tracking
cls._last_pong.pop(session_id, None)
# Clean up keep_server_running flag to avoid stale entries
try:
import main as main_module
main_module.keep_server_running.pop(session_id, None)
except (ImportError, AttributeError, KeyError):
# main module not yet imported or key already removed
pass
# Fail-fast any in-flight commands for this session to avoid waiting for COMMAND_TIMEOUT.
pending_ids = [
command_id
Expand Down Expand Up @@ -364,6 +371,7 @@ async def _handle_register(self, websocket: WebSocket, payload: RegisterMessage)
project_hash = payload.project_hash
unity_version = payload.unity_version
project_path = payload.project_path
keep_server_running = getattr(payload, 'keep_server_running', False)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Add keep_server_running to RegisterMessage schema

PluginHub._handle_register reads getattr(payload, 'keep_server_running', False), but RegisterMessage (in transport/models.py) does not define that field, and Pydantic drops unknown keys by default. In practice, a Unity client sending "keep_server_running": true will still be registered with False, so the new keep-running toggle never takes effect.

Useful? React with 👍 / 👎.

Copy link

Copilot AI Feb 11, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

getattr(payload, 'keep_server_running', False) will always fall back to False because RegisterMessage (in Server/src/transport/models.py) does not define a keep_server_running field, and Pydantic will ignore unknown keys by default. Add keep_server_running: bool = False to the RegisterMessage model (or configure it to allow extra fields) so the flag actually propagates into the registry.

Suggested change
keep_server_running = getattr(payload, 'keep_server_running', False)
keep_server_running = False

Copilot uses AI. Check for mistakes.

if not project_hash:
await websocket.close(code=4400)
Expand All @@ -378,7 +386,15 @@ async def _handle_register(self, websocket: WebSocket, payload: RegisterMessage)
response = RegisteredMessage(session_id=session_id)
await websocket.send_json(response.model_dump())

session = await registry.register(session_id, project_name, project_hash, unity_version, project_path, user_id=user_id)
session = await registry.register(
session_id, project_name, project_hash, unity_version, project_path,
user_id=user_id, keep_server_running=keep_server_running
)

# Store keep_server_running flag in global dict for shutdown logic.
# Import here to avoid circular dependency at module import time.
import main as main_module
main_module.keep_server_running[session.session_id] = keep_server_running
async with lock:
cls._connections[session.session_id] = websocket
# Initialize last pong time and start ping loop for this session
Expand Down
7 changes: 5 additions & 2 deletions Server/src/transport/plugin_registry.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ class PluginSession:
project_name: str
project_hash: str
unity_version: str
registered_at: datetime
connected_at: datetime
registered_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
connected_at: datetime = field(default_factory=lambda: datetime.now(timezone.utc))
tools: dict[str, ToolDefinitionModel] = field(default_factory=dict)
project_id: str | None = None
# Full path to project root (for focus nudging)
project_path: str | None = None
user_id: str | None = None # Associated user id (None for local mode)
keep_server_running: bool = False # When True, server stays running after Unity disconnects


class PluginRegistry:
Expand Down Expand Up @@ -55,6 +56,7 @@ async def register(
unity_version: str,
project_path: str | None = None,
user_id: str | None = None,
keep_server_running: bool = False,
) -> PluginSession:
"""Register (or replace) a plugin session.

Expand All @@ -76,6 +78,7 @@ async def register(
connected_at=now,
project_path=project_path,
user_id=user_id,
keep_server_running=keep_server_running,
)

# Remove old mapping for this hash if it existed under a different session
Expand Down
36 changes: 36 additions & 0 deletions Server/tests/integration/test_plugin_hub_websocket_auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,39 @@ async def test_user_id_passed_to_registry_on_register(self, monkeypatch):
assert session.user_id == "user-99"
assert session.project_name == "TestProject"
assert session.project_hash == "abc123"

@pytest.mark.asyncio
async def test_register_tracks_connection_and_keep_running_state(self, monkeypatch):
"""Register should store the websocket connection and keep-running flag."""
monkeypatch.setattr(config, "http_remote_hosted", False)

registry = PluginRegistry()
loop = asyncio.get_running_loop()
PluginHub.configure(registry, loop)

ws = _make_mock_websocket(headers={})
hub = _make_hub()

import main as main_module
main_module.keep_server_running.clear()

await hub.on_connect(ws)
await hub.on_receive(
ws,
{
"type": "register",
"project_name": "KeepAliveProject",
"project_hash": "keep-alive-hash",
"unity_version": "2022.3",
"keep_server_running": True,
},
)

sessions = await registry.list_sessions()
assert len(sessions) == 1
session_id = next(iter(sessions.keys()))

assert session_id in PluginHub._connections
assert main_module.keep_server_running.get(session_id) is True

main_module.keep_server_running.clear()
Loading