query
Execute advanced Plausible Analytics API queries for custom property breakdowns, behavioral filters, and multi-dimensional time series analysis.
Instructions
Execute a raw Plausible Stats API v2 query. Use this for advanced queries that the other tools don't cover, such as custom property breakdowns, behavioral filters, or combining multiple dimensions with time series.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| site_id | Yes | Domain of the site (e.g. 'example.com') | |
| metrics | Yes | Metrics to retrieve | |
| date_range | Yes | Date range preset or custom [start, end] | |
| dimensions | No | Dimensions to group by | |
| filters | No | Filters in Plausible v2 syntax | |
| order_by | No | Order by, e.g. [['visitors', 'desc']] | |
| pagination | No | Pagination options | |
| include | No | Include options (imports, time_labels, comparisons) |
Implementation Reference
- src/index.ts:277-337 (registration)Registration of the 'query' MCP tool.
server.tool( "query", "Execute a raw Plausible Stats API v2 query. Use this for advanced queries that the other tools don't cover, such as custom property breakdowns, behavioral filters, or combining multiple dimensions with time series.", { site_id: z.string().describe("Domain of the site (e.g. 'example.com')"), metrics: z.array(z.string()).describe("Metrics to retrieve"), date_range: z .union([z.string(), z.tuple([z.string(), z.string()])]) .describe("Date range preset or custom [start, end]"), dimensions: z.array(z.string()).optional().describe("Dimensions to group by"), filters: z.array(z.any()).optional().describe("Filters in Plausible v2 syntax"), order_by: z .array(z.any()) .optional() .describe("Order by, e.g. [['visitors', 'desc']]"), pagination: z .object({ limit: z.number().optional(), offset: z.number().optional(), }) .optional() .describe("Pagination options"), include: z .object({ imports: z.boolean().optional(), time_labels: z.boolean().optional(), total_rows: z.boolean().optional(), comparisons: z .object({ mode: z.string(), date_range: z .union([z.string(), z.tuple([z.string(), z.string()])]) .optional(), }) .optional(), }) .optional() .describe("Include options (imports, time_labels, comparisons)"), }, async ({ site_id, metrics, date_range, dimensions, filters, order_by, pagination, include }) => { const result = await client.query({ site_id, metrics, date_range, dimensions: dimensions ?? undefined, filters: filters ?? undefined, order_by: order_by ?? undefined, pagination: pagination ?? undefined, include: include ?? undefined, }); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } ); - src/plausible-client.ts:61-79 (handler)Implementation of the 'query' method in the Plausible client which makes the actual API request.
async query(params: PlausibleQueryParams): Promise<PlausibleQueryResult> { const response = await fetch(`${this.baseUrl}/api/v2/query`, { method: "POST", headers: { Authorization: `Bearer ${this.apiKey}`, "Content-Type": "application/json", }, body: JSON.stringify(params), }); if (!response.ok) { const body = await response.text(); throw new Error( `Plausible API error (${response.status}): ${body}` ); } return response.json() as Promise<PlausibleQueryResult>; }