A Google Search Console MCP server lets an AI assistant query your Search Console data: clicks, impressions, CTR and position by query and page, plus sitemaps and, on some servers, URL inspection. MCP (Model Context Protocol) is the standard AI assistants use to call outside tools.
Google does not publish a Search Console MCP server (checked 1 October 2026). It has one for Google Analytics, but every Search Console server today is third-party code that calls Google’s public Search Console API. You can reach Search Console from an assistant in three ways:
- An open-source server on your own computer. Free, with your own Google Cloud project and OAuth client. The most complete ones also inspect URLs and manage sitemaps.
- A hosted connector such as Windsor.ai. Nothing to install, it works in ChatGPT as well as Claude, and it can put GA4, Google Ads and other sources in the same conversation.
- Your own connection to the Search Console API, built on a Google Cloud project.
I have used Search Console in Claude every day for more than a year. Until three months ago I used my own Google Cloud setup, and since then the Windsor.ai connector. These three points from that use apply on any route:
- Google does not report the search query for about a third of clicks. It withholds rare queries for privacy, so on windsor.ai in September only 68% of clicks came with their query. A share of all clicks and a share of clicks with a known query are different numbers.
- The branded filter misses misspellings. I build my own brand regex in Claude and keep it for later questions.
- Claude’s suggestions need an SEO check. A high-impression, low-click query is often a cannibalization problem, and Claude has more than once suggested a new article for it instead.
What a Search Console MCP server can reach
Every server is a wrapper around the same four parts of Google’s Search Console API:
| API | What an assistant can ask for | Limits |
|---|---|---|
| Search Analytics | Clicks, impressions, CTR and position by query, page, country, device, date, search type and search appearance | Up to 25,000 rows per request; Google returns the top rows, not every row; 16 months of history |
| URL Inspection | Index status, last crawl, canonical, mobile usability and rich results for one URL | 2,000 inspections per day and 600 per minute per property |
| Sitemaps | Submitted sitemaps, errors, warnings, last download; submit or delete | |
| Sites | The properties your account can see; add or remove a property |
The limits come from Google’s Search Analytics API reference and its usage limits page. Some reports exist only in the Search Console interface, so no server can return them: the Page indexing report’s full list of excluded URLs, Core Web Vitals, manual actions and links.
The routes compared
| Open-source server (mcp-search-console) | Hosted connector (Windsor.ai) | Your own Google Cloud connection | |
|---|---|---|---|
| Setup | Google Cloud project, Search Console API, OAuth Desktop client or service account, uv | Sign in to Windsor.ai, pick the property, add Windsor in your assistant | Google Cloud project, OAuth client, your own code or scripts |
| Works in | Claude Desktop, Claude Code, Cursor, Codex CLI, Gemini CLI | Claude (web, desktop, Claude Code), ChatGPT, Gemini, Copilot | Wherever you run it |
| Search Analytics | Yes | Yes, plus branded, words-in-query and path fields | Yes |
| URL Inspection | Yes | No | Yes |
| Sitemaps | Read, submit, delete | Read | What you build |
| Other sources | No | GA4, Google Ads, 350+ others | No |
| Cost | Free | Free forever plan for one source; paid from $19 a month | Free, plus your time |
My own setup took 5 to 10 minutes for every new Google account I added: a project, the API, an OAuth client and the consent screen. Doing it once is fine. Repeating it for each client account takes time, and the steps are hard to explain to someone who is not technical; a hosted connector needs none of them.
I still use URL inspection often, mostly to check how updated content is crawled and indexed, and the Windsor connector does not have it. If you need inspection from the assistant, use an open-source server or your own Google Cloud connection for that part.
How to set up the open-source server
The open-source server we read for this guide is mcp-search-console (GitHub: AminForou/mcp-gsc), version 0.4.1 from September 2026. Its code has 21 tools covering search analytics, period comparisons, URL inspection and sitemaps. The steps below follow its README; we read the code but did not run it for this article.
Before you start
- A Google account with access to the Search Console property.
- A Google Cloud project where you can enable APIs.
- uv, the Python package runner. The README recommends it because it manages the Python version for you.
Step 1: enable the API and create credentials
In the Google Cloud console, enable the Google Search Console API. Then go to Credentials, create an OAuth client ID of type Desktop app, and download the JSON file. Keep it somewhere permanent.
For a shared or automated setup, create a service account instead, download its key, and add the service account’s email address as a user on the Search Console property.
Step 2: add the server to your client
Claude Code (one line):
claude mcp add gsc --scope user -e GSC_OAUTH_CLIENT_SECRETS_FILE=/full/path/to/client_secrets.json -- uvx mcp-search-console
Claude Desktop: add this under mcpServers in claude_desktop_config.json. Use the full path to uvx, because Claude Desktop does not read your shell’s PATH.
"gscServer": {
"command": "/full/path/to/uvx",
"args": ["mcp-search-console"],
"env": { "GSC_OAUTH_CLIENT_SECRETS_FILE": "/full/path/to/client_secrets.json" }
}
Gemini CLI: add the same block under mcpServers in ~/.gemini/settings.json.
Quit and reopen the app. On the first question a browser window opens for Google sign-in, and the token is saved after that.
Step 3: check what you granted
The server asks Google for the full Search Console scope, which includes write access, even if you only want to read. Very few people on a team should be able to change Search Console settings, so treat this like adding a new owner-level user. Tools that add or remove properties or delete sitemaps stay off unless you set GSC_ALLOW_DESTRUCTIVE=true; leave it unset. Submitting a sitemap is allowed by default.
Step 4: test with a number you know
List my Search Console properties, then show clicks and impressions for [property] for the last 28 days. Tell me the latest date in the data.
Compare the answer with the Performance report for the same dates.
Search Console in ChatGPT and Gemini
ChatGPT accepts MCP servers only as remote HTTPS connectors in Developer Mode (Plus, Pro, Business, Enterprise and Edu, on the web). It cannot start a local server, so the open-source servers do not work in ChatGPT unless you deploy one on a server yourself. Hosted connectors work: Windsor.ai is listed in ChatGPT as a plugin, and the setup is in how to connect Google Search Console to ChatGPT.
Gemini CLI runs local servers, so the configuration above works there. In Gemini Enterprise, Windsor.ai is available as a data store connector (in public preview); the setup is in our Gemini Enterprise guide.
The hosted route: Windsor.ai
Windsor.ai’s MCP server runs on our side. In Claude, open Customize, then Connectors, search for Windsor and click Add. In ChatGPT, install the Windsor plugin. In Claude Code, run claude mcp add --transport http windsor https://mcp.windsor.ai. Sign in to Windsor.ai and connect Search Console once.
Search Console through Windsor is read-only and has no URL inspection. It adds fields the Search Console interface does not have: words_in_query, position_page (which results page) and the path levels of each URL (pathlevel1 to pathlevel4), so “clicks by blog folder” is one request. GA4, Google Ads and 350+ other sources go through the same connector.
Windsor.ai has a free forever plan with one data source, and no credit card is needed. Questions that combine Search Console with GA4 or ad data need a paid plan after the first 30 days, from $19 a month (billed annually) for three sources or $99 a month for seven. See pricing.
The questions I ask most
Which queries lost visibility on a page, and why:
For [page], show the queries that lost the most impressions in the last 28 days compared with the 28 days before, and in the last 7 days compared with the 7 days before. Include position and clicks. For each query, list every one of our pages that ranks for it, so I can see whether the drop comes from cannibalization or something else.
Which pages dropped, and whether search behaviour changed:
Show the pages that dropped the most in the last 7 days compared with the previous 7 days, and compared with the same 7 days last year. For each page, list the queries that lost position, the queries that lost the most impressions and the queries that gained the most impressions.
The gained and lost lists side by side show whether people changed how they search, or whether the page lost rankings.
Long queries that may come from AI assistants:
List every query with 9 or more words, with the page that received its impressions. Add a confidence score for whether the search came through an AI assistant. A search for an address, for example, is unlikely to be AI-assisted.
The score is Claude’s judgment, so I use it to sort the list and do not treat it as a measurement.
Questions we rank for:
List all queries phrased as a question, with our current position for each.
How I used it on our Google Analytics MCP pages
In September I asked Claude which of our GA4 and Claude pages competed with each other. The Search Console data showed two problems:
- A generic MCP query had no page written for it. One of our connector pages had about 9,700 impressions from mid-May to 21 September for generic Google Analytics MCP searches, at an average position of 8, with 34 clicks.
- Two pages split the same Claude queries. A connector page and a how-to ranked mostly in positions 1 to 3 for the same GA4 and Claude searches, with 155 queries in common.
Before acting I checked the live results, because Search Console’s average position covers the whole period. The connector page was no longer on the first two results pages for the main query, so the position of 8 came from earlier months. We split the topic into three pages with one intent each and published Google Analytics MCP as a separate article. The method I use for pairs like this is in how I catch content cannibalization with Claude.
Check the numbers before you act on them
Google does not report the query for about a third of clicks. It leaves out queries it treats as rare, to protect searchers’ privacy. For 2 to 28 September 2026 (the latest date in the data when I pulled it), windsor.ai’s domain property recorded 71,827 clicks and 4.44 million impressions in total. The rows that carry a query added up to 48,727 clicks (68%) and 3.15 million impressions (71%). I have split the data by page, country and date to get under the row limits, and the share of clicks without a query stayed the same, so the gap comes from those hidden queries and no export can recover them. For this article I split the same month by device: the clicks with a query came to 48,727 again, while impressions with a query rose to 3.43 million, because the smaller requests returned more long-tail rows. Ask the assistant to state whether a share is of all clicks or of clicks with a query, and treat query-level impression totals as approximate.

Claude’s answer through the Windsor.ai connector, 1 October 2026. I asked for 2 to 29 September; the data ended on the 28th, and Claude said so before giving the numbers.
Build your own branded filter. On every site I have worked on, the built-in branded filter missed misspellings of the brand name. I ask Claude to write a regular expression from the queries that bring the most clicks to the homepage, check it, and save it in Claude so the next question about branded traffic uses it. Windsor’s branded_vs_nonbranded field has the same gap, because it only looks for the domain name in the query.
Ask for the latest date in the data. Search Console data is usually 2 to 3 days behind, and the delay can be longer during reporting incidents or algorithm updates. Claude answers the question you asked and does not always say how fresh the data is, so I ask for the last date every time.
Name the property and the hostname. A precise prompt returns the same numbers on a domain property and on a URL-prefix property. A vague one can mix in subdomains that rank for the same queries.
Cross-check with a second API tool. The interface shows fewer rows as you add filters, while the assistant reads the API. When I want to check Claude’s numbers I use the Search Analytics for Sheets add-on, which also reads the API. I have not found wrong raw numbers so far.
Check Claude’s advice as well as its numbers. Several times Claude has found a query with many impressions and few clicks and suggested a new article for it. In most of those cases an existing article was already taking impressions from the page meant to rank, and the fix was to update that article so it stopped competing. A new article would have added a third page to the same query.
If you store the rows yourself, key them on every dimension. When rows from a query-and-page request are saved in a table keyed on fewer dimensions, later rows overwrite earlier ones without an error. One of our internal tools undercounted Search Console by about 60% for that reason until we fixed the key.
Large exports need paging, and inspection has a quota. One request returns at most 25,000 rows, and Google returns its top rows rather than all of them, so an assistant that stops after one request reports a partial list as complete. On windsor.ai, one request for 2 to 28 September returned 21,228 queries; the same request split by device returned 54,577. URL inspection allows 2,000 inspections per property per day, so “check every URL in the sitemap” stops partway on a large site.
All windsor.ai figures here come from our own Search Console property (the domain property), pulled through the Windsor.ai connector on 1 October 2026. The site totals were checked with a second pull split by device, which added up to the same clicks and impressions.
Conclusion
Google has no Search Console MCP server, so pick the route by what you need from the assistant. For URL inspection and sitemap work, use an open-source server or your own Google Cloud connection, and grant write access to as few people as possible. For Search Console in ChatGPT, or next to GA4 and ad data in one answer, use a hosted connector. On any route, ask for the latest data date and the base of every share, and check Claude’s advice against what you know about the site.
The Claude setup steps are in how to connect Google Search Console to Claude, and the GA4 version of this guide is Google Analytics MCP.
🚀 Connect Search Console to Claude or ChatGPT with Windsor.ai. Free forever plan, no credit card. Try Windsor.ai.
FAQs
Is a Search Console MCP server free?
Yes, the open-source servers are free, and the Search Console API has no charge. You need a Google Cloud project and your own OAuth client. Hosted connectors charge by plan; Windsor.ai has a free forever plan for one data source.
Can a Search Console MCP server change my Search Console settings?
Yes, if it has write tools and the full scope. mcp-search-console asks for full access and can submit sitemaps; adding or removing properties and deleting sitemaps stay off unless you turn them on. Windsor.ai’s connector is read-only.
Does a Search Console MCP server work with ChatGPT?
Yes, if the server is remote. ChatGPT connects to MCP servers over HTTPS in Developer Mode, so a local open-source server does not work there. A hosted connector such as Windsor.ai does.
Can I see the queries Search Console hides?
No. Google leaves rare queries out of query-level data on every route, including the API. Splitting the request by page, country or date does not bring them back.
Can I combine Search Console with GA4 through MCP?
Yes, with two servers in the same client or one connector that carries both. Search Console reports by full URL and GA4 by page path and hostname, so check that both use the same form of the URL before comparing.


