google-ads-mcp-coolify

by lucksigog

Not rated
GitHub

About

Self-hosted Google Ads MCP server for Coolify, Docker, and any VPS. Streamable HTTP transport with OAuth 2.0 — connects Claude Code, Cursor, and any MCP client to the Google Ads API.

Details

Author
lucksigog
Categories
Marketing, Other, AI

Setup

Install google-ads-mcp-coolify in your MCP client (Claude Desktop, Cursor, Windsurf, and others).

Repository: https://github.com/lucksigog/google-ads-mcp-coolify

Follow the installation instructions in the repository README, then restart your MCP client.

Self-hosted Google Ads MCP server for Coolify, Docker, and any VPS. Streamable HTTP transport with OAuth 2.0 — connects Claude Code, Cursor, and any MCP client to the Google Ads API.

Google Ads MCP Server — Self-Hosted on Coolify (Docker, HTTP/SSE)

Deploy theGoogle Ads MCP Serveron your own VPS withCoolifyin 5 minutes. ConnectsClaude Code,Claude Desktop,Cursor, or any Model Context Protocol client to theGoogle Ads APIvia OAuth 2.0 — over HTTPS, with a public endpoint.

This repo is aproduction-ready Docker wrapperaroundgomarble-ai/google-ads-mcp-serverthat solves the two missing pieces for remote deployment:
- No Dockerfile upstream→ this repo adds one.
- Upstream runs instdiomode(only works locally with Claude Desktop) → this repo wraps it withstreamable-httptransport so it can be reached over the internet.

Perfect for teams running self-hosted MCP infrastructure on platforms likeCoolify,Dokploy,EasyPanel,Railway,Render,Fly.io, or any plain Docker/Kubernetes setup.

- Why self-host a Google Ads MCP server?
-
Features
-
How it works
-
Quick start (Coolify)
-
Quick start (plain Docker)
-
Generating the OAuth credentials.json
-
Connecting from Claude Code / Cursor / Claude Desktop
-
Available MCP tools
-
Security notes
-
Troubleshooting
-
Contributing
-
License

- Privacy: your Google Ads OAuth tokens never leave your infrastructure.
- Multi-client: one deployed instance serves Claude Code, Cursor, Continue, Zed, n8n, and any other MCP-compatible tool.
- No paid SaaS gateway: skip third-party MCP relays — go straight from your AI client to your VPS to the Google Ads API.
- Works behind reverse proxies: HTTPS via Let's Encrypt, custom subdomain, optional auth middleware.

- ✅Streamable HTTP transport(MCP spec) — works with all modern MCP clients
- ✅OAuth 2.0with auto refresh — no manual token rotation
- ✅Bearer token authbuilt-in (MCP_AUTH_TOKEN) — endpoint never publicly accessible by default
- ✅Env-var credentials(GOOGLE_ADS_CREDENTIALS_JSON) — no File Mount required on Coolify
- ✅Single subdomain deployhttps://google-ads-mcp.yourdomain.com/mcp
- ✅Multi-account / MCC supportviaGOOGLE_ADS_LOGIN_CUSTOMER_ID
- ✅Built on FastMCP— fast, async, production-grade
- ✅Up-to-date upstream: each build pulls the latestgomarble-ai/google-ads-mcp-serverfrommain
- ✅Coolify-tested— also runs on Dokploy, EasyPanel, Railway, Fly.io, plain Docker

┌─────────────────┐ HTTPS ┌────────────────────────┐ OAuth ┌──────────────────┐ │ Claude Code / │ ──── /mcp ─────────▶│ This container │ ──── refresh ────▶ │ Google Ads API │ │ Cursor / etc. │ │ (FastMCP HTTP server) │ │ (v19) │ └─────────────────┘ └────────────────────────┘ └──────────────────┘ │ ▼ /app/credentials/credentials.json (mounted as a file by Coolify)

The container does three things at startup:
- Loads OAuth tokens from/app/credentials/credentials.json(file mount).
- Imports the FastMCP app defined in the upstreamserver.py.
- Runs it on0.0.0.0:8000usingstreamable-httptransport.

Coolify → + New Resource → Public Repository

GOOGLE_ADS_DEVELOPER_TOKEN=<your_developer_token> GOOGLE_ADS_AUTH_TYPE=oauth PORT=8000 # Paste the full credentials.json content (single line is fine, JSON parser handles it) GOOGLE_ADS_CREDENTIALS_JSON={"token":"ya29...","refresh_token":"1//0h...","token_uri":"https://oauth2.googleapis.com/token","client_id":"...","client_secret":"...","scopes":["https://www.googleapis.com/auth/adwords"]} # Bearer token for endpoint auth (RECOMMENDED — without it, your endpoint is public) # Generate with: python3 -c 'import secrets; print(secrets.token_urlsafe(32))' MCP_AUTH_TOKEN=<long_random_string> # Optional — only if you use a Manager (MCC) account: # GOOGLE_ADS_LOGIN_CUSTOMER_ID=1234567890

⚠️Do notsetNODE_ENVor any unrelated env var — Coolify injects all env vars as build ARGs, which can break unrelated builds.

4. (Optional) Mount the OAuth credentials as a file

You can skip this entirely if you setGOOGLE_ADS_CREDENTIALS_JSONabove. Use a File Mount only if you prefer keeping the JSON out of env vars:

ClickDeploy. When the container is healthy:

curl -i https://google-ads-mcp.yourdomain.com/mcp # Expected: HTTP 200, 405, or similar — NOT 502
docker build -t google-ads-mcp . docker run -d \ --name google-ads-mcp \ -p 8000:8000 \ -e GOOGLE_ADS_DEVELOPER_TOKEN=your_token \ -e GOOGLE_ADS_AUTH_TYPE=oauth \ -e GOOGLE_ADS_CREDENTIALS_PATH=/app/credentials/credentials.json \ -v $(pwd)/credentials.json:/app/credentials/credentials.json:ro \ google-ads-mcp

You only run thisonce on your local machineto bootstrap the refresh token. The container will refresh access tokens automatically from then on.
- Go toGoogle Cloud Console
- Create anOAuth 2.0 Client IDof typeDesktop application
- Download theclient_secret_.jsonfile
- Make sure the
Google Ads APIis enabled in the project
- Have aGoogle Ads Developer Token(
apply here)

# gen_credentials.py from google_auth_oauthlib.flow import InstalledAppFlow import json, glob, sys matches = glob.glob('client_secret.json') if not matches: sys.exit("Place a client_secret*.json next to this script first.") flow = InstalledAppFlow.from_client_secrets_file( matches[0], scopes=['https://www.googleapis.com/auth/adwords']) creds = flow.run_local_server(port=0) with open('credentials.json', 'w') as f: json.dump({ 'token': creds.token, 'refresh_token': creds.refresh_token, 'token_uri': creds.token_uri, 'client_id': creds.client_id, 'client_secret': creds.client_secret, 'scopes': creds.scopes, }, f, indent=2) print("OK -> credentials.json generated")
python3 -m venv .venv && source .venv/bin/activate pip install google-auth-oauthlib python3 gen_credentials.py

Upload that JSON as a File Mount on Coolify(step 4 above).

Connecting from Claude Code / Cursor / Claude Desktop

claude mcp add --transport http google-ads https://google-ads-mcp.yourdomain.com/mcp \ --header "Authorization: Bearer YOUR_MCP_AUTH_TOKEN" --scope user claude mcp list
claude mcp add --transport http google-ads https://google-ads-mcp.yourdomain.com/mcp --scope user
{ "mcpServers": { "google-ads": { "type": "http", "url": "https://google-ads-mcp.yourdomain.com/mcp", "headers": { "Authorization": "Bearer YOUR_MCP_AUTH_TOKEN" } } } }

Claude Desktop doesn't speak HTTP MCP. If you want it there, install the upstreamgomarble-ai/google-ads-mcp-serverdirectly on your machine.

GAQL reference is exposed as an MCP resource:gaql://reference.

This wrapper ships withbuilt-in Bearer token auth(MCP_AUTH_TOKENenv var). Set it and the endpoint requiresAuthorization: Bearer <token>on every request — no token, no access.

python3 -c 'import secrets; print(secrets.token_urlsafe(32))' # or: openssl rand -base64 32

For team deployments, additional hardening worth considering:

- Per-user tokens with revocation— back the middleware with a Supabase/Postgres table of token hashes (planned in a future release; PRs welcome)
- Cloudflare Access / Tailscale / WireGuard— zero-trust SSO in front of the endpoint
- IP allowlistat the Coolify/Cloudflare layer if connecting from a fixed set of machines

Even withMCP_AUTH_TOKEN, treat the endpoint as a defense-in-depth boundary, not the only line of defense — rotate the token periodically.

sh: tsc: not foundor build fails with missing devDependencies

You're hitting the Coolify env-var-as-build-ARG quirk.Don't setNODE_ENV=productionas an env var on the Coolify service.That gets injected as a build ARG and breaks unrelated Dockerfiles. (This repo is Python, but the same pattern bites Node-based MCP servers.)

CheckBase Directory =/andDockerfile Location =/Dockerfilein the Coolify Configuration tab.

401 Unauthorized/OAuth credentials expired

Opencredentials.jsonand confirmrefresh_tokenis present. If it's missing, regenerate viagen_credentials.pyand re-upload the file mount.

A fresh developer token has limited access (test accounts only). For production accounts, apply forBasic Accessin theGoogle Ads API Center.

You're querying through a Manager (MCC) account. SetGOOGLE_ADS_LOGIN_CUSTOMER_ID=<mcc_id_without_dashes>and redeploy.

Container started but isn't listening on port 8000. Check the build logs — most often thegit cloneof upstream failed. Re-trigger the deploy.

- Optional auth middleware (Bearer / Basic / IP allowlist)
- Pinned upstream SHA option (currently builds againstmain)
- Helm chart / Kubernetes manifests
- Examples for n8n, Make, Zapier MCP integrations

MIT— same license as the upstream gomarble project.

- Upstream MCP server:gomarble-ai/google-ads-mcp-server
- Model Context Protocol:
modelcontextprotocol.io
- Coolify:
coolify.io
- FastMCP:
jlowin/fastmcp

Keywords: google ads mcp server, google ads mcp coolify, self-hosted mcp google ads, mcp server docker, deploy mcp server vps, claude code google ads integration, fastmcp http server, google ads api claude, mcp streamable http, model context protocol google ads, cursor google ads mcp, n8n google ads mcp, self host model context protocol, google ads oauth mcp.

Free MCP that drives an audit of your marketing. Your AI connects, adsOS digs through your ads, email and site, and hands back a growth plan you can run today.

Google Ads reporting and campaign management for Claude; everything it creates starts paused, nothing spends until you turn it on.

Connect your Google Ads and Meta accounts to Claude, Cursor, or any AI tool that supports MCP.

Connect Google Ads to Claude or ChatGPT via Two Minute Reports MCP and get accurate answers about campaigns, creatives, and spend.

Supervised Meta Ads operating system for Claude Code - 57 tools for campaign management, multi-asset ads, targeting, pixel diagnostics, catalogs, and safety gates

Mercopilot connects your Shopify store and your Google Ads account to Claude, ChatGPT, and other AI assistants through a standard called MCP. Once connected, you ask your AI assistant plain-English questions about your store and your ad spend, get a ranked list of what to fix and where to grow, and approve specific changes that are made directly in Shopify or Google Ads. No separate dashboard to monitor, no reports to download.

A shared campaign canvas for you and your AI agent: briefed by your brand rules, gated by your approval.

Run your Linkedin account from claude or chatgpt

Chat with any brand's Meta (Facebook/Instagram) ads inside Claude — research a competitor's ad library, surface their longest-running winners, extract hooks/formats, and clone winning ads for your own brand.

Self-hostable AGPL SEO manager backend with an MCP server for keyword research, content queue, and SERP tracking, built for Claude Code.

Connect Claude, Cursor, or ChatGPT to a Shopify store's real visitor data — heatmaps, session replays, funnels, revenue attribution — with ~70 tools that also write back: edit products, launch popups, apply SEO fixes.

No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.