npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iflow-mcp/serpfire-gsc-mcp-server

v1.0.0

Published

MCP server wrapping Google Search Console API with built-in SEO analysis tools

Downloads

65

Readme

Google Search Console MCP Server

An MCP server that gives Claude direct access to your Google Search Console data — search performance, URL indexation, sitemaps, and built-in SEO analysis tools including trending queries, cannibalization detection, traffic drop diagnostics, and automated query/page grouping.

Prerequisites

  • Node.js >= 18.0.0
  • A C++ compiler (required by the better-sqlite3 dependency):

| Platform | Install | |----------|---------| | macOS | xcode-select --install | | Windows | Visual Studio Build Tools — select "Desktop development with C++" | | Linux (Debian/Ubuntu) | sudo apt-get install build-essential python3 | | Linux (Fedora/RHEL) | sudo dnf groupinstall "Development Tools" && sudo dnf install python3 |

Quick Start

git clone https://github.com/serpfire/gsc-mcp-server.git
cd gsc-mcp-server
npm install

1. Create Google OAuth credentials

  1. Go to Google Cloud Console
  2. Create an OAuth 2.0 Client ID (type: Desktop app)
  3. Enable the Google Search Console API in your project

2. Authenticate

GSC_OAUTH_CLIENT_ID=your-client-id \
GSC_OAUTH_CLIENT_SECRET=your-client-secret \
npm run setup

This opens your browser to sign in with Google. Tokens are stored at ~/.gsc-mcp/tokens.json and auto-refresh. Run setup again anytime to switch accounts.

3. Add to Claude Code

claude mcp add --transport stdio gsc -s user \
  -e GSC_OAUTH_CLIENT_ID=your-client-id \
  -e GSC_OAUTH_CLIENT_SECRET=your-client-secret \
  -- node /absolute/path/to/gsc-mcp-server/src/index.js

Or manually add to ~/.claude.json:

{
  "mcpServers": {
    "gsc": {
      "type": "stdio",
      "command": "node",
      "args": ["/absolute/path/to/gsc-mcp-server/src/index.js"],
      "env": {
        "GSC_OAUTH_CLIENT_ID": "your-client-id",
        "GSC_OAUTH_CLIENT_SECRET": "your-client-secret"
      }
    }
  }
}

Service Account Alternative

For automation or server-to-server use:

{
  "env": {
    "GSC_AUTH_MODE": "service_account",
    "GSC_SERVICE_ACCOUNT_KEY_PATH": "/path/to/key.json"
  }
}

Tools

Core GSC Tools

| Tool | Description | |------|-------------| | list_sites | List all verified GSC properties | | get_site | Get details for a specific site | | query_search_analytics | Query clicks, impressions, CTR, position with dimensions/filters/pagination | | inspect_url | Check URL index/crawl status (2,000/day limit) | | list_sitemaps | List sitemaps for a site | | get_sitemap | Get sitemap details | | submit_sitemap | Submit a new sitemap | | delete_sitemap | Remove a sitemap from GSC | | switch_account | Re-authenticate with a different Google account (OAuth only) |

Data Sync

| Tool | Description | |------|-------------| | sync_search_data | Fetch all performance data into local SQLite cache. Incremental by default. Required before analysis tools. |

Analysis Tools

| Tool | Description | |------|-------------| | find_low_hanging_fruit | Find queries ranking 2-20 with high impressions but low CTR, scored by untapped potential | | detect_cannibalization | Detect queries ranking on 2+ URLs using HHI scoring with action recommendations | | find_trending_queries | Find queries with biggest growth/decline (period-over-period or year-over-year) | | find_trending_pages | Find pages with biggest growth/decline with impact scoring | | analyze_traffic_drop | Diagnose traffic drops across 5 views: site-level, GBP vs organic, groups, segments, brand vs non-brand | | get_group_performance | Aggregated metrics broken down by named groups with share percentages |

Group Management

| Tool | Description | |------|-------------| | create_group | Create a group with OR/AND/NOT regex rules for URL segments or query groups | | list_groups | List all groups, optionally filtered by dimension | | get_group | Get group details including rules | | update_group | Update group description and/or rules | | delete_group | Delete a group and its rules | | test_group | Test a group against cached data — match count, rate, samples |

Auto-Discovery

| Tool | Description | |------|-------------| | discover_query_groups | Auto-cluster queries using word overlap, n-gram similarity, and page co-occurrence | | promote_cluster_to_group | Convert a discovered cluster into a named group | | auto_segment_pages | Auto-create URL segment groups from page URL patterns | | auto_group_queries | Auto-create query groups: brand, topic n-grams, intent modifiers |

Resources

| URI | Description | |-----|-------------| | sites://list | All verified sites (auto-discovery) |

Prompts

| Name | Description | |------|-------------| | seo_performance_analysis | Guided full SEO review (queries, pages, devices, trends) | | index_coverage_check | Systematic URL indexation report |

Example Queries

  • "List my Search Console sites"
  • "Show top 20 queries for sc-domain:example.com last 7 days"
  • "Compare mobile vs desktop for https://example.com/"
  • "Check if https://example.com/new-page is indexed"
  • "Show sitemaps for sc-domain:example.com"
  • "Sync data for sc-domain:example.com and find low-hanging fruit"
  • "Detect keyword cannibalization on sc-domain:example.com"
  • "Show trending queries for sc-domain:example.com last 28 days"
  • "Auto-create query groups for sc-domain:example.com"

Architecture

src/
├── index.js                          # Entry: auth -> client -> db -> server -> stdio
├── server.js                         # McpServer factory
├── auth/
│   ├── index.js                      # Auth factory (auto-detects mode from env)
│   ├── service-account.js            # Service account key file auth
│   ├── oauth.js                      # Browser flow + token persistence + auto-recovery
│   ├── token-store.js                # ~/.gsc-mcp/tokens.json
│   └── setup.js                      # Standalone setup script
├── gsc/                              # Pure GSC API wrappers (no MCP knowledge)
│   ├── client.js
│   ├── sites.js
│   ├── search-analytics.js
│   ├── sitemaps.js
│   └── url-inspection.js
├── db/
│   ├── connection.js                 # SQLite setup with WAL mode
│   └── schema.js                     # Migrations
├── analysis/                         # SEO analysis engine (uses local SQLite)
│   ├── sync.js                       # GSC API -> SQLite incremental sync
│   ├── low-hanging-fruit.js          # Opportunity scoring
│   ├── cannibalization.js            # HHI-based detection
│   ├── trending.js                   # PoP / YoY trending queries & pages
│   ├── traffic-drop.js              # Multi-view drop diagnostics
│   ├── group-performance.js          # Group-level aggregation
│   ├── auto-segment.js              # Automatic URL segmentation
│   ├── auto-group.js                # Automatic query grouping
│   ├── shared.js                     # Shared SQL helpers
│   ├── groups/
│   │   ├── manager.js                # CRUD for groups + rules
│   │   ├── compiler.js               # OR/AND/NOT rule compilation
│   │   └── matcher.js                # Regex matching engine
│   └── semantic/
│       ├── discover.js               # Cluster discovery orchestrator
│       ├── clustering.js             # Connected components algorithm
│       ├── similarity.js             # Multi-signal similarity scoring
│       └── labeler.js                # Cluster naming
├── tools/
│   ├── definitions.js                # Core GSC tools (declarative)
│   ├── analysis-definitions.js       # Analysis tools (declarative)
│   ├── middleware.js                  # Rate limiting + error handling wrapper
│   ├── auth.js                       # switch_account tool
│   └── index.js                      # Registration loop
├── resources.js                      # sites://list resource
├── prompts.js                        # SEO analysis + index check prompts
└── utils/
    ├── logger.js                     # stderr-only (stdout = MCP protocol)
    ├── errors.js                     # Google API error -> MCP error
    ├── constants.js                  # Scopes, rate limits, defaults
    ├── rate-limiter.js               # Sliding window
    └── open-url.js                   # Cross-platform browser opener

Two-layer separation: gsc/ knows nothing about MCP. tools/ knows nothing about Google's API. analysis/ operates on local SQLite data. Each layer is independently testable.

Environment Variables

| Variable | Required | Default | Description | |----------|----------|---------|-------------| | GSC_AUTH_MODE | No | Auto-detected | oauth or service_account. Auto-detected from which credentials are set. | | GSC_OAUTH_CLIENT_ID | OAuth | — | OAuth client ID | | GSC_OAUTH_CLIENT_SECRET | OAuth | — | OAuth client secret | | GSC_OAUTH_REFRESH_TOKEN | No | — | Skip browser flow with a pre-existing token | | GSC_SERVICE_ACCOUNT_KEY_PATH | Service acct | — | Path to JSON key file | | GSC_API_SCOPES | No | webmasters.readonly | Override scopes (comma-separated) | | GSC_LOG_LEVEL | No | info | debug / info / warn / error | | GSC_TOKEN_PATH | No | ~/.gsc-mcp/tokens.json | Custom token storage path | | GSC_DB_PATH | No | ~/.gsc-mcp/data.db | Custom SQLite database path |

Debugging

Launch the MCP Inspector for interactive testing:

npm run inspect

Windows note: The inspect script uses bash. Run it from Git Bash, WSL, or replace with:

npx @modelcontextprotocol/inspector node src/index.js