Skip to main content
Glama
ahonn

Google Search Console MCP Server

by ahonn

search_analytics

Retrieve and analyze search performance data from Google Search Console to understand website visibility, traffic patterns, and optimize content strategy.

Instructions

Get search performance data from Google Search Console

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
siteUrlYesThe site URL as defined in Search Console. Example: sc-domain:example.com (for domain resources) or http://www.example.com/ (for site prefix resources)
startDateYesStart date in YYYY-MM-DD format
endDateYesEnd date in YYYY-MM-DD format
dimensionsNoComma-separated list of dimensions to break down results by, such as query, page, country, device, searchAppearance
typeNoType of search to filter by, such as web, image, video, news
aggregationTypeNoType of aggregation, such as auto, byNewsShowcasePanel, byProperty, byPage
rowLimitNoMaximum number of rows to return (up to 25,000 for enhanced performance)
pageFilterNoFilter by a specific page URL. Use with filterOperator.
queryFilterNoFilter by a specific query string. Use with filterOperator.
countryFilterNoFilter by a country using ISO 3166-1 alpha-3 code (e.g., USA, CHN).
deviceFilterNoFilter by device type.
filterOperatorNoOperator for page and query filters. Defaults to "equals". Enhanced with regex support.equals
regexFilterNoAdvanced regex filter for intelligent query matching

Implementation Reference

  • Core handler function that executes the Google Search Console search analytics API query, handling site URL normalization and permissions.
    async searchAnalytics(siteUrl: string, requestBody: SearchanalyticsQueryRequest) {
      const webmasters = await this.getWebmasters();
      return this.handlePermissionError(
        () => webmasters.searchanalytics.query({ siteUrl, requestBody }),
        () => webmasters.searchanalytics.query({ siteUrl: this.normalizeUrl(siteUrl), requestBody }),
      );
    }
  • MCP tool call handler for 'search_analytics' that validates input with schema, builds the API request body with filters, calls SearchConsoleService.searchAnalytics, and formats the response.
    case 'search_analytics': {
      const args = SearchAnalyticsSchema.parse(request.params.arguments);
      const siteUrl = args.siteUrl;
    
      // --- 动态构建请求体 ---
      const requestBody: any = {
        startDate: args.startDate,
        endDate: args.endDate,
        dimensions: args.dimensions,
        searchType: args.type,
        aggregationType: args.aggregationType,
        rowLimit: args.rowLimit,
      };
    
      const filters = [];
      if (args.pageFilter) {
        filters.push({
          dimension: 'page',
          operator: args.filterOperator,
          expression: args.pageFilter,
        });
      }
      if (args.queryFilter) {
        filters.push({
          dimension: 'query',
          operator: args.filterOperator,
          expression: args.queryFilter,
        });
      }
      if (args.countryFilter) {
          filters.push({
            dimension: 'country',
            operator: 'equals', // Country filter only supports 'equals'
            expression: args.countryFilter,
          });
      }
      if (args.deviceFilter) {
          filters.push({
            dimension: 'device',
            operator: 'equals', // Device filter only supports 'equals'
            expression: args.deviceFilter,
          });
      }
    
      if (filters.length > 0) {
        requestBody.dimensionFilterGroups = [{ filters }];
      }
      // --- 构建结束 ---
    
      const response = await searchConsole.searchAnalytics(siteUrl, requestBody);
      return {
        content: [
          {
            type: 'text',
            text: JSON.stringify(response.data, null, 2),
          },
        ],
      };
    }
  • Zod schema defining the input parameters for the search_analytics tool, including dates, dimensions, filters, and validation.
    export const SearchAnalyticsSchema = GSCBaseSchema.extend({
      startDate: z.string().describe('Start date in YYYY-MM-DD format'),
      endDate: z.string().describe('End date in YYYY-MM-DD format'),
      dimensions: z
        .string()
        .transform((val) => val.split(','))
        .refine((val) =>
          val.every((d) => ['query', 'page', 'country', 'device', 'searchAppearance'].includes(d)),
        )
        .optional()
        .describe(
          'Comma-separated list of dimensions to break down results by, such as query, page, country, device, searchAppearance',
        ),
      type: z
        .enum(['web', 'image', 'video', 'news'])
        .optional()
        .describe('Type of search to filter by, such as web, image, video, news'),
      aggregationType: z
        .enum(['auto', 'byNewsShowcasePanel', 'byProperty', 'byPage'])
        .optional()
        .describe('Type of aggregation, such as auto, byNewsShowcasePanel, byProperty, byPage'),
      rowLimit: z.number().min(1).max(25000).default(1000).describe('Maximum number of rows to return (up to 25,000 for enhanced performance)'),
      pageFilter: z.string().optional().describe('Filter by a specific page URL. Use with filterOperator.'),
      queryFilter: z.string().optional().describe('Filter by a specific query string. Use with filterOperator.'),
      countryFilter: z.string().optional().describe('Filter by a country using ISO 3166-1 alpha-3 code (e.g., USA, CHN).'),
      deviceFilter: z.enum(['DESKTOP', 'MOBILE', 'TABLET']).optional().describe('Filter by device type.'),
      filterOperator: z
        .enum(['equals', 'contains', 'notEquals', 'notContains', 'includingRegex', 'excludingRegex'])
        .default('equals')
        .optional()
        .describe('Operator for page and query filters. Defaults to "equals". Enhanced with regex support.'),
      regexFilter: z.string().optional().describe('Advanced regex filter for intelligent query matching'),
    });
  • src/index.ts:48-52 (registration)
    Registration of the search_analytics tool in the list_tools handler, providing name, description, and input schema.
    {
      name: 'search_analytics',
      description: 'Get search performance data from Google Search Console',
      inputSchema: zodToJsonSchema(SearchAnalyticsSchema),
    },
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure but offers minimal information. It states this is a 'Get' operation (implying read-only) but doesn't mention authentication requirements, rate limits, data freshness, pagination behavior, or error conditions. For a 13-parameter tool with complex filtering options, this is inadequate behavioral context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that immediately communicates the core purpose without unnecessary words. It's appropriately sized for a tool with comprehensive schema documentation and follows the principle of front-loading essential information. Every word earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex tool with 13 parameters, no annotations, and no output schema, the description is insufficient. It doesn't explain what 'search performance data' includes (clicks, impressions, CTR, position), doesn't mention data aggregation or formatting, and provides no context about the Google Search Console API limitations or typical use cases. The agent would struggle to use this tool effectively without additional context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema description coverage is 100%, meaning all parameters are well-documented in the schema itself. The description adds no additional parameter semantics beyond the generic 'search performance data' context. This meets the baseline expectation when schema coverage is complete, but the description doesn't enhance understanding of how parameters interact or typical usage patterns.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the action ('Get') and resource ('search performance data from Google Search Console'), making the purpose immediately understandable. However, it doesn't differentiate this tool from its sibling 'enhanced_search_analytics', which appears to be a related alternative. The description is specific but lacks sibling distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives like 'enhanced_search_analytics' or other siblings. There's no mention of prerequisites, appropriate contexts, or limitations. The agent receives no help in choosing between this and similar tools on the server.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ahonn/mcp-server-gsc'

If you have feedback or need assistance with the MCP directory API, please join our Discord server