Skip to main content
Glama
Boston617Delta

gsc-coverage

gsc-coverage-mcp

A Google Search Console MCP server for Claude (or any MCP client) that pulls every row Google will give you and tells the model how much of the picture those rows cover.

Why

The Search Analytics API returns 1,000 rows by default and at most 25,000 per request. Many GSC connectors make one request and stop. The model does correct math on that first slice and writes a report that reads as if it covered the whole site.

Even a full pull isn't every query. Google drops anonymized and rare queries, so query-level rows never add up to the property totals. On a small site it is normal for query rows to cover only half of all clicks.

That's how an audit goes wrong while every number in it checks out: "dead" pages that actually have impressions, cannibalization that was missed, content gaps for pages you already have, and "lost rankings" that are just two pulls with different coverage.

This server fixes the two parts a connector can fix:

  1. Pagination. search_analytics walks startRow in 25,000-row pages until Google runs out of rows, up to a maxRows safety cap you control.

  2. A coverage report on every pull. Each response includes a coverage block, so the model has to see what it is working from before it writes recommendations.

Related MCP server: Google Search Console MCP Server

What a response looks like

{
  "coverage": {
    "window": { "startDate": "2026-09-01", "endDate": "2026-09-30", "type": "web", "dataState": "final" },
    "dimensions": ["query"],
    "rowsReturned": 3412,
    "pagesFetched": 1,
    "apiExhausted": true,
    "truncated": false,
    "propertyTotals": { "clicks": 1980, "impressions": 412300 },
    "rowSums": { "clicks": 1104, "impressions": 301877 },
    "clickCoveragePct": 55.8,
    "impressionCoveragePct": 73.2,
    "notes": [
      "Query rows never add up to property totals: Google drops anonymized and rare queries. The gap comes from Google's privacy filtering, and the missing clicks still belong to pages you have.",
      "Missing from these rows is not the same as zero. Check any absent URL or query with a direct filter before calling it lost or invisible."
    ]
  },
  "file": "/tmp/gsc-coverage-mcp/pull-1761650000000.csv",
  "preview": [{ "query": "example query", "clicks": 84, "impressions": 2210, "ctr": 3.8, "position": 4.12 }]
}

(Illustrative numbers.)

Large pulls are written to CSV or JSON, and only a preview comes back inline. That keeps 80,000 rows out of the model's context window while still giving it the full file to work with.

Tools

Tool

What it does

list_sites

Lists the properties your credentials can read.

search_analytics

Paginated performance pull with a coverage report.

search_analytics inputs:

Input

Default

Notes

siteUrl

required

Exactly as GSC lists it: sc-domain:example.com or https://www.example.com/

startDate, endDate

required

YYYY-MM-DD

dimensions

["query"]

Any of query, page, country, device, date, searchAppearance, hour

type

web

web, image, video, news, discover, googleNews

dataState

final

all includes fresh, not-yet-final data

aggregationType

API default

auto, byPage, byProperty, byNewsShowcasePanel

filters

none

ANDed { dimension, operator, expression } filters, applied to both the rows and the totals

maxRows

100000

Safety cap across all pages. If it is hit, truncated is true

includeCoverage

true

Pulls property totals for the same window and filters

outputFile

temp CSV

.csv or .json. Used automatically when rows exceed inlineRowLimit

inlineRowLimit

500

Rows returned inline before switching to a file

previewRows

25

Inline preview size when rows go to a file

Setup

Requires Node 18+.

git clone https://github.com/Boston617Delta/gsc-coverage-mcp.git
cd gsc-coverage-mcp
npm install

Credentials

Either of these works:

  • Service account (recommended for anything scheduled). Create a service account and a JSON key, then add the service account's email as a user on each Search Console property (Restricted is enough). Point GOOGLE_APPLICATION_CREDENTIALS at the key. Service accounts don't hit the periodic re-authentication that user logins do, so scheduled jobs keep running.

  • Application Default Credentials. gcloud auth application-default login with the https://www.googleapis.com/auth/webmasters.readonly scope. This works for interactive use, but if your Google Workspace enforces Google Cloud session control, expect to log in again every few days.

If your organization blocks service account keys (iam.disableServiceAccountKeyCreation, on by default for newer Google Cloud orgs), an org policy admin can lift it for a single project:

gcloud resource-manager org-policies disable-enforce iam.disableServiceAccountKeyCreation --project=YOUR_PROJECT

Keep the key file out of version control, readable only by you (chmod 600).

Claude Code

claude mcp add gsc-coverage \
  --env GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json \
  -- node /path/to/gsc-coverage-mcp/src/index.js

Claude Desktop

{
  "mcpServers": {
    "gsc-coverage": {
      "command": "node",
      "args": ["/path/to/gsc-coverage-mcp/src/index.js"],
      "env": { "GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account.json" }
    }
  }
}

Codex

The Codex CLI, IDE extension and desktop app share ~/.codex/config.toml. Add:

[mcp_servers.gsc-coverage]
command = "node"
args = ["/path/to/gsc-coverage-mcp/src/index.js"]
tool_timeout_sec = 180

[mcp_servers.gsc-coverage.env]
GOOGLE_APPLICATION_CREDENTIALS = "/path/to/service-account.json"

Or from the CLI:

codex mcp add gsc-coverage \
  --env GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json \
  -- node /path/to/gsc-coverage-mcp/src/index.js

Codex stops a tool call after 60 seconds by default, and a pull of 100,000 rows can take longer than that, so set tool_timeout_sec in the config. If the desktop app can't start the server, replace node with the full path that which node prints.

What it can't fix

  • Anonymized queries are gone. Google withholds them before any connector, warehouse or export sees the data. The coverage block measures that gap so you can report it.

  • Google's own row limits still apply. Google documents a ceiling of about 50,000 rows per day, per property, per search type for page and query breakdowns. For very large sites, use the Bulk Data Export to BigQuery.

  • Historical rows include dead URLs. GSC still reports pages you removed months ago. Check status codes, redirects, canonicals and indexability on the live site before recommending work on any URL.

A checklist to pair with it

Before trusting any LLM output built on GSC data:

  1. Request every row, and confirm truncated is false.

  2. Read clickCoveragePct. Page-level rows should land close to the property totals, while query-level rows fall short by however much Google anonymized.

  3. Treat missing as unknown, not zero. Filter for the specific URL or query before calling it lost.

  4. Use the same dimensions, filters and window logic for both sides of any comparison.

  5. Check every recommended URL on the live site.

  6. Put the date range, dimensions, row count and coverage in the deliverable.

Development

npm test

Tests use a fake Search Console client, so no credentials are needed.

License

MIT

Available Tools

2 tools
list_sitesA

List the Search Console properties these credentials can read, with permission level.

NameRequiredDescriptionDefault

No parameters

TDQS

A3.7/5.0
Behavior3/5

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

With no annotations, the description carries the full burden; 'List' implies a non-destructive read but that is never asserted outright. It does add useful context by disclosing that a permission level is returned per property, which is behavior beyond the (empty) schema. Pagination, ordering, and whether inaccessible properties are omitted are not covered.

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?

A single sentence with no waste, front-loading the action and resource before the scope and return detail. Nothing could be cut without losing information.

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

Completeness4/5

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

For a trivial zero-argument list tool with no output schema, the description covers what the tool returns (properties plus permission level) and the credential-based scoping. It falls just short on response shape details like ordering or paging, which matter if the account has many properties.

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

Parameters4/5

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

Zero parameters, so there is nothing for the description to disambiguate — baseline 4 applies. The empty schema is consistent with the described behavior of listing everything the credentials can see.

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?

Specific verb and resource ('List the Search Console properties') with an explicit scope qualifier ('these credentials can read') and an indication of what comes back ('with permission level'). It doesn't name or distinguish itself from the sibling search_analytics, but the two differ obviously enough (enumerate properties vs. query analytics).

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

Usage Guidelines3/5

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

The phrase 'these credentials can read' implies a discovery use case — figure out which properties are accessible before calling search_analytics — but the description never states when to use it, when not to, or that search_analytics should be called afterwards. Usage is inferable rather than guided.

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

search_analyticsA

Pull Search Console performance rows, paging past the 25,000-row API cap until Google has no more rows (or maxRows is hit). Every response includes a coverage block: rows returned, pages fetched, whether the pull was truncated, property totals for the same window, and the share of clicks and impressions the rows account for. Read the coverage block and its notes before drawing conclusions. Large pulls are written to a CSV/JSON file and only a preview comes back inline.

NameRequiredDescriptionDefault
typeNoweb
endDateYesYYYY-MM-DD
filtersNoANDed dimension filters.
maxRowsNoSafety cap across all pages.
siteUrlYesProperty exactly as Search Console lists it, e.g. "sc-domain:example.com" or "https://www.example.com/".
dataStateNo"all" includes fresh, not-yet-final data.final
startDateYesYYYY-MM-DD
dimensionsNoBreakdown dimensions. Each added dimension multiplies the row count.
outputFileNoWrite all rows here (.csv or .json). Defaults to a temp CSV when rows exceed inlineRowLimit.
previewRowsNoRows to show inline when rows go to a file.
inlineRowLimitNoReturn rows inline only up to this many.
aggregationTypeNo
includeCoverageNoAlso pull property totals and compute coverage.

TDQS

A4.4/5.0
Behavior4/5

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

With no annotations, the description carries the burden and does so well: it discloses automatic pagination past the API cap, the maxRows safety cap, truncation signalling, and the significant side effect that large pulls are written to a CSV/JSON file with only a preview returned inline. Not covered: auth/property-permission requirements, rate limits, or failure modes.

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?

Four sentences, zero filler, and the front-loaded first sentence states the operation and its pagination scope. Each subsequent sentence adds a distinct, decision-relevant fact (coverage block, how to read it, file spill).

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

Completeness4/5

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

For a 13-parameter tool with no output schema, the description supplies the return contract: coverage block contents, truncation flag, property totals, and the file-plus-preview behavior. The remaining gap is that it never describes the shape of the row objects themselves (dimension keys plus clicks/impressions/CTR/position).

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

Parameters4/5

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

Schema coverage is already 85%, so baseline is 3, but the description adds real meaning on top: maxRows is framed as the cap that ends paging, and outputFile/previewRows/inlineRowLimit are explained collectively as the file-spill-with-preview behavior. It adds little on dimensions, filters, type, or dataState, which the schema already handles.

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

Purpose5/5

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

"Pull Search Console performance rows" names a specific verb and resource, and the sentence immediately scopes it (paging past the 25,000-row API cap until exhausted or maxRows is hit). This is unambiguously distinct from the only sibling, list_sites, which enumerates properties rather than returning performance data.

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

Usage Guidelines4/5

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

Gives clear operating context: the pull auto-paginates, is capped by maxRows, and the coverage block must be read before drawing conclusions. It stops short of explicit when-to-use/when-not-to-use routing or stating prerequisites, but with a single unrelated sibling the practical need is low.

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

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedlist_sites
    • First observedsearch_analytics

TDQS

A4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools target completely different resources: list_sites enumerates accessible properties, while search_analytics pulls performance rows with coverage metadata. There is no plausible way to confuse one for the other, and the descriptions make the boundary explicit.

Naming Consistency5/5

Both names follow the same snake_case verb_noun convention (list_sites, search_analytics), with clear resource nouns. The pattern is predictable and would extend naturally if more tools were added.

Tool Count3/5

Two tools is thin for a Search Console surface, even a narrowly scoped one; a single discovery tool plus a single query tool leaves little room for workflow support. It is defensible for a read-only, coverage-focused server, but sits at the borderline of the 1-2 tool range.

Completeness4/5

The core read path is covered end to end: discover properties, then pull paged performance data with totals and truncation reporting so agents can reason about coverage. Minor gaps exist around adjacent Search Console operations (e.g. sitemaps, URL inspection, or dimension/metric discovery), but nothing that blocks the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Provides comprehensive access to Google Search Console data with enhanced analytics capabilities, supporting up to 25,000 rows of performance data, advanced filtering with regex patterns, and automatic detection of SEO optimization opportunities.
    5,260 npm
    MIT
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    Provides comprehensive access to Google Search Console data with enhanced analytics capabilities, supporting up to 25,000 rows of performance data, advanced filtering with regex patterns, and automatic quick wins detection for SEO optimization opportunities.
    2
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to fetch Google Search Console search analytics reports (clicks, impressions, CTR, position) over MCP, with support for custom date ranges, dimensions, filters, comparisons, and exports.
    MIT
  • A
    license
    B
    quality
    A
    maintenance
    Enables users to query search performance, indexing, sitemaps and properties in plain language from any MCP client, returning worked-out analysis such as cannibalization, striking-distance keywords and decaying pages, with multilingual query variants merged so totals are correct. It also syncs data to a local store for history beyond Google's 16-month limit, including a 24-hour view, hourly data and timezone-adjusted days.
    37
    39 PyPI
    2
    MIT