Skip to content

Commit 9f085c3

Browse files
committed
Improve tray status syncing and diagnostics
1 parent 0b41b9a commit 9f085c3

File tree

4 files changed

+70
-6
lines changed

4 files changed

+70
-6
lines changed

cmd/mcpproxy-tray/internal/api/adapter.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,18 @@ func (a *ServerAdapter) StopServer() error {
7979

8080
// GetStatus returns the current server status
8181
func (a *ServerAdapter) GetStatus() interface{} {
82+
listenAddr := a.client.listenAddress()
83+
if listenAddr == "" {
84+
listenAddr = ":8080"
85+
}
86+
8287
servers, err := a.client.GetServers()
8388
if err != nil {
8489
return map[string]interface{}{
85-
"phase": "Error",
86-
"message": fmt.Sprintf("API error: %v", err),
90+
"phase": "Error",
91+
"message": fmt.Sprintf("API error: %v", err),
92+
"running": false,
93+
"listen_addr": listenAddr,
8794
}
8895
}
8996

@@ -97,6 +104,8 @@ func (a *ServerAdapter) GetStatus() interface{} {
97104
return map[string]interface{}{
98105
"phase": "Running",
99106
"message": fmt.Sprintf("API connected - %d servers", len(servers)),
107+
"running": true,
108+
"listen_addr": listenAddr,
100109
"connected_servers": connectedCount,
101110
"total_servers": len(servers),
102111
}

cmd/mcpproxy-tray/internal/api/client.go

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ import (
99
"crypto/x509"
1010
"encoding/json"
1111
"fmt"
12+
"net"
1213
"net/http"
14+
"net/url"
1315
"os"
1416
"os/exec"
1517
"path/filepath"
@@ -491,10 +493,22 @@ func (c *Client) OpenWebUI() error {
491493
if c.apiKey != "" {
492494
url += "?apikey=" + c.apiKey
493495
}
494-
c.logger.Info("Opening web control panel", "url", c.baseURL+"/ui/")
496+
displayURL := url
497+
if c.apiKey != "" {
498+
displayURL = strings.ReplaceAll(url, c.apiKey, maskForLog(c.apiKey))
499+
}
500+
if c.logger != nil {
501+
c.logger.Info("Opening web control panel", "url", displayURL)
502+
}
495503

496504
cmd := exec.Command("open", url)
497-
return cmd.Run()
505+
if err := cmd.Run(); err != nil {
506+
if c.logger != nil {
507+
c.logger.Error("Failed to open web control panel", "url", displayURL, "error", err)
508+
}
509+
return fmt.Errorf("failed to open web control panel: %w", err)
510+
}
511+
return nil
498512
}
499513

500514
// makeRequest makes an HTTP request to the API with enhanced error handling and retry logic
@@ -631,6 +645,36 @@ func getFloat64(m map[string]interface{}, key string) float64 {
631645
return 0.0
632646
}
633647

648+
func (c *Client) listenAddress() string {
649+
parsed, err := url.Parse(c.baseURL)
650+
if err != nil {
651+
return ""
652+
}
653+
654+
host := parsed.Hostname()
655+
if host == "" {
656+
host = "127.0.0.1"
657+
}
658+
659+
port := parsed.Port()
660+
if port == "" {
661+
if strings.EqualFold(parsed.Scheme, "https") {
662+
port = "443"
663+
} else {
664+
port = "80"
665+
}
666+
}
667+
668+
return net.JoinHostPort(host, port)
669+
}
670+
671+
func maskForLog(key string) string {
672+
if len(key) <= 8 {
673+
return "****"
674+
}
675+
return key[:4] + "****" + key[len(key)-4:]
676+
}
677+
634678
// createTLSConfig creates a TLS config that trusts the local mcpproxy CA
635679
func createTLSConfig(logger *zap.SugaredLogger) *tls.Config {
636680
// Start with system cert pool

internal/tray/managers.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -629,6 +629,7 @@ func (m *MenuManager) getServerStatusDisplay(server map[string]interface{}) (dis
629629
connected, _ := server["connected"].(bool)
630630
quarantined, _ := server["quarantined"].(bool)
631631
toolCount, _ := server["tool_count"].(int)
632+
lastError, _ := server["last_error"].(string)
632633

633634
var statusIcon string
634635
var statusText string
@@ -662,6 +663,9 @@ func (m *MenuManager) getServerStatusDisplay(server map[string]interface{}) (dis
662663
}
663664

664665
tooltip = fmt.Sprintf("%s - %s", serverName, statusText)
666+
if lastError != "" {
667+
tooltip = fmt.Sprintf("%s\nLast error: %s", tooltip, lastError)
668+
}
665669

666670
return
667671
}

internal/tray/tray.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -491,6 +491,8 @@ func (a *App) onReady() {
491491
// Mark core menu items as ready - this will release waiting goroutines
492492
a.coreMenusReady = true
493493
a.logger.Debug("Core menu items initialized successfully - background processes can now start")
494+
// Reapply the last known connection state now that UI widgets exist.
495+
a.applyConnectionStateToUI(a.getConnectionState())
494496
systray.AddSeparator()
495497

496498
// --- Upstream & Quarantine Menus ---
@@ -691,6 +693,11 @@ func (a *App) updateStatusFromData(statusData interface{}) {
691693
message, _ := status["message"].(string)
692694
listenAddr, _ := status["listen_addr"].(string)
693695
serverRunning := a.server != nil && a.server.IsRunning()
696+
if listenAddr == "" && a.server != nil {
697+
if addr := a.server.GetListenAddress(); addr != "" {
698+
listenAddr = addr
699+
}
700+
}
694701

695702
lowerMessage := strings.ToLower(message)
696703
portConflict := phase == phaseError && strings.Contains(lowerMessage, "port") && strings.Contains(lowerMessage, "in use")
@@ -702,8 +709,8 @@ func (a *App) updateStatusFromData(statusData interface{}) {
702709
zap.Bool("port_conflict", portConflict),
703710
zap.Any("status_data", status))
704711

705-
// Use the actual server running state as the authoritative source
706-
actuallyRunning := serverRunning
712+
// Treat either SSE running flag or RPC running flag as authoritative.
713+
actuallyRunning := running || serverRunning
707714

708715
if portConflict {
709716
a.showPortConflictMenu(listenAddr, message)

0 commit comments

Comments
 (0)