google-search-console
by DVeresov
README.md
# GSC MCP — Google Search Console для Claude
MCP-сервер и CLI-выгрузчик в одном файле. Тянет данные из Search Console:
запросы, страницы, позиции, сравнение периодов, брендовый/небрендовый сплит,
«быстрые победы» на позициях 5–20, статус индексации.
Два режима работы:
- **CLI** — запустили, получили папку CSV + `summary.md`. Работает сразу, без настройки Claude.
- **MCP** — подключается к Claude Desktop, можно спрашивать данные прямо в чате.
Начинать проще с CLI: выгрузили, положили в папку проекта, и я читаю файлы.
MCP подключается потом, когда нужны интерактивные срезы.
---
## 1. Установка
```bash
pip install -r requirements.txt
```
Нужен Python 3.10+.
---
## 2. Доступ к Google API
**2.1. Проект и API**
1. Откройте [console.cloud.google.com](https://console.cloud.google.com/), создайте проект (или возьмите существующий).
2. **APIs & Services → Library** → найдите **Google Search Console API** → **Enable**.
**2.2. Сервисный аккаунт**
3. **IAM & Admin → Service Accounts → Create service account**. Имя любое, роли на уровне проекта не нужны — жмите Done.
4. Откройте созданный аккаунт → вкладка **Keys** → **Add key → Create new key → JSON**. Файл скачается сам.
5. Положите его **вне папки репозитория** — например `~/.config/gsc-mcp/service-account.json`
(Windows: `%USERPROFILE%\.config\gsc-mcp\service-account.json`). Путь к нему скрипт берёт
из переменной окружения, поэтому ключ никогда не попадёт в git.
6. Откройте файл и скопируйте значение `client_email` — вида `имя@проект.iam.gserviceaccount.com`.
**2.3. Доступ в Search Console**
7. [search.google.com/search-console](https://search.google.com/search-console) → нужный ресурс → **Настройки → Пользователи и разрешения → Добавить пользователя**.
8. Вставьте `client_email`, права — **Полный доступ (Full)**.
> Для инструмента `inspect_url` (проверка индексации) полного доступа может не хватить —
> API иногда отвечает 403. Тогда добавьте сервисный аккаунт **владельцем ресурса**
> (Настройки → Пользователи и разрешения → Владельцы ресурса → Добавить владельца).
> На остальные инструменты это не влияет.
**2.4. Переменная окружения**
Windows (PowerShell, на текущую сессию):
```powershell
$env:GSC_SERVICE_ACCOUNT_FILE = "$env:USERPROFILE\.config\gsc-mcp\service-account.json"
```
Навсегда:
```powershell
setx GSC_SERVICE_ACCOUNT_FILE "%USERPROFILE%\.config\gsc-mcp\service-account.json"
```
macOS / Linux:
```bash
export GSC_SERVICE_ACCOUNT_FILE=~/.config/gsc-mcp/service-account.json
```
---
## 3. Проверка и первая выгрузка
```bash
# что вообще доступно этому сервисному аккаунту
python gsc_mcp.py list
```
Должно вывести строку вида `sc-domain:example.com siteFullUser`.
Пусто — значит шаг 2.3 не сработал, проверьте email.
```bash
# полная выгрузка за 180 дней
python gsc_mcp.py export ^
--site "sc-domain:example.com" ^
--days 180 ^
--out "D:\projects\gsc_export" ^
--brand "example.com,бренд,brand name"
```
`--site` пишется ровно так, как ресурс называется в GSC:
- домен-ресурс → `sc-domain:example.com`
- URL-префикс → `https://example.com/` (со слэшем на конце)
**Что появится в папке:**
| файл | что внутри |
|---|--------------------------------------------------------------------------|
| `summary.md` | Человекочитаемая сводка: итоги, динамика, бренд/небренд, быстрые решения |
| `queries.csv` | Все запросы: клики, показы, CTR, средняя позиция |
| `pages.csv` | Все страницы с трафиком |
| `query_page.csv` | Пары запрос ↔ страница — видно каннибализацию и нерелевантные посадочные |
| `striking_distance.csv` | Позиции 5–20 при ≥50 показов — самый дешёвый рост |
| `period_comparison.csv` | Текущий период против предыдущего той же длины |
| `countries.csv` | География — видно, есть ли зарубежный спрос |
| `devices.csv`, `dates.csv`, `date_device.csv` | Устройства и дневная динамика |
| `sitemaps.csv` | Карты сайта: отправлено против проиндексировано |
CSV в UTF-8 с BOM — Excel открывает кириллицу без плясок с кодировками.
Разовый срез без полной выгрузки:
```bash
python gsc_mcp.py query --site "sc-domain:example.com" --dimensions query,page --days 90 --limit 100
```
---
## 4. Подключение к Claude Desktop
Claude Desktop → **Настройки → Разработчик → Изменить конфигурацию**.
В `claude_desktop_config.json` добавьте (см. `claude_desktop_config.example.json`):
```json
{
"mcpServers": {
"google-search-console": {
"command": "python",
"args": ["D:\\projects\\gsc-mcp\\gsc_mcp.py"],
"env": {
"GSC_SERVICE_ACCOUNT_FILE": "C:\\Users\\USER\\.config\\gsc-mcp\\service-account.json",
"GSC_OUT_DIR": "D:\\projects\\gsc_export"
}
}
}
}
```
Пути в Windows — с двойными обратными слэшами. Если `python` не в PATH,
укажите полный путь к `python.exe`. Перезапустите Claude Desktop.
---
## 5. Инструменты MCP
| инструмент | зачем |
|---|---|
| `list_properties` | Список доступных ресурсов. Проверка, что доступы работают |
| `query` | Произвольный запрос: любые измерения, фильтры, тип поиска, выгрузка в CSV |
| `top_queries` | Топ запросов, с фильтром по стране и устройству |
| `top_pages` | Топ страниц по кликам |
| `queries_for_page` | По каким запросам показывается конкретная страница |
| `striking_distance` | Запросы на позициях 5–20 — где ссылки окупятся быстрее всего |
| `compare_periods` | Период к периоду, с дельтами по кликам и позициям |
| `branded_split` | Брендовый против небрендового трафика |
| `inspect_url` | Индексация, канонический URL, дата обхода, мобильная пригодность |
| `list_sitemaps` | Карты сайта: отправлено / проиндексировано / ошибки |
| `export_all` | Полная выгрузка в CSV прямо из чата |
Примеры формулировок в чате:
> Покажи топ-50 небрендовых запросов example.com за 6 месяцев по России
> Найди запросы на позициях 5–20 — с них начнём ссылочное
> Сравни последние 90 дней с предыдущими 90 по страницам
> Проверь, проиндексирована ли https://example.com/cases/
---
## 6. Что важно знать про данные
**Задержка.** Search Console финализирует данные с лагом. Скрипт по умолчанию
берёт период, заканчивающийся 3 дня назад — иначе последние дни выглядят
как провал трафика, которого не было.
**Глубина.** GSC хранит максимум 16 месяцев. `--days 480` — предел.
Если сайт подключён недавно, истории будет меньше — это видно по `dates.csv`.
**Только Google.** В GSC нет данных Яндекса, а Яндекс — около 70% поиска в РФ.
Для полной картины baseline нужна выгрузка из Яндекс.Вебмастера отдельно.
Эти цифры не суммируются и не сравниваются напрямую: разные методики подсчёта показов.
**Скрытые запросы.** Google прячет низкочастотные запросы ради приватности.
Сумма кликов по `queries.csv` будет меньше общей цифры в интерфейсе — это норма,
а не ошибка выгрузки.
**Квоты.** API лимитирован по числу запросов. Скрипт делает повторы с
экспоненциальной задержкой при 429/503, так что большие выгрузки просто идут
дольше, а не падают.
---
## 7. Если что-то не работает
| симптом | причина |
|---|---|
| `list` возвращает пусто | `client_email` не добавлен в Search Console, или добавлен в другой ресурс (домен vs URL-префикс — это разные ресурсы) |
| 403 на `searchanalytics` | Не включён Google Search Console API в проекте GCP |
| 403 только на `inspect_url` | Нужны права владельца ресурса |
| `No credentials` | Не выставлена `GSC_SERVICE_ACCOUNT_FILE`; после `setx` нужен новый терминал |
| Пустые CSV при живом сайте | Неверный формат `--site`. Сверьтесь с выводом `python gsc_mcp.py list` — копируйте оттуда дословно |
| Сервер не виден в Claude | Проверьте путь к `python.exe` и двойные слэши в JSON, перезапустите приложение |
---
## 8. Самопроверка
`_selftest.py` гоняет весь код против поддельного API — без сети и без ключей.
Полезно после любой правки:
```bash
python _selftest.py
```