Skip to main content
Glama
ogatomo21

google-analytics-adsense-remote-mcp

by ogatomo21

Google Analytics + AdSense Remote MCP

A read-only Remote MCP server for GA4 and the AdSense Management API v2, running on Cloudflare Workers. HTTP routing uses Hono, the MCP transport uses createMcpHandler(), and client OAuth authorization uses Cloudflare Access Managed OAuth.

One Worker is pinned to a single set of Google OAuth refresh tokens and handles all GA4 properties and AdSense accounts that Google account can read. Tool calls cannot swap in different OAuth credentials, Google API hosts, or write operations.

One-click deploy to Cloudflare

Deploy to Cloudflare

The button clones this public GitHub repository into your own account, then builds and deploys it after you enter the Worker name and the following settings.

  • Non-secret settings: CF_ACCESS_TEAM_DOMAIN, CF_ACCESS_AUD

  • Secrets: GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET, GOOGLE_REFRESH_TOKEN

Before pressing the button, issue GOOGLE_REFRESH_TOKEN by authorizing only the read-only scopes using the steps below. You enable the Cloudflare Access Application and Managed OAuth yourself after deployment.

Related MCP server: Google Analytics MCP server on Cloudflare Workers

Endpoints

Endpoint

Authentication

Description

GET /

None

Service overview. Does not return credentials.

GET /health

None

Health check.

ALL /mcp

Cloudflare Access

Streamable HTTP MCP endpoint.

MCP tools

  • ga4_run_report, ga4_run_realtime_report, ga4_run_pivot_report, ga4_run_funnel_report

  • ga4_get_metadata, ga4_check_compatibility

  • ga4_admin_read: GET/list operations under accountSummaries, accounts, and properties in the GA4 Admin API v1alpha.

  • adsense_generate_report

  • adsense_read: GET/list operations under accounts in the AdSense Management API v2.

All tools are annotated as read-only in MCP, and inputs are validated with Zod. External URLs, arbitrary HTTP headers, and arbitrary POST/PUT/PATCH/DELETE execution are not accepted. Raw Google errors are not included in MCP responses, but the full contents are written to the Worker Logs of the Cloudflare account where the Worker is deployed, for troubleshooting.

Preparing Google OAuth

  1. Enable the Google Analytics Data API, Google Analytics Admin API, and AdSense Management API in your Google Cloud Project.

  2. Configure the OAuth consent screen and request only GA4's https://www.googleapis.com/auth/analytics.readonly and AdSense's https://www.googleapis.com/auth/adsense.readonly.

  3. Create an OAuth Client ID under Credentials and select Desktop app as the Application type. AdSense does not support service accounts and requires the Installed Application flow.

  4. Refresh tokens may not be displayable again, so store them in a secure password manager when issued. Do not put them in the repository, Issues, CI logs, or wrangler.jsonc.

Google revokes access tokens after a short time. The Worker reacquires an access token using the refresh token grant on each MCP tool execution, so the Worker does not need to persist tokens.

Issuing a refresh token with Python

Works with Python 3.10 or later only; no additional packages are required. scripts/get_google_refresh_token.py uses PKCE, listens for a local callback, and does not save credentials, access tokens, or refresh tokens to files.

Redirect URI settings in Google Cloud Console

This Worker does not receive callbacks directly from Google. The OAuth client you create under Credentials must be a Desktop app. With a Desktop app, you do not need to configure Authorized redirect URIs or Authorized JavaScript origins in the Cloud Console.

At runtime, the Python script picks a free local port and sends a loopback redirect URI such as the following to Google.

http://127.0.0.1:54321/callback/

This is the loopback callback Google allows for Desktop apps. Do not register https://<worker-host>/callback, https://<worker-host>/mcp, or Cloudflare Access URLs as redirect URIs on the Google OAuth client. Also avoid using this script with a Web application type OAuth client.

python scripts/get_google_refresh_token.py

You will be prompted for GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET. In the browser, log in with the Google account the Worker will use and authorize only the following read-only scopes.

To revoke the browser authorization, press Ctrl+C in the terminal that is listening. This closes the local callback listener and exits without saving tokens.

  • https://www.googleapis.com/auth/analytics.readonly

  • https://www.googleapis.com/auth/adsense.readonly

Copy the single line displayed on success and enter it in the GOOGLE_REFRESH_TOKEN Secret field of the Deploy Button, or in the following interactive command.

pnpm wrangler secret put GOOGLE_REFRESH_TOKEN

If the Client ID / secret are also unset, configure them the same way.

pnpm wrangler secret put GOOGLE_CLIENT_ID
pnpm wrangler secret put GOOGLE_CLIENT_SECRET

If the Google OAuth consent screen remains External + Testing, the refresh token typically expires after 7 days. Before continued use, migrate to Production and complete the verification Google requires. If invalid_grant occurs, revoke this app's access in your Google account, rerun this script, and update the Worker Secret.

Local development

Requirements: Node.js 20 or later, Corepack, and a Cloudflare account that can use Cloudflare Zero Trust.

corepack enable
pnpm install
Copy-Item .dev.vars.example .dev.vars
pnpm check
pnpm dev --local

Set the real Google credentials in .dev.vars. This file is not added to Git.

Deploying to Cloudflare

  1. Change name, CF_ACCESS_TEAM_DOMAIN, and CF_ACCESS_AUD in wrangler.jsonc to your own Cloudflare Access settings.

  2. Set the secrets individually.

pnpm wrangler secret put GOOGLE_CLIENT_ID
pnpm wrangler secret put GOOGLE_CLIENT_SECRET
pnpm wrangler secret put GOOGLE_REFRESH_TOKEN
pnpm run deploy
  1. In the Cloudflare Zero Trust Dashboard, create an MCP server application targeting the Worker's https://<worker-host>/mcp.

  2. Create an Access Policy for the allowed email addresses or ID group, and deny users outside it.

  3. In Advanced settings, enable Managed OAuth. Confirm that the Application Audience tag and Team Domain match the Worker settings.

Cloudflare Access handles OAuth discovery, Dynamic Client Registration, Authorization Code Flow, PKCE, and access token refresh. Do not add your own /authorize, /token, or /register endpoints inside the Worker.

Connecting MCP clients

The MCP endpoint is https://<worker-host>/mcp. On the first connection, the Cloudflare Access login and authorization screen opens.

  • Inspector: start npx @modelcontextprotocol/inspector@latest, connect the endpoint, and Scan / List Tools for all tools.

  • Codex, etc.: register the endpoint in an OAuth-capable Remote MCP configuration.

  • ChatGPT: register the endpoint in a Custom MCP app / connector in Developer mode, complete OAuth authorization, then run Tool Scan. ChatGPT availability depends on your plan, Workspace settings, and region.

Verification

pnpm check

check runs ESLint, TypeScript, Vitest, Worker binding type synchronization, and wrangler deploy --dry-run in sequence. It does not automatically test queries against a real Google account. After deployment, run one GA4 report and one AdSense report each through Access using Inspector and the MCP client you will use.

Troubleshooting Google API issues

When a Google API call fails, the Worker outputs a JSON diagnostic event to Cloudflare Workers Logs. It outputs the Google HTTP response body, request URL and body, and the exception name, message, and stack trace without truncation. This is a debugging setting visible only to log viewers of the Cloudflare account where the Worker is deployed. If you forward, share, or publish logs externally, disable this detailed logging beforehand. It will still not be included in MCP responses.

pnpm wrangler tail --format json

Example: {"event":"google_request_failed","tool":"ga4_run_report","category":"google_api","upstreamStatus":403,"error":{"request":{"url":"..."},"responseBody":"...","stack":"..."}}. oauth_refresh is a refresh token renewal failure, google_api is a GA4 / AdSense API rejection, and unexpected is an unexpected failure such as a network issue.

License

MIT License

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server for querying Google Analytics accounts, properties, reports, and realtime data using the Data API and Admin API.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    Remote MCP server for the Google Ads API running on Cloudflare Workers. Provides read-only access to Google Ads data through GAQL, including customer listing, MCC expansion, paginated search, and resource metadata retrieval.
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Self-hosted MCP server for Google Analytics over HTTP, providing URL-addressable access with API key auth. It enables clients to run reports, list accounts/properties, and use compact paginated reports for token efficiency.
    MIT

View all related MCP servers

Related MCP Connectors

  • Hosted remote MCP server for YNAB on Cloudflare Workers with OAuth

  • Streamable HTTP MCP server for Google Calendar and Sheets with OAuth login.

  • Read-only MCP server for ClassQuill, a tutoring-business-management platform.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ogatomo21/google-analytics-adsense-remote-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server