DEV Community

Cover image for Google's Search Console API Fails Silently, So I Built an MCP Server That Doesn't
Moein
Moein

Posted on

Google's Search Console API Fails Silently, So I Built an MCP Server That Doesn't

An open-source, local, read-only MCP server that checks your request before Google quietly hands back nothing

Ask the Google Search Console API for clicks filtered by country us and you get zero rows. No error, no warning, just nothing.

It's not the only one. All of these come back empty with no error:

  • an invalid regex, or one that isn't RE2
  • a two-letter country code
  • an unknown device
  • hourly data older than about ten days
  • a date range in the future

But an empty result is also a valid answer, so you can't tell a broken request from a quiet week.

It gets worse when an AI assistant makes the calls. Given zero rows, a model will explain the zero. It can't tell you the request was malformed, because nothing told it so.

So I built an MCP server for Search Console that checks for these cases before the call goes out and tells you in plain words what's wrong. It's open source under the MIT license, on PyPI as open-gsc-mcp, and the code is at github.com/onlymoein/google-search-console-mcp.

What it is

It's a local Model Context Protocol server that connects Claude Code, Claude Desktop, Cursor or any other MCP client to the Search Console API. You ask in plain language; it makes correct API calls and returns structured data.

The checks are the core of it. I verified the rules against the live API with a probe script that's in the repo, rather than copying them from blog posts. It also catches the combinations that fail with a terse 400 instead, like grouping searchAppearance with another dimension, and explains each one.

Every analytics result includes the exact request sent to Google, so you can see what was actually asked. And each search surface (Discover, Images, video, Google News, the News tab) gets its own tool that only accepts what that surface supports.

Why did traffic move?

The real question is usually "why did clicks drop?" explain_change is built for that. You give it two periods and it splits the rise or fall by page, query, country, device and search appearance. It separates lost impressions from a lower click-through rate, which are two very different problems. And it lines the change up with Google's published updates, so you can see whether one landed in or near the window.

Rebuilding the Page indexing report

The API doesn't expose the Page indexing report's URL lists. Its URL Inspection endpoint checks one URL at a time, 2,000 a day per property.

audit_indexing rebuilds the lists from that. It inspects every URL in your sitemaps within the daily quota, saves its progress locally, and picks up where it stopped the next day. Results are grouped by index status with likely fixes, plus canonical conflicts, indexed pages with no impressions, and pages missing from your sitemaps.

A single call from your assistant covers about 50 URLs. For a large site, run the audit from a terminal, or daily from cron, to use the full 2,000:

uvx open-gsc-mcp@latest audit sc-domain:example.com
Enter fullscreen mode Exit fullscreen mode

Read-only, local, no telemetry

The server is read-only by default. The write tools don't exist unless you set GSC_ENABLE_WRITES=1, and the login only asks Google for read-only access unless you sign in with --write.

It runs locally over stdio with no telemetry. Besides Google, the only site it reads is your own, during an audit. It stores two things: your login, with owner-only permissions, and your audit progress in a single SQLite file only you can read.

Quick start

You need uv, a Google account with access to a Search Console property, and an OAuth client from Google Cloud. Setting up the client takes about five minutes, once, and the README walks through each step.

Sign in:

uvx open-gsc-mcp@latest auth login --client-file ~/.config/open-gsc-mcp/client_secret.json
Enter fullscreen mode Exit fullscreen mode

Add it to Claude Code:

claude mcp add --scope user gsc -- uvx open-gsc-mcp@latest
Enter fullscreen mode Exit fullscreen mode

Restart the client and ask something like "Which queries lost the most clicks this month on example.com?" Claude Desktop and Cursor setup is in the README.

Try it and tell me what breaks

The project is unofficial and not affiliated with Google. You use your own Google Cloud credentials.

If you work with Search Console data, try it. If you hit a request that returns nothing and the server didn't catch it, that's exactly the kind of issue I want to hear about. Open an issue on GitHub, or find me on X at @onlymoein.

And if it saves you an afternoon of wondering why your report is empty, a star on the repo helps other people find it:

github.com/onlymoein/google-search-console-mcp

Top comments (0)