gsc-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| GSC_SKIP_OAUTH | No | Set to 'true' when using service account to skip OAuth flow | |
| GA4_PROPERTY_ID | No | Google Analytics 4 property ID (optional, for GA4 tools) | |
| GSC_CREDENTIALS_PATH | No | Path to OAuth client credentials JSON file | |
| GSC_SERVICE_ACCOUNT_PATH | No | Path to service account JSON file |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| get_capabilitiesA | List all 43 available tool names in this MCP server. |
| list_propertiesA | List all GSC properties the authenticated account can access, with their permission levels. |
| get_site_detailsA | Get the permission level for a specific GSC property URL. |
| 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 |
| 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. |
| compare_search_periodsA | Compare two consecutive equal-length windows and report delta in clicks and impressions. Period B is the most recent |
| 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. |
| 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. |
| 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 |
| 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). |
| traffic_dropsB | 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. |
| 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). |
| seo_striking_distanceA | 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. |
| seo_cannibalizationA | 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. |
| seo_lost_queriesA | 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. |
| inspect_urlA | 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). |
| batch_url_inspectionA | Inspect up to 10 URLs at once in GSC. Returns the same fields as inspect_url for each URL. |
| 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. Use batch_url_inspection if you need results for all URLs regardless of status. |
| 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. |
| 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'. |
| list_sitemapsB | List all sitemaps submitted to a GSC property, with submission dates, status, and error counts. |
| submit_sitemapB | Submit a new sitemap URL to a GSC property. If already submitted, GSC updates the existing entry. |
| 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. |
| 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. |
| sitemap_auditA | Fetch a sitemap, parse its URLs, and cross-reference with GSC indexed pages. 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). Returns urls_declared, urls_in_gsc, urls_missing_from_gsc, a missing_sample (up to 20), and a verdict: empty | fetch_error | partial | healthy. |
| 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. |
| 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. |
| 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. |
| 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). |
| 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. |
| 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. |
| 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:
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. |
| 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 |
| 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). |
| 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. |
| 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. 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). |
| discover_performanceA | Get Discover performance: top pages by impressions (Discover does not support query dimension). |
| news_performanceA | Get Google News performance: top pages by impressions (News does not support query dimension). |
| 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 |
| 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. |
| 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):
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. |
| 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. |
| 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. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/FlorianBruniaux/google-search-console-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server