gsc-doctor
# gsc-doctor
An MCP server for Google Search Console, built around one question that the existing tools answer badly: **why are my pages not indexed?**
Google exposes the Pages report in the Search Console UI, but there is no bulk API for it. You can only inspect URLs one at a time. Most Search Console MCP servers stop at thin one-tool-per-endpoint wrappers and leave you to do that fan-out by hand. `gsc-doctor` does it for you: it reads your sitemap, inspects every URL, groups the results by coverage state, and annotates each group with what the state actually means and what to do about it.
## Tools
| Tool | What it does |
| --- | --- |
| `diagnose_indexing` | Reads URLs from your sitemap (or an explicit list), inspects each, and returns a grouped coverage report with plain-language guidance. This is the reason the project exists. |
| `list_properties` | Lists the properties your service account can read, with permission levels. Run this first to get the exact `siteUrl` string. |
| `inspect_url` | Full URL Inspection result for a single page: index status, Google's chosen canonical, crawl details, mobile usability, rich results. |
| `search_analytics` | Clicks, impressions, CTR and average position, broken down by query, page, country, device, date or search appearance. |
| `list_sitemaps` | Every submitted sitemap with last download time, errors, warnings and URL counts. |
| `submit_sitemap` | Submits a sitemap. Only registered when `GSC_ALLOW_WRITES=true`. |
Beyond the raw coverage state, `diagnose_indexing` flags problems that are easy to miss in the UI:
- Pages where Google picked a different canonical than the one you declared
- `noindex` arriving via meta tag or `X-Robots-Tag` header
- robots.txt blocks
- Failed page fetches
- Indexed pages that no submitted sitemap references
## Setup
### 1. Enable the API and create a service account
1. Open the [Google Cloud Console](https://console.cloud.google.com/) and create (or pick) a project.
2. Enable the **Google Search Console API** for that project.
3. Go to **IAM & Admin > Service Accounts** and create a service account.
4. Under its **Keys** tab, add a key of type JSON and download it.
### 2. Grant it access to your property
Open Search Console, then **Settings > Users and permissions > Add user**. Paste the service account's `client_email` (it looks like `name@project.iam.gserviceaccount.com`) and give it **Full** or **Restricted** access.
This step is the one people forget. Without it every call returns HTTP 403.
### 3. Install
```bash
git clone https://github.com/gerald-guledew/gsc-doctor.git
cd gsc-doctor
npm install
npm run build
```
### 4. Register with Claude Code
```bash
claude mcp add gsc-doctor --env GSC_CREDENTIALS_PATH=/absolute/path/to/key.json -- node /absolute/path/to/gsc-doctor/dist/index.js
```
Or add it to your MCP client config directly:
```json
{
"mcpServers": {
"gsc-doctor": {
"command": "node",
"args": ["/absolute/path/to/gsc-doctor/dist/index.js"],
"env": {
"GSC_CREDENTIALS_PATH": "/absolute/path/to/key.json"
}
}
}
}
```
## Configuration
| Variable | Purpose |
| --- | --- |
| `GSC_CREDENTIALS_PATH` | Path to the service account JSON key. |
| `GSC_CREDENTIALS_JSON` | The key as an inline JSON string, for environments that inject secrets as env vars. Takes precedence over the path. |
| `GSC_ALLOW_WRITES` | Set to `true` to enable `submit_sitemap`. Off by default. |
If neither credential variable is set, the server falls back to Application Default Credentials.
## Usage
Ask your assistant things like:
- "Why aren't my pages indexed?"
- "Diagnose indexing for sc-domain:example.com"
- "Which queries drove impressions last month but almost no clicks?"
- "Is https://example.com/pricing/ indexed, and which canonical did Google choose?"
Property identifiers must match Search Console exactly: `sc-domain:example.com` for a domain property, `https://example.com/` for a URL-prefix property. Use `list_properties` if you are unsure.
## Security
- Writes are opt-in. With `GSC_ALLOW_WRITES` unset the server requests the read-only OAuth scope, so the token it holds is incapable of mutating your property even if something tried.
- Credentials never leave your machine. The server runs locally and talks only to Google's API.
- `.gitignore` already excludes the common service account key filename patterns. Keep your key out of the repo.
## Limitations
These are constraints of Google's API, not of this server:
- **No "Request Indexing".** The UI button has no API equivalent. The separate Indexing API officially accepts only `JobPosting` and `BroadcastEvent` markup. Tools that point it at ordinary pages are working outside Google's documented policy.
- **No bulk Pages report.** URL Inspection is per-URL, quota roughly 2,000 per day and 600 per minute per property. `diagnose_indexing` defaults to 50 URLs per run for that reason.
- **No Removals, manual actions or security issues.** Not exposed by the API at all.
- **No Core Web Vitals.** That data lives in the separate CrUX API.
- Search Console data lags real time by about three days, which is why `search_analytics` defaults its end date accordingly.
## License
MIT
TDQS
Scored across 5 tools
Each tool targets a distinct Search Console concern: property discovery, sitemap listing, bulk indexing analysis, single-URL inspection, and performance analytics. The potential overlap between diagnose_indexing and inspect_url is clearly separated by bulk versus single-page scope.
Most names follow a verb_noun snake_case pattern, with list_properties and list_sitemaps being perfectly parallel. diagnose_indexing uses a gerund object and search_analytics reads as a domain term rather than a clear verb_noun action, so the pattern is not perfectly uniform.
Five tools is a tight, well-scoped set for a diagnostic Search Console server. Each tool earns its place and there are no redundant or filler tools.
The read-only diagnostic workflow is covered end-to-end: discover the property, inspect sitemaps, analyze indexing at scale, drill into a single URL, and query performance metrics. Mutation tools would be out of scope for a 'doctor' server.