Skip to content

feat(analytics): initialize Google Analytics MCP server#392

Open
yuriassuncx wants to merge 10 commits into
decocms:mainfrom
yuriassuncx:feat/ga4-analytics-mcp
Open

feat(analytics): initialize Google Analytics MCP server#392
yuriassuncx wants to merge 10 commits into
decocms:mainfrom
yuriassuncx:feat/ga4-analytics-mcp

Conversation

@yuriassuncx

@yuriassuncx yuriassuncx commented Apr 19, 2026

Copy link
Copy Markdown

This pull request introduces a new official Google Analytics (GA4) MCP integration under the google-analytics directory. It provides a complete implementation including configuration, authentication, server setup, and a suite of tools for interacting with Google Analytics 4 data and properties. The integration is ready for deployment and includes documentation and template files to help with customization and extension.

The most important changes are grouped as follows:

1. New MCP Integration: Core Implementation

  • Added a new google-analytics MCP package with its own package.json, .gitignore, and README.md, establishing the project structure and dependencies. [1] [2] [3]
  • Implemented the main server entrypoint in server/main.ts to configure the runtime, set up OAuth for Google Analytics, and register all tools for the MCP.

2. Google Analytics Tools and Functionality

  • Added tools for querying Google Analytics data: run-report, run-realtime-report, get-account-summaries, get-property-details, get-custom-dimensions-and-metrics, and list-google-ads-links, each implemented in their respective files under server/tools/. These tools leverage the Google Analytics Data and Admin APIs and are registered in tools/index.ts. [1] [2] [3] [4] [5]
  • Provided a set of example tool implementations in example-tool.ts.example to illustrate how to extend the MCP with custom logic, API calls, database queries, and event publishing.

3. Authentication and Environment Handling

  • Implemented Google OAuth2 authentication flow for secure access to Analytics data, including helper functions for extracting the access token from the environment (server/lib/env.ts) and a client wrapper for the Google Analytics APIs (server/lib/ga-client.ts). [1] [2]

4. Configuration and Deployment

  • Added app.json and app.json.example for MCP metadata, configuration, and deployment customization. [1] [2]
  • Updated deploy.json to include the new google-analytics MCP for deployment on the target platform.

5. Documentation and Usage Instructions

  • Provided clear setup and usage instructions in README.md, guiding users on configuration, tool implementation, deployment, and testing.
  • Added a detailed prompt in server/instructions.ts to guide LLM interactions with the MCP, ensuring correct usage patterns and best practices for querying Analytics data.

Summary by cubic

Initialize the GA4 MCP server under google-analytics with OAuth and a fetch-based client to remove GA SDKs, simplify auth, and expose tools for reports (including funnels), realtime, accounts, property metadata, Ads links, and annotations. Also migrated Google MCP connection URLs from decocache.com to deco.site for stable endpoints and OAuth redirects.

  • New Features

    • New google-analytics MCP server with Google OAuth2 (read-only) and runtime setup.
    • Tools: run-report, run-funnel-report, run-realtime-report, get-account-summaries, get-property-details, get-custom-dimensions-and-metrics, list-google-ads-links, list-property-annotations.
    • Reports support filters, ordering, pagination, currency, and quota; env helper for Bearer token; README/app.json (+ example) and deploy.json entry.
  • Bug Fixes

    • Replaced GA SDKs with a fetch client to resolve google-auth-library type conflicts.
    • Pagination for Admin list endpoints with a MAX_PAGES cap; custom dimensions/metrics fetched in parallel; property annotations use the v1alpha endpoint.
    • Hardened auth/validation: strict normalizeProperty (accepts numeric IDs), sanitized GA errors, Authorization header precedence, 204 response guard, improved token parsing, required metrics in report schemas, and integer limits.
    • Migrated all Google MCP connection URLs to deco.site for correct OAuth redirects and stable connections.

Written for commit 5b5f232. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4 issues found across 20 files

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread google-analytics/server/tools/properties.ts Outdated
Comment thread google-analytics/server/tools/reports.ts Outdated
Comment thread google-analytics/server/tools/reports.ts Outdated
Comment thread google-analytics/server/tools/reports.ts Outdated
yuriassuncx and others added 2 commits June 10, 2026 11:37
…ation

- Replace error: any + .message with instanceof Error guard in all 5
  catch blocks (accounts, properties x2, reports x2)
- Make metrics required (.min(1)) in runReport and runRealtimeReport schemas

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@yuriassuncx yuriassuncx force-pushed the feat/ga4-analytics-mcp branch from feeff43 to f7838ef Compare June 10, 2026 14:38
yuriassuncx and others added 8 commits June 10, 2026 11:42
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The @google-analytics/data and @google-analytics/admin SDKs use
google-gax with an internal google-auth-library version that is
incompatible with the top-level dependency, causing TS2322 errors
on the authClient constructor option.

Replace with a plain fetch client (Bearer token via Authorization
header) following the same pattern as google-search-console MCP.
This removes the OAuth2Client / AnyAuthClient type mismatch entirely.

Changes:
- ga-client.ts: rewrite as a fetch-based client with GA4 Data API
  and Admin API methods (no gRPC, no google-auth-library)
- accounts/properties/reports/ads tools: update call sites to use
  the new flat client API (no tuple destructuring)
- package.json: remove @google-analytics/admin, @google-analytics/data,
  google-auth-library; bump @decocms/runtime to 1.3.1 (matches root)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…l GA MCP

Security:
- Add normalizeProperty() with strict /^properties\/\d+$/ validation; prevents
  path traversal via ../ in URL segments (fetch normalizes dot-segments per RFC 3986)
- Fix header spread order — Authorization is now last, cannot be overridden by callers

Correctness:
- Fix listAccountSummaries: GA4 defaults to pageSize=50; now loops all pages (max 200)
- Add 204 guard in request() before res.json() to prevent SyntaxError on empty bodies
- Fix limit type: z.number() → z.number().int().positive() (GA4 requires integer)
- Run listCustomDimensions + listCustomMetrics in parallel via Promise.all

Parity with official google-analytics-mcp:
- Add dimensionFilter, metricFilter, orderBys, offset, currencyCode, returnPropertyQuota
  to run-report and run-realtime-report
- Add list-property-annotations tool (GET /{property}/propertyAnnotations)
- Property IDs now accept bare numeric strings ("1234567") — auto-normalized to
  "properties/1234567" at the client layer

Tooling:
- Add "types": ["bun-types"] to tsconfig.json so IDE resolves Response/fetch globals

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…h official GA MCP

- Fix listPropertyAnnotations: was calling non-existent v1beta endpoint;
  switched to v1alpha + correct resource name (reportingDataAnnotations)
- Add pagination to listCustomDimensions, listCustomMetrics, listGoogleAdsLinks
  via shared listAllPages helper (was silently truncating at 50 results)
- Refactor listAccountSummaries to use the same listAllPages helper
- Add MAX_PAGES=50 guard to all pagination loops to prevent infinite loops
  on repeated nextPageToken (GA4 quota events)
- Sanitize GA4 API error responses: surface only error.code + error.message,
  not the full response body which may contain OAuth scope details
- Fix token guard in env.ts: strip + trim before the empty-string check so
  "Bearer " (with no token) is caught as unauthenticated
- Remove dead gaPropertyId field from Env (was never read by any tool)
- Add run-funnel-report tool: covers the one gap vs official google/analytics-mcp
- Fix FunnelStepSchema: typed z.object with required name + filterExpression
  instead of open z.record (gives LLM actionable field-level guidance)
- Update instructions.ts: document funnel report tool and usage tips
- Fix app.json icon: replace broken developers.google.com favicon with
  gstatic.com Analytics SVG (confirmed 200 + CORS-safe)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… reports

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace sites-*.decocache.com → sites-*.deco.site across all app.json files
so OAuth redirect URIs and MCP connection endpoints resolve correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…to deco.site

Update connection URLs for all Google-family MCPs to use the new deco.site
domain. OAuth redirect URIs (e.g. https://sites-google-analytics.deco.site/oauth/callback)
have already been registered in Google Cloud Console.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant