What it does
What changed between two periods: the rows of one dimension that grew or shrank the most, in one call instead of diffing two list calls. period_a is the period to explain (default last_7_days), period_b what it is compared against (default: the equally long window directly before period_a). The dimension fixes the metric, so every number matches the corresponding list tool: page → pageviews (top_pages); entry_page → entry sessions (top_entry_pages); referrer → entry sessions per referring host (top_referrers); channel → entry sessions per channel (top_referrers with group_by: channel, direct included); source → entry sessions per utm source/medium/campaign (top_sources); event → occurrences per custom event (list_events, without pageview and engagement). The response names it in `metric`. Entry sessions count direct browser visits only ('user' class), one per session from its first pageview in the period, in every privacy mode; pageviews and event counts include AI-mediated human browsing (ai_user_action). Returns `gainers` and `losers`, each up to `limit` rows ranked by absolute change. Each row has key (for source an object with utm_source, utm_medium and utm_campaign), a_value (period_a), b_value (period_b), absolute_change and percent_change, a percentage relative to period_b: 47.5 means +47.5%. percent_change is null when b_value is 0, and the row then carries "new": true; a row that fell to 0 carries "gone": true. `total` gives the same numbers for the dimension as a whole, with `of` naming what it counts (all pageviews; all entry sessions; entry sessions with a referrer; entry sessions with any utm tag; all custom event occurrences). It is computed separately, not summed from the listed rows. period_a and period_b are echoed with label, from and to. A `note` is added when the two periods differ in length, since absolute changes are then not like for like, or when a period had more than 1000 rows, in which case only the top 1000 were compared.
Example prompts
Ask Claude (or any MCP client connected to mcp-analytics) something like:
Use the top_movers tool on mysite.com.
The client will pick top_movers automatically based on the prompt and your account's available sites.
Arguments
| Name | Type | Required | Description / Default |
|---|---|---|---|
site_id |
string | required | Site identifier from list_sites (8-character base32, e.g. 'wjxayhdd'). |
dimension |
string enum: page, entry_page, referrer, channel, source, event |
required | What the rows are: page (pageviews per URL path), entry_page (entry sessions per landing page), referrer (entry sessions per referring host), channel (entry sessions per channel), source (entry sessions per utm source/medium/campaign) or event (occurrences per custom event). |
period_a |
string | optional |
Time window. Keywords: today, yesterday, last_N_days (N from 1 to 730: today plus the N-1 days before, e.g. last_7_days, last_28_days), last_24_hours, this_week, last_week (weeks start on Monday), this_month, last_month, this_year, last_year, last_12_months. Or a custom date range YYYY-MM-DD..YYYY-MM-DD (inclusive). Days follow the site's timezone (list_sites; echoed as `timezone` in every response).
default: last_7_days
|
period_b |
string | optional | The period to compare period_a against, same format as period_a. Default: the window directly before period_a with the same elapsed length (today until now against yesterday until the same time; last_7_days against the 7 days before). For this_month and this_year the default is capped at the end of the previous month or year, so it can be shorter; the response then adds a note. |
limit |
integer | optional |
Maximum rows in each of gainers and losers. Capped at 50 server-side.
default: 5
|
min_volume |
integer | optional |
Leave out rows below this value in BOTH periods, so that 1 → 3 does not rank as +200%. 0 keeps every row.
default: 5
|
filters |
object | optional | Optional segment filter. All given keys must match (AND; no OR, no negation); an empty string means not set. Keys: path (exact) or path_prefix; device_type, browser, os (exact, case-sensitive); referrer_host, utm_source, utm_medium, utm_campaign (exact); channel (search, ai_assistant, social, email, paid, campaign, referral, direct; as top_referrers group_by: channel assigns it). path/path_prefix match rows: pageviews count rows on matching paths, sessions/visitors count those with at least one matching row, and bounce_rate/avg_session_duration_seconds use all rows of those sessions. referrer_host, utm_* and channel match the session's entry (its first pageview in the period) and then select every row of the matching sessions, in every privacy mode. In top_entry_pages, top_referrers, top_sources and get_overview's top_source, path/path_prefix also test the entry: path_prefix '/blog/' there means sessions that entered on /blog/. Source and device filters make every number browser-only: server-side-ingested rows (including AI-mediated ai_user_action) have no session and no device fields, so they never match; the response then adds a `filter_note`. In get_overview, bot_share is null under any key other than path/path_prefix. With conversion_event the filter narrows the units; the conversion itself still counts anywhere in the period. The applied filters are echoed back as `filters`. |
How to call it directly
If you're integrating from your own code rather than a chat client, this is the JSON-RPC payload:
curl -X POST https://mcp-analytics.com/mcp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "top_movers",
"arguments": {
"site_id": "abc12345",
"dimension": "browser"
}
}
}'
Token comes from /settings after you sign up. Replace any required arguments above.
Related tools
top_pages: Most-viewed URL paths.breakdown: Breakdown of visits by browser, os, device_type, or country (country empty in MVP).get_account: Account info — email, current plan, total active sites, total_hits_this_month (across all sites), plan_limit, and api_token_first_chars (first 10 chars of the legacy API token, for identification only — not enough to authenticate).list_sites: List all sites on the authenticated account.engagement_overview: Real reading time + scroll depth from the engagement beacon (fired on pagehide).