Skip to main content
/m/:id is the screen you open an MCP to see. Everything on it is computed API-side, so the REST API and the MCP tools return the same figures rather than deriving them again. All sixteen metrics have a panel here. Four of them did not for a while, and a metric the product counts and never shows is a metric it does not have.

The header

A date range and one filter control covering both tools and clients, with the active filters as removable chips directly beneath. The range picker commits on click rather than making a five-word decision take three, and prints the resolved dates underneath — “last month” is a name, not a date range. Every bucket is UTC, so a range is a set of whole UTC days. Omitting a range gives you the last 30 days ending today, which is also the window the MCP list uses, so clicking a row confirms the figure you clicked.
A one-day window is drawn by the hour. The metrics table is keyed by the hour, so Today and Yesterday plot twenty-four points, and the sparklines follow the same axis. Anything wider stays daily — ninety days of hours is 2,160 bars nobody can read. The API decides it and sends granularity beside the series, rather than the chart guessing from the number of points.
See Date ranges for the eleven presets and how your plan clamps them.

The four cards

Each carries a delta against the preceding window of equal length, and a sparkline of its own series. A figure with no direction is not a metric: 340 calls is neither good nor bad until you know last month was 90. Which direction counts as an improvement is decided API-side, because it is domain knowledge rather than presentation — calls rising is healthy, latency and cost rising are not. The arrow follows the actual change and the colour follows the verdict, because the two come apart for latency and cost.
A previous period of zero yields no delta rather than an infinite one. Going from nothing to something is a start, not a percentage.
There are four cards rather than eight. Eight was tried: a grid that size stops being a summary and becomes a second table, where nothing is emphasised because everything is. The extra figures sit with whatever explains them — retries under first-call success, failure and empty rates on the outcome breakdown, average response beside latency.

Below the cards

In order down the page:

Calls per day

Stacked by outcome, with the first-call rate on a right axis as a dashed line.

Outcome breakdown

ok, empty, bad_args, tool_error, crashed — server-wide, each bar naming the tool contributing most to it.

Latency distribution

Four buckets, server-wide.

Clients

One row per model: calls, first-call, retries, the four outcomes, p95, average response.

Calls per session

Even bands of three, beside the schema budget.

Schema budget

What every registered tool costs before anyone asks a question.

Insights

What is actually wrong, with a number and a consequence.

Tool health

Every tool: share of traffic, calls, first-call, the four outcomes, p95, schema.

Tool pairs

Which tools get called alongside each other. Last, and the one panel that can be absent entirely.
The outcome breakdown and the latency buckets render from the same components the tool page uses, against the same shapes — so there is one definition of what “ok” counts rather than one screen subtracting empty answers and the other not. Insights sit above the tool table, not above the page. They were moved to the very top once, on the reasoning that the panel is the answer and the table is only the evidence. That is right about the ordering of the two and wrong about the top of the page: the panel is prose of no fixed height, so it pushed the four cards below the fold, and a screen opening on red and amber reads as an alarm rather than a dashboard.

The two filters are not symmetric

They live in one popover because they compose: search_orders, as read by Cursor is the sharpest question the product can answer, and asking it through two separate controls means never seeing both halves at once. tool_hours is keyed by hour, tool and client, so:
  • A client filter narrows everything. Calls, outcomes, latency, retries, first-call, response size, the series, session depth and cost per session — sessions and tool_pairs carry a client name too.
  • A tool filter narrows all of that except the session family.
They come back null rather than as an unfiltered figure sitting in a filtered row, where it would read as though it had been narrowed. The panel says so on screen — and only for the filter it applies to, since stating the caveat under a client filter would teach you to distrust a figure that is correct. Two smaller consequences worth knowing: “Never called” follows the client filter and ignores the tool filter. Under a tool filter, everything you excluded is absent, so a naive reading would report six confident “has never been called” findings about precisely the tools you told it to ignore. Under a client filter it must not skip: sync_catalog has never been called by Cursor is true, and sharper than the server-wide version. The schema total ignores both filters, because the bill does — every registered schema ships at every connection, whichever tools you are looking at and whichever model is connecting. A filtered total would understate it. The panel says what changed and what did not instead of silently not responding.

Options carry their counts, and the counts do not move

Every tool and client in the filter panel shows its call count, right-aligned so the column can be read down. Those counts are deliberately unfiltered even while a filter is on: they are the sizes of the choices, not of the current selection. A count that shrank as you selected things would make the first tool you picked look smaller than it is.

Nothing recorded reads as zero

A quiet range still draws its flat line along zero. A server that has never been called has a complete answer — nothing happened — and a new MCP covered in dashes reads as broken rather than waiting. The honest not yet computed is kept for the one case where it is true: calls exist and the nightly pass has not reached them, where a zero would instead claim every call failed. That is why Today shows no retries, first-call or tool pairs, and Yesterday is the shortest window where every metric in the product has a figure. A dash survives only where a figure genuinely does not apply — the session family under a tool filter.

The page refreshes itself, and says nothing about it

Metrics re-read every 30 seconds, the live call feed every 5, and nothing at all on a hidden tab. There is no “Live” badge: refreshing is what a dashboard does, and a badge announcing it spends a header slot describing our mechanism rather than your server.