Skip to main content

Needs Attention

MCPProxy computes one needs-attention list from in-memory state — server health, tool approval counts, connect status, session history — and every surface renders it verbatim: the Web UI's Home page, the macOS tray's "Needs Attention" group and Home section, and the CLI's attention command, the first line of status, and the first section of doctor.

No surface derives its own version of this list. Before this list existed, the Web UI Dashboard, the macOS tray and the CLI each had their own predicate over server health, and the three disagreed about what counted as "needs attention" — a quarantined server with a transport fault, for example, could show as an error on one surface and a review item on another. This page is the parity table for how the list is computed, its kinds, ranks and fixes.

Where it lives​

SurfaceLocation
REST APIGET /api/v1/attention
Web UIHome page (/) attention list, header pill (hidden at 0), sidebar Home badge
macOS tray"Needs Attention (N)" menu group, Home section (first, above the topology)
CLImcpproxy attention; first line of mcpproxy status; first section of mcpproxy doctor
SSEattention.changed event ({count, ids}, narrowed per subscriber)

Kinds, ranks and fixes​

The list is sorted by rank ascending, then by subject name. Each item's id is stable (kind:type:subject[:state]), so a surface can diff successive lists instead of re-rendering the whole thing on every change.

KindRankConditionFix
sign_in_required10health.status == sign_in_required (includes a quarantined OAuth server, or a failed token refresh)login → opens the server, which offers Sign in
missing_secret20health.status == needs_secretset_secret → opens the server's secret form
config_error30health.status == needs_configconfigure/edit_url → opens the server's Configuration tab, field focused
server_error40Not quarantined, and health.status has been error or connecting for ≥ 60 secondsrestart → the server menu action; logs are one click away
server_review50admin_state == quarantined (and enabled)review → opens the review location — never a one-click approve
tool_review60 (changed) / 61 (pending)A trusted server with ≥ 1 tool in that approval state; one item per state, so a server with both is two itemsreview → opens the review location, filtered to that state
client_never_seen70A client MCPProxy recorded as connected ≥ 5 minutes ago, with no MCP session observed sincereload_hint → shows how to restart the client

Never an item: a disabled server, a server connecting for under 60 seconds, a ready server whatever its proactive actions (a login nudge for a token expiring soon is not a blocking state), and update availability (that has its own nudge). A quarantined server is only a server_review item, never also server_error — restarting a server before it is reviewed fixes nothing, and the review screen already shows the transport error.

Conditions key on health.status and admin_state, never on the presence of an entry in actions — actions also carries proactive nudges on a perfectly usable server (the same status/usable/actions vocabulary every surface renders health through) and cannot by itself distinguish a blocking state from a hint.

Fixes are never a one-click approve​

A review fix always opens a screen; it never calls an approve or unquarantine endpoint directly from the list. Reviewing a quarantined server or a changed/pending tool is a decision a person makes on that server's own review screen, with the diff or the transport error in front of them — not a button on a summary row. This is the same rule the macOS tray already enforced for its per-server actions, extended to every surface.

Live updates​

The backend recomputes the list (debounced) whenever the underlying state changes, and separately arms a timer for the earliest pending time-based threshold — a server crossing from connecting to server_error at 60 seconds, or a client crossing into client_never_seen at 5 minutes — so the list is correct even on a quiet instance where nothing else happens to trigger a recompute. Every surface holding a live connection (the Web UI and the macOS tray, both over Server-Sent Events) receives an attention.changed notification and refreshes; the CLI and GET /api/v1/attention always read the current computed list.

Testing the client_never_seen threshold live means waiting out the real 5 minutes unless it is shrunk first: set the test-only environment variable MCPPROXY_ATTENTION_NEVER_SEEN_AFTER (e.g. 5s) before starting the daemon to override the threshold for that run. An unset or unparseable value keeps the 5-minute default; there is no equivalent hook for the 60-second server_error threshold.

Scoped callers​

An administrator (the API key, the local socket, or a server-edition admin user) sees every item. A scoped caller — an agent token, or a non-admin server-edition user session — sees only items whose subject is a server it may enumerate, and never sees a client item at all.