# gtm-ga4 [Health: Active]

**Category:** 💻 Developer Tools  
**Repository:** https://github.com/mharnett/mcp-gtm-ga4  
**GitHub Stars:** 2  
**Views:** 0  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/gtm-ga4

## Description
GTM + GA4 MCP: tag management, consent auditing, workspace versioning, reports.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

```json
"mcpServers": {
  "gtm-ga4": {
    "command": "npx",
    "args": ["-y","mcp-gtm-ga4"]
  }
}
```

## Documentation & README

# mcp-gtm-ga4

MCP server for Google Tag Manager and GA4 -- tag management, consent auditing, workspace versioning, and analytics reporting via Claude.

## Features

- **14 tools** spanning GTM workspace management (tags, triggers, variables), consent compliance auditing, workspace preview/versioning, and GA4 reporting
- **Sandbox safety** -- all write operations verify they target the resolved workspace, refusing to write to non-sandbox workspaces
- **Multi-client support** -- configure per-client via environment variables
- **Auto-detects Default Workspace ID** -- no need to manually specify workspace IDs unless using a custom sandbox

## Installation

```bash
npm install mcp-gtm-ga4
```

Or clone and build:

```bash
git clone https://github.com/mharnett/mcp-gtm-ga4.git
cd mcp-gtm-ga4
npm install
npm run build
```

## Configuration

**Security:** Never share your `.mcp.json` file or commit it to git -- it may contain API credentials. Add `.mcp.json` to your `.gitignore`.

Runtime configuration is via environment variables.

| Variable | Required | Description |
|---|---|---|
| `GOOGLE_APPLICATION_CREDENTIALS` | Yes | Path to a Google credential JSON key file (service account **or** authorized-user — see Authentication below) |
| `GTM_ACCOUNT_ID` | Yes | GTM account ID |
| `GTM_CONTAINER_ID` | Yes | GTM container ID |
| `GA4_PROPERTY_ID` | Yes | GA4 property ID |
| `GTM_SANDBOX_WORKSPACE_ID` | No | Override workspace ID (auto-detects Default Workspace if omitted) |
| `MCP_SERVER_NAME` | No | Server name (defaults to package name `mcp-gtm-ga4`) |

See `config.example.json` for a reference template. The only value read from disk is `oauth.scope` (in an optional `config.json`) — the single source of truth for the OAuth scope the onboarding paths request. If no `config.json` is present, the committed minimum scope is used.

## Authentication

This MCP supports **two** auth models. Both feed the same `GOOGLE_APPLICATION_CREDENTIALS` runtime path.

### Precedence & mechanism

There is **no runtime service-account-vs-OAuth toggle**. Both models converge on a
single slot — `GOOGLE_APPLICATION_CREDENTIALS` — which the runtime hands to
`GoogleAuth({ keyFile })`. Whichever file you point that env var at *is* the
credential:

- a **service-account JSON key** (option 1 below), or
- the **`authorized_user` keyfile** the `auth` subcommand writes (option 2) — a
  file that plugs into the exact same slot.

So the only real precedence rule is failure handling: **an explicitly-configured
keyfile is used; when `GOOGLE_APPLICATION_CREDENTIALS` is unset the server fails
loudly at startup** with an onboarding error naming both the service-account path
and the `auth` OAuth helper. It deliberately does **not** fall back to Google's
Application Default Credentials (gcloud user creds / GCE metadata server) — no
silent machine-local default, no silent runtime failover.

### 1. Service account (primary, recommended for unattended/server use)

Create a service account in your GCP project, download its JSON key, grant it the
GTM container role (on the target GTM container) and GA4 property access, and
point `GOOGLE_APPLICATION_CREDENTIALS` at the key file. No OAuth flow, no browser,
no refresh token. **This is the recommended path for headless/server/unattended
deployments.**

### 2. User OAuth (interactive, for users without a service account)

If you can't use a service account, mint a user credential with your **own** Google OAuth client (a "Desktop app" OAuth 2.0 Client ID created in your own GCP project — enable the Tag Manager API and the Google Analytics Admin + Data APIs). Two equivalent onboarding commands, both hardened with PKCE (RFC 7636, S256) and both requesting the scope from `config.json` (`oauth.scope`) so they never drift:

```bash
export GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com
export GOOGLE_CLIENT_SECRET=your-client-secret

# Option A: write an authorized_user credential file directly
node dist/index.js auth --output ./gtm-ga4-credentials.json
# then set GOOGLE_APPLICATION_CREDENTIALS=./gtm-ga4-credentials.json

# Option B: the standalone helper (prints GOOGLE_REFRESH_TOKEN + a ready-to-save
# authorized_user JSON you can write to a file for GOOGLE_APPLICATION_CREDENTIALS)
node get-refresh-token.cjs
```

The refresh token / credential is written by you and read from your environment only. Nothing is shared and no OAuth client keyfile is bundled. **Do not** run the helper with stdout redirected to a shared log — the refresh token is printed to stdout by design.

### OAuth scopes requested

The onboarding paths request exactly the scopes this MCP's tools use (from `config.example.json` → `oauth.scope`):

| Scope | Needed by |
|---|---|
| `tagmanager.edit.containers` | `gtm_create_tag`, `gtm_update_tag`, `gtm_create_variable`, `gtm_update_variable`, `gtm_delete_variable`, tag/trigger/variable reads |
| `tagmanager.edit.containerversions` | `gtm_create_version` |
| `tagmanager.publish` | `gtm_create_version`, `gtm_preview` (quick preview) |
| `analytics.readonly` | `gtm_ga4_run_report`, `gtm_ga4_realtime_report`, `gtm_ga4_list_custom_dimensions` |
| `analytics.edit` | `gtm_ga4_create_custom_dimension` |

`tagmanager.readonly` is intentionally **not** requested — the edit scopes already grant read access.

## Usage

### Claude Code (.mcp.json)

```json
{
  "mcpServers": {
    "gtm-ga4": {
      "command": "node",
      "args": ["/path/to/mcp-gtm-ga4/dist/index.js"],
      "env": {
        "GOOGLE_APPLICATION_CREDENTIALS": "/path/to/service-account.json",
        "GTM_ACCOUNT_ID": "1234567890",
        "GTM_CONTAINER_ID": "9876543",
        "GA4_PROPERTY_ID": "331956119"
      }
    }
  }
}
```

### npx

```bash
GTM_ACCOUNT_ID=1234567890 \
GTM_CONTAINER_ID=9876543 \
GA4_PROPERTY_ID=331956119 \
GOOGLE_APPLICATION_CREDENTIALS=/path/to/sa.json \
npx mcp-gtm-ga4
```

**Claude Desktop:** Add to `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) or `%APPDATA%\Claude\claude_desktop_config.json` (Windows).

## Safety

### Workspace sandbox protection

All write operations (`gtm_update_tag`, `gtm_create_tag`, `gtm_preview`, `gtm_create_version`) verify they target the resolved workspace before executing. If a request attempts to write to a different workspace, the server returns a `SafetyError` and blocks the operation.

This prevents accidental production changes when the MCP server is configured against a sandbox workspace.

## Tools

### GTM Tags

| Tool | Description |
|---|---|
| `gtm_list_tags` | List all tags in the workspace with consent status and firing triggers |
| `gtm_get_tag` | Get full tag configuration by tag ID |
| `gtm_update_tag` | Update an existing tag (merge patch via JSON) |
| `gtm_create_tag` | Create a new tag from a JSON definition |

### GTM Structure

| Tool | Description |
|---|---|
| `gtm_list_triggers` | List all triggers (ID, name, type) |
| `gtm_list_variables` | List all variables (ID, name, type) |

### GTM Consent

| Tool | Description |
|---|---|
| `gtm_audit_consent` | Audit all tags for consent configuration compliance |

### GTM Workspace

| Tool | Description |
|---|---|
| `gtm_preview` | Generate a quick preview of the current workspace |
| `gtm_create_version` | Create a new container version from the workspace |

### GA4 Reports

| Tool | Description |
|---|---|
| `gtm_ga4_run_report` | Run a GA4 report with dimensions, metrics, date range, and filters |
| `gtm_ga4_realtime_report` | Run a GA4 realtime report (last 30 minutes) |

### GA4 Admin

| Tool | Description |
|---|---|
| `gtm_ga4_list_custom_dimensions` | List all custom dimensions for the property |
| `gtm_ga4_create_custom_dimension` | Create a new custom dimension |

## Architecture

- **GTM API**: `googleapis` (Tag Manager v2)
- **GA4 Data**: `@google-analytics/data` (BetaAnalyticsDataClient)
- **GA4 Admin**: `@google-analytics/admin` (AnalyticsAdminServiceClient)
- **Resilience**: `cockatiel` (retry, circuit breaker, timeout policies)
- **Logging**: `pino` with `pino-pretty`
- **Transport**: MCP SDK stdio transport

## License

MIT

## Author

Built by Mark Harnett / [drak-marketing](https://github.com/drak-marketing)

