Feature: Add MCP remote_open/remote_close remote control sessions

Add M1 of MCP remote control (docs/Mcp_RemoteControl_Design.md): the
remote_open / remote_close tools plus the ScreenCtrlSession state machine.

remote_open establishes a hidden screen sub-connection by reusing
WebService::StartRemoteDesktop (COMMAND_SCREEN_SPY -> CScreenSpyDlg ->
RegisterScreenContext), polls for the sub-connection plus its physical
resolution (TOKEN_BITMAPINFO -> NotifyResolutionChange -> GetScreenSize),
then records the session (single device, single session, reverse-mapped
subCtx for OfflineProc cleanup) and returns {session_id, screen_w,
screen_h}. remote_close validates session_id and tears down the
sub-connection idempotently. A McpRemoteControl settings checkbox (default
off, requires McpReadonly=0) gates the tools; every open/close is audited
via WM_SHOWERRORMSG.

Gating: multi-monitor hosts are rejected with -32008 (phase 1 supports only
single monitor, where Observe=main screen and Act=virtual desktop coincide);
the monitor count comes from the client heartbeat RES_RESOLUTION ("N:W*H").

Known limitations (deferred to the injection milestones): mutual exclusion
with human remote-desktop viewing is one-directional in M1 (a human who
joins during an MCP session can tear it down on disconnect), and subCtx is
not yet dereferenced so no liveness re-check is needed until
remote_mouse/remote_keyboard.

Co-Authored-By: deepseek-v4-pro
This commit is contained in:
yuanyuanxiang
2026-08-25 12:55:52 +02:00
parent 84e3565de1
commit 6045baadb8
7 changed files with 469 additions and 4 deletions

View File

@@ -1670,6 +1670,17 @@ void CWebService::NotifyResolutionChange(uint64_t device_id, int width, int heig
}
}
bool CWebService::GetScreenSize(uint64_t device_id, int& width, int& height) {
width = 0;
height = 0;
std::lock_guard<std::mutex> lock(m_DeviceCacheMutex);
auto it = m_DeviceCache.find(device_id);
if (it == m_DeviceCache.end()) return false;
width = it->second->screen_width;
height = it->second->screen_height;
return width > 0 && height > 0;
}
void CWebService::NotifyAudioState(uint64_t device_id, bool enabled) {
if (m_bStopping) return;