Blog · Claude × Search Console

Connect Google Search Console to Claude and Claude Code: three ways, and what each is for

Published · Updated · 12 min read

There are three ways to connect Google Search Console to Claude, and Google publishes none of them: as of September 26, 2026, Google ships official MCP servers for Google Analytics and Google Ads, but not for Search Console. You can run a community MCP server such as mcp-gsc on your own machine with your own Google Cloud credentials; you can add a data vendor's hosted Claude connector (Supermetrics, Windsor.ai, Porter Metrics); or you can sync the property into a data backend that Claude Code queries with read-only SQL — the route TableBI takes. The first two call the Search Console API at the moment you ask. The third keeps a stored copy that separates site totals, which include the anonymized queries Google leaves out of every query table, from the query-and-page detail. This guide compares the routes side by side, then walks through the third one: connect once with tablebi connect gsc, ask in SQL, fall back to live API calls (tablebi gsc query, inspect, sitemaps) for what the tables don't hold, and pin a self-refreshing SEO dashboard.

Three ways to connect Search Console to Claude, and what each one is for

Every "Search Console MCP server" you can install today is third-party. Google's own list of official MCP servers names a Google Analytics server and no Search Console one, and Google Cloud's list of Google-managed MCP servers (updated September 25, 2026) has no Search Console entry either. Claude's built-in Google connectors cover Gmail, Google Calendar and Google Drive — not Search Console. What remains are community MCP servers you run yourself, hosted connectors from marketing-data vendors, and synced backends.

RouteWhat Claude readsCan it change Search Console?What you set upPrice
mcp-gsc (community MCP server)20 tools over the live API: search analytics by country, device and period, URL inspection (10 URLs per batch), sitemapsYes — it submits sitemaps; adding or removing properties and deleting sitemaps stay off unless you set GSC_ALLOW_DESTRUCTIVE to trueYour own Google Cloud project with the Search Console API enabled, plus an OAuth client or a service-account key; runs locally via uvx; updated September 2026Free, open source (MIT)
mcp-server-gsc (community MCP server)Search analytics up to 25,000 rows per request, regex filters, a "quick wins" finder, URL inspection, sitemap listsIt lists a submit_sitemap tool, but its code asks Google only for the read-only Search Console scopeA service-account key whose email you add to the property; Node.js 18+ via npx; updated September 2026Free, open source (MIT)
Supermetrics' Claude connectorPerformance data fetched per question — query, page, country, device, date, search type — plus sitemap and indexed-URL counts; no URL inspectionNo — its write actions cover ad platforms onlyClick Connect on its listing in Claude's directory, then authorize Search Console14-day free trial; paid plans from €49/month billed monthly
Windsor.ai's Claude connectorSearch Console fields (10 metrics, 43 dimensions by Windsor's count), including search type: web, image, video, news, DiscoverNo Search Console write actions listedPick Search Console at Windsor.ai, then add the Windsor connector in Claude (Customize → Connectors)Free plan (one source, last 30 days of data); paid plans from $19/month billed yearly ($23 month to month), as of September 2026
TableBI (this page)A synced copy in four tables — query × page detail, site totals with anonymized traffic, per-page totals, country × device — plus live calls (tablebi gsc query, inspect, sitemaps) for search appearance, URL inspection and sitemap statusNo — read-only by designOne OAuth: tablebi connect gsc --site sc-domain:example.com; Google credentials stay on TableBI's serverFree: one source and one live dashboard; Operator $29/month, by request (pricing)

Sources, read September 26, 2026 (prices as of September 2026): AminForou/mcp-gsc (tools, credentials, changelog), ahonn/mcp-server-gsc (tools, credentials, source code), Supermetrics' Search Console to Claude page and pricing, Windsor.ai's Search Console to Claude page and pricing, Porter Metrics' connector page, google/mcp (Google's list of official MCP servers), Google Cloud's supported MCP products, Google's Analytics and Google Ads MCP servers, and Claude's Google Workspace connectors.

Porter Metrics sells a connector in the same class and states that it is read-only: it never requests write scopes from Search Console, you paste its MCP URL into Claude as a custom connector, and it has a free plan, then $12.50 per property per month billed annually. On GitHub, mcp-gsc had about 1,700 stars and mcp-server-gsc about 270 on September 26, 2026; many smaller Search Console MCP projects exist, some of which bundle Bing Webmaster Tools or GA4 as well.

Pick by the job. An agent that should submit sitemaps — write access, not just reads — run by someone comfortable keeping Google Cloud credentials on their own machine, is what mcp-gsc is for. A marketer who works in claude.ai and already pays for a data platform gets Search Console in a few clicks through a vendor connector — and, per Claude Code's MCP documentation, connectors added in claude.ai also appear in Claude Code when you log in with the same account. A question that comes back every week, spans several properties or joins other channels is what a synced backend is built for: the numbers are stored once, with totals and query detail kept apart, instead of being re-fetched in every conversation. The rest of this page walks through that third route; the same comparison for paid search is in connect Google Ads to Claude Code.

The limit no route removes: anonymized queries

Google leaves anonymized queries — queries searched by no more than a few dozen people over two to three months — out of every query table in Search Console and in the API, but counts them in the chart totals (Google Search Central, "A deep dive into Search Console performance data filtering and limits"). Sum the rows of a query report and you get fewer clicks than the overview shows; how many fewer depends on the site. The Search Analytics API reference adds a second cap: a request returns at most 25,000 rows, and the API returns top rows rather than guaranteeing every row.

So a "top queries" answer from any MCP tool or connector describes the itemized part of your traffic, not all of it. TableBI stores both halves — site totals in search_console_totals_raw, which match the Search Console overview, and itemized queries in search_console_raw — and tablebi context reports, per site, what share of the last 28 days' clicks came from anonymized queries. The gap for every connected site, in one query:

claude code → tablebi
tablebi ask "WITH totals AS (
               SELECT site, SUM(clicks) AS all_clicks
               FROM search_console_totals_raw
               WHERE search_type = 'web'
                 AND date >= (SELECT MAX(date) FROM search_console_totals_raw) - 27
               GROUP BY site),
             by_query AS (
               SELECT site, SUM(clicks) AS query_clicks
               FROM search_console_raw
               WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 27
               GROUP BY site)
             SELECT site, all_clicks, query_clicks,
                    1 - query_clicks / NULLIF(all_clicks, 0) AS hidden_share
             FROM totals JOIN by_query USING (site)
             ORDER BY all_clicks DESC LIMIT 10"

The working rule that follows: take headline numbers and trends from the totals, and treat any query-level list as a subset that answers "which queries?", never "how much?".

Connect Search Console to Claude Code once

terminal
npm i -g @tablebi/cli
tablebi login
tablebi install

# browser opens for OAuth; one command per property
tablebi connect gsc --site sc-domain:example.com

tablebi install plants the TableBI skill in ~/.claude/skills/tablebi (the skill ships inside the npm package), so Claude Code knows these commands from then on — "which queries are slipping?" in plain English is enough to trigger the right query. How skills work, and which other marketing skills are worth installing, is covered in Claude Code marketing skills. The connection is read-only, and nothing is installed on your website.

Search Console data lands in four tables, each answering one kind of question:

  • search_console_raw — query × page detail by day: date, site, query, page, clicks, impressions, position, ctr. Anonymized queries are excluded, as in every query table.
  • search_console_totals_raw — daily site totals per search type (web, image, video, news, Discover, Google News), anonymized traffic included; headline numbers use search_type = 'web'.
  • search_console_pages_raw — daily totals per page, including clicks that came from anonymized queries.
  • search_console_geo_raw — daily country × device totals per site, countries as three-letter lowercase codes such as usa.

Search Console rows also appear in the cross-channel facts table next to GA4, Google Ads and Meta Ads (beta), but there they carry only date, platform and account; query, page, country and device live in the four tables above. Each new session starts with tablebi context --json, one call that reloads definitions, connected sources, how fresh each one is and the per-site anonymized share.

Worth saying explicitly: this is a read-only path. tablebi ask runs read-only SQL over synced data, and tablebi gsc query, inspect and sitemaps only read from the API; nothing your agent does here can submit a sitemap, remove a URL or change a property setting.

Four Search Console queries worth stealing

1. Queries gaining or losing impressions

claude code → tablebi
tablebi ask "SELECT query,
             SUM(CASE WHEN date >= (SELECT MAX(date) FROM search_console_raw) - 13
                 THEN impressions ELSE 0 END) AS imp_recent,
             SUM(CASE WHEN date < (SELECT MAX(date) FROM search_console_raw) - 13
                 THEN impressions ELSE 0 END) AS imp_prior
             FROM search_console_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 27
             GROUP BY query
             ORDER BY (imp_recent - imp_prior) ASC LIMIT 20"

The latest 14 days against the 14 before — the fastest way to see a core update or a decaying page in one table. The window anchors to MAX(date) in the data, not the wall clock; the query layer rejects current_date by design. Add AND site = 'example.com' to narrow it to one property.

2. Pages whose CTR underperforms their position

claude code → tablebi
tablebi ask "SELECT page,
             avg_position(SUM(position * impressions), SUM(impressions)) AS avg_pos,
             ctr(SUM(clicks), SUM(impressions)) AS ctr,
             SUM(impressions) AS impressions
             FROM search_console_pages_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_pages_raw) - 27
             GROUP BY page
             HAVING avg_position(SUM(position * impressions), SUM(impressions)) <= 5
                AND SUM(impressions) >= 100
             ORDER BY ctr ASC LIMIT 20"

Ranking in the top five but clicked like page two usually means the title or snippet is losing the result page — the cheapest win in SEO, because a rewrite needs no new links. This reads the per-page table, so clicks from anonymized queries count. avg_position() and ctr() are definition macros: the average position is weighted by impressions instead of averaging rows equally, and the arithmetic is fixed in the engine, so the agent never re-derives it differently on a Tuesday.

3. The portfolio view

claude code → tablebi
tablebi ask "SELECT site, SUM(clicks) AS clicks, SUM(impressions) AS impressions,
             ctr(SUM(clicks), SUM(impressions)) AS ctr
             FROM search_console_totals_raw
             WHERE search_type = 'web'
               AND date >= (SELECT MAX(date) FROM search_console_totals_raw) - 27
             GROUP BY site ORDER BY clicks DESC"

Client sites, a programmatic portfolio, docs plus a marketing site: one row per property, from the totals table, so each figure matches that property's Search Console overview, anonymized traffic included.

4. Country × device

claude code → tablebi
tablebi ask "SELECT country, device, SUM(clicks) AS clicks,
             ctr(SUM(clicks), SUM(impressions)) AS ctr
             FROM search_console_geo_raw
             WHERE date >= (SELECT MAX(date) FROM search_console_geo_raw) - 27
             GROUP BY country, device
             ORDER BY clicks DESC LIMIT 20"

Where clicks come from, and whether mobile turns impressions into clicks the way desktop does. The geo table is site-level; "which queries in Germany?" is a live question for tablebi gsc, below.

When the synced tables can't answer: tablebi gsc

Some Search Console questions are too narrow or too rare to store: queries by country, search appearance, hourly data, Discover by page, indexing status. For those, the pass-through commands — tablebi gsc query, inspect and sitemaps — send the question straight to the Search Console API for a property you have connected.

claude code → tablebi
# queries × device for one country (the synced geo table is site-level)
tablebi gsc query --site example.com --dims query,device --filter "country = deu" --days 28

# search appearance, and Discover by page
tablebi gsc query --site example.com --dims searchAppearance --days 28
tablebi gsc query --site example.com --type discover --dims page --days 28

# indexing: up to 20 URLs per call, 200 per site per day
tablebi gsc inspect --site example.com https://example.com/pricing/
tablebi gsc sitemaps --site example.com

The flags mirror the API: --dims takes query, page, country, device, searchAppearance, date and hour; --type takes web, image, video, news, discover and googleNews; --data-state final keeps only finalized days; --limit goes up to 25,000 rows. Answers come back with notes — for example when a window includes preliminary days, or when grouping by query leaves anonymized traffic out. For the API-level details behind all this, see the Search Console API alternative.

Search Console's newest days are preliminary

Google's Performance report help says the newest data can be preliminary and may still change, and its troubleshooting guide says collected data is usually available in 2–3 days (Performance report, troubleshooting data discrepancies). The API makes the choice explicit: dataState "all" includes fresh data, "final" returns finalized data only. TableBI syncs with fresh data, so the tables usually run through yesterday, and the latest two days or so are re-pulled on every sync while Google finishes them.

Two mechanisms keep the agent honest about it. Every answer carries a trust block: per-source freshness (the exact date each source runs through), caveats such as "the last two days are preliminary" or "Search Console clicks are not GA4 sessions", and lineage. And windows are written against the data's own high-water mark:

the honest date window
-- anchors to the freshest synced day, not the wall clock,
-- so a 28-day window is 28 days of *actual* data
WHERE date >= (SELECT MAX(date) FROM search_console_totals_raw) - 27

Rule of thumb: treat the last two days as provisional, compare complete weeks, and let the freshness readout — not memory — say how current the numbers are.

Pin a weekly SEO dashboard

Once a query earns its keep, stop re-running it — pin it. One command turns SQL into a dashboard at a public, read-only URL that refreshes itself as new data syncs in (on a schedule, and when someone opens it):

claude code → tablebi
tablebi pin --title "SEO weekly" \
  --widget "Daily clicks (28d)::line=SELECT date, SUM(clicks) AS clicks
    FROM search_console_totals_raw WHERE search_type = 'web'
    AND date >= (SELECT MAX(date) FROM search_console_totals_raw) - 27
    GROUP BY date ORDER BY date" \
  --widget "Top queries=SELECT query, SUM(clicks) AS clicks, SUM(impressions) AS impressions
    FROM search_console_raw
    WHERE date >= (SELECT MAX(date) FROM search_console_raw) - 27
    GROUP BY query ORDER BY clicks DESC LIMIT 20"
✓ published → https://dk.tablebi.com/d/dsh_…  (public, read-only, self-refreshing)

::line renders a line chart; widgets without it render as tables. The daily line reads the totals table, so it matches the Search Console overview; the query table underneath is the itemized subset. Here is a real one — an SEO portfolio overview pinned from live Search Console data:

That dashboard is not a screenshot and nobody rebuilds it on Mondays — it keeps itself current. Widget types, sharing and refresh behavior are covered in Claude Code dashboards; the cross-channel version of this workflow, with GA4 and paid sources in the same backend, is in Claude Code for marketing, and the same three-way comparison for Google Analytics is connect GA4 to Claude; for ad platforms it is Google Ads and Meta Ads.

Using Codex instead of Claude Code

Every route that runs on your machine works in OpenAI's Codex too. Codex keeps its MCP servers in ~/.codex/config.toml, one [mcp_servers.<name>] table per server with command, args and env, and OpenAI's MCP page says the Codex CLI, the IDE extension and the ChatGPT desktop app share that file; codex mcp add <name> -- <command> writes it for you. A community Search Console server goes in with the same command and environment variables its README gives for Claude. For TableBI, tablebi install --codex plants the skill in ~/.agents/skills, and adding --mcp also appends a [mcp_servers.tablebi] table for the built-in local MCP server. Checked October 1, 2026: Google still publishes no Search Console MCP server.

Errors you will run into

What you seeWhyWhat to do
insufficientPermissions (403)The Google account or service account behind the server can't see that propertyAdd the account as a user of the property in Search Console, or sign in with one that already is
accessNotConfigured (403)The Search Console API isn't enabled in your Cloud projectEnable it for the project whose credentials the server uses
quotaExceeded or rateLimitExceededSearch Console's load limits: query-and-page requests over long ranges are the most expensiveWait 15 minutes after a short-term overage and spread requests across the day, per Google's usage limits
An empty result for a site you know has trafficThe site URL doesn't match the property: a domain property is sc-domain:example.com, a URL-prefix property the full URL with its trailing slashList your properties and copy the exact string
Query rows add up to less than the site totalAnonymized queries (see above)Use site totals for totals; query rows for the queries Google lists
Google says "This app isn't verified" when you connect TableBITableBI's Google verification is in reviewChoose Advanced, then continue to console.tablebi.com; the scope is read-only

Error names and meanings are from Google's Search Console API errors page, read October 1, 2026.

FAQ

Is there an official Google Search Console MCP server?

No. As of September 26, 2026, Google publishes official MCP servers for Google Analytics and Google Ads but none for Search Console: neither Google's list of official MCP servers nor Google Cloud's list of managed MCP servers has a Search Console entry. Every "Search Console MCP server" is third-party — community projects such as AminForou/mcp-gsc and ahonn/mcp-server-gsc, or hosted connectors from data vendors.

How do I connect Google Search Console to Claude Code?

Three ways: register a community MCP server such as mcp-gsc with claude mcp add and your own Google Cloud credentials; add a vendor connector in claude.ai, which Claude Code picks up when you log in with the same claude.ai account; or install TableBI (npm i -g @tablebi/cli, tablebi login, tablebi install) and run tablebi connect gsc --site sc-domain:example.com for read-only SQL over a synced copy.

Can Claude submit sitemaps or change settings in Search Console?

Not through TableBI: tablebi ask runs read-only SQL, and tablebi gsc query, inspect and sitemaps only read — search analytics, URL inspection and sitemap status. The community server mcp-gsc can submit sitemaps, and it can delete sitemaps or properties once you set GSC_ALLOW_DESTRUCTIVE to true. The vendor connectors compared above are for analysis.

Why don't my query totals match the Search Console overview?

Anonymized queries. Google leaves queries searched by no more than a few dozen people over two to three months out of every query table and API response, but counts them in chart totals, so summed query rows come up short. TableBI keeps both: search_console_totals_raw matches the overview, search_console_raw holds the itemized queries, and tablebi context reports the gap per site.

How fresh is Search Console data in TableBI?

Usually through yesterday. TableBI requests Google's fresh data, so the newest two days or so are preliminary, and each sync re-pulls them until Google finalizes them. Every answer carries a trust block showing the date each source runs through.

Can I share results with someone who doesn't use a terminal?

Yes — pin the analysis. tablebi pin turns queries into a dashboard at a public, read-only URL that refreshes itself as new data syncs. Send the link; they never touch the CLI.

What does the TableBI route cost?

The Free plan covers one connected source and one live dashboard. Operator is $29 a month, by request, without those two ceilings. TableBI hosts no model, so there is no inference charge: your own Claude Code does the reasoning.

Try it

Give your Claude Code a data backend in five minutes.

terminal
npm i -g @tablebi/cli && tablebi install