Skip to main content
Glama
Shin-sibainu

Google Search Console MCP Server

by Shin-sibainu
README.md
# Google Search Console MCP Server

A Model Context Protocol (MCP) server that provides programmatic access to Google Search Console API data through Claude Code and Cursor.

## Quick Start

**New to this MCP server?** Jump to [Step-by-Step Setup Guide](#step-by-step-setup-guide) for complete instructions.

## Features

- ๐Ÿ” **List Sites** - Get all Search Console properties you have access to
- ๐Ÿ“Š **Search Analytics** - Query search performance data with flexible filtering
- ๐Ÿ—บ๏ธ **Sitemap Information** - Retrieve sitemap status and indexing statistics
- ๐Ÿ”Ž **URL Inspection** - Check detailed indexing status of specific URLs
- ๐Ÿ“ค **Submit URL for Indexing** - Request Google to index or remove URLs
- ๐Ÿ“ˆ **Compare Periods** - Compare search performance between two time periods
- ๐Ÿ›ก๏ธ **Robust Error Handling** - Detailed error messages with actionable guidance
- ๐Ÿ”„ **Automatic Retry Logic** - Handles rate limits and transient failures
- โœ… **Input Validation** - Validates all parameters before API calls

## Prerequisites

Before using this MCP server, you need:

### 1. Google Search Console

- Site registered in Search Console
- Site ownership verified
- Access to the Search Console property you want to query

### 2. Google Cloud Platform (GCP)

- A GCP project (free tier is sufficient)
- **Google Search Console API** enabled
- **OAuth 2.0 Client ID** credentials (Desktop app type)
- (Optional) **Indexing API** enabled if you want to use `submit_url_for_indexing`

๐Ÿ’ก **Note**: You only need to set up GCP once. The `CLIENT_ID` and `CLIENT_SECRET` are reusable across multiple sites in your Search Console.

## Setup

### 1. Configure Claude Code

Create `.mcp.json` in your project root:

```json
{
  "mcpServers": {
    "google-search-console": {
      "command": "npx",
      "args": ["-y", "-p", "google-search-console-mcp-server", "google-search-console-mcp"],
      "env": {
        "GOOGLE_CLIENT_ID": "your-client-id.apps.googleusercontent.com",
        "GOOGLE_CLIENT_SECRET": "your-client-secret",
        "GOOGLE_REFRESH_TOKEN": "your-refresh-token"
      }
    }
  }
}
```

โš ๏ธ **Important**: The `args` must include all three parts:
1. `"-y"` - Auto-confirm npx prompt
2. `"-p", "google-search-console-mcp-server"` - Package name
3. `"google-search-console-mcp"` - Executable name (different from package name!)

๐Ÿ’ก **Note**: `GOOGLE_REDIRECT_URI` defaults to `http://localhost:8080` and doesn't need to be specified unless you want to use a different port.

### 2. Get Google OAuth Credentials

๐Ÿ’ก **Tip**: You can use an existing OAuth 2.0 Client ID from other services (Supabase, Firebase, etc.) or create a new one.

1. Go to [Google Cloud Console](https://console.cloud.google.com/)
2. **Create or select a project**
3. **Enable APIs**:
   - Navigate to "APIs & Services" โ†’ "Enable APIs and Services"
   - Search and enable **"Google Search Console API"**
   - (Optional) Enable **"Indexing API"** if you want to use `submit_url_for_indexing`
4. **Create or use existing OAuth 2.0 Client ID**:
   - Go to "APIs & Services" โ†’ "Credentials"
   - **Option A**: Use existing OAuth 2.0 Client (skip to step 5)
   - **Option B**: Create new โ†’ "OAuth 2.0 Client ID" โ†’ Application type: **Desktop app**
5. **Configure Authorized redirect URIs**:
   - Click on the OAuth 2.0 Client ID
   - Under "Authorized redirect URIs", click "Add URI"
   - Add: `http://localhost:8080` (no trailing slash!)
   - Click "Save"
6. โš ๏ธ **IMPORTANT: Add test users** (if OAuth consent screen is in Testing mode):
   - Go to "OAuth consent screen"
   - Check the "Publishing status" - if it shows **"Testing"**:
   - Scroll to "Test users" section
   - Click "+ ADD USERS"
   - Add your Google account email (the one you'll use to authenticate)
   - Click "Save"
   - **Without this step, you'll get `access_denied` errors!**

๐Ÿ’พ **Save your credentials**: Copy the `CLIENT_ID` and `CLIENT_SECRET`. You'll need them in the next step.

### 3. Get Refresh Token

Run the interactive setup command:

```bash
npx -y -p google-search-console-mcp-server google-search-console-mcp-setup
```

You'll be prompted to enter:
- `GOOGLE_CLIENT_ID` (from step 2)
- `GOOGLE_CLIENT_SECRET` (from step 2)
- `GOOGLE_REDIRECT_URI` (press Enter for default: `http://localhost:8080`)

A browser window will open for authentication. After authorizing, the command will output the complete `.mcp.json` configuration with all three credentials including the `GOOGLE_REFRESH_TOKEN`.

Copy the configuration and paste it into your `.mcp.json`, then reload Claude Code window.

## Usage

Once configured, you can use the tools in Claude Desktop or Claude Code:

```
Show me my Google Search Console sites
```

or

```
Get search performance data for example.com for the last 7 days
```

## Available Tools

### 1. `list_sites`

Get all Search Console sites you have access to.

**Parameters**: None

**Example**:

```
Search Consoleใฎใ‚ตใ‚คใƒˆไธ€่ฆงใ‚’ๆ•™ใˆใฆ
```

### 2. `get_analytics`

Query search performance data for a specified date range.

**Parameters**:

- `siteUrl` (required): Site URL (e.g., "https://example.com/")
- `startDate` (required): Start date (YYYY-MM-DD)
- `endDate` (required): End date (YYYY-MM-DD)
- `dimensions` (optional): Array of dimensions ["query", "page", "country", "device", "searchAppearance"]
- `rowLimit` (optional): Max rows (default: 100, max: 25000)
- `startRow` (optional): Starting row for pagination

**Example**:

```
example.comใฎ้ŽๅŽป7ๆ—ฅ้–“ใฎใƒˆใƒƒใƒ—ใ‚ฏใ‚จใƒชใ‚’ๅ–ๅพ—ใ—ใฆ

example.comใฎ2025ๅนด1ๆœˆ1ๆ—ฅใ‹ใ‚‰1ๆœˆ31ๆ—ฅใพใงใฎใ€
ใƒšใƒผใ‚ธๅˆฅใจใƒ‡ใƒใ‚คใ‚นๅˆฅใฎใƒ‘ใƒ•ใ‚ฉใƒผใƒžใƒณใ‚นใ‚’500ไปถๅ–ๅพ—ใ—ใฆ
```

### 3. `get_sitemaps`

Retrieve sitemap information for a site.

**Parameters**:

- `siteUrl` (required): Site URL

**Example**:

```
example.comใฎใ‚ตใ‚คใƒˆใƒžใƒƒใƒ—ๆƒ…ๅ ฑใ‚’็ขบ่ชใ—ใฆ
```

### 4. `inspect_url`

Inspect the indexing status of a specific URL.

**Parameters**:

- `siteUrl` (required): Site URL (e.g., "https://example.com/")
- `inspectionUrl` (required): Full URL to inspect

**Example**:

```
https://example.com/blog/article ใฎใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚น็Šถๆ…‹ใ‚’ๆคœๆŸปใ—ใฆ
```

### 5. `submit_url_for_indexing`

Submit a URL to Google for indexing or request URL removal using the Indexing API.

**Parameters**:

- `url` (required): Full URL to submit (e.g., "https://example.com/page")
- `type` (optional): Notification type - "URL_UPDATED" (default) or "URL_DELETED"

**Example**:

```
https://example.com/new-article ใ‚’ใ‚คใƒณใƒ‡ใƒƒใ‚ฏใ‚นใซ้€ไฟกใ—ใฆ

https://example.com/old-page ใ‚’ๅ‰Š้™ค็”ณ่ซ‹ใ—ใฆ๏ผˆtype: URL_DELETED๏ผ‰
```

**Note**: Requires Indexing API to be enabled in Google Cloud Console and the `https://www.googleapis.com/auth/indexing` scope.

### 6. `compare_periods`

Compare search performance metrics between two time periods (e.g., this week vs last week).

**Parameters**:

- `siteUrl` (required): Site URL (e.g., "https://example.com/")
- `currentStartDate` (required): Current period start date (YYYY-MM-DD)
- `currentEndDate` (required): Current period end date (YYYY-MM-DD)
- `previousStartDate` (required): Previous period start date (YYYY-MM-DD)
- `previousEndDate` (required): Previous period end date (YYYY-MM-DD)
- `dimensions` (optional): Array of dimensions to group by
- `rowLimit` (optional): Max rows (default: 100, max: 25000)

**Example**:

```
Compare this week vs last week performance for example.com

Compare query performance for example.com between January 2025 and December 2024
(currentStartDate: 2025-01-01, currentEndDate: 2025-01-31,
 previousStartDate: 2024-12-01, previousEndDate: 2024-12-31,
 dimensions: ["query"])
```

## API Limits

- **Daily quota**: 2,000 requests per project
- **Per 100 seconds**: 600 requests
- **Data availability**: Up to 16 months of historical data
- **Data latency**: Typically 2-3 days

## Error Handling & Retry Logic

This MCP server includes comprehensive error handling:

### Automatic Retries

- **Rate Limiting (429)**: Automatically retries with exponential backoff
- **Server Errors (5xx)**: Retries up to 3 times with increasing delays
- **Transient Failures**: Smart retry logic with jitter to prevent thundering herd

### Input Validation

All tools validate inputs before making API calls:

- **Site URL**: Validates URL format and structure
- **Dates**: Validates YYYY-MM-DD format and logical date ranges
- **Row Limits**: Ensures limits are within API constraints (1-25,000)

### Detailed Error Messages

Error messages include:

- Clear description of what went wrong
- HTTP status code
- Actionable steps to resolve the issue

Example:

```
Access denied for list sites (403)
Verify your authentication credentials and ensure you have access to this Search Console property.
You may need to add your account as a test user in Google Cloud Console.
```

## Troubleshooting

### Setup Issues

#### "invalid_client" Error During Authentication

**Problem**: When running the setup command, you get `Error during authentication: invalid_client`.

**Causes & Solutions**:

1. **CLIENT_ID and CLIENT_SECRET mismatch**
   - Verify they're from the same OAuth 2.0 Client in GCP Console
   - Copy them again directly from Google Cloud Console

2. **Missing `http://localhost:8080` in Authorized redirect URIs**
   - If you're reusing OAuth credentials from other services (Supabase, Firebase, etc.)
   - **Solution**: Add `http://localhost:8080` to "Authorized redirect URIs" in the OAuth 2.0 Client settings
   - You can have multiple redirect URIs (e.g., `https://xxx.supabase.co/auth/v1/callback` AND `http://localhost:8080`)

3. **CLIENT_SECRET was regenerated**
   - If you reset the secret in GCP Console, use the new one
   - Old secrets become invalid immediately

#### "could not determine executable to run" Error

**Problem**: `npx google-search-console-mcp-server` fails with "could not determine executable to run".

**Solution**: The package name and executable name are different. Use the correct `.mcp.json` configuration:

```json
{
  "mcpServers": {
    "google-search-console": {
      "command": "npx",
      "args": ["-y", "-p", "google-search-console-mcp-server", "google-search-console-mcp"],
      "env": { ... }
    }
  }
}
```

#### MCP Server Shows "โœ˜ failed" in Claude Code

**Debugging steps**:

1. **Check the error details**:
   - In Claude Code's MCP status screen, press Enter on the failed server
   - Scroll down to see the stderr (error output)

2. **Test manually**:
   ```bash
   cd your-project-directory
   export GOOGLE_CLIENT_ID="your-id"
   export GOOGLE_CLIENT_SECRET="your-secret"
   export GOOGLE_REFRESH_TOKEN="your-token"
   npx -y google-search-console-mcp-server
   ```

3. **Common causes**:
   - **Search Console API not enabled**: Enable it in GCP Console
   - **Wrong credentials**: Verify CLIENT_ID, CLIENT_SECRET, and REFRESH_TOKEN
   - **Expired token**: Run the setup command again to get a new REFRESH_TOKEN
   - **npx cache issue**: Clear npx cache: `rm -rf ~/.npm/_npx`

4. **Reload Claude Code**: After fixing `.mcp.json`, reload the window (Ctrl/Cmd + Shift + P โ†’ "Developer: Reload Window")

### Runtime Errors

#### "Missing required environment variables"

Make sure your `.mcp.json` file has all three environment variables: `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET`, and `GOOGLE_REFRESH_TOKEN`.

#### "redirect_uri_mismatch"

Ensure `http://localhost:8080` (no trailing slash!) is added to **Authorized redirect URIs** in the OAuth 2.0 Client settings in Google Cloud Console.

#### "Error 403: access_denied"

1. โš ๏ธ **Most common cause - OAuth consent screen is in Testing mode**:
   - Go to "OAuth consent screen" in GCP Console
   - If "Publishing status" shows **"Testing"**, you MUST add your email to "Test users"
   - Click "+ ADD USERS" in the "Test users" section
   - Add your Google account email (the one you're authenticating with)
   - Click "Save"
   - **This is the #1 cause of access_denied errors!**
2. **API not enabled**: Enable "Google Search Console API" in GCP Console
3. **No access to the site**: Verify you have access to the Search Console property you're querying

#### "Invalid site URL format"

Site URLs must be complete URLs like:

- `https://example.com/` (for URL-prefix properties)
- `sc-domain:example.com` (for domain properties)

#### "Date range too old"

Search Console data is only available for the last 16 months.

#### "Rate limit exceeded"

The tool will automatically retry with backoff. If you continue to hit limits:

- Wait a few minutes between requests
- Reduce `rowLimit` in analytics queries
- API Limits: 2,000 requests/day, 600 requests/100 seconds

#### Token Expired

If you see authentication errors, your refresh token may have expired. Re-run the authentication setup:

```bash
npx -y -p google-search-console-mcp-server google-search-console-mcp-setup
```

Copy the new `GOOGLE_REFRESH_TOKEN` to your `.mcp.json`.

## Development

### Build

```bash
npm run build
```

### Watch Mode

```bash
npm run dev
```

### Re-authenticate

```bash
node build/auth/setup-auth.js
```

## Project Structure

```
src/
โ”œโ”€โ”€ index.ts                 # MCP server entry point
โ”œโ”€โ”€ auth/
โ”‚   โ”œโ”€โ”€ google-auth.ts       # OAuth 2.0 client
โ”‚   โ””โ”€โ”€ setup-auth.ts        # Authentication CLI
โ”œโ”€โ”€ tools/
โ”‚   โ”œโ”€โ”€ list-sites.ts        # List sites tool
โ”‚   โ”œโ”€โ”€ get-analytics.ts     # Search analytics tool
โ”‚   โ”œโ”€โ”€ get-sitemaps.ts      # Sitemap info tool
โ”‚   โ”œโ”€โ”€ inspect-url.ts       # URL inspection tool
โ”‚   โ”œโ”€โ”€ submit-url.ts        # Submit URL for indexing
โ”‚   โ””โ”€โ”€ compare-periods.ts   # Compare time periods
โ”œโ”€โ”€ types/
โ”‚   โ””โ”€โ”€ index.ts             # Type definitions
โ””โ”€โ”€ utils/
    โ””โ”€โ”€ error-handler.ts     # Error handling & validation
```

## Security Notes

- Never commit `.env` or `.mcp.json` files to version control
- Keep your refresh token secure
- Use readonly scope (`webmasters.readonly`) when possible
- Refresh tokens provide persistent access - store them securely

## License

MIT

## Contributing

Contributions are welcome! Please feel free to submit issues or pull requests.

---

## Resources

- [Google Search Console API Documentation](https://developers.google.com/webmaster-tools/search-console-api-original)
- [Model Context Protocol](https://modelcontextprotocol.io/)
- [Claude Code Documentation](https://docs.claude.com/claude-code)