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, yesterday
  • last_7_days, last_30_days, last_90_days, last_12_months
  • YYYY-MM-DD..YYYY-MM-DD for 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