Skip to main content
Glama

ga4-mcp-worker

«Только чтение» — MCP-сервер Google Analytics 4, работающий на Cloudflare Workers, чтобы коллеги могли запрашивать GA4 через Claude без каких-либо локальных установок — без Python, без gcloud, без ADC-файла, а с этой версии ещё и без общего пароля. Подключение теперь означает: нажать «Connect», войти со своим аккаунтом Google и задавать вопросы по GA4 от своего имени.

Он повторяет набор инструментов официального googleanalytics/google-analytics-mcp stdio-сервера, но вызывает REST API Google Analytics напрямую, потому что клиентские библиотеки Google не работают в среде выполнения Workers.

Сначала прочтите это: docs/IMPLEMENTATION-NOTES.md § Что проверено, а что нет. Сквозная проверка вживую уже есть, но несколько участков (endpoints v1alpha, пагинация) пока покрыты только фикстурами.

Режим авторизации: персональный OAuth

Каждый сотрудник входит под своим аккаунтом Google. Никакого общего секрета и никакого единого учётного Google-токена, на который полагаются все, — нет. Полный дизайн и отличие от отменённого режима общего секрета см. в PRODUCTION.md § 1 и docs/PRODUCTION-PART2.md § 8. Вход ограничен аккаунтами Google @zuddl.com (ALLOWED_EMAIL_DOMAIN в wrangler.toml).

GOOGLE_CLIENT_ID и GOOGLE_CLIENT_SECRET по-прежнему обязательны — Google требует, чтобы каждое приложение, запрашивающее данные пользователя, было зарегистрировано, и эти два значения и есть регистрация, они задаются один раз при деплое. Исчезли вручную сгенерированный refresh-токен и пароль, который коллеги вводили раньше.


Документация

Файл

Назначение

SETUP-GUIDE.md (+ часть 2)

Первый деплой, объясняющийся с нуля — без предварительных знаний об OAuth. Создание приложения Google, деплой, тестирование, подключение Claude. Начните тут.

PRODUCTION.md (+ часть 2)

Модель учётных данных, мониторинг, квоты GA4, ротация секретов, локальная разработка, runbook-процедуры, чек-лист безопасности, внутреннее устройство OAuth. Читать перед масштабным развёртыванием.

docs/IMPLEMENTATION-NOTES.md

Подводные камни, которые эта реализация корректно обходит, что проверено и что нет, а также стоимость эксплуатации.

src/index.ts

MCP-сервер: инструменты, fetch-хелперы, нормализатор, роутер. Обильно прокомментирован.

src/google-oauth.ts

Обработчик «входа через Google» — /authorize и /callback. Обильно прокомментирован.

wrangler.toml

Конфигурация воркера. Обратите внимание на nodejs_compat — см. частые ловушки.

.dev.vars.example

Шаблон для локальной разработки. Скопируйте в .dev.vars (в git не попадает).


Related MCP server: GA4 MCP Server

Наши свойства GA4

Property ID

Название

Measurement ID

Статус

314138239

Новое свойство GA4 веб-сайта zuddl

G-JWBQ2Z84QF

Каноническое — используйте это, если не указано иное.

260479909

legacy

—

Устаревшее. Только исторические данные; для текущей отчётности не использовать.

328977581

legacy

—

Устаревшее. Только исторические данные; для текущей отчётности не использовать.

Сервер не привязан к property: каждый инструмент принимает property_id, и это может быть как 314138239, так и "properties/314138239". Если значение не передано, используется DEFAULT_PROPERTY_ID из wrangler.toml, который указывает на каноническое свойство, чтобы коллегам не приходилось запоминать номер. Вызовите get_account_summaries, чтобы перечислить всё, что реально доступно данным учётным данным.


Инструменты (9)

Инструмент

Метод и endpoint

Назначение

run_report

POST analyticsdata.googleapis.com/v1beta/properties/{id}:runReport

Рабочая лошадка. Историческая отчётность. Полный набор параметров.

run_realtime_report

POST .../v1beta/properties/{id}:runRealtimeReport

Последние ~30 минут. Отдельная и более компактная схема.

run_funnel_report

POST .../v1alpha/properties/{id}:runFunnelReport

Upорядоченные шаги и отсев пользователей.

run_conversions_report

POST .../v1alpha/properties/{id}:runReport

Конверсии, расходы на рекламу, ROAS, атрибуционное моделирование. Ограниченный список полей.

get_custom_dimensions_and_metrics

GET .../v1beta/properties/{id}/metadata

Пользовательские поля с доступным для запросов apiName. Вызывать перед использованием кастомных полей.

get_account_summaries

GET analyticsadmin.googleapis.com/v1beta/accountSummaries

Всё, что эти учётные данные могут прочитать. Без аргументов.

get_property_details

GET .../v1beta/properties/{id}

Часовой пояс, валюта, уровень обслуживания. Часовой пояс объясняет расхождения дат.

list_property_annotations

GET .../v1alpha/properties/{id}/reportingDataAnnotations

Датированные заметки, объясняющие всплески и падения.

list_google_ads_links

GET .../v1beta/properties/{id}/googleAdsLinks

Связанные аккаунты Google Ads. Подтверждает, могут ли метрики стоимости рекламы содержать данные

run_report принимает полный официальный набор параметров: property_id, date_ranges (это список, поэтому сравнение периодов можно делать в одном запросе), dimensions, metrics, dimension_filter, metric_filter, order_bys, limit, offset, currency_code, return_property_quota. run_realtime_report принимает ту же форму, за вычетом date_ranges и currency_code.

Описания инструментов намеренно длинные — они содержат рабочие примеры для каждой формы фильтра и являются единственным местом, где модель узнает формат запроса. Редактирование их следует рассматривать как изменение поведения программы.


Endpoint’s

Endpoint

Авторизация

Назначение

POST /mcp

OAuth bearer-токен

MCP-соединение (Streamable HTTP). /sse нет.

GET /authorize, POST /tokens, POST /register

—

OAuth-эндпоинты, реализованные через @cloudflare/workers-oauth-provider.

GET /callback

—

Сюда Google перенаправляет после входа. Не предназначен для непосредственного открытия человеком.

GET /health

нет

Проверка состояния. 200 {"status":"ok","auth":"oauth", ...} или 503 с деталями. См. пояснение ниже — здесь это значит меньше, чем могло бы значить при режиме общего секрета. Ничего не утекает. На точкиhealth можно установить монитор доступности.

GET /

нет

простой текстовый статус-баннер, показывающий текущий режим авторизации.

Всё остальное возвращает 404.

/health в OAuth-режиме доказывает меньше. Нет единого общего секрета, который можно было бы проверить, поэтому 200 подтверждает только то, что регистрация приложения настроена и хранилище пользовательских разрешений (OAUTH_KV) доступно, а не что вход конкретного человека всё ещё действителен. Грант отдельного пользователя может истечь или быть отозванным, в то время как /health остаётся зелёным. Это присуще персональной авторизации, а не недостаток.

Worker пишет одну строку журнала на каждый MCP-запрос, каждую отклонённую попытку авторизации, каждую ошибку инструмента и каждое срабатывание проверки health, плюс события уровня OAuth (oauth_authorise_redirect, oauth_authorised, oauth_domain_rejected и т. д.). Никакие токенные материалы не логируются никогда. Все запросы к Google API отправляют пользовательский User-Agent (ga4-mcp-server /1.0.0 (+cloudflare-workers)), чтобы использование квот было attributable.


Защита режима «только чтение»

Три независимых уровня, все на месте:

  1. OAuth-scope — каждый токен (старый общий или новый персональный) запрашивается только с https://www.googleapis.com/auth/analytics.readonly и ничем иным (плюс openid/email для идентификации в OAuth-режиме — см. src/google-oauth.ts, а эти разрешения не дают доступа к данным). Записи Google отклонит на своей стороне. Это настоящая гарантия. В SETUP-GUIDE.md на шагах показана проверка через tokeninfo.

  2. Список разрешённых эндпоинтов — except regex, которое проверяется в обоих fetch-хелперах до любого сетевого вызова. Будущая правка, добавляющая пишущий эндпоинт, вызовет исключение, а не уйдёт по сети.

  3. Нет мутирующих глаголов — в коде нет PATCH, PUT или DELETE. Вызовов fetch ровно три: выдача токена (POST), gaGet (GET) и gaPost (POST).

:runReport, :runRealtimeReport и :runFunnelReport — это HTTP POST, но, по сути, запросы: тело должно нести описание отчёта, потому что оно слишком велико для строки запроса. В GA4 ничего не создаётся и не изменяется.


Быстрые команды

npm install
npm run typecheck && npm run dry-run
npm run deploy
npm run tail
curl -s https://ga4-mcp-worker.YOUR-SUBDOMAIN.workers.dev/health

Задайте два секрета, которые нужны в любом режиме авторизации (вставляйте интерактивно — при передачи через пайп значения ломаются):

npx wrangler secret put GOOGLE_CLIENT_ID
npx wrangler secret put GOOGLE_CLIENT_SECRET

Подключение из Claude Code — заголовки не нужны, так как вход происходит через браузер:

claude mcp add --transport http --scope user ga4 https://ga4-mcp-worker.YOUR-SUBDOMAIN.workers.dev/mcp

Затем в интерактивной сессии claude выполните /mcp, выберите ga4 и войдите с помощью Google.


Дополнительно

  • Подводные камни, покрытие тестами и эксплуатационные расходы: docs/IMPLEMENTATION-NOTES.md

  • Пошаговое руководство по первому развертыванию: SETUP-GUIDE.md → часть 2

  • Укрепление безопасности, мониторинг и руководство по OAuth: PRODUCTION.md → часть 2

Related MCP Connectors

Related MCP Servers

  • A
    license
    A
    quality
    B
    maintenance
    Connects Google Analytics 4 data to Claude, Cursor and other MCP clients, enabling natural language queries of website traffic, user behavior, and analytics data with access to 200+ GA4 dimensions and metrics.
    10
    1,541 PyPI
    243
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Connects MCP clients like Claude Desktop to Google Analytics 4 Data API, enabling natural language queries for reports, top pages, traffic sources, conversions, realtime users, and period comparisons.
    7
    48 PyPI
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    Enables querying Google Analytics 4 data using natural language through MCP clients like Claude and Cursor, supporting 200+ dimensions and metrics for traffic, user behavior, and e-commerce analysis.
    MIT