What it does
Compare a metric between two periods. Returns a_value, b_value, absolute_change and percent_change. percent_change is a percentage relative to period_b: 21.9 means +21.9%, -8.0 means -8.0% (null when b_value is 0). metric=pageviews includes AI-mediated human browsing (ai_user_action); metric=sessions and metric=visitors are browser-only (server-side-ingested rows carry no session or visitor id). metric=sessions counts sessions with at least one pageview in the period. metric=visitors is always 0 on privacy_mode=strict sites (no visitor IDs computed by design) — use sessions there. metric=events compares one named event (pass event_name), e.g. conversions this month vs last; it counts rows like pageviews, so it includes AI-mediated human browsing.
Example prompts
Ask:
"Compare last 7 days vs the previous 7 days for mysite.com."
"How does this month look compared to last month?"
"Pageviews trend week-over-week."
A typical response:
Pageviews, last 7 days vs previous 7 days:
Period A (May 12-18): 42,180
Period B (May 5-11): 31,420
Change: +34.2%
Absolute delta: +10,760
Best day in A: May 16 (8,114 views)
Best day in B: May 9 (5,847 views)
Returns a single object with both period values, the percentage and absolute delta, and bucket info if the period is sub-week granularity.
Period strings the parser understands:
today,yesterdaylast_7_days,last_30_days,last_90_days,last_12_monthsYYYY-MM-DD..YYYY-MM-DDfor explicit ranges (inclusive)
There are no "previous week" or "last month" keywords. For those, the
agent computes the dates and passes an explicit range, e.g.
period_b: "2026-05-05..2026-05-11".
Volume metric: counts include AI-mediated human browsing. If you want
to compare only direct browser traffic, you can filter using
traffic_class_breakdown for each period instead.
Works for a single custom event too: pass metric: "events"
plus event_name to compare, say, this month's inquiries
against last month's.
Common workflow: pair with
top_pages on both
periods to identify pages driving the change.
Arguments
| Name | Type | Required | Description / Default |
|---|---|---|---|
site_id |
string | required | Site identifier from list_sites (8-character base32, e.g. 'wjxayhdd'). |
metric |
string enum: pageviews, visitors, sessions, events |
required | Metric to compare across periods. pageviews includes AI-mediated human browsing; sessions and visitors are browser-only. 'events' counts occurrences of the single event named in event_name (row count, like pageviews). |
period_a |
string | required | First period (same format as `period` elsewhere). Returned as a_value. |
period_b |
string | required | Second period to compare against (same format). Returned as b_value. |
event_name |
string | optional | Required when metric=events, rejected with any other metric. Case-sensitive event name — use list_events to discover the names this site actually sends. Counts match the total_count event_details reports for the same event and period (volume metric, includes AI-mediated human browsing). |
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": "compare_periods",
"arguments": {
"site_id": "abc12345",
"metric": "pageviews",
"period_a": "last_7_days",
"period_b": "previous_7_days"
}
}
}'
Token comes from /settings after you sign up. Replace any required arguments above.
Related tools
top_referrers: Top referring hosts.top_sources: Top UTM source/medium/campaign combinations.top_entry_pages: Landing pages: the URL path each session entered the site on.list_events: All event names with counts (includes 'pageview' and custom events).get_tracking_snippet: Return the HTML <script> snippet for a given site_id.