feat(ui): maintainer dashboard panel for per-tool MCP usage counts - #6548
Conversation
New McpToolUsageCard, wired into MaintainerPanel's qualityDashboard, showing per-tool call counts, success/failure rates, and a local-vs-remote split over the dashboard's window. The backend aggregation (from the PostHog telemetry wrappers JSONbored#6235/ JSONbored#6236/JSONbored#6358 already write to) is tracked separately -- matching AcceptanceRateCard's own established precedent, this card assumes qualityDashboard.mcpToolUsage may be absent from the payload today and degrades to a "not yet available" empty state until that aggregation lands, rather than assuming a value or blocking on it shipping first. Uses AnalyticsCardShell for chrome/state handling and TableScroll's accessible-table pattern (caption, scope=col headers, focusable region) for the per-tool breakdown, matching this codebase's existing dashboard conventions. Closes JSONbored#6241
|
Superagent didn't find any vulnerabilities or security issues in this PR. |
|
Tip ✅ LoopOver review result - approve/merge recommendedReview updated: 2026-07-16 13:20:49 UTC
Review summary Nits — 5 non-blocking
Decision drivers
Context & advisory signals — never blocks the verdict
Linked issue satisfactionAddressed Review context
Contributor next steps
Signal definitions
🧪 Chat with LoopOverAsk LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.
Full command reference: https://loopover.ai/docs/loopover-commands 🧪 Experimental — new and may change. Visual preview
Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy · Diff highlights exactly what changed. 🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed 💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →. Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.
|





Closes #6241
Summary
Part of #6228 (now fully resolved by shipped code — the remote and local PostHog telemetry wrappers, #6355/#6358/#6368, already instrument the MCP tool-dispatch chokepoint on both servers). This is the consumption side: a new
McpToolUsageCardmaintainer-dashboard panel showing per-tool call counts, success/failure rates, and a local-vs-remote split over a selectable window.McpToolUsageCardis wired intoMaintainerPanel'squalityDashboard.mcpToolUsage(a new, optional field), rendered right afterGateOutcomeCard. The backend aggregation that would populate this field from the already-shipped PostHog telemetry is tracked separately and not built here — per the issue's own text, this panel is "buildable and testable against a defined mock data shape even before real production data volume exists." MatchingAcceptanceRateCard's own established precedent in this exact codebase, the card assumesmcpToolUsagemay be absent from the dashboard payload today and degrades to a "not yet available" empty state (distinct from the "payload exists but zero tools called" empty state) rather than assuming a value or blocking this issue on that aggregation shipping first.AnalyticsCardShellfor chrome/state handling (loading/empty/ready), matching every other card in this folder.activation-preview.tsx's established accessible-table pattern:TableScroll's keyboard-focusable labelled region, asr-onlycaption, andscope="col"headers.successCount / callCount, rendered as—(never divides by zero) when a tool has zero calls.Scope
type(scope): short summaryConventional Commit format.apps/loopover-ui/**) and does not mix unrelated backend, MCP, docs, or deploy changes.CONTRIBUTING.mdand does not reintroduce GitHub Pages, VitePress,site/, orCNAME.Validation
npm --workspace @loopover/ui run typecheck— clean.npm run ui:lint— 0 errors, only pre-existing warnings in unrelated files.npm --workspace @loopover/ui run test(full workspace) — 48 files, 300 tests, all passing.mcp-tool-usage-card.test.tsx(6 tests): both empty-state variants (payload absent vs. payload present with zero tools), row rendering + sort order + success-rate math, the zero-calls divide-by-zero guard, theTableScrolla11y wiring, and the forbidden-terms sweep.maintainer-panel.test.tsxverifying the real wiring — not just the isolated component: renders the empty state whenmcpToolUsageis absent from the dashboard payload, and renders real per-tool rows when it's present. Verified both genuinely fail without the<McpToolUsageCard>render call viagit stashonmaintainer-panel.tsx, then restored and re-confirmed passing.git diff --checknpm run actionlintnpm run docs:drift-check/manifest:drift-check/command-reference:checknpm audit --audit-level=moderate— 0 vulnerabilities.npm run typecheck/npm run test:coverage— this sandbox's roottsc --noEmitreliably OOMs regardless of diff content (reproduced repeatedly this session); the workspace-scoped@loopover/uitypecheck (clean) plus the full workspace test run (300/300 passing) cover this diff's actual surface.apps/**is excluded from Codecov'scoverage.include, so nocodecov/patchcheck applies to this diff, per the issue's own Test Coverage Requirements.If any required check was skipped, explain why:
typecheck/test:coverage: established OOM pattern in this sandbox, unrelated to diff content; superseded by the scoped checks above.Safety
MaintainerPanel's existing role check, unchanged.mcpToolUsageis a new optional field on an existing response type, with no backend change in this PR (per the issue's own UI-only scope).data.qualityDashboard.mcpToolUsage, the real dashboard payload; when the backend hasn't populated that field yet it shows a real, honest "not yet available" empty state (not a fabricated demo value), matchingAcceptanceRateCard's identical, already-reviewed pattern.UI Evidencesection below with screenshots. — See below.CHANGELOG.mduntouched.UI Evidence
A new card titled "MCP tool usage" appears in the maintainer dashboard's quality section, directly after "Gate outcomes." With no data it shows the shared
EmptyState("Not yet available" / a description explaining the field isn't populated yet); with data it shows a30d windowpill and a table of tool name / calls / success rate / local / remote, sorted by call count descending.ui:buildcouldn't run in this sandbox (a pre-existing, unrelated@scalar/api-referenceresolution failure reproduced on cleanmain) to produce a live screenshot; covered instead by the new render tests asserting the exact rendered rows and empty-state copy.Notes
The backend aggregation populating
qualityDashboard.mcpToolUsagefrom the already-shipped PostHog telemetry (#6235/#6236/#6358) is a natural follow-up issue, not built here per this issue's explicit UI-only scope.