> ## Documentation Index
> Fetch the complete documentation index at: https://docs.getmcpulse.com/llms.txt
> Use this file to discover all available pages before exploring further.

# The overview

> What every card, chart and panel on an MCP's main screen is measuring, and how the date range, the tool filter and the client filter change each one.

`/m/:id` is the screen you open an MCP to see. Everything on it is computed API-side, so the [REST API](/api/introduction) and the [MCP tools](/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.

<Note>
  **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.
</Note>

See [Date ranges](/api/concepts/date-ranges) for the eleven presets and how your plan clamps them.

## The four cards

| Card                   | What it is                                                 |
| ---------------------- | ---------------------------------------------------------- |
| **Total calls**        | Every `tools/call` in range                                |
| **First-call success** | The share that got what the model wanted first time        |
| **p95 latency**        | The bucket the 95th-slowest call falls in                  |
| **Cost per session**   | Response bytes priced as input tokens, divided by sessions |

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.

<Note>
  A previous period of zero yields **no delta** rather than an infinite one. Going from nothing to something is a start, not a percentage.
</Note>

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:

<CardGroup cols={2}>
  <Card title="Calls per day" icon="chart-line" href="/metrics/calls">
    Stacked by outcome, with the first-call rate on a right axis as a dashed line.
  </Card>

  <Card title="Outcome breakdown" icon="chart-pie" href="/metrics/outcomes">
    ok, empty, bad\_args, tool\_error, crashed — server-wide, each bar naming the tool contributing most to it.
  </Card>

  <Card title="Latency distribution" icon="gauge-high" href="/metrics/latency">
    Four buckets, server-wide.
  </Card>

  <Card title="Clients" icon="users" href="/metrics/clients">
    One row per model: calls, first-call, retries, the four outcomes, p95, average response.
  </Card>

  <Card title="Calls per session" icon="layer-group" href="/metrics/sessions">
    Even bands of three, beside the schema budget.
  </Card>

  <Card title="Schema budget" icon="file-code" href="/metrics/schema-size">
    What every registered tool costs before anyone asks a question.
  </Card>

  <Card title="Insights" icon="lightbulb" href="/insights/overview">
    What is actually wrong, with a number and a consequence.
  </Card>

  <Card title="Tool health" icon="wrench" href="/tools/health">
    Every tool: share of traffic, calls, first-call, the four outcomes, p95, schema.
  </Card>

  <Card title="Tool pairs" icon="link" href="/metrics/tool-pairs">
    Which tools get called alongside each other. Last, and the one panel that can be absent entirely.
  </Card>
</CardGroup>

The outcome breakdown and the latency buckets render from the same components the [tool page](/tools/detail) 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.**

| Blanked by a tool filter | Why                                            |
| ------------------------ | ---------------------------------------------- |
| Sessions                 | A session belongs to the server, not to a tool |
| Calls per session        | Same — the denominator is server-wide          |
| Cost per session         | Same                                           |

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](/api/concepts/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](/metrics/live-calls) 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.
