get-breakdown
Break down website metrics by dimensions like page, source, or country. Get top pages, traffic sources, and visitor locations with filters and custom date ranges.
Instructions
Break down stats by a dimension (e.g. page, source, country, device, browser, OS, UTM tags). Use this for 'top pages', 'traffic sources', 'visitor countries', etc.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| site_id | Yes | Domain of the site (e.g. 'example.com') | |
| metrics | No | Metrics to retrieve | |
| date_range | No | Time period. Use a preset like '30d' or a custom range ['2024-01-01', '2024-01-31'] | 30d |
| dimensions | Yes | Dimensions to group by. Common: 'event:page' for top pages, 'visit:source' for traffic sources, 'visit:country_name' for geography | |
| filters | No | Filters array using Plausible v2 syntax, e.g. [['is', 'event:page', ['/blog*']]] | |
| limit | No | Max number of results to return (default 10) |
Implementation Reference
- src/index.ts:195-273 (registration)Registration of the 'get-breakdown' tool via server.tool(), defining its name, description, schema, and handler.
server.tool( "get-breakdown", "Break down stats by a dimension (e.g. page, source, country, device, browser, OS, UTM tags). Use this for 'top pages', 'traffic sources', 'visitor countries', etc.", { site_id: z.string().describe("Domain of the site (e.g. 'example.com')"), metrics: metricsSchema, date_range: dateRangeSchema, dimensions: z .array( z.enum([ "event:page", "event:hostname", "event:goal", "visit:source", "visit:referrer", "visit:utm_source", "visit:utm_medium", "visit:utm_campaign", "visit:utm_content", "visit:utm_term", "visit:device", "visit:browser", "visit:browser_version", "visit:os", "visit:os_version", "visit:country", "visit:country_name", "visit:region", "visit:city", "visit:entry_page", "visit:exit_page", ]) ) .describe( "Dimensions to group by. Common: 'event:page' for top pages, 'visit:source' for traffic sources, 'visit:country_name' for geography" ), filters: filtersSchema, limit: z .number() .optional() .describe("Max number of results to return (default 10)") .default(10), }, async ({ site_id, metrics, date_range, dimensions, filters, limit }) => { const result = await client.query({ site_id, metrics, date_range, dimensions, filters: filters ?? undefined, pagination: { limit }, }); // Format as rows with dimension labels + metrics const rows = result.results.map((r) => { const row: Record<string, unknown> = {}; dimensions.forEach((d, i) => { row[d] = r.dimensions[i]; }); metrics.forEach((m, i) => { row[m] = r.metrics[i]; }); return row; }); return { content: [ { type: "text", text: JSON.stringify( { site_id, date_range, dimensions, data: rows }, null, 2 ), }, ], }; } ); - src/index.ts:238-272 (handler)Handler function for get-breakdown that calls client.query() with dimensions, transforms results into rows keyed by dimension/metric names, and returns them as JSON text.
async ({ site_id, metrics, date_range, dimensions, filters, limit }) => { const result = await client.query({ site_id, metrics, date_range, dimensions, filters: filters ?? undefined, pagination: { limit }, }); // Format as rows with dimension labels + metrics const rows = result.results.map((r) => { const row: Record<string, unknown> = {}; dimensions.forEach((d, i) => { row[d] = r.dimensions[i]; }); metrics.forEach((m, i) => { row[m] = r.metrics[i]; }); return row; }); return { content: [ { type: "text", text: JSON.stringify( { site_id, date_range, dimensions, data: rows }, null, 2 ), }, ], }; } - src/index.ts:198-237 (schema)Input schema for get-breakdown: site_id, metrics (reusing metricsSchema), date_range (reusing dateRangeSchema), dimensions array of allowed dimension values, filters (reusing filtersSchema), and optional limit (default 10).
{ site_id: z.string().describe("Domain of the site (e.g. 'example.com')"), metrics: metricsSchema, date_range: dateRangeSchema, dimensions: z .array( z.enum([ "event:page", "event:hostname", "event:goal", "visit:source", "visit:referrer", "visit:utm_source", "visit:utm_medium", "visit:utm_campaign", "visit:utm_content", "visit:utm_term", "visit:device", "visit:browser", "visit:browser_version", "visit:os", "visit:os_version", "visit:country", "visit:country_name", "visit:region", "visit:city", "visit:entry_page", "visit:exit_page", ]) ) .describe( "Dimensions to group by. Common: 'event:page' for top pages, 'visit:source' for traffic sources, 'visit:country_name' for geography" ), filters: filtersSchema, limit: z .number() .optional() .describe("Max number of results to return (default 10)") .default(10), }, - src/index.ts:64-70 (helper)Shared dateRangeSchema used by get-breakdown (and other tools) for specifying a time period.
const dateRangeSchema = z .union([ z.enum(["day", "7d", "30d", "month", "6mo", "12mo", "year", "all"]), z.tuple([z.string(), z.string()]).describe("Custom range: [start, end] in YYYY-MM-DD format"), ]) .describe("Time period. Use a preset like '30d' or a custom range ['2024-01-01', '2024-01-31']") .default("30d"); - src/index.ts:72-92 (helper)Shared metricsSchema used by get-breakdown (and other tools) defining valid metrics like visitors, pageviews, bounce_rate, etc.
const metricsSchema = z .array( z.enum([ "visitors", "visits", "pageviews", "views_per_visit", "bounce_rate", "visit_duration", "events", "scroll_depth", "percentage", "conversion_rate", "group_conversion_rate", "average_revenue", "total_revenue", "time_on_page", ]) ) .describe("Metrics to retrieve") .default(["visitors", "pageviews", "bounce_rate", "visit_duration"]);