opengsc
Provides read-only access to Google Search Console data, enabling tools to list properties, query search analytics by query/page/country/device/date, list sitemaps, and inspect URL index status.
Click on "Deploy 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., "@opengscWhich queries get impressions but few clicks on my site last 28 days?"
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.
easygsc
Let your AI app (Claude, Codex, Gemini, Cursor, VS Code Copilot or any other MCP app) read your Google Search Console data and help you with SEO.
Read-only. It can see your data, never change it.
Small. 4 tools, ~1,600 lines of Python you can audit in one sitting.
Private. Talks only to Google. No telemetry, no third-party servers.
Ask things like "Which queries get impressions but few clicks?" or "Is this page indexed?" and your AI pulls the real numbers from Search Console.
Setup (about 5 minutes)
You need:
A Google account with access to at least one Search Console property.
uv installed. It also installs Python for you if needed.
Windows:
winget install astral-sh.uvmacOS/Linux:
curl -LsSf https://astral.sh/uv/install.sh | sh
Step 1. Run the guided setup
uvx easygsc setupIt walks you through the Google Cloud steps one at a time, opening the right page in your browser and waiting for you to finish:
Create a project.
Enable the Search Console API.
Configure the consent screen (External).
Create a Desktop app OAuth client and download its JSON.
Fill in Branding with your website's links (no logo).
Publish the app.
Then it finds the JSON in your Downloads folder (or the OneDrive one, or asks for the path), checks it is a Desktop client, copies it to ~/.config/easygsc/client_secret.json with 0600 permissions, runs the Google login, checks that your properties are readable, and moves on to Step 2. It tells you which file it used and where it installed it.
It never overwrites a different client file without asking, and only deletes your download if you say yes.
No browser? Add
--no-browserto print the URLs instead.Type
qor press Ctrl+C at any prompt to stop; runuvx easygsc setupagain to resume.
Step 2. Pick your AI apps
Setup ends with a numbered list of AI apps. The ones it finds on your computer are marked; press Enter to connect those, or type the numbers you want, like 1,3.
App | What setup does |
Claude Desktop | Asks you to quit it, then adds easygsc to |
Claude Code | Runs |
Codex (OpenAI) | Runs |
Gemini CLI | Adds it to |
Google Antigravity | Adds it to |
Cursor | Adds it to |
VS Code (GitHub Copilot) | Adds it to your user |
Windsurf / Devin Desktop | Adds it to |
LM Studio | Adds it to |
Another app | Shows the command, arguments and JSON to paste into the app's MCP settings. |
Then do what it says for each app (usually: restart it) and ask "List my Search Console sites."
Your settings are safe. It only edits plain JSON files, saves a backup next to each one first (
<file>.<date>.bak), keeps all your other settings, and asks before replacing an existingeasygscentry. A file it can't edit safely, such as one with comments, is left alone and you get the exact text to paste.Add an app later with
easygsc connect(uvx easygsc connect).Browser-only chats (ChatGPT, claude.ai or Gemini on the web) can't start programs on your computer, so they can't use easygsc. Use their desktop or command-line app: Claude Desktop, Claude Code, Codex or Gemini CLI.
Claude Desktop: open Settings → Developer → Edit Config and add easygsc to claude_desktop_config.json:
{
"mcpServers": {
"easygsc": {
"command": "uvx",
"args": ["easygsc@0.2.0"]
}
}
}If the file already has other servers, add only the "easygsc": {...} block inside mcpServers. Then quit Claude Desktop completely (including the tray/menu bar icon) and reopen it.
Claude Code (pick one):
# as a plugin
claude plugin marketplace add diegomm27/easygsc
claude plugin install easygsc@easygsc
# or as a plain MCP server
claude mcp add easygsc -- uvx easygsc@0.2.0Any other MCP client: run uvx easygsc@0.2.0 over stdio.
If the app can't find uvx, use its full path (which uvx, or where uvx on Windows) as the command. easygsc connect does this for you.
Related MCP server: gsc-mcp
CLI commands
Command | What it does |
| Guided setup: Google Cloud steps, client file, login, check, connect your AI apps. |
| Add easygsc to your AI apps (the last step of |
| Run the Google login ( |
| Auth mode, token expiry, readable properties, config paths, version. |
| Run the MCP server over stdio (also the default with no arguments). |
1. Create a Google OAuth client
This gives easygsc permission to ask Google for your data. You do it once.
Create a project. Open console.cloud.google.com/projectcreate, name it
easygscand click Create. Make sure it is selected in the project picker at the top.Tip: use a dedicated project. The consent screen is shared by everything in a project.
Enable the API. Open the Search Console API page and click Enable.
Set up the consent screen. Open Google Auth Platform and click Get started:
App name:
easygscUser support email: your email
Audience: External
Contact email: your email
Accept the policy and click Create.
Create the client. Open Clients, click Create client:
Application type: Desktop app (not Web application)
Name:
easygscClick Create, then Download JSON right away. Google won't show the secret again.
Fill in Branding. Open Branding. Google won't let you publish without these links:
App logo: leave it empty. Uploading one forces Google verification.
Application home page: your website, e.g.
https://example.comPrivacy policy link: your website's privacy page. If it has none, use
https://github.com/diegomm27/easygsc#security-and-transparencyTerms of service link: leave it empty.
Authorized domains: your domain, e.g.
example.com(the one you verified in Search Console). Addgithub.comtoo if you used the link above.Click Save.
Publish the app. Open Audience and click Publish app, then confirm. The status should read In production.
Why: in Testing mode, Google expires your login every 7 days.
Is it safe? Yes. Publishing does not make your data public. Anyone who logs in through it only sees their own Search Console, and nobody can read yours without your Google login.
2. Put the JSON file in place
Rename the downloaded file to client_secret.json and move it here:
OS | Location |
Windows |
|
macOS / Linux |
|
Windows (PowerShell):
mkdir $HOME\.config\easygsc -Force
Move-Item $HOME\Downloads\client_secret_*.json $HOME\.config\easygsc\client_secret.jsonmacOS / Linux:
mkdir -p ~/.config/easygsc
mv ~/Downloads/client_secret_*.json ~/.config/easygsc/client_secret.jsonWindows gotcha: if you rename the file in Explorer with extensions hidden, it can end up as
client_secret.json.json. Check withdir $HOME\.config\easygsc.
3. Log in and check
uvx easygsc authYour browser opens:
Pick the Google account that has access to Search Console.
You'll see "Google hasn't verified this app". That's expected for a personal app: click Advanced → Go to easygsc.
Allow read access to Search Console.
Your login is saved to ~/.config/easygsc/token.json. On a machine without a browser, add --no-browser and open the printed URL yourself.
Check that everything works:
uvx easygsc doctorYou should see auth check: OK and a property count above 0.
Try it
Start a new chat and ask:
"List my Search Console properties."
"Top 50 queries by impressions in the last 28 days for sc-domain:example.com."
"Which pages have lots of impressions but a CTR under 2%?"
"Queries where I rank between 5 and 15 on mobile."
"Check the status of my sitemaps."
"Is https://example.com/blog/post indexed?"
Start with the first one: it returns the exact property names (sc-domain:... or https://.../) the other tools need.
Tools
Tool | What it returns |
| Properties you can read, with your permission level. |
| Clicks, impressions, CTR and position, by query, page, country, device, date or search appearance. Supports filters. |
| Submitted sitemaps, last download, errors and warnings. |
| Index status, canonical, last crawl, mobile usability. Limited by Google to 2,000 calls/day per property. |
Data comes back unprocessed (TSV or Google's raw JSON), so Claude works with exact numbers.
Parameter | Default | Options |
| last 28 days, ending 3 days ago (GSC data lag) |
|
|
|
|
| none | list of |
|
|
|
|
|
|
|
| 1 to 25000 |
|
| for pagination |
The output ends with a metadata block. more_may_exist: true means the page was full; ask for the next one with start_row.
Troubleshooting
Problem | Fix |
| Run |
| The client file is incomplete or was edited. Download it again from the Clients page and run |
| The client must be Desktop app. Open the JSON: it should start with |
"Google hasn't verified this app" | Normal. Click Advanced → Go to easygsc. |
| Login expired or was revoked. Usually the app was left in Testing: publish it (Manual setup, step 1.6), then run |
| Wrong property name or no access. Use the exact string from |
| You logged in with an account that has no Search Console access. Run |
Your AI app doesn't see the tools | Fully quit and reopen the app (Claude Desktop: also from the tray/menu bar icon). Claude Code: |
| The app can't find uv. Run |
Want to undo a connection | Each edited file has a |
| Google's daily limits. Wait and retry. |
No data for old dates | Search Console only keeps 16 months. |
Query totals don't add up | Google hides rare queries for privacy, so per-query sums are lower than the site total. |
To revoke access at any time: myaccount.google.com/permissions → easygsc → Remove access.
Security and transparency
Permission requested: only
https://www.googleapis.com/auth/webmasters.readonly. easygsc cannot submit sitemaps, edit properties or manage users.Network lock: every request goes through one guard (
src/easygsc/allowlist.py) that only allowswww.googleapis.com,searchconsole.googleapis.com,oauth2.googleapis.comandaccounts.google.com. Anything else, redirects included, fails before it's sent.Endpoints used:
sites.list,searchAnalytics.query,sitemaps.list,urlInspection.index.inspect. Nothing else.Files on disk:
~/.config/easygsc/client_secret.json(yours, installed byeasygsc setupwith0600permissions) and~/.config/easygsc/token.json(your login, also0600; best effort on Windows). Keeptoken.jsonprivate: whoever has it can read your Search Console.AI app settings:
setupandconnectonly touch the apps you pick, back up each file first and make no network calls (src/easygsc/connect.py).Dependencies:
mcp,google-auth,google-auth-oauthlib, pinned exactly. That's all.Not included on purpose: writes, analysis or scoring, telemetry, update checks, bundled prompts.
easygsc looks for credentials in this order (doctor shows which one it used):
Service account: set
EASYGSC_SERVICE_ACCOUNT_FILEto the path of a service account JSON key. Then add the service account's email as a user of your property in Search Console (Settings → Users and permissions). No browser login needed, good for servers.Refresh token from the environment:
easygsc authprintsEASYGSC_REFRESH_TOKEN=...once. Set that variable (plus the OAuth client, see below) to run without atoken.jsonfile, for example in a container. Treat it like a password.Saved login:
~/.config/easygsc/token.json, created byeasygsc auth.
Instead of client_secret.json, you can provide the OAuth client with the EASYGSC_CLIENT_ID and EASYGSC_CLIENT_SECRET environment variables.
Development
git clone https://github.com/diegomm27/easygsc.git
cd easygsc
uv sync # install with dev dependencies
uv run pytest # tests (no network, HTTP is mocked)
uv run ruff check src tests && uv run ruff format --check src tests
claude plugin validate . # check the plugin manifestCI runs lint and tests on Linux, macOS and Windows (Python 3.10 and 3.12). Releases are published to PyPI through Trusted Publishing.
License
MIT. See LICENSE.
Available Tools
4 toolsinspect_urlA
Run URL Inspection for one URL inside one property.
Returns the result as compact JSON exactly as the API sends it: index status, coverage, canonical, last crawl, mobile usability if present. Counts against Google's 2,000/day per-property quota.
| Name | Required | Description | Default |
|---|---|---|---|
| url | Yes | ||
| site_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well on two fronts: it discloses the return shape (index status, coverage, canonical, last crawl, mobile usability) and a real operational limit (Google's 2,000/day per-property quota). It stops short of stating auth/permission requirements or that the target URL must belong to the supplied verified property, both of which affect whether a call succeeds.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three short sentences, front-loaded with the operation and its scope, then return shape, then cost. Every sentence adds information. Structure is slightly fragmented by line breaks but nothing is wasted.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description is not obligated to explain returns, yet it summarizes them usefully and adds the quota cost. For a two-required-parameter read operation with no annotations, that covers most of what an agent needs; the remaining gap is permission/verification prerequisites.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. 'One URL inside one property' does map the two unnamed parameters to concepts (url = the inspected URL, site_url = the containing property), but it gives no format guidance, e.g. whether site_url must be a URL-prefix or sc-domain property identifier. Partial compensation only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb-and-resource and adds real scope: 'Run URL Inspection for one URL inside one property.' The one-URL/one-property constraint cleanly separates it from siblings like list_sites, list_sitemaps, and search_analytics, which operate at property or site level. It only lacks an explicit naming of those alternatives, which keeps it from a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied rather than stated: a single-URL scope and a per-property daily quota hint at high-cost, targeted use, and the quota warning is a genuine invocation consideration. But there is no explicit when-to-use/when-not-to-use framing and no reference to the sibling tools, so the agent must infer the boundary.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sitemapsB
List submitted sitemaps for one property with status and counts.
Top-level fields are TSV; the nested contents array is compact JSON exactly as the API sends it.
| Name | Required | Description | Default |
|---|---|---|---|
| site_url | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does add one genuinely useful trait — the response shape (TSV top-level, compact JSON contents array) — but says nothing about permissions needed, pagination, sitemap-index handling, or whether the call is read-only, which for a bare read tool leaves meaningful gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with the operation and scope, the second reserved for output shape. No filler; the line break is slightly awkward but content earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, and the description covers the essential purpose for a one-parameter read tool. Still, with zero annotations and an undocumented required parameter, an agent lacks the property-identifier format and the permission expectations it needs to call this correctly the first time.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter site_url has 0% schema description coverage, so the description must compensate. "For one property" hints that the parameter identifies a property, but the critical format ambiguity (URL prefix form vs. a sc-domain-style identifier) is not resolved anywhere.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ("List submitted sitemaps") plus scope ("for one property") and what the result carries (status and counts). Siblings — list_sites, search_analytics, inspect_url — operate on different resources, so confusion is unlikely even without an explicit differentiator.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: an agent infers it should call this when it wants sitemap data for a property. There is no statement of when not to use it, no prerequisite (e.g., verification/permission requirement), and no pointer to an alternative for broader site diagnostics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_sitesA
List Search Console properties the account can read, with permission level.
Returns TSV: site_urlpermission_level. Use the site_url values as-is for the site_url argument of the other tools.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden and does reasonably well: it implies a read-only, permission-scoped operation ('properties the account can read') and discloses the return shape ('TSV: site_url<TAB>permission_level'). It does not cover auth requirements or pagination, but for a zero-argument read-only listing the risk surface is minimal.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, front-loaded with what is returned first and the practical follow-up instruction second. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a no-parameter discovery tool, everything an agent needs is present: what is listed, the permission scoping, the exact output format, and how to reuse the returned values. An output schema exists, so the TSV explanation is a small redundancy rather than a gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so the baseline is 4. The schema is fully covered and there is nothing for the description to compensate for; the note about site_url is guidance for other tools, not a parameter of this one.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('List Search Console properties') plus the scope ('the account can read') and an extra detail (permission level). The resource is unmistakably distinct from the siblings search_analytics, list_sitemaps, and inspect_url.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly tells the agent the downstream use: 'Use the site_url values as-is for the site_url argument of the other tools.' That is clear context for why and when to call it, though it names no exclusions or conditions under which it should be skipped.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_analyticsA
Query search analytics for one property.
site_url: property from list_sites. start_date/end_date: YYYY-MM-DD (default: last 28 days ending 3 days ago). dimensions: subset of query, page, country, device, date, searchAppearance. filters: list of {dimension, operator, expression} with operators equals, notEquals, contains, notContains, includingRegex, excludingRegex. search_type: web, image, video, news, discover, googleNews. data_state: final or all. row_limit: 1..25000; start_row: pagination offset.
Returns TSV rows plus a metadata block (date range, rows returned, more_may_exist: true when rows == row_limit, so paginate with start_row).
| Name | Required | Description | Default |
|---|---|---|---|
| filters | No | ||
| end_date | No | ||
| site_url | Yes | ||
| row_limit | No | ||
| start_row | No | ||
| data_state | No | final | |
| dimensions | No | ||
| start_date | No | ||
| search_type | No | web |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden and does most of it: it discloses default date window, valid enum values, the 1..25000 row_limit bound, and — most valuable — the pagination contract ('more_may_exist: true when rows == row_limit, so paginate with start_row'). It omits auth/permission requirements and any quota or rate-limit behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose leads, parameter semantics follow in a compact labeled list, and the return/pagination contract closes it out. Given nine parameters and a zero-description schema, no sentence is filler and nothing important is buried.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still usefully supplements it with the more_may_exist/start_row pagination rule, which is the piece an agent most needs to iterate correctly. Combined with full parameter documentation, nothing essential for calling this complex tool is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 9 parameters, so the description must compensate, and it does: it documents site_url provenance, date formats and defaults, allowed dimension values, the full filter object shape and operator list, search_type and data_state enumerations, and row_limit/start_row semantics. Nearly every parameter gains meaning absent from the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Query search analytics') plus the scope constraint ('for one property'), which immediately separates it from the sibling inventory tools. It also names list_sites as the source of site_url, giving an agent a concrete anchor for what this tool operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The prerequisite for the required parameter is stated ('site_url: property from list_sites'), which is useful routing guidance, and defaults for date range and data_state are given. However, there is no explicit when-to-use versus when-not-to-use guidance, and the sibling inspect_url is never contrasted with this tool.
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.
4 tool updates
v0.1.0- First observed
inspect_url - First observed
list_sitemaps - First observed
list_sites - First observed
search_analytics
TDQS
Scored across 4 tools
Each tool maps to a distinct GSC resource/action: list_sites (properties), search_analytics (performance data), list_sitemaps (sitemap status), and inspect_url (per-URL indexing). There is no meaningful overlap in purpose, so an agent can select the right tool unambiguously.
All four tools use snake_case verb_noun form (list_sites, search_analytics, list_sitemaps, inspect_url), which is highly predictable. The only minor deviation is the mix of verbs (list/search/inspect) rather than a single repeated prefix, though each verb matches its action.
Four tools cover the core read surface of Search Console cleanly with no filler. It sits at the thin end of the well-scoped range but each tool clearly earns its place.
The set covers the primary read operations (properties, analytics, sitemaps, URL inspection) well. Write operations like adding/deleting sites or submitting sitemaps are absent, but these are minor gaps for a read-oriented analysis server.
Maintenance
Related MCP Connectors
Read-only Google Search Console MCP server for AI assistants.
Read-only Google Search Console and Google Analytics for AI agents.
Hosted, read-only Google Search Console MCP: performance, comparisons, URL inspection, sitemaps.
Read-only Search Console analytics, URL inspection, indexing diagnostics, and sitemaps.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceRead-only MCP server for Google Search Console data, enabling search analytics, URL inspection, indexing diagnostics, and sitemap management through MCP clients.7 npmMIT
- AlicenseNot gradedqualityCmaintenanceProvides read-only access to Google Search Console data, including search analytics, sitemap status, and URL inspection, for MCP clients like Claude.4 npmMIT
- AlicenseAqualityAmaintenanceEnables MCP clients to query Google Search Console search performance, inspect indexing, analyze sitemaps, and run SEO analyses such as cannibalisation detection, query clustering, and wins/losses, all with read-only access.2042 npmApache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables Claude to query Google Search Console data, including search analytics, sitemaps, URL inspection, and page indexing audits.117 npmMIT