> ## 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.

# August 2026

> Release notes for MCPulse.

<Update label="2026-08-30" description="Billing">
  ### Plans, and where each limit is enforced

  Free, **Pro at $49** and **Scale at $100**, monthly or yearly — with a year priced as ten months, because our merchant of record charges a percentage *plus 50¢* and a year is one of those rather than twelve.

  **MCP access is on every plan, Free included.** It reads that account's own data through that account's own window, so a free account gets seven days of it inside Claude. It is the best demonstration this product has and it costs nothing to give away.

  **History and retention are the same lever, said once.** If an account keeps seven days, "last 30 days" is not a feature being withheld — it is a window with nothing in it. But the counters are never deleted, only hidden: `tool_hours` is one row per hour per tool per client, so upgrading reveals history that was already there and downgrading loses nothing. Only the per-call log is genuinely deleted, at 7 / 90 / 365 days.

  **Recording stops at the cap rather than billing past it.** Ingest answers `402`, a banner appears above the overview, and the chart is flat from the moment it stopped. The SDK treats a refused batch the way it treats a network failure, so a cap costs you data and never a tool call.

  Every gate lives in the API, never in the interface alone — and a test reads the route files and counts them, because every other test in the suite runs as an account that is allowed, so a hole in a paywall would otherwise be invisible to all of them.

  Payment is [Polar](https://polar.sh) as merchant of record: they are the seller, so tax in every jurisdiction is theirs rather than ours. Checkout is a redirect and the customer portal is a signed link — MCPulse never holds a card number.

  See [Plans](/billing/plans).
</Update>

<Update label="2026-08-30" description="Onboarding">
  ### Every new account is seeded with a sample MCP

  `Acme Orders`, with thirty days of traffic, seven tools and three clients — deliberately shaped to trip all five insight rules and to show a 54-point first-call gap between two models on one tool.

  It is an ordinary row in the ordinary tables, so no panel knows it exists and there is no second code path to keep correct. It carries a Sample badge and a Remove button, is excluded from your plan's usage, and ships two alert rules of which one has already fired.

  Account creation now happens **when you click the magic link**, on a page that says what it is doing while it does it. Supabase has no "email verified" hook; a session is the closest honest thing to one, since it cannot exist until somebody has clicked a link in their own inbox.

  See [The sample MCP](/mcps/sample).
</Update>

<Update label="2026-08-30" description="Alerts">
  ### Alert rules replaced the notification matrix

  The account settings page used to hold six events × two channels — "first-call success drops", "a tool starts crashing". Those were the right five findings in the wrong place, for one reason: they had no threshold and no scope. *Tell me when first-call drops* cannot say **how far**, or **on which tool**, or **for which model**.

  So they are now per-MCP rules on `/m/:id/alerts`, scoped by exactly the two dimensions the metrics table is keyed by. The difference is the whole point: *first-call on `search_orders`, for Cursor, below 60%* fires on a real 19%, where a server-wide rule at 70% stays silent because the average across clients is 81%.

  The weekly digest went the same way, plus a reason of its own: as an account-wide switch it covered every MCP including the sample one, so a person who cared about a single server got sixteen thousand fabricated calls in their Monday email.

  `/settings/channels` now holds four **destinations** and nothing else. In-app and email are yours; Slack and Discord belong to the account and deliver once per firing, because an incoming webhook posts to one fixed channel and sending the same message there once per team member is the same message five times.

  Only in-app actually sends. The other three record deliveries as queued, and every channel carries a `delivers` flag the page renders as "Not sending yet" — a toggle that silently does nothing is the worst control on any page.

  See [Alert rules](/alerts/rules) and [Channels](/alerts/channels).
</Update>

<Update label="2026-08-30" description="Metrics">
  ### One metrics table, keyed by the hour and by the client

  There were three: one counting by tool and forgetting who called, one counting by client and forgetting which tool, and one holding the same numbers again at a coarser grain. Now there is `tool_hours`, and a day is twenty-four of its rows summed by Postgres on the way out.

  **Two things became possible that were not.** *What has my server done today* — a day-grained table drew a single point for a one-day window, and a single point is not a line; `Today` and `Yesterday` now plot twenty-four. And *how is `search_orders` doing for Cursor only* — the information existed, in two rows that could never be re-joined.

  The client filter now narrows everything, and it composes with the tool filter. The clients panel gained first-call, retries, p95 and the four outcomes, and every client name is a button that scopes the page to it.

  **Failed became four columns.** `Bad args`, `Tool errors`, `Crashes` and `Empty`, from one shared definition used by both tables. Pooling is what made the old column useless: 389 bad arguments is a schema the model cannot fill in, 42 tool errors is a handler refusing work, and 3 crashes is a bug — one number, three fixes. The calls chart names them in its tooltip.

  Eleven date presets, in two kinds. Rolling — today, yesterday, 3, 7, 30, 90 days — and calendar: this month, last month, last 3 months, this year, last year. `Last 3 months` is three *finished* months, because the rolling version is already there under its own name.

  See [The overview](/metrics/overview) and [Date ranges](/api/concepts/date-ranges).
</Update>

<Update label="2026-08-30" description="Dashboard">
  ### Live calls, paged on the server

  The per-call feed is now `Live calls`, and every page of it is reachable. It used to fetch the newest fifty and page through them in the browser, which meant a month of calls had a fourth page and no fifth.

  Ten per page, cursored on the row id rather than an offset: the feed is live, and `offset=20` shifts by one every time a call lands, showing page three a row page two already showed. The timestamp says which day, on a 24-hour clock, in local time — a call is a moment, where every bucketed figure is UTC.

  The tool table reached twelve columns when the outcomes were split out, so it gained a **column picker** rather than a horizontal scrollbar: the columns you cannot see are the ones you forget you have. The menu is read off the column definitions, so its words are the headers' words by construction.

  The install page opens on **a card per language** — the ten official MCP SDKs, nine of them marked Coming soon. Showing the nine is the point: the question a Python author opens that page with is *is there one for me*.

  See [Live calls](/metrics/live-calls).
</Update>

<Update label="2026-08-14" description="Documentation">
  ### These docs

  The product, the REST API, the SDK and the MCP server, documented. Every threshold and default on these pages is read from the code rather than restated from memory — see `AGENTS.md` in this repository for which file settles what.
</Update>

<Update label="2026-08-14" description="MCP server">
  ### MCPulse is now an MCP server

  You can connect Claude, Claude Code, Cursor or any OAuth-capable MCP client and work on your own servers directly. **24 tools** — 14 read, 7 write, 3 destructive — covering everything the dashboard does except ingest.

  **Writes needed no new permission code.** Every tool calls the same service function the REST route calls and hits the same guard, so a member is refused over MCP with the same sentence the dashboard gives them. That is the return on "routes are thin, logic lives in services".

  **Two writes deliberately do not exist.** No `create_key`: the full key exists once, in the response, and a tool result goes into a model's context and from there into transcripts and provider logs. No `delete_account`: it was built with the dashboard's type-the-name safeguard and removed anyway, because a model already holds the name from `get_account`, so the one thing the confirmation was meant to prove is the one thing it cannot.

  **Five metric tools rather than one per metric.** Every registered tool costs its schema in the context window of every session, which is metric 15 and the dead-tool insight — sixteen near-identical tools over one metrics query would have earned MCPulse its own warnings. So narrowing is a parameter: `get_overview({ metrics: ["calls"] })` returns calls and nothing else.

  Two arguments exist specifically because a model is not a date picker. `mcp` accepts a **name** as well as an id, so "how is the orders server doing" needs no lookup first — and ambiguity is an error rather than a guess. `last_days` accepts a count, because a model asked for "the last 30 days" would otherwise have to know today's date and do arithmetic, and one that is a day out reports a number that is quietly wrong rather than visibly broken.

  Auth is OAuth 2.1 with PKCE, with Supabase as the authorization server and MCPulse as a resource server only. See [MCP authentication](/mcp/auth).

  Every figure comes from the same services the dashboard reads. No metric is computed in the MCP layer, because there is none that could be.
</Update>

<Update label="2026-08-14" description="Initial release">
  ### MCPulse

  Analytics for MCP servers, in three pieces.

  **`@mcpulse/sdk`** — one import, one wrap, no runtime dependencies. Records what each tool call did and posts it in batches. Never throws, never blocks, and never sends arguments or results. See [Install the SDK](/sdk/install).

  **The API** — ingest, the metric services, and the account surface. Every number is computed server-side so that the dashboard and the MCP server get the same answer without either re-deriving it.

  **The dashboard** — the overview, tool health, tool detail, insights, keys and settings.

  The sixteen metrics: calls per tool, calls per day, which client, crashes, tool errors, bad arguments, empty answers, speed, result size, sessions, cost per session, retries, first-call success, tool pairs, schema size and dead tools.

  Three of them — retries, first-call success and tool pairs — are computed by a [nightly pass](/api/concepts/nightly-pass) and lag a day, because they are questions about a sequence rather than about a call.
</Update>
