diff --git a/ROADMAP.md b/ROADMAP.md index 78ac342af..2051c7d4c 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1036,6 +1036,6 @@ Legend: `shipped` ≥95% checked · `in-flight` 1–94% · `drafted` 0% · `—` | [106-security-residual-fixes](./specs/106-security-residual-fixes/) | `shipped` | 18/19 (95%) | | [107-server-edition-sso-hardening](./specs/107-server-edition-sso-hardening/) | `shipped` | 126/126 (100%) | | [108-profiles-v3](./specs/108-profiles-v3/) | `shipped` | 185/186 (99%) | -| [109-ux-navigation-consistency](./specs/109-ux-navigation-consistency/) | `shipped` | 200/201 (100%) | +| [109-ux-navigation-consistency](./specs/109-ux-navigation-consistency/) | `shipped` | 206/207 (100%) | | [110-catalog-popularity](./specs/110-catalog-popularity/) | `in-flight` | 19/23 (83%) | | [112-client-header-forwarding](./specs/112-client-header-forwarding/) | `shipped` | 38/40 (95%) | diff --git a/docs/web-ui/dashboard.md b/docs/web-ui/dashboard.md index a73b0297a..f633245b0 100644 --- a/docs/web-ui/dashboard.md +++ b/docs/web-ui/dashboard.md @@ -31,9 +31,9 @@ The tray application opens the Web UI with the API key automatically. Home answers one question first: **what needs me?** -- **Needs attention** is the one list MCPProxy computes for every surface: sign-in prompts, servers waiting for review, missing secrets, configuration problems and clients that connected but were never seen. Items are ordered by rank, each with one button that goes to the screen that fixes it (Sign in, Review, Add secret). With nothing to do Home reads "All clear" and the usage strip moves to the top. See [Needs Attention](/features/needs-attention). -- The **usage strip** shows calls today, blocked calls, errors and the estimated tokens kept out of every request; each number links to the matching [Activity](/web-ui/activity-log) view. -- The **topology** shows your clients, MCPProxy and your servers. +- **Needs attention** is the one list MCPProxy computes for every surface: sign-in prompts, servers waiting for review, missing secrets, configuration problems and clients that connected but were never seen. Items are ordered by rank, each with one button that goes to the screen that fixes it (Sign in, Review, Add secret). With nothing to do Home reads "All clear" and the usage strip moves to the top, except on a fresh instance with no servers, where a "Get started" card (Add a server, Connect a client, Run setup wizard) replaces it. See [Needs Attention](/features/needs-attention). +- The **usage strip** shows calls, blocked calls and errors; each number links to the matching [Activity](/web-ui/activity-log) view. +- The **topology** shows your clients, MCPProxy and your servers. The chip above the hub shows the estimated per-request token saving, marked "estimate" until a real `retrieve_tools` call has been observed. The same count appears on the **header pill** (hidden at 0) and as the **badge** on the sidebar's Home entry. `mcpproxy attention` and the macOS tray show the same list; see [Attention Command](/cli/attention-command). diff --git a/frontend/src/composables/useScopeQuery.ts b/frontend/src/composables/useScopeQuery.ts index 916817d34..d92558094 100644 --- a/frontend/src/composables/useScopeQuery.ts +++ b/frontend/src/composables/useScopeQuery.ts @@ -381,8 +381,11 @@ export interface UseScopeQueryResult { /** Rule 8: null when the active parameters are contradictory (today, an * explicit `server` that disagrees with `tool`'s server prefix) — the * caller must issue no request and render the conflict empty state instead - * (chips carry `conflicting: true` for the pair). */ - toRest: () => Record | null + * (chips carry `conflicting: true` for the pair). `ignoreConflict` returns + * the map the non-conflicting parameters produce anyway, for a caller that + * reads only parameters independent of the conflicting pair (a page whose own + * state already resolved it while the URL write-back is still in flight). */ + toRest: (opts?: { ignoreConflict?: boolean }) => Record | null linkTo: (page: PageId, patch?: Record) => RouteLocationRaw chips: ComputedRef } @@ -436,7 +439,7 @@ export function useScopeQuery(page: PageId): UseScopeQueryResult { set(patch) } - function toRest(): Record | null { + function toRest(opts?: { ignoreConflict?: boolean }): Record | null { const out: Record = {} const snapshot: Record = {} for (const def of defsForPage(page)) snapshot[def.name] = state[def.name] @@ -470,7 +473,7 @@ export function useScopeQuery(page: PageId): UseScopeQueryResult { // Rule 8 ("Contradictory parameters"): no REST query could express both // active values, so no request is issued at all — never a partial one // built from whichever fields didn't conflict. - if (conflicted) return null + if (conflicted && !opts?.ignoreConflict) return null // Usage `window` (url-filter-contract.md `from`/`to` row): computed from // BOTH values together, including when neither is present (window=all) — diff --git a/frontend/src/views/Activity.vue b/frontend/src/views/Activity.vue index 3c3c7c680..f8047f9c0 100644 --- a/frontend/src/views/Activity.vue +++ b/frontend/src/views/Activity.vue @@ -110,6 +110,7 @@ filterStatus === part.status && part.status !== '' ? 'font-semibold underline' : '', ]" :aria-pressed="filterStatus === part.status" + :title="part.key === 'blocked' && activeView === 'calls' ? BLOCKED_CALLS_TITLE : undefined" @click="applySummaryFilter(part)" > {{ part.label }} @@ -260,7 +261,7 @@ -->
Events (24h)
{{ summary.total_count }}
-
{{ summary.call_count }} calls
+
{{ summary.call_count }} {{ summary.call_count === 1 ? 'call' : 'calls' }}
+ - + + + +
+
+
+

Get started

+

MCPProxy has no servers yet. Add one and connect an AI client to start using tools through the proxy.

+
+
    +
  1. + 1. Add a server + +
  2. +
  3. + 2. Connect a client + + ✓ connected +
  4. +
+
+ +
+
+
- +