Grenada Google Ads MCP
Provides tools for managing Google Ads accounts, including campaign and ad group creation, keyword management, performance reporting, and billing operations.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Grenada Google Ads MCPshow me my top campaigns by clicks this month"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Grenada Google Ads MCP
Multi-user remote Model Context Protocol connector for Google Ads, running on Cloudflare Workers.
Owner: Mostafa Ghanem — مصطفى غانم
Organization: Grenada Studio
Support: m.ghanem@grenadastudio.com
Runtime: Cloudflare Workers · D1 · KV
Transport: Remote MCP over Streamable HTTP at
POST /mcpGoogle Ads: REST API, version pinned by a single environment variable
What it does
Any authorised user signs in with their own Google account, and every Google Ads account they can reach becomes available to their MCP client (Claude, ChatGPT, Codex, MCP Inspector…).
Guarantees baked into the server, not left to the model:
Rule | Where it is enforced |
The user is never asked for an MCC / |
|
A user can only touch accounts discovered for their user id |
|
Manager accounts can never return metrics |
|
Campaigns/ad groups/ads/keywords are created | every |
A daily budget is mandatory, no silent default |
|
Enabling, budget raises and deletions need an explicit one-time confirmation |
|
Read-only GAQL, always bounded by a LIMIT |
|
Per-user rate limits (60 read / 10 write / 20 GAQL / 2 mutate per min) |
|
Refresh tokens AES-GCM encrypted, never logged |
|
Every write recorded in an audit log |
|
Related MCP server: Google Ads MCP Server
Tools — 62 implemented
29 read-only · 25 medium-risk · 8 high-risk (confirmation always required).
Area | Tools |
Accounts (4) |
|
Campaigns (9) |
|
Ad groups (4) |
|
Ads (6) |
|
Keywords (11) |
|
Reports (6) |
|
Assets (3) |
|
Audiences (3) |
|
Billing (2) |
|
Extensions (6) |
|
Performance Max & Shopping (4) |
|
Advanced (4) |
|
¹ high risk — answers CONFIRMATION_REQUIRED with a one-time token before doing anything.
Deviations from the reference catalog
Two of the 62 names in TOOL_CATALOG.md describe features of the reference product, not of the
Google Ads API, so they were rebuilt natively instead of copied:
Reference tool | What this project ships | Why |
|
| Bulk-uploads images from any public URL (including Dropbox direct links) with per-URL error reporting, instead of binding the connector to one storage vendor. |
|
| "Account slots" are a billing-plan concept of the reference service. This connector has no slots: every discovered account is usable, so the equivalent action is re-running discovery. |
Two more are worth knowing about because the API constrains them:
get_google_ads_auction_insightsreturns your own impression-share and top/absolute-top position metrics. The Google Ads API does not expose the competitor rows shown in the Auction Insights UI report — no implementation can return those.query_google_ads_api_docsanswers from a curated GAQL reference compiled into the Worker (src/google-ads/api-docs.ts), so it needs no third-party documentation service and works before a Google account is even connected.
Placeholder credentials
The repository ships with placeholders only — there is not a single real secret in it.
.dev.vars.example lists the five values you replace before going live:
GOOGLE_OAUTH_CLIENT_ID PLACEHOLDER_GOOGLE_OAUTH_CLIENT_ID.apps.googleusercontent.com
GOOGLE_OAUTH_CLIENT_SECRET PLACEHOLDER_GOOGLE_OAUTH_CLIENT_SECRET
GOOGLE_ADS_DEVELOPER_TOKEN PLACEHOLDER_DEVELOPER_TOKEN
TOKEN_ENCRYPTION_KEY PLACEHOLDER_TOKEN_ENCRYPTION_KEY_CHANGE_ME
MCP_COOKIE_ENCRYPTION_KEY PLACEHOLDER_COOKIE_ENCRYPTION_KEY_CHANGE_METhe whole app boots, serves every page and passes every test with these placeholders in place; only the calls that actually reach Google will fail until they are replaced.
Encryption keys: any string works (it is stretched with SHA-256), but generate real ones for
production with openssl rand -base64 32.
Local development
npm installcp .dev.vars.example .dev.varsnpx wrangler d1 migrations apply DB --localnpm run devThen check http://127.0.0.1:8787/health, /, /privacy, /terms, /data-deletion.
Run the checks:
npm run typecheck && npm testDeployment
The short way
Authenticate once, in an interactive terminal:
npx wrangler loginThen run the deploy script — it creates the D1 database and both KV namespaces, writes their ids
into wrangler.jsonc, generates and stores the encryption keys, pushes every secret, applies the
migrations, deploys, and prints the live URL plus the exact redirect URI to register with Google:
pwsh ./deploy.ps1Once you have the real Google credentials, re-run it with them:
pwsh ./deploy.ps1 -GoogleClientId "...apps.googleusercontent.com" -GoogleClientSecret "GOCSPX-..." -DeveloperToken "..."The script is safe to re-run: existing resources are reused and the encryption keys are generated
only once, into the git-ignored .deploy-keys.local.txt. Back that file up — losing
TOKEN_ENCRYPTION_KEY makes every stored Google refresh token unreadable and forces all users to
reconnect.
The manual way
1. Cloudflare resources
npx wrangler loginnpx wrangler d1 create grenada_google_ads_mcpnpx wrangler kv namespace create OAUTH_KVnpx wrangler kv namespace create CACHE_KVCopy the printed ids into wrangler.jsonc, replacing REPLACE_WITH_D1_DATABASE_ID,
REPLACE_WITH_OAUTH_KV_ID and REPLACE_WITH_CACHE_KV_ID.
2. Secrets
npx wrangler secret put GOOGLE_OAUTH_CLIENT_IDnpx wrangler secret put GOOGLE_OAUTH_CLIENT_SECRETnpx wrangler secret put GOOGLE_ADS_DEVELOPER_TOKENnpx wrangler secret put TOKEN_ENCRYPTION_KEYnpx wrangler secret put MCP_COOKIE_ENCRYPTION_KEY3. Migrate and deploy
npx wrangler d1 migrations apply DB --remotenpm test && npm run deploywrangler deploy prints the live URL. Put that URL in vars.PUBLIC_BASE_URL in wrangler.jsonc
and deploy once more, so the OAuth metadata advertises the right issuer.
4. Google Cloud Console
In the OAuth client (type: Web application) add the authorised redirect URI:
https://<your-worker-url>/google/callbackPublish the OAuth consent screen with the scope https://www.googleapis.com/auth/adwords, and point
the privacy policy and terms links at /privacy and /terms.
5. Custom domain (optional, last)
Once grenadastudio.com is on Cloudflare, uncomment the routes block in wrangler.jsonc, set
PUBLIC_BASE_URL to https://google-ads-mcp.grenadastudio.com, redeploy, and add the matching
redirect URI in Google Cloud Console.
Connecting a client
Add the remote MCP server:
https://<your-worker-url>/mcpThe client performs dynamic client registration at /register, is redirected through /authorize
to Google, and receives its token from /token. One Google sign-in covers both the MCP session and
the Google Ads grant.
Verify manually with the MCP Inspector, or directly:
curl -s https://<your-worker-url>/healthRollback
npx wrangler deployments listnpx wrangler rollback --message "reverting to previous version"D1 migrations are additive; rolling the Worker back does not require a schema change.
Project layout
src/
index.ts HTTP router
mcp/
server.ts JSON-RPC dispatch, tool middleware, audit
permissions.ts risk map + rate limits
confirmations.ts two-phase confirmation for high-risk writes
tools/ accounts, campaigns, ad-groups, ads, keywords, reports,
assets, audiences, billing, extensions, pmax, advanced
auth/
mcp-oauth.ts OAuth 2.1 authorization server for MCP clients
google-oauth.ts Google consent, code exchange, refresh, revoke
token-store.ts encrypted refresh token + cached access token
google-ads/
client.ts single REST choke point, version from env
account-discovery.ts listAccessibleCustomers + customer_client tree walk
account-resolver.ts ownership check + login-customer-id decision
gaql.ts read-only GAQL sanitiser, date filters
mutate.ts mutate helpers, atomic multi-resource writes, update masks
api-docs.ts curated GAQL reference used by query_google_ads_api_docs
errors.ts Google error -> internal error code
db/repositories.ts D1 access
db/audit.ts audit log + redaction
crypto/aes-gcm.ts AES-GCM, HMAC, SHA-256, base64, PKCE helpers
routes/pages.ts home, privacy, terms, data deletion, account
routes/google.ts connect, callback, disconnect, refresh
migrations/0001_initial.sql
migrations/0002_feedback.sql
test/ 122 unit + security testsAcceptance checklist
Worker bundles and runs (
wrangler deploy --dry-run,wrangler dev)/healthrespondsPOST /mcpreturns 401 withWWW-Authenticatewhen unauthenticatedOAuth discovery metadata served at both
.well-knownpathsDynamic client registration works; unknown clients are rejected at
/authorizePKCE
S256required; redirect URIs matched exactlyinitializeandtools/listanswer over/mcp(62 tools)Structured error envelopes (
GOOGLE_NOT_CONNECTED,VALIDATION_ERROR,RATE_LIMITED)Rate limiting verified live: the 21st raw-GAQL call in a minute is rejected
Confirmation lifecycle verified live: token issued → tampered arguments rejected → identical arguments accepted → replay of the same token rejected
Manager-account guard verified live on a reporting tool
Google consent URL carries
access_type=offline,prompt=consent,include_granted_scopes=trueD1 migrations apply from scratch
No secrets in the repository
Privacy, Terms and Data deletion pages present
npm run typecheckclean,npm testgreen (122 tests)End-to-end run against real Google credentials — needs the real developer token and OAuth client
This server cannot be installed
Maintenance
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
- Alicense-qualityDmaintenanceA typed MCP server that wraps the Google Ads API v20, enabling AI agents to manage campaigns, budgets, keywords, conversions, and run GAQL search via structured MCP tools.Last updated22MIT
- Flicense-qualityDmaintenanceMCP server that lets any LLM manage Google Ads campaigns from the terminal. Supports read and write operations.Last updated
- Alicense-qualityDmaintenanceMCP server for Google Ads campaign reporting and management via Claude, enabling GAQL queries, performance metrics, and campaign modifications.Last updated18MIT
- Alicense-qualityDmaintenanceA comprehensive Google Ads API integration for AI assistants through the Model Context Protocol. This server enables Claude AI and other MCP-compatible clients to manage Google Ads campaigns, analyze performance, and execute GAQL queries with natural language commands.Last updatedMIT
Related MCP Connectors
Hosted Amazon Seller Central and Amazon Ads MCP server for Claude, ChatGPT, Cursor, and agents.
Hosted Amazon Seller and Vendor MCP server for Claude, ChatGPT, Cursor, Codex, Gemini, Copilot.
Hosted Google Calendar MCP server for AI agents. No self-hosting or Google Cloud setup.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
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/Mostafa-Ghanem/google-ads-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server