search_analytics_query
Retrieve and analyze Google Search Console traffic metrics including clicks, impressions, CTR, and position data with flexible filtering and grouping options.
Instructions
Query search traffic data from Google Search Console. Returns clicks, impressions, CTR, and position data with flexible filtering and grouping.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| siteUrl | Yes | The site URL | |
| startDate | Yes | Start date in YYYY-MM-DD format | |
| endDate | Yes | End date in YYYY-MM-DD format | |
| dimensions | No | Dimensions to group by: country, device, page, query, searchAppearance, date, hour (hour requires dataState='hourly_all') | |
| type | No | Search type filter: web, image, video, news, discover, googleNews (default: web) | |
| dimensionFilterGroups | No | Filter groups to apply to the query | |
| aggregationType | No | How data is aggregated (default: auto) | |
| rowLimit | No | Maximum number of rows to return (1-25000, default: 1000) | |
| startRow | No | Zero-based row offset for pagination | |
| dataState | No | 'all' includes fresh (possibly incomplete) data, 'final' only finalized data, 'hourly_all' required when using 'hour' dimension |
Implementation Reference
- src/index.ts:450-483 (handler)The handler for search_analytics_query, which constructs the API request body and calls the Google Search Console API.
async ({ siteUrl, startDate, endDate, dimensions, type, dimensionFilterGroups, aggregationType, rowLimit, startRow, dataState, }) => { try { const body: Record<string, unknown> = { startDate, endDate }; if (dimensions) body.dimensions = dimensions; if (type) body.type = type; if (dimensionFilterGroups) body.dimensionFilterGroups = dimensionFilterGroups; if (aggregationType) body.aggregationType = aggregationType; if (rowLimit !== undefined) body.rowLimit = rowLimit; if (startRow !== undefined) body.startRow = startRow; if (dataState) body.dataState = dataState; const result = await apiCall( `${WEBMASTERS_BASE}/sites/${encodeSiteUrl(siteUrl)}/searchAnalytics/query`, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(body), }, ); return toolResult(result); } catch (e) { return errorResult(e); - src/index.ts:403-450 (registration)The registration and schema definition for the search_analytics_query tool using zod validation.
server.tool( "search_analytics_query", "Query search traffic data from Google Search Console. Returns clicks, impressions, CTR, and position data with flexible filtering and grouping.", { siteUrl: z.string().describe("The site URL"), startDate: z .string() .describe("Start date in YYYY-MM-DD format"), endDate: z .string() .describe("End date in YYYY-MM-DD format"), dimensions: z .array(dimensionEnum) .optional() .describe( "Dimensions to group by: country, device, page, query, searchAppearance, date, hour (hour requires dataState='hourly_all')", ), type: searchTypeEnum .optional() .describe( "Search type filter: web, image, video, news, discover, googleNews (default: web)", ), dimensionFilterGroups: z .array(dimensionFilterGroupSchema) .optional() .describe("Filter groups to apply to the query"), aggregationType: z .enum(["auto", "byPage", "byProperty", "byNewsShowcasePanel"]) .optional() .describe("How data is aggregated (default: auto)"), rowLimit: z .number() .min(1) .max(25000) .optional() .describe("Maximum number of rows to return (1-25000, default: 1000)"), startRow: z .number() .min(0) .optional() .describe("Zero-based row offset for pagination"), dataState: dataStateEnum .optional() .describe( "'all' includes fresh (possibly incomplete) data, 'final' only finalized data, 'hourly_all' required when using 'hour' dimension", ), }, async ({