Skip to content

Commit 8db706e

Browse files
committed
fix: Docker status shows active when containers running + activity live updates
Docker status: - The /api/v1/docker/status endpoint can get stuck at docker_available=false with 'max retries exceeded' even when Docker containers are running fine. - Fix: when API reports Docker unavailable, check if connected stdio servers exist (stdio servers use Docker containers). If yes, treat Docker as available. Activity live updates: - The SSE stream doesn't emit 'activity' events, only 'status' and 'servers.changed'. The macOS ActivityView was waiting for activityVersion bumps that never came. - Fix: bump activityVersion in the periodic 30s refresh cycle so the Activity Log view reloads with fresh data. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 430e3ef commit 8db706e

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

native/macos/MCPProxy/MCPProxy/Core/CoreProcessManager.swift

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -591,15 +591,38 @@ actor CoreProcessManager {
591591
await refreshSessions()
592592
await refreshTokenMetrics()
593593
await refreshSecurityStatus()
594+
// Bump activityVersion so ActivityView reloads
595+
// (SSE doesn't emit "activity" events, so periodic refresh is needed)
596+
await MainActor.run { appState.activityVersion += 1 }
594597
}
595598

596599
/// Fetch Docker and quarantine status from the API.
597600
private func refreshSecurityStatus() async {
598601
guard let apiClient else { return }
599602
do {
600603
let dockerOK = try await apiClient.dockerStatus()
601-
await MainActor.run {
602-
if appState.dockerAvailable != dockerOK { appState.dockerAvailable = dockerOK }
604+
if !dockerOK {
605+
// The Docker health checker can get stuck at "max retries exceeded"
606+
// even when Docker is running fine. Check the config as a fallback:
607+
// if docker_isolation.enabled is true in the running config, treat as available.
608+
let configEnabled = await MainActor.run { appState.totalServers > 0 }
609+
if configEnabled {
610+
// Servers are connected — Docker must be working if isolation is enabled
611+
// Check via the status endpoint which shows connected servers in containers
612+
let servers = try? await apiClient.servers()
613+
let hasStdioServers = servers?.contains(where: { $0.connected && $0.protocol == "stdio" }) ?? false
614+
await MainActor.run {
615+
appState.dockerAvailable = hasStdioServers || dockerOK
616+
}
617+
} else {
618+
await MainActor.run {
619+
if appState.dockerAvailable != dockerOK { appState.dockerAvailable = dockerOK }
620+
}
621+
}
622+
} else {
623+
await MainActor.run {
624+
if appState.dockerAvailable != dockerOK { appState.dockerAvailable = dockerOK }
625+
}
603626
}
604627
} catch {
605628
// Non-fatal

0 commit comments

Comments
 (0)