API & MCP

Tool reference

Every Sonar MCP tool, its arguments, and an example of what it returns.

Each tool is called with tools/call, passing its name and arguments. See The Sonar MCP server for the request format. The examples below come from Sonar's demo sites; long lists are shortened with ….

Arguments marked optional can be left out. period is always one of 24h, 7d, 30d, 90d or all.

list_sites

The websites you can see, with the IDs the other tools need. No arguments.

[
  { "id": 49, "name": "Awesome Agency", "domain": "https://awesome-agency.example" },
  { "id": 50, "name": "Harbour Dental", "domain": "https://harbourdental.example" },
  { "id": 51, "name": "Northwind Coffee", "domain": "https://northwindcoffee.example" }
]

get_overview

Headline numbers for a period, the same numbers for the period before it, and the top 5 pages, sources and campaigns.

Argument Type
site_id integer From list_sites
period string Optional. Defaults to 7d
{
  "period": "last 30 days",
  "current": { "visitors": 91, "pageviews": 175, "conversions": 0, "avg_session_seconds": 33 },
  "previous_period": { "visitors": 77, "pageviews": 190, "conversions": 0, "avg_session_seconds": 31 },
  "top_pages": [
    { "path": "/", "visitors": 37 },
    { "path": "/new-patients/", "visitors": 25 },
    …
  ],
  "top_sources": [
    { "source": "direct", "visitors": 65 },
    { "source": "Google", "visitors": 21 },
    …
  ],
  "top_campaigns": []
}

conversions counts goal completions. previous_period is null for all.

top_pages

The pages with the most visitors. Query strings are ignored, so /fees/?ref=ad counts as /fees/.

Argument Type
site_id integer
period string Optional. Defaults to 7d
limit integer Optional. 1 to 50, defaults to 10
[
  { "path": "/", "visitors": 37 },
  { "path": "/new-patients/", "visitors": 25 },
  { "path": "/fees/", "visitors": 24 },
  { "path": "/blog/", "visitors": 11 },
  { "path": "/blog/how-often-should-you-see-a-hygienist/", "visitors": 7 }
]

traffic_sources

Where visitors came from: search engines, other websites, or direct. Takes the same arguments as top_pages.

[
  { "source": "direct", "visitors": 65 },
  { "source": "Google", "visitors": 21 },
  { "source": "harbourdental.example", "visitors": 15 },
  …
]

campaigns

Traffic from links with UTM tags, grouped by campaign, source or medium.

Argument Type
site_id integer
group_by string Optional. campaign (default), source or medium
from, to string Optional. Dates as YYYY-MM-DD; to is included. Leave both out for all time
{
  "totals": { "pageviews": 510, "visitors": 410 },
  "rows": [
    { "value": "web-design-search", "pageviews": 284, "visitors": 236 },
    { "value": "web-development-search", "pageviews": 81, "visitors": 65 },
    { "value": "autumn-newsletter", "pageviews": 78, "visitors": 64 },
    …
  ]
}

list_sessions

Visits, newest first, 20 at a time.

Argument Type
site_id integer
period string Optional. Defaults to 7d
outcome string Optional. converted, chatted or browsed (neither)
source string Optional. Only visits from this source, such as google
device string Optional. desktop, mobile or tablet
landing string Optional. Only visits that started on this path, such as /pricing/
before string Optional. next_before from the previous result, for the next 20
{
  "sessions": [
    {
      "id": "En6zYlyfOsqSAgGR-cdJ…",
      "visitor_name": null,
      "city": null,
      "country": "United Kingdom",
      "country_code": "GB",
      "browser": "Chrome",
      "os": "Mac OS",
      "device_type": "desktop",
      "source": "Direct",
      "landing_path": "/",
      "started_at": "2026-10-17T21:54:41.64+00:00",
      "last_activity": "2026-10-17T21:56:25.872+00:00",
      "duration_seconds": 104,
      "page_count": 4,
      "converted": true,
      "chatted": false,
      "is_bot": false
    },
    …
  ],
  "total": 12,
  "counts": { "live": 0, "chats": 0, "bots_hidden": 0 },
  "next_before": null
}

total is the number of matching visits. When next_before isn't null, pass it as before to get the next page. visitor_name is set when someone on your team has named the visitor.

get_session

One visit in full: each page in order with the time spent on it, conversions, interactions such as form enquiries, and the chat transcript if there was one.

Argument Type
site_id integer
session_id string An id from list_sessions, or a session_id from interactions, for the same site
{
  "id": "fFbBpqy0pVfZbnHJxl8b…",
  "source": "Direct",
  "landing_path": "/",
  "duration_seconds": 104,
  "page_count": 4,
  "converted": true,
  …
  "pages": [
    { "path": "/", "title": "Awesome Agency | Websites, brands and apps that work", "entered_at": "2026-10-17T21:54:41.64+00:00", "seconds_on_page": 4 },
    { "path": "/contact/", "title": "Contact us | Awesome Agency", "entered_at": "2026-10-17T21:54:45.372+00:00", "seconds_on_page": 18 },
    { "path": "/thank-you/", "title": "Thank you | Awesome Agency", "entered_at": "2026-10-17T21:55:03.482+00:00", "seconds_on_page": 82 },
    …
  ],
  "events": [
    { "type": "conversion", "at": "2026-10-17T21:55:03.482+00:00", "label": "Converted: Thank you page" },
    { "type": "interaction", "at": "2026-10-17T21:56:23.372+00:00", "label": "Form submission: Contact us" },
    …
  ],
  "chat": null
}

The visit also has every field from list_sessions. seconds_on_page is null for the last page, because time is measured up to the next page. When the visitor chatted, chat has the messages in order, each with its role, content and created_at.

interactions

Form enquiries, orders and video responses sent to Sonar, with which sources and landing pages brought them. See Interactions for how to connect your forms and shop.

Argument Type
site_id integer
period string Optional. Defaults to 30d
{
  "period": "90d",
  "totals": {
    "interactions": 19,
    "linked": 18,
    "sessions": 1659,
    "rate": 0.0108,
    "by_type": [{ "type": "form_submission", "n": 19, "linked": 18 }],
    "order_value": null,
    "currency": null
  },
  "by_source": [
    { "label": "Google", "sessions": 395, "interactions": 10, "converting": 10, "rate": 0.0253 },
    { "label": "Direct", "sessions": 1070, "interactions": 5, "converting": 5, "rate": 0.0047 },
    …
  ],
  "by_landing": [ … ],
  "items": [
    {
      "id": 170,
      "type": "form_submission",
      "source": "gravity_forms",
      "title": "Contact us",
      "occurred_at": "2026-10-17T21:56:23.372+00:00",
      "value": null,
      "currency": null,
      "match_method": "page_id",
      "entry_page": "/",
      "visit_source": "Direct",
      "campaign": null,
      "session_id": "-X2uBwsbg48fGYISWxKe…"
    },
    …
  ]
}
  • linked counts interactions matched to a visit. converting counts visits with at least one interaction, and rate is converting divided by sessions (visits).
  • by_source and by_landing are the top 10 traffic sources and landing pages.
  • order_value is the total of orders, when they're all in one currency.
  • items are the latest 10 interactions. Pass an item's session_id to get_session to see the visit behind it.

ask_sonar

Any question in plain English, answered from the site's data. Use it for anything the other tools don't cover.

Argument Type
site_id integer
question string Up to 1,000 characters
period string Optional. Defaults to 7d. A period named in the question, such as "last month", takes priority
{
  "question": "Which day of the week gets the most visitors?",
  "period": "last 30 days",
  "rows": [
    { "day_of_week": "Wednesday", "visitors": 19, "pageviews": 40 },
    { "day_of_week": "Friday", "visitors": 18, "pageviews": 32 },
    { "day_of_week": "Tuesday", "visitors": 17, "pageviews": 21 },
    …
  ]
}

The columns depend on the question. Up to 200 rows are returned, with a note when there were more. If Sonar can't answer a question, the result has isError: true; try rephrasing it.