Google Search Console MCP Server
This server provides an MCP interface to Google Search Console, enabling AI agents to:
List and manage Search Console properties.
Diagnose setup issues with automated checks for OAuth, tokens, configuration, and browsers.
Inspect URL indexing status via the URL Inspection API.
Monitor API quotas (Request-Indexing and URL Inspection budgets) per property.
Retrieve Search Analytics performance data (clicks, impressions, CTR, position) with flexible dimensions.
Submit or resubmit sitemaps.
Walk through setup and authentication steps.
Detect installed Chromium browsers and profiles for browser-driven actions.
Provides tools for interacting with Google Search Console, enabling URL index status checks, indexing requests, sitemap submission, search analytics retrieval, and quota monitoring.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Google Search Console MCP ServerCan you check if https://example.com/landing-page is indexed?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Google Search Console MCP Server
An MCP server that gives Claude and other AI agents real control over Google Search Console — list your properties, check whether a URL is indexed, submit sitemaps, pull search analytics, and diagnose setup problems, all from a conversation.
Built for SEO practitioners tired of checking index status and submitting sitemaps by hand, one property at a time, and for the AI agents that can do it for them.
Project status
Pre-alpha. The MCP surface is wired up; browser-driven submission is not.
Eight tools are registered on the server and covered by a wire-level smoke test that connects a real MCP client session and confirms every tool answers with a description. Storage, quota accounting, OAuth, and config are the foundation underneath them. The sign-in path now exists end to end and can be walked by hand — see docs/manual-smoke.md — but the submission path does not, and no real Google account has authenticated against this code yet; see Known gaps.
Milestone | Scope | State |
1. Foundation | Paths, logging, SQLite store, quota engine, OAuth + PKCE, config | Done |
2. MCP surface | The tools below, exposed over MCP | Done |
3A. Onboarding | Guided sign-in, browser/profile detection, the bridge extension | Done |
3B. Submission | Browser-driven Request Indexing, job control | Next |
4. Reporting | Indexation audits, discovery loops, bulk runs | Planned |
Watch or star the repo if you want to know when Milestone 3B ships.
Related MCP server: ga4-mcp
Tools
Shipped and registered on the MCP server today:
Tool | What it does |
| List every Search Console property the account can reach |
| Diagnose auth, config and environment problems |
| Index status for one or more URLs via the URL Inspection API (read-only, spends no Request-Indexing slot) |
| Request-Indexing and URL Inspection budget remaining today, per property |
| Clicks, impressions, CTR and position from Search Analytics |
| Submit or resubmit sitemaps to a property |
| Walk through sign-in and setup; idempotent, returns the single next step |
| Locate installed browsers and profiles for browser-driven submission |
Planned
Not yet built — tracked for future milestones:
Tool | What it does | Milestone |
| Submit a URL for indexing, quota permitting | 3B |
| Kick off a batch indexing-request job | 3B |
| Check on a running indexing job | 3B |
| Cancel a running indexing job | 3B |
| Find URLs Google has not indexed | 4 |
| Bulk indexation audit across a property | 4 |
Why quota accounting is the hard part
Most tools in this space get Google's limits wrong, then get throttled and blame detection. Both limits that matter are per property, not per account:
Limit | Value | Mechanic |
Request Indexing | ~11 slots per property | Rolling — each slot frees 24h + 1 min after its own use |
URL Inspection | 2,000 per day per property | Daily reset |
URL Inspection | 600 per minute per property | Rate limit |
Properties are independent, so eight properties means eight independent budgets. This server tracks slots individually rather than counting a daily total, so it knows the exact minute the next slot opens — and it deliberately over-counts rather than under-counts when a race is possible, because a short wait is cheaper than a hard Quota Exceeded.
Requirements
Python 3.11 or newer
A Google account with Search Console properties
A Chromium browser — Chrome, Brave, Edge, Vivaldi, Opera or Chromium.
gsc_setuploads a browser extension into one of your existing profiles, and there is no way to complete setup without one. Firefox and Safari are not Chromium and will not work.Your own Google OAuth client (see Install below) — this package does not embed one yet
Install
git clone https://github.com/Mrshahidali420/google-search-console-mcp.git
cd google-search-console-mcp
python -m venv .venv
.venv/Scripts/python -m pip install -e . # POSIX: .venv/bin/pythonYou must bring your own OAuth client
gsc-mcp does not ship an embedded Google OAuth client. The Google Cloud
app for this project does not exist yet, and a real client secret can
never be committed to a public repository — so EMBEDDED_CLIENT_ID and
EMBEDDED_CLIENT_SECRET in gsc_mcp/deps.py are empty strings by design.
Until a verified app ships, every install needs its own:
All of this happens in Google Cloud Console, free, and takes about five minutes. Do the steps in order — step 4 is the one people skip, and skipping it fails at the very end.
Create a project. Use the project dropdown in the top bar → New project. Any name. Wait for it to be created, then make sure it is the project selected in that dropdown; everything below applies to the selected project only.
Enable the Search Console API. Search "Search Console API" in the console's search bar, open it, and click Enable. Without this, every call returns a 403 that mentions the API being disabled.
Configure the OAuth consent screen. In the left menu: APIs & Services → OAuth consent screen.
User type: External. ("Internal" only exists on Workspace accounts and restricts the app to your own organisation.)
App name: anything — you are the only user who will see it.
User support email and developer contact email: your own address.
You do not need to add scopes here. This server requests its scope at sign-in time, and adding it on this screen does not change what you are granted.
Save through to the end.
Add yourself as a Test user. Still on the OAuth consent screen, find Test users (on newer consoles: Audience → Test users) and add the Google address that owns your Search Console properties.
This step is not optional and it is the one that fails late. The Search Console scope (
webmasters) is a sensitive scope, so while your app sits in Testing status — which is where every new app starts — Google will only let listed test users sign in. Everyone else gets403: access_deniedon the consent screen, after creating the project, enabling the API, creating the client, setting the environment variables, and runninggsc_setup. Nothing earlier warns you.You do not need to publish the app or submit it for verification. A Testing app with you as a test user works indefinitely for your own account; the only cost is that the refresh token expires every 7 days and you sign in again.
Create the OAuth client. APIs & Services → Credentials → Create credentials → OAuth client ID, application type Desktop app. Copy the client ID and client secret it shows you — the secret is shown once, though you can always create another client.
Desktop app is the right type: this server signs you in over a loopback redirect on
127.0.0.1, which is what that type allows. Do not pick "Web application" and do not add a redirect URI by hand.Set the two environment variables below before starting the server. Without them, any tool that needs to talk to Google returns
{"ok": false, "error": "not_configured", ...}rather than doing anything —gsc_list_sites,gsc_check_status,gsc_performance, andgsc_submit_sitemapsall behave this way.gsc_doctorandgsc_quotaare the two exceptions:gsc_doctorstill runs and reportsoauth_client: not okas one line in its checks list rather than failing outright, which makes it the right first tool to run when something is stuck;gsc_quotais local-only and returns[]on an empty store regardless of OAuth configuration.
export GSC_MCP_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GSC_MCP_CLIENT_SECRET="your-client-secret"
# Windows PowerShell:
# $env:GSC_MCP_CLIENT_ID = "your-client-id.apps.googleusercontent.com"
# $env:GSC_MCP_CLIENT_SECRET = "your-client-secret"Connect it to an MCP client
Point your MCP client at the installed console script. For Claude
Desktop, add to its claude_desktop_config.json:
{
"mcpServers": {
"gsc-mcp": {
"command": "C:\\path\\to\\google-search-console-mcp\\.venv\\Scripts\\gsc-mcp.exe",
"env": {
"GSC_MCP_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
"GSC_MCP_CLIENT_SECRET": "your-client-secret"
}
}
}
}On POSIX, use .venv/bin/gsc-mcp as the command instead. Any other
MCP-speaking client that can launch a stdio server works the same way —
the entry point is the gsc-mcp console script installed above, and the
server talks the standard MCP stdio transport (gsc_mcp.server:main).
This has not yet been exercised against a real Claude Desktop session or a real Google account; see Known gaps.
Getting started
Once the server is installed and connected, the whole of setup is one tool
called repeatedly. gsc_setup() is idempotent: it never resumes a session,
it re-reads the whole state on every call, and it hands back the single
next thing to do. Call it in a loop until it returns ok: true.
1. Install and connect — see Install above.
2. Set the two environment variables. GSC_MCP_CLIENT_ID and
GSC_MCP_CLIENT_SECRET, from your own Google Cloud OAuth client. A release
build will eventually embed a verified client and this step will go away;
it has not shipped, and EMBEDDED_CLIENT_SECRET in gsc_mcp/deps.py is an
empty string by design because a real secret can never be committed to a
public repository.
3. Run gsc_setup(). It opens a Google consent screen in your browser
and returns the URL as well, so a headless machine can still complete it by
hand. Approve it, then call gsc_setup() again — the second call collects
the redirect, stores the token, and moves on. Nothing about your sign-in is
returned to the caller: not the token, not the authorization code, not the
PKCE verifier.
4. Load the bridge extension. gsc_setup() will tell you where it
extracted the extension to and which browser profile to load it into. In
that browser: open its extensions page (chrome://extensions,
brave://extensions, edge://extensions, and so on — gsc_setup() gives
you the exact URL for your browser), turn on Developer mode, choose
Load unpacked, and select the folder it named.
You will see a warning banner, and it is expected. The extension asks for the
debuggerpermission, so Chromium shows a prominent bar saying an extension is debugging your browser, and may warn you when you enable Developer mode. That permission is not incidental. Search Console applies a soft throttle to Request Indexing clicks that did not come from a real pointer, and synthetic DOM clicks trip it. The extension therefore issues trusted input events through the Chrome DevTools Protocol instead, which is whatdebuggergrants and the only way to grant it. The banner is Chromium correctly reporting a real capability — read it as "yes, this is the extension you just installed", not as malware. It only ever attaches tosearch.google.com, the one host in itshost_permissions.
5. Run gsc_doctor(). Seven checks, in order: oauth_client, token,
config, store, properties, browser, extension. Every failing one
carries a concrete fix. Sample output, on a machine where everything is
working:
{
"ok": true,
"checks": [
{"name": "oauth_client", "ok": true, "detail": "configured", "fix": ""},
{"name": "token", "ok": true, "detail": "token file present", "fix": ""},
{"name": "config", "ok": true, "detail": "config valid", "fix": ""},
{"name": "store", "ok": true, "detail": "schema version 2", "fix": ""},
{"name": "properties", "ok": true, "detail": "2 properties", "fix": ""},
{"name": "browser", "ok": true,
"detail": "Google Chrome / Default is the profile to use", "fix": ""},
{"name": "extension", "ok": true,
"detail": "the gsc-mcp bridge extension is installed in Google Chrome / Default at version 1.10.0; whether its background service worker is running is not checked in this milestone",
"fix": ""}
]
}Reading the browser and extension checks
These two are about your local machine rather than your Google account, and they are worded carefully because the failure modes are easy to misread.
"Could not be checked" never means "not installed." The extension check
reads your browser's own preferences files. Those files are frequently
locked, mid-write, cloud-synced, or held open by antivirus. When a read
does not happen, the check says the question could not be checked and
that the extension may already be there. That is not a polite way of saying
it is missing, and the fix is to run gsc_doctor() again (closing the
browser first if it is running) — not to reinstall an extension that is
sitting right where you put it. The same distinction runs through
gsc_detect_browsers, whose has_extension field is three-valued: true
present, false every preferences file was read and it was not among them,
null the check could not be performed.
Microsoft Edge can report a Microsoft account where a Google one is expected. Edge stores signed-in account addresses in the same file and the same key Chrome uses for Google accounts, but by default it signs profiles in to Microsoft identities. Nothing on disk tells the two apart. So for an Edge profile, an address found is not evidence of a Google sign-in — and if your Microsoft address happens to be the same as your Google one, what looks like a confirmed match is not confirmed at all. The tools hedge this rather than assert it: an Edge profile is reported with "this profile's Google sign-in could not be confirmed". Check it yourself before relying on it. Brave, Vivaldi, Opera and plain Chromium record no Google account at all and are hedged for the different reason that there is nothing to read.
A changed extension ID means re-pairing, not breakage. The extension
ships with no manifest key, so Chromium derives its ID by hashing the
absolute path it was loaded from. That ID is stable for as long as the
extraction directory is stable — and it changes if that directory moves:
an upgrade that relocates the config directory, a different GSC_MCP_HOME,
a migration to a new machine. When it changes, the extension check stops
recognising the loaded copy and reports it as not installed. Nothing is
broken and nothing is corrupted; the fix is to load the unpacked extension
again from the new folder, exactly as in step 4.
A green extension check means registered, not running. It says the
extension is loaded into that profile at that version. Whether its MV3
background service worker is alive needs a live connection from the bridge,
and that check arrives with Milestone 3B.
Development
.venv/Scripts/python -m pip install -e ".[dev]" # POSIX: .venv/bin/python
.venv/Scripts/python -m pytest -vArchitecture
gsc_core is a standalone engine with no MCP dependency, so it can be driven by the MCP server, a CLI, or a future desktop app without change.
Module | Responsibility |
| Where files live, per platform |
| Logging to stderr and file — never stdout, which MCP reserves for JSON-RPC |
| SQLite: sites, urls, submissions, jobs, quota slots |
| Per-property rolling slot accounting |
| OAuth 2.0 with PKCE S256, hardened token storage, refresh |
| User-tunable settings with validation |
| Which Chromium browsers are installed, and where they keep their state |
| Which profiles each browser has, and which Google account is signed into each |
| Where the bridge extension is extracted to, and what ID Chromium gave it |
Privacy
To tell you which browser profile to use, this tool reads the profile list and the signed-in account address out of the browser's own files on your machine — Local State and each profile's Preferences / Secure Preferences. The same files are read a second time, for a different reason, to find out whether the bridge extension is loaded in that profile and at what version.
That read is entirely local. The address is used in memory to show you which profile is signed into which account, and:
it is never transmitted anywhere,
it is never written to disk by this tool,
it is never written to the log, at any level — failures reading these files are logged by exception type name only, precisely so that neither an address nor a path containing your Windows username can end up in a log file you might attach to a bug report.
Nothing in the tool opens these files for writing. No address is ever returned by a tool either, in either direction — not one found in a profile, and not your own authorised address. A tool result is rendered into a transcript and retained by whatever MCP client is driving the server, none of which this project controls, so a profile is identified by browser and profile directory and nothing else.
Known gaps
Stated plainly, because they are the things a reviewer should look at first:
No test proves
icaclsactually applied an ACL on Windows — the Windows test only observes that the call was made, so_hardencould no-op there and the suite would stay green. The POSIX equivalents now execute on Linux and macOS on every push, so this gap is Windows-only.The sign-in path now exists and is testable; the submission path still does not.
gsc_setup,gsc_detect_browsersand the two newgsc_doctorchecks make it possible to walk from a clean install to a signed-in, extension-loaded machine. Nothing yet submits a URL for indexing —gsc_request_indexingand the job tools land in Milestone 3B.No real Google account has authenticated against this code. Every OAuth path is exercised against fakes; the live path is docs/manual-smoke.md, and that checklist has not yet been run for real. Until it has, "you can sign in" is a claim the test suite cannot support.
macOS and Linux browser detection has only ever run against fixtures, never on real hardware, here or in CI. The first person to run the smoke checklist on a Mac or a Linux box is performing that test.
gsc_detect_browsersreportsmatches_authorised_accountasnullon every real machine today. The flag reads anaccount_emailkey from the stored token, and nothing writes it: the current scope set returns no identity claim and the consent step does not record the authorising account. The plumbing is correct and inert. Treat the field as "unknown", not as "does not match".The
extensioncheck reports whether the extension is registered, not whether it is working. MV3 worker-liveness detection needs a live bridge connection and arrives with 3B.Google OAuth verification for the sensitive
webmastersscope has not started.No OAuth client is embedded yet, so users must supply their own Google Cloud credentials (see Install above).
mcpis pinned>=1.2,<2.0.mcp2.0 removedFastMCPoutright — confirmed directly against the 2.0 wheel, which has nofastmcpmodule at all — so this server does not receive anymcp2.x fixes, and it hard-conflicts with any other installed package that requiresmcp>=2. Lifting the ceiling means porting this server to whatever construction API replaced it.
Contributing
Contributions are genuinely welcome — issues, pull requests, bug reports, docs fixes, all of it. Start with CONTRIBUTING.md. Good first issues are the CI legs listed under Known gaps.
License
Functional Source License 1.1 with an Apache 2.0 future grant (FSL-1.1-ALv2).
In plain terms: use it, modify it, contribute to it, run it on client work — just don't sell a competing product built from it. Every release converts to Apache 2.0 two years after publication, so nothing here is locked away permanently.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityCmaintenanceMCP server for querying Google Search Console data — search analytics, URL inspection, sitemap monitoring, and more — read-only tools for any MCP-compatible AI client.Last updated7Apache 2.0
- AlicenseBqualityDmaintenanceAn MCP server integrating Google Analytics 4, Search Console, and Indexing API, enabling AI agents to run reports, inspect URLs, manage properties, and request indexing.Last updated1679MIT
- AlicenseAqualityCmaintenanceA lightweight, fast MCP server for Google Search Console. Query search analytics, manage sitemaps, and inspect URLs directly from your AI assistant.Last updated7Apache 2.0
- Alicense-qualityDmaintenanceThis MCP server provides LLMs with programmatic access to Google Search Console data and functionality, including search analytics, sitemap management, site management, and URL inspection.Last updatedMIT
Related MCP Connectors
SEO MCP server: crawl your site, find AI-visibility gaps, and ship the fix from your coding agent.
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
Hosted MCP with 91 agent tools: X, domains, SEO, Maps, Trends, Search, YouTube, TikTok, and more.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Mrshahidali420/google-search-console-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server