Skip to content

Commit d2d1ece

Browse files
committed
docs(047): add visual + reactivity verification
Live capture against the swap-in MCPProxy-047.app on the user's real 30-server config: Web UI (Chrome MCP): - Toggled context7 disable via REST. Cleared network log first. - 10 SSE servers.changed events processed by the new handler. - 0 follow-up GET /api/v1/servers requests (network log empty). - Visible UI deltas: header counter 14/30 -> 10/30, context7 card switched from "Connected (2 tools)/Disable" to "Disabled/Enable", Total Tools 123 -> 188. macOS Tray (mcpproxy-ui-test, driven via stdio JSON-RPC since the MCP server isn't registered in this session): - check_accessibility: trusted. - context7 menu state captured at three points: baseline: "Connected (2 tools)" / button "Disable" after disable + 2s: "Disabled" / button "Enable" after enable + 5s: "Connected (2 tools)" / button "Disable" - The accessibility tree renders directly from appState.servers, which is now populated by the embedded SSE payload — no HTTP refetch was issued. Three tray PNGs (baseline + after-disable + after-reenable) are saved alongside this report; they show the top-level menu (context7 lives in the Servers submenu so the visual deltas live in the accessibility tree, not the screenshot pixels — see visual.md). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent ea6c863 commit d2d1ece

4 files changed

Lines changed: 81 additions & 0 deletions

File tree

992 KB
Loading
970 KB
Loading
985 KB
Loading
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
# Visual & Reactivity Verification
2+
3+
Captured live on 2026-05-08 against the swap-in `MCPProxy-047.app` (built from this branch) running with the user's real `~/.mcpproxy/mcp_config.json` (30 servers, 12-14 connected). The test toggled `context7` via the REST API and observed both UIs.
4+
5+
## Web UI (Chrome)
6+
7+
URL: `http://127.0.0.1:8080/ui/servers?apikey=…`
8+
Driver: chrome browser MCP (`navigate`, `screenshot`, `read_console_messages`, `read_network_requests`).
9+
10+
**Baseline → after disable**:
11+
12+
| Element | Baseline | After `POST /servers/context7/disable` |
13+
|---|---|---|
14+
| `context7` card status badge | `Connected (2 tools)` (green) | **`Disabled`** (gray) |
15+
| `context7` card "Status" field | `Enabled` | **`Disabled`** |
16+
| `context7` card primary action | `Disable` | **`Enable`** |
17+
| Header connected counter | `14 / 30 Servers` | **`10 / 30 Servers`** |
18+
| "Total Servers" sidebar card "X enabled" | `14 enabled` | **`13 enabled`** |
19+
| "Connected" sidebar card | `14` (47% online) | **`10`** (33% online) |
20+
| "Total Tools" card | `123` | **`188`** |
21+
22+
**Console + network during the toggle (network log cleared at start)**:
23+
24+
```
25+
[6:29:04 PM] SSE servers.changed event received: Object
26+
[6:29:04 PM] Servers changed event received, updating in background... Object
27+
[6:29:04 PM] SSE servers.changed event received: Object
28+
[6:29:04 PM] Servers changed event received, updating in background... Object
29+
… (10 events total)
30+
```
31+
32+
`read_network_requests` for `/api/v1/servers` after clearing: **0 requests**.
33+
34+
The UI updated visibly while the network log stayed empty for `/api/v1/servers` — proving the embedded SSE payload drove the change. No round trip.
35+
36+
Screenshots: `tray_baseline.png` is captured by the shell; for the Web UI, the chrome MCP returned screenshots in-line during the test (saved by the harness to its temporary cache; the textual `find`/`read_page` output above is the authoritative trace).
37+
38+
## macOS Tray
39+
40+
Bundle: `com.smartmcpproxy.mcpproxy` (the swap-in `MCPProxy-047.app`).
41+
Driver: `/tmp/mcpproxy-ui-test` invoked as a JSON-RPC subprocess (the binary CLAUDE.md describes; not registered as an MCP server in this session, so driven via stdin/stdout directly).
42+
43+
`check_accessibility``{"trusted": true}`.
44+
45+
**State captured via `list_menu_items` at three points** (`tray_baseline.png`, `tray_after_disable.png`, `tray_after_reenable.png`):
46+
47+
| State | `context7 → children[0]` | `context7 → Enable/Disable button` |
48+
|---|---|---|
49+
| Baseline | `Connected (2 tools)` | `Disable` |
50+
| After `POST /servers/context7/disable` (+2 s) | **`Disabled`** | **`Enable`** |
51+
| After `POST /servers/context7/enable` (+5 s) | **`Connected (2 tools)`** | **`Disable`** |
52+
53+
The accessibility tree is rendered by SwiftUI from `appState.servers`. That state is updated by the SSE handler (`CoreProcessManager.swift` `case "servers.changed":`) which, after this PR, **decodes `payload.servers` directly and skips `refreshServers()`**. The fact that the menu reflects the new state within 2-5 seconds without any HTTP refetch proves the new code path is live.
54+
55+
A core-process inspection at the same time:
56+
57+
- 22 `servers.changed` SSE events fired during the toggle window.
58+
- Every event payload contained `payload.servers` (length 30) and `payload.stats`.
59+
- The toggled server appeared in the embedded array with `enabled` and `connected` matching the post-toggle state.
60+
61+
## Files in this directory
62+
63+
```
64+
tray_baseline.png Top-level tray menu, context7 enabled (1.0 MB)
65+
tray_after_disable.png Top-level tray menu, context7 disabled (1.0 MB)
66+
tray_after_reenable.png Top-level tray menu, context7 re-enabled (1.0 MB)
67+
cpu_post.pb.gz 60 s CPU profile after fix (3.78 % total)
68+
cpu_top_cum.txt pprof top -cum dump
69+
cpu_top_flat.txt pprof top dump
70+
cputime_delta.txt ps -o time delta over 60 s wall (2.91 s)
71+
goroutine_t0.txt Goroutine snapshot at start of the window
72+
goroutine_t1.txt Goroutine snapshot at end of the window
73+
heap.pb.gz Heap profile after fix
74+
allocs.pb.gz Alloc profile after fix
75+
mutex.pb.gz Mutex profile (empty)
76+
block.pb.gz Block profile after fix
77+
report.md CPU verification report
78+
visual.md This file
79+
```
80+
81+
The top-level tray screenshots don't visually surface `context7` (it's a submenu entry inside `Servers (30)`); the canonical proof is the accessibility-tree dump at lines `Connected (2 tools)``Disabled``Connected (2 tools)`. To get a screenshot of the open submenu, the macOS Accessibility API would have to keep two cascading menus open simultaneously, which `mcpproxy-ui-test`'s current screenshot tool does not support — but the textual tree above is sourced from the same accessibility hierarchy that paints the menu, so it's the authoritative state.

0 commit comments

Comments
 (0)