Skip to main content

GA4 MCP server with full Admin API read/write access

Project description

ga-mcp-full

A Model Context Protocol server that exposes the full Google Analytics 4 surface — both the Admin API (property & configuration management) and the Data API (reporting) — to MCP-compatible clients such as Claude Code, Claude Desktop, Cursor, Zed, and anything else that speaks stdio MCP.

Thirty-plus tools cover:

  • Property management — create, list, update, delete, archive, retention settings
  • Custom dimensions & metrics — create, list, update, archive
  • Audiences — create, list, archive
  • Key events — CRUD
  • Data streams — CRUD
  • Linked accounts — Firebase, BigQuery, Google Ads
  • Measurement Protocol secrets — CRUD
  • Reporting — standard reports, realtime reports, metadata discovery

Install

The preferred install is via the Robworks Claude Code Plugins marketplace:

pip install ga-mcp-full  # once published to PyPI; for now use: pip install -e /path/to/ga-mcp-full
claude plugin marketplace add ringo380/robworks-claude-code-plugins
claude plugin install ga-mcp-full@robworks-claude-code-plugins

Why a two-step install: the plugin just wraps the Python CLI — it does not bundle the Python interpreter. You install the CLI once (pip), then the plugin registers the MCP server, slash commands, and SessionStart hook with Claude Code.

Alternative: direct from the plugin repo

If you prefer to install the plugin directly from this repo without going through the Robworks marketplace:

pip install -e /path/to/ga-mcp-full
claude plugin marketplace add ringo380/ga-mcp-full   # uses the plugin repo as its own marketplace (once marketplace.json is added here)
claude plugin install ga-mcp-full

Note: this repo currently only ships a plugin.json, not a marketplace.json. Use the Robworks marketplace above as the install path.

Alternative: standalone MCP (no Claude Code plugin)

pip install -e /path/to/ga-mcp-full

Then add to your MCP client config. Example for Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "ga-mcp-full": {
      "command": "ga-mcp-full",
      "args": ["serve"]
    }
  }
}

For Cursor, Zed, or other clients, consult their MCP integration docs — the server command and arg pair is always ga-mcp-full serve.

Requirements

  • Python 3.10 or newer
  • Google Analytics 4 property you have Editor or Administrator access to (the scope requested is analytics.edit)

That's it — no Google Cloud Console visit needed for the default install. A public Desktop OAuth client is bundled with the package.

Authentication

The server resolves credentials in this order (see ga_mcp/auth.py):

  1. Cached OAuth tokens at ~/.config/ga-mcp/credentials.json. Refresh tokens renew expired access tokens silently.
  2. Application Default Credentials — from gcloud auth application-default login.
  3. Fresh OAuth browser flow — using GA_MCP_CLIENT_ID + GA_MCP_CLIENT_SECRET env vars, ~/.config/ga-mcp/client_secrets.json, or the bundled public Desktop client (in that order).

First-time setup (majority path)

  1. Install: pip install ga-mcp-full (or pip install -e . for a dev checkout).
  2. Run /ga-mcp-full:auth-login in Claude Code (or ga-mcp-full auth login at the shell).
  3. Approve the analytics.edit scope when the browser opens.
  4. The refresh token lands in ~/.config/ga-mcp/credentials.json (mode 0600).

The OAuth flow uses PKCE (S256) and binds the loopback redirect to a random free port on 127.0.0.1, per Google's installed-app OAuth guidance. No prior Google Cloud Console client configuration is required.

You'll see an "unverified app" warning — this is expected for now

The bundled OAuth client is a real production app owned by this project, but Google's brand verification for sensitive scopes (like analytics.edit) takes several business days the first time. Until verification clears, the consent screen displays:

Google hasn't verified this app The app is requesting access to sensitive info in your Google Account…

To proceed: click AdvancedGo to ga-mcp-full (unsafe). The warning is Google's default posture for unverified apps — it doesn't indicate anything is actually wrong with the tool. Review the privacy policy if you want to know exactly what data is accessed (it's all local, per-user, per the scope you approved). The warning will disappear once Google's review completes.

Users who want to avoid the warning entirely can use their own OAuth client — see Power users below.

Power users: use your own OAuth client

If you want quota isolation, a custom consent screen, or to avoid the verification-window warning:

  1. Create an OAuth 2.0 Client ID of type Desktop app at Google Cloud Console → APIs & Services → Credentials in a project where the Google Analytics Admin API and Data API are enabled.
  2. Override the bundled defaults via either:
    • Env vars in your shell profile: GA_MCP_CLIENT_ID=... and GA_MCP_CLIENT_SECRET=...
    • Or drop the downloaded JSON at ~/.config/ga-mcp/client_secrets.json (mode 0600).
  3. Run ga-mcp-full auth login as usual — the env vars / legacy JSON take precedence over the bundled client.

Already using gcloud?

If you have gcloud auth application-default login --scopes=https://www.googleapis.com/auth/analytics.edit configured, the server auto-detects ADC and skips OAuth entirely. No further setup needed.

Why not the /mcp Authenticate button?

Claude Code's /mcp menu OAuth flow only applies to HTTP-transport MCP servers per the MCP 2025-06-18 authorization spec (stdio servers "SHOULD NOT" use it). ga-mcp-full is stdio, so auth is handled out-of-band via the bundled slash commands and the SessionStart hook. An HTTP transport mode that participates in the /mcp OAuth flow is a possible future addition.

Bundled Claude Code components

Slash commands

Command Purpose
/ga-mcp-full:setup Guided first-run — install the CLI (if needed) and run the browser login
/ga-mcp-full:auth-login Run the OAuth browser flow and cache tokens
/ga-mcp-full:auth-logout Remove cached OAuth credentials
/ga-mcp-full:auth-status Show current auth state and credential source

SessionStart hook

hooks/scripts/ensure-auth.sh runs at the start of every Claude Code session (startup|resume|clear|compact). It is non-blocking and only writes to stderr — if authentication is missing, it prints a one-line hint pointing at /ga-mcp-full:setup; it never exits non-zero and never blocks the session.

MCP tools

After plugin install the server registers as plugin:ga-mcp-full:ga-mcp-full and tools surface as mcp__ga-mcp-full__*. Browse them with /mcp inside Claude Code.

CLI reference

ga-mcp-full                 # Start the MCP server over stdio
ga-mcp-full serve           # Same as above (explicit)
ga-mcp-full auth login      # OAuth browser flow; caches refresh token
ga-mcp-full auth logout     # Clear cached credentials
ga-mcp-full auth status     # Show current auth state and credential source
ga-mcp-full --help          # Full help

Development

git clone https://github.com/ringo380/ga-mcp-full.git
cd ga-mcp-full
python -m venv .venv && source .venv/bin/activate
pip install -e .
ga-mcp-full auth status

Project layout:

ga_mcp/
├── server.py          # MCP server entrypoint
├── cli.py             # CLI dispatcher
├── auth.py            # OAuth + credential resolution
└── tools/
    ├── admin/         # 11 modules — property, custom dimensions/metrics, audiences, etc.
    ├── reporting/     # 3 modules — core, realtime, metadata
    └── utils.py

Public Claude Code artifacts: .claude-plugin/plugin.json, .mcp.json, commands/, hooks/.

Issues and PRs welcome at https://github.com/ringo380/ga-mcp-full/issues.

Troubleshooting

Symptom Fix
"Google hasn't verified this app" on the consent screen Expected during brand verification. Click AdvancedGo to ga-mcp-full. Or set up your own OAuth client (see README "Power users")
GA auth required: run /ga-mcp-full:auth-login in Claude Code, then retry. The cached refresh token is missing or revoked. Rerun the slash command — it's the entire fix
OAuth browser window shows "access_denied" during login Your Google account doesn't have Editor/Admin on any GA4 property. Grant access in GA4 → Admin → Account/Property Access Management
Token refresh failed ga-mcp-full auth logout && ga-mcp-full auth login
/mcp shows the server but no tools Confirm ga-mcp-full auth status reports authenticated; tools are gated behind a working Analytics API client
Claude Code doesn't see the plugin claude plugin list — confirm ga-mcp-full@robworks-claude-code-plugins is installed and enabled. Restart the session if you just enabled it
"insufficientPermissions" errors on Admin API writes Verify your Google account has Editor/Admin role on the target GA4 property

Related

License

MIT — see LICENSE (once added).

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ga_mcp_full-0.3.0.tar.gz (27.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ga_mcp_full-0.3.0-py3-none-any.whl (33.8 kB view details)

Uploaded Python 3

File details

Details for the file ga_mcp_full-0.3.0.tar.gz.

File metadata

  • Download URL: ga_mcp_full-0.3.0.tar.gz
  • Upload date:
  • Size: 27.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ga_mcp_full-0.3.0.tar.gz
Algorithm Hash digest
SHA256 cc080f0e831095327e4899bf99760887cef1ba7ae63bb816fb0c62ed3c0660ab
MD5 adab9f455ff6fcbe72ab3d48f2cec4a5
BLAKE2b-256 45c61f52f5f750d63da7dd48b250218a6ed9d3474e225867afbe25fbcea53196

See more details on using hashes here.

Provenance

The following attestation bundles were made for ga_mcp_full-0.3.0.tar.gz:

Publisher: release.yml on ringo380/ga-mcp-full

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file ga_mcp_full-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: ga_mcp_full-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 33.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for ga_mcp_full-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 213afe89c8024ba6f5fb29951c023d748bf4e7552090e9727f3bf5991c9edc3b
MD5 0df412a47635d5befc8ab3a73e367c8f
BLAKE2b-256 52f8669d2b4d51f84d16a0a2c5b73cc978a70d47225e338e3d6ff9d365efe55d

See more details on using hashes here.

Provenance

The following attestation bundles were made for ga_mcp_full-0.3.0-py3-none-any.whl:

Publisher: release.yml on ringo380/ga-mcp-full

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page