Skip to main content
Glama

Search Console MCP

PyPI Python 3.11+ Tools Providers Tests Publish License: MIT

Know what to fix to improve your search rankings, without becoming an SEO expert.

Ask Claude or Codex to analyze your site's latest SEO changes and suggest what to fix first. Search Console MCP gives your assistant the search metrics and page audits it needs to explain traffic drops, find ranking opportunities, and turn the findings into a prioritized action plan.

Search Console MCP is the open-source connection between your data and your AI assistant. The server retrieves metrics and runs analyses; Claude, Codex or another MCP client explains the findings and proposes corrections. A coding assistant with access to your repository can also help implement the fixes you choose.

The diagram covers the 96-tool MCP server. The repository also includes 15 shared Claude/Codex SEO playbooks and a separate opt-in bounded native audit prototype with nine source-review profiles. The post-1.5.0 recap and release-readiness record separates merged source features, published package contents and remaining quality checks.

What you get

Analyze my site's latest SEO changes. Explain what improved or declined, find opportunities to rank higher, and suggest the fixes I should make first.

Your AI assistant uses the connected tools to produce:

  • A diagnosis of recent changes: which pages and queries gained or lost clicks, impressions or positions, with evidence and possible explanations.

  • A prioritized list of opportunities: pages close to page one, search results getting impressions but few clicks, and competing pages targeting the same query.

  • Concrete suggested fixes: title and description changes, content briefs, internal-link improvements, and technical or indexing issues to investigate.

  • A follow-up comparison: rerun the analysis after making changes to see how clicks, impressions and positions evolved.

For example, if a page gets impressions but few clicks, the assistant can inspect its title and description and suggest a rewrite. If a page is close to page one, it can check its content and internal links before recommending changes. These are example workflows, not measured results for your site.

Initial account setup and review of suggested changes are still required. Recurring checks need a scheduler or automation in your client; the server does not run them on its own. Ranking improvements must be measured after the changes and are not guaranteed.

A real audit

See a real analysis of my Claude Code Ultimate Guide site, run on 2026-10-07 with 14 live MCP calls. It measured 459 clicks and 55,921 impressions over 28 days, investigated three pages and proposed actions tied to the observed data. The request/response trace shows the parameters, timestamps and selected results. These are analysis findings; no site correction or ranking gain has been measured from this run.

Related MCP server: mcp-seo-audit

What it covers

Need

Main capabilities

Search performance

Queries, pages, dates, search types, anomalies, quick wins and traffic drops

Google and Bing comparison

Side-by-side query or page metrics without merging incompatible position semantics

Site health

GSC, GA4, CrUX, schema and public-page signals with graceful degradation

Technical and content SEO

Metadata, headings, hreflang, internal links, structured data, preload and content quality

Indexing and feeds

Google indexing requests, sitemaps, IndexNow and guarded Bing URL or feed submissions

Automation

MCP tools, gsc-cli, Claude agents, reusable skills and machine-readable architecture docs

Choose your starting point

New to SEO? Start with a site assessment: understand what to analyze and why, get three first actions, and learn which metrics to follow. You can begin with public pages, then connect Google Search Console for search performance data. GA4 and Bing are optional.

Choose a workflow to get a prompt to copy, the data it needs and an illustrative result:

  • Start with SEO: assess your site, get three priorities and a measurement plan, with explanations in plain language.

  • Understand a traffic drop: compare periods with Google Search Console; optional GA4 adds visitor behavior.

  • Find ranking opportunities: use configured Google or Bing search metrics and inspect the relevant pages.

  • Check page visibility: audit public pages and use Google Search Console for indexing status; Bing can add crawl signals.

Replace the example site in the prompt with your own. Every copied prompt explicitly asks the assistant to use Search Console MCP, verify its tools and guide installation or Google setup if needed. It includes the installation guide, Google setup guide and the matching GitHub example. The prompts request analysis and recommendations without applying site changes.

Quick start

Start here

Goal

Command or guide

Result

Run the published package

uvx gsc-mcp-tools

Starts all 96 Google, Bing, GA4, CrUX, IndexNow and technical SEO tools over stdio

Install for Codex or Claude Desktop

Installation guide

Persistent executable, upgrades, client configuration and verification

Develop from the source checkout

Install from source

Editable install for unreleased changes and local development

Run the checkout bounded audit

Source workflow installation

Checkout environment, explicit request plan and optional native report generation

Configure Google access

Google setup guide

Service Account or OAuth access to the selected properties

Configure Bing access

Bing setup guide

One account-level key for the verified sites visible to that account

Run a first audit

Starter prompts

Full audit, health check, page inspection or GA4 analysis prompt

Use the shell instead of MCP

CLI usage

Commands generated from the source registry

Requirements

  • Python 3.11+

  • For Google tools: a Google Cloud project with the Search Console API, Web Search Indexing API and Google Analytics Data API enabled, plus a Service Account JSON key or OAuth Desktop credentials

  • For Bing tools: a Bing Webmaster Tools account, at least one verified site and a Bing Webmaster API key

Published package

Use the published package for the complete 96-tool registry, including Bing:

uvx gsc-mcp-tools

For a persistent MCP client, install the latest stable package once and configure the absolute executable path. This avoids keeping an extra uvx launcher process beside every running server:

uv tool install gsc-mcp-tools
command -v gsc-mcp-tools
gsc-cli list

Upgrade that installation when a new release is available:

uv tool upgrade gsc-mcp-tools

To reproduce this release exactly, use uv tool install --force gsc-mcp-tools==1.6.0. A version-pinned installation remains pinned; install a newer explicit version or reinstall without ==... before using uv tool upgrade.

Release 1.2.0 was built and published by GitHub Actions through PyPI Trusted Publishing. The workflow checks that the tag matches pyproject.toml, runs the full test suite, validates and smoke-tests the built wheel, then publishes that same artifact with a short-lived OIDC credential. See the GitHub release and PyPI files.

pip install gsc-mcp-tools

Configure the providers you use

Installation guide: docs/installation.md covers persistent and one-time installs, upgrades, Codex project scoping, Claude Desktop, provider variants and verification.

Provider setup: docs/google-setup.md covers Google credentials and GA4. docs/bing-setup.md covers the Bing Webmaster API key, verified sites and the separate IndexNow key.

First audit prompts: docs/starter-prompt.md contains ready-to-use prompts for Google, Bing, cross-engine comparison, single-page inspection, eligible Indexing API submissions and GA4 analysis.

Use only the variables required by the provider families you enable:

export GSC_SERVICE_ACCOUNT_PATH=/absolute/path/to/service-account.json
export GSC_SKIP_OAUTH=true
export GA4_PROPERTY_ID=123456789   # only needed for GA4 tools
# Load CRUX_API_KEY from your secret store for CrUX tools.
# Load BING_WEBMASTER_API_KEY from your secret store for Bing tools.
gsc-mcp

CRUX_API_KEY is a Google API key (not a service account) with the Chrome UX Report API enabled in your GCP Console. It is separate from GSC auth and only required for CrUX tools.

Claude Desktop

Install the latest stable package once with uv tool install gsc-mcp-tools, then copy the absolute path returned by command -v gsc-mcp-tools into the configuration:

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "gsc-mcp": {
      "command": "/absolute/path/to/gsc-mcp-tools",
      "env": {
        "GSC_SERVICE_ACCOUNT_PATH": "/absolute/path/to/service-account.json",
        "GSC_SKIP_OAUTH": "true"
      }
    }
  }
}

Remove credentials for tool families you do not use, then restart Claude Desktop. Saving the file does not restart the MCP process.

For local development, set command to the checkout's absolute executable path, for example /absolute/path/to/google-search-console-mcp/.venv/bin/gsc-mcp. Version 1.4.0 exposes 89 tools, including seo_change_impact, rewrite_fidelity_check, search_weekday_reference, crawl_import_preview and draft inputs for editorial_audit. Releases 1.3.0 and 1.3.1 contain 85 tools; version 1.2.0 contains 81.

Codex

Codex starts a dedicated stdio MCP server for each task that loads it. A declaration in the user-level ~/.codex/config.toml therefore applies to every project and can leave many legitimate server processes alive while tasks remain active. Running through uvx adds a launcher process to each server.

Install the package once:

uv tool install gsc-mcp-tools
command -v gsc-mcp-tools

Then add the server only to trusted projects that need search data by creating .codex/config.toml in the project root:

[mcp_servers.gsc-mcp]
command = "/absolute/path/to/gsc-mcp-tools"
startup_timeout_sec = 60

[mcp_servers.gsc-mcp.env]
GSC_SERVICE_ACCOUNT_PATH = "/absolute/path/to/service-account.json"
GSC_SKIP_OAUTH = "true"

Keep this file untracked when it contains credentials. Remove provider variables you do not use. Codex loads project .codex/config.toml only for trusted projects; project configuration and precedence are documented in the official Codex configuration guide.

Do not add a global single-instance lock to a stdio server. Each client owns a separate stdin/stdout channel, so blocking later instances would break concurrent tasks instead of sharing one server safely. A shared deployment would require the streamable HTTP transport and its own authentication boundary.

Select MCP tool families (since 1.3.1)

Since version 1.3.1, set GSC_MCP_TOOL_FAMILIES=analytics,seo,sitemaps,links in the MCP server environment to expose these families plus core. The default exposes all 96 tools in version 1.6.0. Restart the server or client after changing the selection; gsc-cli list keeps the full catalogue. Selection does not grant provider access or write permission. See the tool-family configuration for all family names and startup validation. Version 1.3.0 predates this setting.

Bing Webmaster API key

  1. Sign in to Bing Webmaster Tools and verify every site you want the account to access.

  2. Open the API access settings and generate an API key.

  3. Store the key in your secret manager or local environment as BING_WEBMASTER_API_KEY. Never pass it as a tool argument or commit it to a file.

  4. Call each Bing tool with its site argument, for example https://example.com/. One user-level key can access every verified site visible to that account.

The Bing Webmaster API key and the IndexNow key have different scopes:

  • Bing Webmaster API reads private account data and manages verified sites. The server reads its user-level key from BING_WEBMASTER_API_KEY.

  • IndexNow notifies participating engines about changed URLs. Its key must be verifiable on each target host or subdomain, and indexnow_submit currently receives that key as an explicit argument.

  • The Bing Webmaster Tools web interface exposes features that the public API does not. Full URL Inspection and AI Performance are not available through the public API used here.

Do not reuse the Bing Webmaster API key as an IndexNow key.

Multi-property support

To query a different GA4 property without changing the config, pass property_id directly to any GA4 or cross tool:

ga4_traffic_sources(property_id="987654321")
traffic_health_check(site="sc-domain:example.com", property_id="987654321")

Troubleshooting

uvx gsc-mcp-tools launches but no tools appear in Claude Desktop

Fully quit Claude Desktop (Cmd+Q) and reopen it. Saving the config file is not enough; the MCP process is only started on launch.

Codex keeps many gsc-mcp-tools processes alive

Check whether gsc-mcp is declared in user-level ~/.codex/config.toml. Move it to project-level .codex/config.toml when it is not needed in every task, and configure the executable installed by uv tool install instead of uvx. Restart Codex after changing the configuration; already-running tasks keep the server configuration they loaded at startup.

GSC_SERVICE_ACCOUNT_PATH is set but auth fails

Use an absolute path. Relative paths and ~/ tilde expansion are not resolved. Check with echo $GSC_SERVICE_ACCOUNT_PATH that the value is a full /Users/... path.

GA4 tools return "property_id required"

Either set GA4_PROPERTY_ID in your config env block, or pass property_id directly to the tool call. The env var is the default; the parameter overrides it per call.

crux_page_vitals or crux_history returns "CRUX_API_KEY not set"

CrUX tools require a separate Google API key (not the service account) with the Chrome UX Report API enabled. Create one in Google Cloud Console under Credentials, enable the API, then inject the key from your secret store into the server environment as CRUX_API_KEY.

Indexing API returns 403 on submit_url

The service account needs Owner-level access on the GSC property, not just Full access. Go to Search Console Settings > Users and permissions, find the service account email, and upgrade its role to Owner.

submit_batch quota warning at 180/200

The Indexing API default quota is 200 requests per day per GCP project. The tool warns at 180. To increase it, request a quota increase in Google Cloud Console under APIs & Services > Quotas.

The data behind the recommendations

Google Search Console and Bing Webmaster Tools show how people find your pages in search. Optional GA4 data adds what those visitors do on your site; CrUX and public-page audits help identify performance, content and technical issues. Your assistant can use these sources together to decide which pages need attention.

Version 1.6.0 exposes 96 FastMCP tools, including local log analysis, four crawl snapshot commands, inventory differences and an indexing evidence matrix. The server handles authentication, API calls, validation, retries and structured JSON output. Use a starter prompt to run your first analysis.

IMPORTANT

gsc-mcp-tools==1.2.0 is the first published version with Bing support. It includes 19 Bing tools, cross-engine comparison and Bing support in three SEO analyses.

NOTE

An API submission reported as accepted proves neither crawl nor indexation. Search Console MCP keeps observed facts, derived metrics and recommendations separate.

Why private search data needs MCP

Public web search cannot answer questions tied to private Search Console, Bing Webmaster Tools or GA4 properties. Search Console MCP lets an assistant analyse those measured values while preserving provider boundaries and uncertainty.

GSC data is private. No web search agent can read it.

Given "which of my pages are wasting impressions with zero clicks?", an AI without API access has two honest options: admit it cannot answer, or guess from publicly visible signals. Neither is a diagnosis.

With this server, Claude pulls the actual numbers: /projects/ at position 10.1 with 87 impressions and 0 clicks, CTR benchmark 2.3% at that rank. That is the concrete gap between "you should optimize your meta titles" (available from any AI with internet access) and "your /projects/ page has 87 impressions and 0 clicks, rewrite the title" (requires your numbers).

Some tasks work without private data: checking indexation with site:, parsing sitemap structure, reading robots.txt. For those, any web-capable agent gets you there. But for anything that requires private GSC metrics (traffic drops, striking-distance queries, CTR anomalies, Indexing API submissions), there is no substitute for API access.

The server also handles Google and Bing API mechanics: isolated credentials, bounded retries, same-origin checks for Bing writes, true HTTP batch for Google indexing requests, and structured JSON output across the source registry. The two providers keep distinct position semantics and expose uncertainty instead of forcing incomparable data into one claim.

How it works

flowchart TD
    C[Claude, Codex<br/>or another MCP client] --> S[FastMCP server]
    S --> R[Shared source registry<br/>96 tools]
    R --> A[Read and analysis tools]
    R --> W[Guarded write tools]
    A --> G[Google APIs<br/>GSC, GA4, CrUX]
    A --> B[Bing Webmaster API]
    A --> P[Public pages<br/>robots, sitemaps, HTML]
    A --> L[(Local drift baselines)]
    W --> V[Validate target, scope<br/>and explicit confirmation]
    V --> M[Google indexing and sitemaps<br/>Bing submissions and IndexNow]
    G --> O[Structured JSON<br/>facts, derived values and _meta]
    B --> O
    P --> O
    L --> O
    M --> O
    O --> C

Google and Bing share clicks, impressions and derived CTR where those fields exist. Provider-specific values remain separate, and cross-engine deltas appear only when both observed windows are exact and equal.

Evidence and safety

NOTE

Unavailable metrics are reported as unavailable. Unsupported Bing analyses return an explicit limitation, and Google and Bing positions stay separate. Cross-engine click and impression deltas are omitted unless both observed windows are exact and equal. Compare Google and Bing coverage.

Every tool returns structured JSON. The _meta block records diagnostics such as the provider and observed window where the tool can establish them. Search Console MCP does not turn an unavailable field into a negative result or merge Google and Bing ranking semantics into one number.

GA4 reports identify the effective property in _meta.sources.ga4.property, including when GA4_PROPERTY_ID supplies the default. Combined reports also retain the requested GSC property in _meta.sources.gsc.site. _meta.params preserves the original inputs, so an omitted property_id can remain null there while the resolved source is known. Missing child provenance remains null; the server does not infer a GA4-to-GSC site mapping. See the source identity contract.

Remote writes require the agent to identify the exact target and volume, read current state where available, and obtain explicit confirmation before calling the tool. The returned API status is reported without extrapolating crawl, indexation or ranking effects.

Search engine coverage

Analysis

Google

Bing

Raw query, page and date metrics

Supported

Supported within Bing's observed window

quick_wins

Supported

Supported with engine="bing" when position is present

seo_striking_distance

Supported

Supported with engine="bing" when position is present

prune_candidates

Supported

Supported with engine="bing"; indexation must be checked separately

traffic_drops, seo_lost_queries

Supported

Explicit refusal: exact period comparison unavailable

check_alerts, seo_cannibalization

Supported

Explicit refusal: bulk page-query dimension unavailable

Cross-engine query or page comparison

Supported through compare_search_engines

Deltas are omitted unless both observed windows are exact and equal

Bing keyword-research endpoints are not exposed. GetKeywordStats and GetRelatedKeywords returned HTTP 400 in the redacted live canary, so their contract remains UNKNOWN.

Submission workflow and confirmation

There are nine tools that mutate remote state: five existing tools (submit_url, submit_batch, submit_sitemap, sitemaps_delete, indexnow_submit) and four Bing tools (bing_url_submit, bing_urls_submit_batch, bing_feed_submit, bing_feed_remove). Before any call, the agent must read the current state, name the exact target and volume, obtain explicit confirmation, call the tool once, then report its returned status without extrapolation.

Use this sequence for search changes:

  1. Analyse measured data and state its observed window.

  2. Recommend a change, separating measured facts, derived metrics and recommendations.

  3. Correct the page or feed outside this MCP server.

  4. Submit only after explicit confirmation and same-origin validation.

  5. Verify the returned API status. An accepted request proves neither crawl nor indexation.

  6. Measure a later comparable window before attributing an effect.

Current Bing runtime limits are explicit: data freshness is unknown; quota integers are not known to represent totals or remaining capacity; non-empty crawl issues, nested backlink rows and RemoveFeed remain unverified against live production data. No Bing write was executed against a production site during validation. Batch URL submission is therefore refused before mutation. bing_url_info can report a last crawl date, but it cannot provide a complete public URL Inspection verdict.

Tools (98)

This source branch adds two experimental SerpApi tools to the released 96-tool surface. They default to offline preview/import; actual Google acquisitions require explicit enablement, a private key, a verified free plan and a request identifier. Two public desktop/mobile captures and local replay were verified; broader provider coverage and diagnostic quality remain unqualified. See the SerpApi setup and comparison guide. This change is not a package release.

Version 1.5.0 includes the bounded local crawl-log audit. Its validation record distinguishes declared bots and current registry membership from historical identity.

The versioned crawl inventory contract adds optional site-owned local storage, bounded detail pages, exact-URL reconciliation and explicit cleanup. Imported metadata and scores are not independently verified provider evidence.

Release gsc-mcp-tools==1.3.0 includes ga4_ai_referrals, editorial_audit, search_change_breakdown and link_targets_audit, field-level evidence methods, content-trust observations and comparison/challenge fixes. Version 1.3.1 retains 85 tools and adds optional MCP discovery selection, CLI JSON string lists, and the SEO/Bing feedback fixes described in the changelog. Version 1.4.0 has 89 tools, adding declared-change follow-up, draft/rewrite checks, weekday-reference and caller-supplied crawl previews described in bounded audit workflows and editorial workflows. Version 1.5.0 adds seven local evidence tools, richer traffic references and an opt-in extraction profile. Version 1.6.0 retains 96 tools, fixes missing comparison/indexing values and packages experimental audit/native APIs; runner scripts and workspace skills require the repository checkout. See the evidence and safety guide for availability, source matching and method limits.

Category

Tool

Description

Meta

get_capabilities

List all available tools

Experimental SERP

serpapi_search

Preview or explicitly capture one Google SERP on a verified free plan; durable attempt limits, no retries or paid fallback

Experimental SERP

serpapi_import_preview

Qualify caller-supplied Google SERP JSON offline; retain missing fields and producer feature types

Properties

list_properties

List all GSC properties

Properties

get_site_details

Get details for a specific property

Analytics

get_search_analytics

Query search performance data

Analytics

get_performance_overview

Aggregate totals + top queries

Analytics

search_change_breakdown

Compare explicit equal Google windows with independent bounded page/query/country/device views, coverage and residuals

Analytics

search_weekday_reference

Default since 1.4.0: disjoint Google windows aligned by weekday and ending by Pacific J-3. Version 1.5.0 adds optional annual/robust references and mixed/undetermined results; descriptive, no causal attribution

Analytics

compare_search_periods

Compare two consecutive periods

Analytics

get_search_by_page_query

Performance broken down by page and query

Analytics

get_advanced_search_analytics

Flexible query with custom dimensions and filters

Analytics

analytics_anomalies

Z-score anomaly detection on daily clicks

Analytics

discover_performance

Top pages by impressions in Google Discover

Analytics

news_performance

Top pages by impressions in Google News

Analytics

search_type_breakdown

Clicks and impressions split across web, Discover, News, image, video

Analytics

ai_overviews_impact

Generic Web search appearances; AI exposure unverified, explicit 400/403 limits

SEO

quick_wins

Pages in positions 4-15 with CTR below benchmark

SEO

traffic_drops

Declining clicks with metric-based candidate diagnoses, not causal proof

SEO

check_alerts

Traffic concentration risks and ranking opportunities

SEO

seo_striking_distance

Queries in positions 8-15, one push away from page 1

SEO

seo_cannibalization

Queries split across pages (HHI score); search operators excluded by default since 1.3.1

SEO

seo_lost_queries

Queries with a click drop >= 80% vs the previous period

Inspection

inspect_url

URL indexing status via URL Inspection API

Inspection

batch_url_inspection

Inspect up to 10 URLs at once

Inspection

check_indexing_issues

Inspect URLs and categorize by issue type

Indexing

submit_url

Request indexing for a single URL

Indexing

submit_batch

Request indexing for multiple URLs (true HTTP batch)

Sitemaps

list_sitemaps

List submitted sitemaps

Sitemaps

submit_sitemap

Submit a sitemap URL

Sitemaps

sitemaps_get

Fetch details for a single sitemap

Sitemaps

sitemaps_delete

Delete a submitted sitemap (with safety check)

Sitemaps

sitemap_audit

Fetch a sitemap and compare its URLs with 90 days of Search Analytics page rows; does not measure indexation

GA4

ga4_organic_landing_pages

Sessions and engagement for organic landing pages

GA4

ga4_traffic_sources

Sessions and conversions by channel, source and medium

GA4

ga4_ai_referrals

Recorded assistant-attributed visits, exact source rules and coverage-gated shares

GA4

ga4_page_performance

7 metrics per page path, optional CONTAINS filter

GA4

ga4_realtime

Active users right now by screen, country and device

GA4

ga4_user_behavior

Device, country and user-type breakdowns in one batch call

GA4

ga4_conversion_funnel

Converting pages and event counts, optional event filter

GA4

ga4_funnel

Multi-step funnel report via GA4 v1alpha RunFunnelReport, conversion rate per step

Cross

traffic_health_check

Equal requested dates, zero/empty/unavailable states and coverage-gated heuristic ratios

Cross

page_analysis

GSC+GA4 join per page with opportunity score, sorted by priority

Cross

page_health_score

Composite 0-100 score (GSC 30 pts, GA4 25 pts, CrUX 25 pts, schema 20 pts), graceful degradation per component

Cross

content_brief

Per-page top queries, question queries, and GA4 session data for content planning

CrUX

crux_page_vitals

Real-user Core Web Vitals (LCP, INP, CLS, FCP, TTFB) for a URL from the Chrome UX Report API

CrUX

crux_history

Historical Core Web Vitals trend (weekly data points) for a URL

Technical

schema_validate

Fetch any public URL and validate its JSON-LD schemas; suggests missing schemas by URL pattern

Technical

crawl_log_audit

Since 1.5.0: bounded local common/combined logs, masked paths/IPs, declared bots and optional current Google IP membership; no indexing inference

Local inventories

crawl_snapshot_import / crawl_snapshot_read / crawl_snapshot_join / crawl_snapshot_delete

Optional site-owned SiteOne storage, bounded details, exact-URL reconciliation and explicit cleanup

Local comparisons

crawl_diff

Exact observed inventory membership and compatible imported field differences; no deletion/indexing inference

Inspection evidence

indexing_evidence_matrix

Keep supplied per-URL inspection, HTML, GSC, inventory and log observations separate with unknown current indexing

Technical

crawl_import_preview

Since 1.4.0: preview bounded caller-supplied SiteOne JSON in memory; no crawl, file/network access, secrets or GSC join

Technical

schema_generate

Generate a Schema.org JSON-LD block for Reservation, OrderAction, DiscussionForumPosting, or ProfilePage

Drift

drift_baseline

Capture a baseline snapshot of a page (title, H1-H3, schema, canonical, CWV) stored locally in SQLite

Drift

drift_compare

Diff a live fetch against the stored baseline and apply 17 rules (8 CRITICAL, 6 WARNING, 3 INFO)

Drift

drift_history

List previous comparison runs for a URL with triggered findings per run

Editorial

editorial_audit

FR/EN house-style warnings, localized excerpts and faithful rewrite guidance; caller plain/Markdown drafts since 1.4.0 with native source spans and bounded parsing; no AI-authorship score

Editorial

rewrite_fidelity_check

Since 1.4.0: protected literals and qualifier review candidates; semantic fidelity and factual truth remain unassessed

Follow-up

seo_change_impact

Since 1.4.0: declared event and descriptive Google before/after evidence; no persistence or causal effect

Content

content_quality

Fetch a URL for local filler, density, repetition and thin-content heuristics; optional main-content profile requires independent evaluation

Content

hreflang_audit

Fetch a URL and validate its hreflang implementation: x-default, ISO 639-1 codes, region codes, self-ref, protocol consistency

Content

page_technical_audit

Fetch a URL and audit meta tags (title, description, canonical, robots), viewport, HTML lang, security headers, robots.txt Googlebot access

Content

preload_audit

Audit Speculation Rules, bfcache eligibility, and LCP preload signals: inline speculationrules blocks, Speculation-Rules header, link preload tags, deprecated prerender, cache-control blockers

CrUX

crux_lcp_subparts

Decompose LCP into four subparts (TTFB, resource load delay, duration, render delay) with dominant phase identification for targeted CWV remediation

Indexing

indexnow_submit

Submit URLs to IndexNow (Bing, Yandex, Seznam, Naver) via one POST; SSRF-safe URL validation, skipped-invalid count, ok/partial/error verdict

SEO

parasite_risk

Scan URL paths for parasite SEO patterns matching Google's 2024-11-19 site-reputation policy: sponsored/affiliate sections, Forbes Advisor, CNN Underscored patterns, affiliate query params

Technical

ai_visibility_audit

Check robots.txt and llms.txt; version 1.3.1 checks 10 agents, including ClaudeBot, Claude-User and Claude-SearchBot

Technical

gbp_deprecation_lint

Scan a page for deprecated Google Business Profile features: .business.site links, Reserve with Google, GBP appointment widgets

Technical

pagespeed_audit

Run a PageSpeed Insights API v5 audit: Lighthouse performance score, Core Web Vitals, top 3 improvement opportunities (requires GOOGLE_API_KEY)

Content

heading_audit

Audit heading structure: H1 uniqueness, level jumps (H2 to H4), title vs H1 word-for-word duplication, headings carrying no information, words per H2

Links

link_targets_audit

Observe bounded internal destination HTTP statuses and redirect hops while preserving source anchors; no recursive crawl

Links

internal_links_audit

Audit a page's internal links weighted by zone (body, nav, footer, header, aside): targets linked only from footer/nav, generic and empty anchors, internal nofollow, self-links

Links

link_equity_map

Crawl the top pages by impressions, build the internal link graph, cross it with GSC: pages at position 11-20 with no body inbound link, orphan candidates, footer-only targets, hubs

SEO

prune_candidates

Classify pages by measured traffic (has_traffic, impressions_no_clicks, low_impressions, zero_impressions) before any pruning call; a page with clicks is never a candidate

Bing read

bing_sites_list

List sites visible to the Bing account and their observed verified state

Bing read

bing_query_stats

Query performance in Bing's observed rolling window

Bing read

bing_page_stats

Page performance in Bing's observed rolling window

Bing read

bing_page_query_stats

Query performance for one page

Bing read

bing_rank_traffic_stats

Daily clicks and impressions; no rank field is inferred

Bing read

bing_crawl_stats

Dated crawl counters in the requested local window

Bing read

bing_crawl_issues

Crawl issue flags; non-empty live item shape remains unverified

Bing read

bing_crawl_settings_get

Observed crawl-rate setting from the partial contract

Bing read

bing_url_info

Observed URL fields and last crawl date, without an indexation verdict

Bing read

bing_url_traffic

URL clicks, impressions and derived CTR

Bing read

bing_feeds_list

List registered Bing feeds

Bing read

bing_feed_details

Return every observed feed-detail row

Bing read

bing_url_submission_quota

Return quota integers with total-versus-remaining semantics marked unknown

Bing read

bing_link_counts

Backlink count page; nested runtime shape remains unverified

Bing read

bing_url_links

Backlinks for one URL; nested runtime shape remains unverified

Bing write

bing_url_submit

Submit one same-origin URL; acceptance does not prove indexation

Bing write

bing_urls_submit_batch

Validate a batch, then refuse it while quota semantics remain unknown

Bing write

bing_feed_submit

Submit one same-origin feed without claiming crawl or indexation

Bing write

bing_feed_remove

Remove a registered same-origin feed after explicit confirm=true; runtime contract unverified

Cross-engine

compare_search_engines

Compare query or page metrics; deltas require equal exact observed windows and positions stay side by side

CLI usage

After installation, gsc-cli is available as a standalone shell command. It derives its commands from the same registry as the MCP server. Version 1.6.0 retains the 96 commands from 1.5.0. Version 1.4.0 has 89 commands, up from 85 in releases 1.3.0 and 1.3.1, adding seo_change_impact, rewrite_fidelity_check, search_weekday_reference and crawl_import_preview. Draft inputs extend editorial_audit without adding a command. Version 1.2.0 has 81 commands. MCP family selection does not restrict CLI commands.

# List the commands in the installed build
gsc-cli list

# Run Google or Bing tools with flags
gsc-cli get-search-analytics --site https://example.com/ --days 28
gsc-cli bing-query-stats --site https://example.com/ --days 28 --limit 100

Bing from the CLI

# Load BING_WEBMASTER_API_KEY from your local secret store before this command.
gsc-cli bing-sites-list
gsc-cli bing-query-stats --site https://example.com/ --days 28 --limit 100
gsc-cli compare-search-engines \
  --google-site sc-domain:example.com \
  --bing-site https://example.com/ \
  --days 28 \
  --dimension query

BING_WEBMASTER_API_KEY is process configuration. It never appears in the CLI flags, tool parameters, result metadata or sanitized Bing errors.

# Run another registered tool
gsc-cli get-performance-overview --site https://example.com/

# Multi-value flags for list parameters
gsc-cli batch-url-inspection \
  --urls https://example.com/page-1/ \
  --urls https://example.com/page-2/ \
  --site https://example.com/

# GA4 funnel with a JSON steps array
gsc-cli ga4-funnel \
  --steps '[{"name":"Visit","event":"page_view"},{"name":"Convert","event":"purchase"}]' \
  --start-date 28daysAgo \
  --end-date today

# Keep the _meta diagnostic block in output
gsc-cli list-properties --meta

# Pipe to jq
gsc-cli get-search-analytics --site https://example.com/ | jq '.rows[:5]'

String-list flags also accept a JSON array of strings:

gsc-cli batch-url-inspection --site https://example.com/ \
  --urls '["https://example.com/page-1/","https://example.com/page-2/"]'

Repeat the flag or use a JSON array; commas are literal URL characters, not separators. For example, --urls 'https://example.com/a,b?q=x,y' supplies one URL. Malformed arrays and non-string entries are rejected before a provider call. JSON string-list support is available since 1.3.1; repeated flags also work in release 1.3.0.

Set GSC_SERVICE_ACCOUNT_PATH for non-interactive use (same as the MCP server). To cache OAuth credentials interactively, run:

gsc-cli auth login --allow-browser

Exit codes: 0 success, 1 Google API error, 2 credential/config error or invalid arguments.

Quota note: submit-batch and submit-url use the Google Indexing API (200 req/day limit). Each gsc-cli call starts a fresh process, so cross-invocation quota tracking is not implemented. The @with_retry decorator still catches 429s, but the in-process counter resets every call.

Agents and shared SEO skills

The repository ships 13 Claude Code agents, 15 shared SEO skills, one Claude development skill and 2 development commands. The nine SEO workflow agents below each reference a focused skill. A read-only evidence reviewer keeps its findings beside the unapproved draft; three additional specialist agents cover Python implementation, pytest and security review. The controlled workflow pilot records that interactive workflow's bounded checks.

The optional bounded native source workflow uses experimental APIs packaged in 1.6.0 and a checkout runner with nine narrower source-review profiles, immutable acquired observations and durable provider, tool and native-attempt ceilings. Both installed native CLI hosts completed an offline source case; this does not establish authenticated provider acquisition, full interactive playbooks or expert report quality. Current output-limit validation bounds each stdout/stderr stream and regular-file writes to at most 2,000,000 bytes on Linux/macOS, preserves lower inherited file limits and cleans up ordinary process-group descendants. The file ceiling can affect host state; it is not an aggregate disk quota or host memory limit. Version 1.6.0 packages the Python APIs; runner scripts and shared workspace skills still require the repository checkout. No new console command is installed.

The live GSC pilot record describes authenticated acquisition, private storage, explicit windows and identical source projections reviewed by Claude/Codex. This source-only pilot does not validate interactive playbooks or human quality. A Google-only configuration does not require a Bing site.

The initial native client playbook trials record explicit skill loading and MCP replay calls in both clients. Eleven of twelve retained controlled cases passed after targeted instruction retests; the Claude missing-traffic case still overstated an explanation. The separate C1 follow-up adds an insufficient-evidence branch and eight retained cases passing the frozen C1 criteria, including a positive arithmetic control. These verdicts do not establish whole-report accuracy, automatic routing, new provider acquisition or human SEO quality.

Agents

Agent

Skill

When to use

gsc-seo-reporter

seo-weekly-report

Weekly traffic recap, period-over-period summary

gsc-traffic-doctor

traffic-drop-diagnosis

Sudden or sustained drop in clicks or impressions

gsc-content-optimizer

content-opportunities

Observed content optimization candidates; no predicted gains

gsc-cannibalization-checker

cannibalization-check

Multiple pages competing for the same query

gsc-indexing-auditor

indexing-audit

Crawl errors, pages not indexed, coverage gaps

gsc-sitemap-auditor

sitemap-audit

Sitemap submission and sampled search visibility

gsc-schema-auditor

schema-audit

JSON-LD local required-field checks; eligibility unassessed

gsc-page-analyst

page-deep-dive

Full diagnostic for a single URL

gsc-ai-overviews-analyst

ai-overviews-impact

Generic search appearances with unavailable/unverified AI exposure

To use an agent from Claude Code, ask naturally ("why did traffic drop?") or invoke it by name. Each agent loads its skill at runtime and returns a structured answer, not a narration of what it did.

Skills

SEO skills have one canonical source in .agents/skills/, discovered by Codex and projected into .claude/skills/ for Claude. Each contains supported calls, evidence limits and shared FR/EN routing cases. Use them directly or through the Claude agents. Shared-playbook validation records discovery and routing checks; the separate native source runner does not execute these interactive playbooks or establish human SEO accuracy.

Skill

Command

When to use

seo-weekly-report

/seo-weekly-report

Weekly traffic recap, period-over-period summary

traffic-drop-diagnosis

/traffic-drop-diagnosis

Sudden or sustained drop in clicks or impressions

content-opportunities

/content-opportunities

Observed content optimization candidates; no predicted gains

cannibalization-check

/cannibalization-check

Multiple pages competing for the same query

indexing-audit

/indexing-audit

Crawl errors, pages not indexed, coverage gaps

sitemap-audit

/sitemap-audit

Sitemap submission and sampled search visibility

schema-audit

/schema-audit

JSON-LD local required-field checks; eligibility unassessed

page-deep-dive

/page-deep-dive

Full diagnostic for a single URL

ai-overviews-impact

/ai-overviews-impact

Inspect generic Web search appearances without AI attribution

heading-audit

/heading-audit

Heading hierarchy, H1 uniqueness, title overlap and section density

internal-linking-audit

/internal-linking-audit

Link placement by page zone, anchors and footer-only targets

link-equity-map

/link-equity-map

Site-wide link flow crossed with Search Console positions

onpage-audit

/onpage-audit

One-page audit combining technical, content, link, schema and search data

crawl-import

/crawl-import

Versioned SiteOne inventories, exact-URL joins and explicit local retention

crawl-log-audit

/crawl-log-audit

Bounded local server access logs, HTTP status and declared bot evidence

python-clean-code

/python-clean-code

Review a module for clean code violations before PR

add-tool

/add-tool

Step-by-step workflow to add a new MCP tool

run-tests

/run-tests

Run the pytest suite with automatic failure diagnosis

Documentation

Need

Document

Install, upgrade and configure an MCP client

Installation guide

Configure Google APIs and authentication

Google setup guide

Configure Bing Webmaster Tools

Bing setup guide

Run the first audit

Starter prompts and examples/

Compare search changes, follow a declared edit and check link destinations

Bounded audit workflows

Review a draft or compare a proposed rewrite

Editorial workflows

Understand the modules and data flow

Architecture

Run the optional source-only native audit

Bounded native source workflow

Compare extraction profiles offline

Extraction profiles and labeled-snippet benchmark

Supply independent human cases and frozen targets

Expert evaluation intake and query evaluation contract

Review delivered source limits and remaining inputs

Delegated validation, 2026-10-10 and remaining action plan

Review Bing evidence and runtime limits

Bing API contract

Verify SEO expert feedback fixes and catalogue measurements

Feedback validation record

Review local audit validation and its evidence limits

Audit validation records

Review product designs and implementation plans

Product design records

Track releases and current changes

Changelog

Navigate the public site and review dated updates

HTML sitemap, what’s new and website maintenance

Give the repository to an AI assistant

Machine-readable project index

The docs/machine-readable/ directory contains structured architecture docs designed to give any AI agent (Claude, Cursor, Copilot...) an accurate picture of the project without reading the full codebase:

  • Editorial audit and rewrite profile: scoped FR/EN warnings and instructions for preserving meaning during rewrites.

  • llms.txt: quick reference covering all 96 source tools, module map, security rules, test patterns, and a decision tree for common tasks

  • adr-index.yaml: 16 Architecture Decision Records reconstructed from git history

  • code-map.yaml: full module/test/dependency map

  • constraints.yaml: forbidden patterns (no stdlib XML on external input, no pickle for tokens, no unvalidated URLs in sitemap fetch...) and required patterns

  • tech-decisions.yaml: stack decisions by domain (auth, retry, output contract, packaging...)

Load llms.txt via your AI context or reference it in your CLAUDE.md with @docs/machine-readable/llms.txt.

Development

The classifier evaluation guide and human intake worksheet specify independent labels, family-disjoint splits and targets frozen before tuning. Equal declared annotator/reviewer identifiers are rejected; distinct strings do not authenticate humans. The extraction benchmark compares hash-checked local HTML using labeled inclusion/omission snippets. Its release quality remains UNKNOWN, synthetic results are ineligible for adoption and downstream warnings are not_measured. See the remaining action plan for task-specific inputs.

Source checkout for development

git clone https://github.com/FlorianBruniaux/google-search-console-mcp
cd google-search-console-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e .
gsc-cli list

The final command reads the shared registry and lists the 98 commands available in this source branch. Use this installation when developing or testing unreleased changes; the native audit and evaluation scripts add no public MCP tool or CLI command.

For client executable paths and the distinction between repository skills, Claude Desktop and native source-review profiles, follow the source workflow installation instructions. The Python APIs are packaged in 1.6.0; runner scripts and workspace skills require the checkout. See the 1.6.0 release validation.

Run the tests

pip install -e ".[dev]"
pytest tests/ -v

The C1 follow-up consolidated on 11 October 2026 records 2,081 Python tests passing with the optional content package installed, plus 113 local browser tests. This is the recorded dev/content run, not a base-package test count. Provider calls use mocks; controlled inputs do not establish live provider access or expert SEO accuracy. Earlier subprocess and extraction checks retain their own 10 October validation record.

Project origins

Why this implementation exists

Two projects shaped the approach here. AminForou/mcp-gsc (Python, 1k+ stars) has strong search analytics and handles OAuth and Service Account auth cleanly, but does not include the Google Indexing API at all. Suganthan-Mohanadasan/Suganthans-GSC-MCP (Node.js) adds the Indexing API but implements submit_batch as a sequential loop with a 100ms delay between requests, not a real HTTP batch, and mixes plain-text and JSON outputs with no retry logic.

This project takes the auth and SEO patterns from the first, the Indexing API scope from the second, and closes the gaps in both. Python was the natural choice: google-api-python-client ships service.new_batch_http_request() natively, which makes true HTTP multipart batching possible without reimplementing the wire format by hand.

Feature

AminForou/mcp-gsc

Suganthan

gsc-mcp

Google Indexing API

No

Yes (fake batch)

Yes (true HTTP batch)

submit_batch

N/A

Sequential loop

new_batch_http_request(), 100/chunk

Token storage

pickle

pickle

JSON (creds.to_json())

Retry on 429/5xx

No

No

Yes, exponential backoff

Quota tracking

No

No

Yes, warns at 180/200

Output format

Mixed text+JSON

Mixed

100% JSON + _meta block

Credits

This project took inspiration from claude-seo (MIT, agricidaniel). Four components were adapted:

  • SSRF protection (src/gsc_mcp/url_safety.py): the URL safety module with DNS-rebinding mitigation, IPv4 obfuscation normalization, and multi-cloud metadata endpoint blocklist, ported from requests to httpx.

  • JSON-LD generators (schema_generate tool): the four high-leverage schema types (Reservation, OrderAction, DiscussionForumPosting, ProfilePage) adapted from scripts/schema_generate.py.

  • Schema templates (src/gsc_mcp/data/schema_templates.json): 11 JSON-LD placeholder templates (VideoObject, ProductGroup, ItemList, Certification, etc.) from schema/templates.json.

  • SEO drift monitoring (src/gsc_mcp/tools/drift.py): the 17-rule diff methodology from scripts/drift_baseline.py and scripts/drift_compare.py, credited to Dan Colta in the original CONTRIBUTORS.md.

Assets with incompatible licenses (CC BY-SA 4.0, CC BY 4.0) were excluded. See NOTICE for full attribution.

Explore the ecosystem

These projects extend the workflow without duplicating this tool:

  • Research with yt-insights: connect corpus building to post-publication performance measurement.

  • Learn with Claude Code Ultimate Guide: frame MCP choice, permissions, and research workflows.

Browse the complete open-source galaxy

License

MIT

Available Tools

81 tools
ai_overviews_impactA

Get queries where AI Overview appearance data is available.

Uses the searchAppearance dimension with dataState=all to capture AI Overview impressions. Returns an error dict when the property does not support this dimension (HTTP 400/403) instead of raising.

Inputs: site (required), days, limit. Returns: result

ai_visibility_auditA

Check robots.txt AI crawler access and llms.txt presence for a URL's origin.

Fetches {origin}/robots.txt and checks each known AI crawler agent. Also checks for {origin}/llms.txt (Model Context Protocol discoverability file). No authentication required.

Verdicts: open (all AI crawlers allowed) | partial (some blocked) | closed (all blocked or disallow all) | fetch_error.

Inputs: url (required). Returns: result

analytics_anomaliesA

Detect days with statistically abnormal click volumes using z-score analysis.

A day is flagged as a spike or drop when abs(z_score) > threshold (default 2.5). Returns mean_daily_clicks, std_daily_clicks, and the list of anomalous days with their z-score. Use days=90 or more for meaningful baseline statistics.

Inputs: site (required), days, threshold. Returns: result

batch_url_inspectionA

Inspect up to 10 URLs at once in GSC. Returns the same fields as inspect_url for each URL.

Inputs: site (required), urls (required). Returns: result

bing_crawl_issuesC

Decode Bing crawl issue flags using the synthetic-fixture contract.

Inputs: site (required), limit. Returns: result

bing_crawl_settings_getC

Return only Bing's observed crawl-rate value from the partial contract.

Inputs: site (required). Returns: result

bing_crawl_statsC

Return dated Bing crawl counts inside the requested local window.

Inputs: site (required), days. Returns: result

bing_feed_detailsC

Return every Bing feed-detail row from the observed list response.

Inputs: site (required), feed_url (required). Returns: result

bing_feed_removeB

Remove a registered same-origin feed only after explicit confirmation.

Inputs: site (required), feed_url (required), confirm. Returns: result

bing_feeds_listC

Return Bing feeds with only the observed, non-indexation fields.

Inputs: site (required). Returns: result

bing_feed_submitA

Submit one same-origin feed to Bing without claiming indexation.

Inputs: site (required), feed_url (required). Returns: result

bing_page_query_statsC

Return Bing query performance for one requested page.

Inputs: page (required), site (required), days, limit. Returns: result

bing_page_statsC

Return Bing page performance, normalizing Bing's Query field to page.

Inputs: site (required), days, limit. Returns: result

bing_query_statsC

Return Bing query performance filtered to the requested rolling window.

Inputs: site (required), days, limit. Returns: result

bing_rank_traffic_statsC

Return Bing daily clicks and impressions without inventing rank fields.

Inputs: site (required), days. Returns: result

bing_sites_listB

Return verified-state summaries for sites visible to the Bing account.

Inputs: no named parameters. Returns: result

bing_url_infoC

Return only fields observed from Bing URL info, without indexation claims.

Inputs: url (required), site (required). Returns: result

bing_urls_submit_batchD

Preflight a Bing URL batch and refuse while quota semantics are unknown.

Inputs: site (required), urls (required). Returns: result

bing_url_submission_quotaC

Return Bing quota integers without claiming total or remaining semantics.

Inputs: site (required). Returns: result

bing_url_submitB

Submit one same-origin URL to Bing without claiming indexation.

Inputs: url (required), site (required). Returns: result

bing_url_trafficC

Return observed URL traffic and derived CTR without rank fields.

Inputs: url (required), site (required). Returns: result

check_alertsB

Scan for structural SEO risks: traffic concentration and high-impression low-rank pages.

Flags 'traffic_concentration' (severity: high) when a single query drives more than 50% of all clicks (fragility indicator) and 'high_impression_low_rank' (severity: medium) when a page gets more than 5000 impressions at position > 10 (content optimisation opportunity).

Inputs: site (required), days, engine. Returns: result

check_indexing_issuesA

Inspect up to 10 URLs and return only those with indexing problems, plus a summary count by category.

Categories: indexed, not_indexed, robots_blocked, fetch_error, canonical_issue, unknown. Use batch_url_inspection if you need results for all URLs regardless of status.

Inputs: site (required), urls (required). Returns: result

compare_search_enginesB

Compare Google and Bing query or page metrics without inferring causality.

Click and impression deltas are returned only when both providers expose the same exact observed window. Positions remain side by side because the two providers use different position semantics.

Inputs: bing_site (required), google_site (required), days, limit, +1 more. Returns: result

compare_search_periodsA

Compare two consecutive equal-length windows and report delta in clicks and impressions.

Period B is the most recent days days (with a 3-day lag). Period A is the days days immediately before that. Useful for week-over-week or month-over-month trends.

Inputs: site (required), days. Returns: result

content_briefA

Gather SEO content intelligence for a single page: top queries, question queries, and GA4 engagement.

Step 1 — GSC: fetches search analytics with dimensions ["query", "page"], filters rows to the target page (via _normalize_url), sorts by clicks descending, and returns the top 20.

Step 2 — GA4: calls ga4_page_performance for the same page to get active_users and engagement_rate. Wrapped in try/except RuntimeError; returns None if GA4 credentials are missing or the property is not configured.

Question classification: queries whose first word (lowercased) is one of who/what/when/where/why/how.

Useful for brief-writing, content refreshes, and intent analysis.

Inputs: site (required), page_url (required), days, property_id. Returns: result

content_qualityA

Analyse page content quality against Google QRG signals (E-E-A-T heuristics).

Fetches the URL, extracts visible text, then scores against thin content, filler language, information density (named entities + numbers per token), and bigram repetition. No Google API calls. No authentication required.

Filler phrase list adapted from claude-seo (agricidaniel, MIT). Verdicts: good | needs_work | thin_content | fetch_error.

Inputs: url (required). Returns: result

crux_historyA

Fetch 40 weeks of Core Web Vitals history for a URL from the CrUX History API.

form_factor: "ALL_FORM_FACTORS" | "PHONE" | "DESKTOP" | "TABLET" metric: one of largest_contentful_paint | interaction_to_next_paint | cumulative_layout_shift | first_contentful_paint | experimental_time_to_first_byte Returns p75 per weekly collection period, oldest to newest. Requires CRUX_API_KEY environment variable.

Inputs: url (required), metric, form_factor. Returns: result

crux_lcp_subpartsA

Decompose LCP into its four subparts via the CrUX API for actionable performance diagnosis.

Returns p75 values for TTFB, resource load delay, resource load duration, and element render delay, plus the dominant phase (the subpart with the highest p75 ms). Knowing which phase dominates turns "LCP is 4.2s" into a specific fix (server, preload, image size, or render-blocking resources).

form_factor: "PHONE" (default) | "DESKTOP" | "TABLET" | "ALL_FORM_FACTORS" Requires CRUX_API_KEY environment variable. Verdicts: good | needs_improvement | poor | not_enough_data | missing_key | fetch_error. Adapted from claude-seo lcp_subparts.py (agricidaniel, MIT).

Inputs: url (required), form_factor. Returns: result

crux_page_vitalsA

Fetch current Core Web Vitals (LCP, INP, CLS, FCP, TTFB) for a URL from the CrUX API.

form_factor: "ALL_FORM_FACTORS" | "PHONE" | "DESKTOP" | "TABLET" Returns p75 percentile and a good/needs_improvement/poor rating per metric. If the URL has insufficient data (<1000 real users over 28 days), returns verdict=not_enough_data. Requires CRUX_API_KEY environment variable (Google API key with Chrome UX Report API enabled).

Inputs: url (required), form_factor. Returns: result

discover_performanceA

Get Discover performance: top pages by impressions (Discover does not support query dimension).

Inputs: site (required), days, limit. Returns: result

drift_baselineA

Capture an SEO baseline snapshot for a URL.

Fetches the page, extracts critical SEO signals (title, meta tags, canonical, headings, JSON-LD, OpenGraph), and stores them in a local SQLite database as a "known good" reference. Call drift_compare later to detect regressions.

Adapted from scripts/drift_baseline.py in claude-seo (Dan Colta methodology, MIT). No Google API calls. CWV capture requires CRUX_API_KEY (skipped otherwise).

Inputs: url (required), skip_cwv. Returns: result

drift_compareA

Compare current page state to a stored baseline and report SEO drift.

Applies 17 comparison rules (8 CRITICAL, 6 WARNING, 3 INFO) and returns triggered findings with severity, old/new values, and recommended actions. Call drift_baseline first if no baseline exists for this URL.

Adapted from scripts/drift_compare.py in claude-seo (Dan Colta methodology, MIT). No Google API calls. CWV comparison requires CRUX_API_KEY (skipped otherwise).

Inputs: url (required), skip_cwv, baseline_id. Returns: result

drift_historyA

Return recent drift comparisons for a URL.

Shows comparison timestamps, triggered finding counts by severity, and baseline IDs. Use drift_compare to run a fresh comparison.

Inputs: url (required), limit. Returns: result

ga4_conversion_funnelA

Fetch GA4 conversion data: pages that generated conversions, and event counts.

Runs two reports in sequence: pages ranked by conversion count, and events ranked by event_count (optionally filtered to a specific event_name). Useful for identifying which pages and events drive goals. Dates use GA4 relative format. hostname and country narrow both reports to a specific host or country.

Inputs: country, end_date, hostname, event_name, +2 more. Returns: result

ga4_funnelA

Run a GA4 funnel report using the v1alpha RunFunnelReport API.

Each step is a dict with 'name' (display label) and 'event' (GA4 event name). Requires at least 2 steps. Returns users per step and conversion rate relative to step 1. Step 1 conversion_rate is always null. Pass property_id to override GA4_PROPERTY_ID for multi-property setups.

Inputs: steps (required), end_date (required), start_date (required), property_id. Returns: result

ga4_organic_landing_pagesA

Fetch GA4 landing page performance filtered to organic traffic only.

Dates use GA4 relative format: '28daysAgo', 'today', '7daysAgo', 'yesterday', or 'YYYY-MM-DD'. Returns sessions, engaged_sessions, bounce_rate, avg_session_duration, conversions, and revenue per landing page. Pass property_id to override GA4_PROPERTY_ID for multi-property setups. hostname and country narrow results to a specific host or country.

Inputs: limit, country, end_date, hostname, +2 more. Returns: result

ga4_page_performanceB

Fetch GA4 page-level metrics: views, active users, session duration, engagement and bounce rates, conversions, and revenue.

Optionally filter to pages whose path contains page_path (substring match). Dates use GA4 relative format: '28daysAgo', 'today', '7daysAgo', 'YYYY-MM-DD'. hostname and country narrow results to a specific host or country.

Inputs: country, end_date, hostname, page_path, +2 more. Returns: result

ga4_realtimeA

Fetch active users in the last 30 minutes from the GA4 Realtime API.

Groups active users by screen name, country, and device category. Use for live traffic monitoring. No date range applies — this reflects the current moment only. hostname narrows results to a specific host (country is already a dimension, not a filter).

Inputs: hostname, property_id. Returns: result

ga4_traffic_sourcesA

Fetch GA4 sessions grouped by channel group, source, and medium.

Shows which traffic channels (Organic Search, Direct, Referral, etc.) drive the most sessions, engagement, conversions, and revenue. Dates use GA4 relative format: '28daysAgo', 'today', 'YYYY-MM-DD'. hostname and country narrow results.

Inputs: country, end_date, hostname, start_date, +1 more. Returns: result

ga4_user_behaviorA

Fetch GA4 sessions and engagement rate broken down by device, country, and user type.

Executes a single batch request returning three reports: by device category, by country (top 20), and by new vs returning users. Useful for audience analysis. hostname and country narrow results across all three sub-reports.

Inputs: country, end_date, hostname, start_date, +1 more. Returns: result

gbp_deprecation_lintA

Scan a page for deprecated Google Business Profile (GBP) features.

Checks for GBP chat widget embed scripts, dead .business.site links, and Reserve with Google (deprecated) integrations. No authentication required.

Verdicts: clean | deprecated_found | fetch_error.

Inputs: url (required). Returns: result

get_advanced_search_analyticsA

Fetch GSC search analytics with full control over search_type, data_state, dimensions, and row limit.

search_type: 'web' (default), 'image', 'video', or 'news'. data_state: 'final' (default, omit to use API default) or 'all' (includes fresh unverified data). dimensions: list of 'query', 'page', 'device', 'country', 'searchAppearance'. Use when get_search_analytics defaults are not sufficient.

Inputs: site (required), row_limit, data_state, dimensions, +2 more. Returns: result

get_capabilitiesA

List all available tools and declared search-engine credentials.

Inputs: no named parameters. Returns: result

get_performance_overviewB

Summarise total clicks, impressions, average CTR and average position for a site.

Returns aggregate totals plus the top 10 queries by clicks over the rolling window.

Inputs: site (required), days. Returns: result

get_search_analyticsB

Fetch GSC search analytics (clicks, impressions, CTR, position) for a site.

Groups results by the requested dimensions (query, page, device, country). Data has a 3-day reporting lag; the window covers the days days ending 3 days ago.

Inputs: site (required), days, row_limit, dimensions. Returns: result

get_search_by_page_queryA

Fetch GSC data grouped by both page and query simultaneously.

Useful for identifying which query drives which page and diagnosing on-page relevance issues.

Inputs: site (required), days, row_limit. Returns: result

get_site_detailsA

Get the permission level for a specific GSC property URL.

Inputs: site_url (required). Returns: result

heading_auditA

Audit the heading structure of a page: H1 uniqueness, hierarchy, and title overlap.

Checks that exactly one H1 exists, that heading levels do not skip (H2 straight to H4), that the is not a word-for-word copy of the H1 (a duplicate wastes a second angle on the target keyword), and that headings actually say something rather than filling a slot ("Introduction", "Conclusion").

Also reports words per H2, since a long page with no subheadings reads as a wall.

No Google API calls. No authentication required. Verdicts: healthy | issues_found | fetch_error.

Inputs: url (required). Returns: result

hreflang_auditA

Fetch a URL and validate its hreflang implementation.

Checks: missing x-default, invalid ISO 639-1 language codes, invalid ISO 3166-1 region codes, missing self-referencing tag, and mixed HTTP/HTTPS in the alternate set. Single-page audit: does not follow each alternate URL to verify bidirectional return tags.

Validation rules derived from skills/seo-hreflang/SKILL.md in claude-seo (agricidaniel, MIT). No authentication required. Verdicts: valid | issues_found | no_hreflang | fetch_error.

Inputs: url (required). Returns: result

indexnow_submitA

Submit URLs to IndexNow, notifying Bing, Yandex, Seznam, and Naver simultaneously.

Each URL must pass strict SSRF validation and match site's exact HTTPS origin. A 200 or 202 means only that the notification was received, never that a URL was crawled or indexed. The key is sent to IndexNow but never returned in output.

Inputs: key (required), site (required), urls (required). Returns: result

inspect_urlB

Inspect a single URL in GSC to get its indexing status, last crawl time, and canonical URL.

Returns verdict (PASS/NEUTRAL/FAIL), robotsTxtState, indexingState, pageFetchState, googleCanonical, userCanonical, and a derived category (indexed, robots_blocked, fetch_error, canonical_issue, not_indexed, unknown).

Inputs: url (required), site (required). Returns: result

list_propertiesA

List all GSC properties the authenticated account can access, with their permission levels.

Inputs: no named parameters. Returns: result

list_sitemapsB

List all sitemaps submitted to a GSC property, with submission dates, status, and error counts.

Inputs: site (required). Returns: result

news_performanceA

Get Google News performance: top pages by impressions (News does not support query dimension).

Inputs: site (required), days, limit. Returns: result

page_analysisA

Join GSC and GA4 data at the page level and rank by opportunity score.

GSC rows are fetched with dimensions=["page"] (already aggregated per page). GA4 organic landing pages are fetched with a high limit to avoid truncation. Pages are joined on _normalize_url. Pages that appear in only one source get None for the missing fields.

opportunity_score = log10(impressions+1)10 + engagement_rate100 + log10(conversions+1)*20

engagement_rate is derived as engaged_sessions/sessions (GA4 native formula) because ga4_organic_landing_pages does not expose it directly.

Results are sorted by opportunity_score descending, truncated to limit. hostname and country narrow the GA4 query to a specific host or country.

Inputs: site (required), days, limit, country, +2 more. Returns: result

page_health_scoreA

Compute a 0-100 health score for a single page by combining GSC, GA4, CrUX, and schema data.

Each component contributes a portion of the total score (100 pts):

  • GSC (30 pts): indexing_state == "INDEXING_ALLOWED" -> 20 pts; verdict == "PASS" -> 10 pts

  • GA4 (25 pts): active_users > 0 -> 15 pts; engagement_rate > 0.4 -> 10 pts

  • CrUX (25 pts): LCP good -> 10 pts; INP good -> 8 pts; CLS good -> 7 pts

  • Schema (20 pts): schemas found -> 10 pts; no validation errors -> 10 pts

GA4, CrUX, and Schema components are each wrapped in try/except RuntimeError so that missing credentials or insufficient data degrade the score gracefully. The final score is renormalized over available components: score = round((earned / max_available) * 100). If all components fail, returns score=0.

property_id overrides GA4_PROPERTY_ID for multi-property setups. hostname and country are forwarded to GA4 for scoped queries.

Inputs: url (required), site (required), country, hostname, +1 more. Returns: result

pagespeed_auditB

Run a PageSpeed Insights audit via Google's PSI API v5.

Requires GOOGLE_API_KEY environment variable (plain API key, not service account). The PageSpeed Insights API must be enabled in the GCP project.

strategy: "mobile" (default) or "desktop". Returns Lighthouse performance score, Core Web Vitals, and top opportunities. Verdicts: good (score>=90) | needs_improvement (50-89) | poor (<50) | missing_key | fetch_error.

Inputs: url (required), strategy. Returns: result

page_technical_auditA

Audit on-page technical SEO: meta tags, canonical, robots.txt, security headers.

Fetches the URL (follow_redirects=False for SSRF safety) and /robots.txt. Checks: title and meta description length, canonical presence and consistency, meta robots directives, viewport tag, HTML lang attribute, security response headers (X-Frame-Options, X-Content-Type-Options, Referrer-Policy), redirect detection, and whether Googlebot is blocked in robots.txt.

For pages behind redirects, supply the final canonical URL directly. No Google API calls. No authentication required. Verdicts: healthy | issues_found | fetch_error.

Inputs: url (required). Returns: result

parasite_riskA

Scan URL paths for parasite SEO patterns matching Google's 2024-11-19 site-reputation policy.

Pure URL analysis, no HTTP fetches. Detects sponsored/affiliate/partner path segments, commercial product sections (/best-deals/, /top-picks/), known editorial domain patterns (Forbes Advisor /advisor/, CNN Underscored /underscored/, /select/, /commerce/), and affiliate query parameters (?ref=, ?aff=, ?partner=).

site_risk is the maximum risk level across all URLs. Verdicts: clean | at_risk | high_risk. No Google API calls. No authentication required. Adapted from claude-seo parasite_risk.py (agricidaniel, MIT).

Inputs: site (required), urls (required). Returns: result

preload_auditA

Audit Speculation Rules, bfcache eligibility, and LCP preload signals for a URL.

Fetches the page and response headers (SSRF-safe via safe_httpx_get), then checks:

  • Speculation Rules: (prefetch/prerender actions)

  • Speculation-Rules HTTP response header (Chrome 122+)

  • Deprecated tags (removed in Chrome 120)

  • bfcache blocker: Cache-Control: no-store in response headers

Verdicts: optimised | improvements_available | not_implemented | fetch_error. No Google API calls. No authentication required. Adapted from claude-seo preload_check.py (agricidaniel, MIT).

Inputs: url (required). Returns: result

prune_candidatesA

Classify pages by measured traffic before any pruning decision is taken.

Buckets every page Search Console reports over days:

  • has_traffic: at least one click. Never a candidate. Full stop.

  • impressions_no_clicks: seen in results, never clicked. Review, do not delete.

  • low_impressions: under 10 impressions. Weak signal, needs a human look.

  • zero_impressions: no impressions at all. The only defensible candidates.

The tool deliberately returns no "delete these" list. It returns evidence, and the buckets carry the recommended action. A page absent from this report was absent from Search Console too, which is a crawling question, not a pruning one.

Pair with content_quality and internal_links_audit before acting: a page with no impressions and no internal link may be starved rather than worthless.

Inputs: site (required), days, engine, max_pages. Returns: result

quick_winsA

Identify pages ranking between positions 4-15 whose CTR is below the industry benchmark for their rank.

Sorted by opportunity_score = (benchmark_ctr - actual_ctr) * impressions. High scores mean large click gains are possible with CTR optimisation (title/meta improvements).

Inputs: site (required), days, engine, min_impressions. Returns: result

schema_generateC

Generate a Schema.org JSON-LD block for one of four high-leverage types.

Adapted from scripts/schema_generate.py in claude-seo (agricidaniel, MIT). Supports: reservation, order_action, discussion, profile. No authentication required. No Google API calls made.

schema_type: one of "reservation", "order_action", "discussion", "profile". Returns the generated JSON-LD block. Verdicts: generated | error.

Inputs: schema_type (required), url, name, text, +25 more. Returns: result

schema_validateA

Fetch a URL and validate its JSON-LD structured data schemas.

Detects all blocks, checks required fields per schema type, and suggests missing schemas based on URL patterns. Does not require authentication -- works on any public URL.

Returns detected schemas, validation results per schema, and recommendations. The valid flag and verdict check only this tool's local required-field presence rules, not full Schema.org validity or Google rich-result eligibility. Recommended properties are reported separately and do not affect validity. Verdicts: healthy (all schemas valid) | missing_schemas (none found) | invalid_schemas (found but at least one has missing required fields) | fetch_error (URL not reachable).

Inputs: url (required). Returns: result

search_type_breakdownA

Aggregate clicks and impressions broken down by search type for a site or specific URL.

Makes one GSC call per search type (web, discover, googleNews, image, video) and returns total clicks and impressions for each. If url is provided, results are scoped to that page.

Inputs: site (required), url, days. Returns: result

seo_cannibalizationB

Detect queries where multiple pages compete for the same ranking slot.

Uses the Herfindahl-Hirschman Index (HHI) to measure click concentration across pages. conflict_score = 1 - HHI: values near 1 mean clicks are split evenly across pages (high competition). Filters to queries with at least min_impressions total impressions to exclude noise.

Inputs: site (required), days, engine, min_impressions. Returns: result

seo_lost_queriesB

Find queries that had significant clicks previously but now have 80%+ fewer clicks.

Only queries with at least 5 clicks in the previous period are included to filter noise. Note: uses date.today() without a GSC reporting lag, so the most recent 2-3 days of the current period may include incomplete data and produce false positives.

Inputs: site (required), days, engine. Returns: result

seo_striking_distanceB

List queries ranking between positions 8-15, sorted by impressions descending.

These are the best candidates for ranking improvement: close enough to page 1 that targeted content or link optimisation can move them into top positions.

Inputs: site (required), days, engine, min_impressions. Returns: result

sitemap_auditA

Fetch a sitemap and compare its URLs with pages visible in Search Analytics.

Handles both regular sitemaps () and sitemap index files (), with one level of recursion for sitemap indexes. Uses defusedxml for safe XML parsing (prevents XXE and billion-laughs attacks from untrusted external XML).

Search Analytics is not an indexation inventory: a page without search data can still be indexed. The original urls_in_gsc, urls_missing_from_gsc, missing_sample and verdict fields are retained for compatibility, but only describe Search Analytics visibility. Prefer the explicit visibility fields.

Inputs: site (required), sitemap_url (required). Returns: result

sitemaps_deleteA

Delete a submitted sitemap from a GSC property.

Requires the URL to end with '.xml' or contain '/sitemap' as a safety guard against accidental deletion. Removes the entry from GSC tracking only; does not delete the sitemap file.

Inputs: site (required), sitemap_url (required). Returns: result

sitemaps_getA

Get details for a specific sitemap already submitted to a GSC property.

Returns content type counts (URLs, images, videos), error and warning counts, and status flags.

Inputs: site (required), sitemap_url (required). Returns: result

submit_batchA

Submit multiple URLs to the Google Indexing API in HTTP batches of 100.

Returns per-URL results, total submitted/error counts, and remaining daily quota. Daily limit is 200 requests total. A quota_warning is added to the response when usage exceeds 180. url_type: 'URL_UPDATED' (default) or 'URL_DELETED'.

Inputs: urls (required), url_type. Returns: result

submit_sitemapB

Submit a new sitemap URL to a GSC property. If already submitted, GSC updates the existing entry.

Inputs: site (required), sitemap_url (required). Returns: result

submit_urlA

Submit a single URL to the Google Indexing API for crawl notification.

url_type must be 'URL_UPDATED' (page added or changed, default) or 'URL_DELETED' (page removed). Requires a service account with Indexing API access — OAuth is not sufficient. Transient 429/5xx errors are retried automatically (up to 3 times). Credential errors and non-retryable failures propagate to the caller.

Inputs: url (required), url_type. Returns: result

traffic_dropsA

Find queries whose clicks dropped compared to the previous equally-sized period.

Each result includes a diagnosis: 'ranking_loss' (position degraded by more than 2), 'ctr_collapse' (CTR fell more than 30%), or 'demand_decline' (impressions also fell). Note: uses date.today() without a GSC reporting lag, so the most recent 2-3 days may be incomplete.

Inputs: site (required), days, engine. Returns: result

traffic_health_checkA

Compare total GSC clicks with total GA4 organic sessions to detect tracking gaps.

Fetches aggregate GSC clicks (no page dimension) and sums all organic sessions from GA4. The ratio ga4_sessions / gsc_clicks indicates tracking health:

  • "no_gsc_data" : zero GSC clicks (ratio is None, nothing to compare)

  • "tracking_gap" : ratio < 0.6 (GA4 records far fewer sessions than GSC clicks)

  • "filter_issue" : ratio > 1.3 (GA4 records more sessions than GSC clicks)

  • "healthy" : 0.6 <= ratio <= 1.3

Boundaries 0.6 and 1.3 are inclusive of the healthy range (strict < and >). GA4 is queried with limit=10000 to avoid under-counting sessions on large sites. hostname and country narrow the GA4 query to a specific host or country.

Inputs: site (required), days, country, hostname, +1 more. Returns: result

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    C2.6/5.0

    Scored across 81 tools

    Disambiguation2/5

    Many tools overlap closely: get_search_analytics vs get_advanced_search_analytics, quick_wins vs seo_striking_distance, traffic_drops vs seo_lost_queries vs analytics_anomalies, and inspect_url vs batch_url_inspection vs check_indexing_issues. Bing, GA4, and CrUX tools add parallel near-duplicates, making tool selection error-prone despite helpful descriptions.

    Naming Consistency3/5

    All names use snake_case, but the pattern is mixed: some are verb_noun (list_properties, inspect_url), others are noun phrases (quick_wins, content_quality, schema_validate), and many are grouped by prefixes (bing_, ga4_, crux_, sitemaps_). It is readable but not a single predictable convention.

    Tool Count1/5

    81 tools is an extreme mismatch for a single MCP server, far beyond the 3-15 well-scoped range. The surface includes many near-duplicates across GSC, Bing, GA4, CrUX, and audit categories, creating high selection and maintenance burden.

    Completeness4/5

    Coverage is very broad: GSC analytics, indexing, sitemaps, Bing Webmaster tools, GA4, CrUX, on-page audits, schema, drift, and submissions. Minor gaps exist, such as property administration and some provider-specific lifecycle operations, but most core SEO workflows are supported.

    Maintenance

    ActivityMaintained
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • F
      license
      B
      quality
      D
      maintenance
      An MCP server that integrates Google Search Console and Google Analytics 4 to provide unified SEO and web traffic analysis. It allows users to fetch search performance data, merge page metrics, and generate automated trend reports or actionable insights through tool calls.
      16
      1
      -
    • A
      license
      B
      quality
      B
      maintenance
      SEO audit and Google Search Console MCP server with 23 tools. Search analytics, URL inspection, Indexing API, Core Web Vitals (CrUX), striking distance keywords, keyword cannibalization detection, branded query analysis, and automated site audits.
      43
      3
      MIT
    • A
      license
      B
      quality
      D
      maintenance
      An MCP server integrating Google Analytics 4, Search Console, and Indexing API, enabling AI agents to run reports, inspect URLs, manage properties, and request indexing.
      16
      429 npm
      2
      MIT
    • A
      license
      Not graded
      quality
      B
      maintenance
      MCP server for Google Search Console, enabling querying search analytics, URL inspection, sitemap management, and more via natural language.
      16,878 npm
      3
      MIT