{
  "markdown": "# google-ads-mcp-server\n\n[![CI](https://github.com/getmcpads-com/google-ads-mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/getmcpads-com/google-ads-mcp-server/actions/workflows/ci.yml)\n[![License: Apache 2.0](https://img.shields.io/badge/License-Apache_2.0-blue.svg)](LICENSE)\n[![Node](https://img.shields.io/badge/node-%E2%89%A518-brightgreen.svg)](package.json)\n\nAn open-source [Model Context Protocol](https://modelcontextprotocol.io) server for the\n**Google Ads API**. It lets Claude, ChatGPT, Cursor or any MCP client read and analyse your\nGoogle Ads data, plan keywords, and change campaigns if you choose to.\n\nYou run it. Your credentials stay on your machine. Nothing is proxied through a third party.\n\n```bash\nnpx -y @getmcpads/google-ads-mcp-server\n```\n\nAlso listed in the [MCP Registry](https://registry.modelcontextprotocol.io) as **`com.getmcpads/google-ads`**, so clients that read the registry can install it by name.\n\n> **Prefer not to run it yourself?** [getmcpads.com](https://www.getmcpads.com) is the hosted\n> version of this server, with Google Ads alongside Meta Ads, TikTok Ads, Pinterest Ads, GA4 and\n> Search Console behind a single endpoint, hosted OAuth, and cross-platform reporting.\n> Same tools, same safety model, no setup.\n\n---\n\n## What you get\n\n| | |\n|---|---|\n| **31 read tools** | Campaigns, ad groups, budgets, bidding strategies, search terms, landing pages, Performance Max assets and placements, Shopping, recommendations, change history |\n| **7 write tools** | Off by default. Status, budgets, bids, schedules, renames, campaign creation. Each one **previews before it applies** |\n| **Full Keyword Planner** | Keyword ideas, historical metrics, forecasts, ad group themes, geo target suggestions |\n| **130 metrics, 84 dimensions** | With a compatibility matrix that catches invalid combinations before they hit the API |\n| **5 resources** | Live catalogues the model can read: metrics, dimensions, compatibility rules, 11 workflow recipes |\n| **GAQL and beyond** | `google_ads_run_gaql` for raw queries, and `google_ads_run_readonly_rpc` for the services GAQL cannot reach |\n\n### You do not need to know GAQL\n\nThe Google Ads API is queried with GAQL, its own query language, and most of its surface is\nonly reachable that way. This server carries the metric and dimension catalogues, so the model\nasks for `cost` and `conversions` by name and the server writes the query.\n\n`google_ads_validate_query` lets it check a combination before spending a call on it, and\n`google_ads_run_gaql` is still there when you want to write GAQL yourself.\n\n### Keyword Planner is not in GAQL\n\nKeyword ideas, historical volumes and forecasts live in a separate RPC service that GAQL\ncannot reach at all. Same for Reach Planner, audience insights and benchmarks. This server\ncovers them through `google_ads_run_readonly_rpc` and dedicated tools.\n\n---\n\n## How this compares to Google's own MCP server\n\nGoogle shipped an official Google Ads MCP server in April 2026. It takes the opposite design\napproach, and the comparison is more nuanced than for other platforms.\n\n| | **This server** | Google's official server | [getmcpads.com](https://www.getmcpads.com) |\n|---|---|---|---|\n| Tools | **38** (31 read + 7 write) | 3: list accounts, GAQL search, resource metadata | 38, plus 5 other platforms |\n| Hosting | **Self-hosted.** stdio, local process | Self-hosted (pipx) or Cloud Run | Hosted for you |\n| Requires knowing GAQL | No, catalogues drive the query | **Yes**, for anything beyond listing accounts | No |\n| Keyword Planner | **Yes.** Ideas, history, forecasts, ad group themes | Not available | Yes |\n| Reach Planner, audience insights | **Yes**, through the read-only RPC | Not available | Yes |\n| Performance Max diagnostics | **Yes**, dedicated tools | Through hand-written GAQL | Yes |\n| Writes | **Yes, preview first.** Applied only on `confirm: true` | None, read-only by design | Yes, preview first |\n| Metric compatibility | **Query planner splits incompatible requests** | None | Same planner |\n| Auditable | **Yes.** Apache-2.0 | Yes, it is open too | This server, audited |\n\n**Be fair about it.** Google's server is self-hostable too, so \"your data stays on your\nmachine\" is not a difference here. Its 3 tools are a deliberate minimalist design: one GAQL\ntool can express most of the reporting surface, and a model fluent in GAQL will do a lot with\nvery little.\n\nThe difference is where the knowledge lives. There, it lives in the model, which has to write\ncorrect GAQL against a schema of thousands of fields. Here, it lives in the server, in\ncatalogues and a compatibility matrix. Add to that the planning services GAQL cannot reach at\nall, and writes that cannot fire on the first call.\n\n**Choose Google's** if your model writes good GAQL and you only need reporting.\n**Choose this one** if you want named metrics instead of query language, Keyword Planner and\nReach Planner access, or guarded writes.\n**Choose [getmcpads.com](https://www.getmcpads.com)** if you want this server's capabilities\nwithout running it, or you need more than one ad platform in the same conversation.\n\n---\n\n## Getting credentials\n\nThis is the heaviest setup of any advertising platform. Four values are needed, and one of\nthem requires a review by Google. Budget an hour the first time.\n\n### 1. Developer token\n\nFrom a **manager (MCC) account**, open **Tools → API Center** and apply for a token.\nIt starts at *Test Account* level, which only reaches test accounts. Apply for\n**Basic Access** to reach live accounts. Google reviews the application, which can take a\nfew days.\n\n📖 [Developer token documentation](https://developers.google.com/google-ads/api/docs/get-started/dev-token)\n\n### 2. OAuth client\n\nIn a [Google Cloud project](https://console.cloud.google.com/), enable the **Google Ads API**,\nthen create an OAuth client under **APIs & Services → Credentials**. Choose **Desktop app**\nfor local use. Note the **client ID** and **client secret**.\n\n### 3. Refresh token\n\nRun the OAuth consent flow once, signed in as the Google account that can see your ad\naccounts, and keep the **refresh token** it returns. Google's own helper script does this in\none command.\n\n📖 [OAuth desktop flow](https://developers.google.com/google-ads/api/docs/oauth/cloud-project)\n\n**The refresh token does not expire.** It is the sensitive value here: anyone holding it can\nmint access tokens indefinitely. Treat it like a password, and use an OAuth client dedicated\nto this server so you can revoke it on its own.\n\n### 4. Login customer ID, if you use a manager account\n\nIf the accounts you query sit under an MCC, set `GOOGLE_ADS_LOGIN_CUSTOMER_ID` to the manager\naccount ID. Dashes are accepted and stripped. Skip it for a standalone account.\n\nYou can also leave it unset. Google refuses any request against a managed account unless the\ncall names its manager, with a `USER_PERMISSION_DENIED` that mentions neither the account nor\nthe manager, so it reads as missing access rather than as a missing header. When the variable\nis unset and the account you query is not directly accessible, the server asks the managers it\ncan reach which accounts they hold, and announces the one that holds yours. The answer is\nresolved once and kept for the life of the process.\n\nSetting the variable is still faster: it skips that discovery entirely, and it is the right\nchoice when every account you query sits under the same MCC.\n\nRun **`google_ads_health_check`** as your first call. It verifies all four credentials, lists\nthe accounts you can actually reach, and reports what is missing, without printing any secret.\n\n---\n\n## Setup\n\n### Claude Desktop\n\n`~/Library/Application Support/Claude/claude_desktop_config.json` (macOS)\nor `%APPDATA%\\Claude\\claude_desktop_config.json` (Windows):\n\n```json\n{\n  \"mcpServers\": {\n    \"google-ads\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@getmcpads/google-ads-mcp-server\"],\n      \"env\": {\n        \"GOOGLE_ADS_DEVELOPER_TOKEN\": \"your-developer-token\",\n        \"GOOGLE_ADS_CLIENT_ID\": \"your-client-id\",\n        \"GOOGLE_ADS_CLIENT_SECRET\": \"your-client-secret\",\n        \"GOOGLE_ADS_REFRESH_TOKEN\": \"your-refresh-token\"\n      }\n    }\n  }\n}\n```\n\nRestart Claude Desktop. Ask it: *\"list my Google Ads accounts\"*.\n\n### Claude Code\n\n```bash\nclaude mcp add google-ads --env GOOGLE_ADS_DEVELOPER_TOKEN=... --env GOOGLE_ADS_CLIENT_ID=... --env GOOGLE_ADS_CLIENT_SECRET=... --env GOOGLE_ADS_REFRESH_TOKEN=... -- npx -y @getmcpads/google-ads-mcp-server\n```\n\n### Cursor\n\n`.cursor/mcp.json` in your project, same shape as the Claude Desktop config above.\n\n### From source\n\n```bash\ngit clone https://github.com/getmcpads-com/google-ads-mcp-server.git\ncd google-ads-mcp-server\nnpm install && npm run build\ncp .env.example .env   # then fill in your credentials\nnpm start\n```\n\n### Configuration\n\n| Variable | Default | Meaning |\n|---|---|---|\n| `GOOGLE_ADS_DEVELOPER_TOKEN` | none | **Required.** From the API Center, Basic Access or above |\n| `GOOGLE_ADS_CLIENT_ID` | none | **Required.** OAuth client ID |\n| `GOOGLE_ADS_CLIENT_SECRET` | none | **Required.** OAuth client secret |\n| `GOOGLE_ADS_REFRESH_TOKEN` | none | **Required.** From the consent flow |\n| `GOOGLE_ADS_LOGIN_CUSTOMER_ID` | none | Optional. Manager (MCC) account ID. Resolved automatically when unset |\n| `GOOGLE_ADS_ENABLE_WRITES` | *unset* | Set to `1` to register the 7 write tools |\n| `LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error` |\n\nCheck your setup at any time:\n\n```bash\nnpm run doctor\n```\n\n---\n\n## Writes, and why they preview first\n\nWrite tools are **disabled by default**. Enable them with `GOOGLE_ADS_ENABLE_WRITES=1`.\nGoogle's own server has none at all, so this is the part to read carefully.\n\nWhen enabled, every write tool returns a preview and changes nothing:\n\n```jsonc\n// google_ads_update_campaign_budget { customerId: \"123-456-7890\", budgetId: \"555\", dailyAmount: 50 }\n{\n  \"applied\": false,\n  \"action\": \"google_ads_update_campaign_budget\",\n  \"change\": { \"customer\": \"1234567890\", \"budget\": \"555\",\n              \"newDailyBudget\": 50, \"inMicros\": 50000000 },\n  \"message\": \"Preview only, nothing was changed. Repeat the same call with confirm: true to apply this change to the live account.\"\n}\n```\n\nOnly a second call carrying `confirm: true` touches the live account.\n\nThis is deliberate. An assistant composes these calls, and it can pick the wrong customer, the\nwrong campaign, or the wrong order of magnitude on a budget. A mandatory preview makes the\nmistake visible before it costs money, and gives a human the stopping point the protocol does\nnot guarantee on its own.\n\nTwo further guardrails:\n\n- **`google_ads_create_campaign` always creates the campaign `PAUSED`.** There is no option to\n  create it active. Someone has to look at it before it spends.\n- **Amounts are converted to micros for you.** Google holds money in millionths, so 12.50 in\n  the account currency is `12500000`. The preview shows both, so a factor-of-a-thousand\n  mistake is visible before it applies.\n\n| Tool | What it changes |\n|---|---|\n| `google_ads_update_campaign_status` / `google_ads_update_adgroup_status` | Pause, re-enable or remove |\n| `google_ads_update_campaign_budget` | Daily budget |\n| `google_ads_update_adgroup_bid` | Default CPC bid |\n| `google_ads_update_campaign_schedule` | Start and end dates |\n| `google_ads_rename_campaign` | Name only |\n| `google_ads_create_campaign` | Creates a budget, then a campaign, always `PAUSED` |\n\n---\n\n## Tools\n\n<details>\n<summary><b>31 read tools</b></summary>\n\n### Discovery and health\n| Tool | Purpose |\n|---|---|\n| `google_ads_health_check` | Validates all four credentials and lists reachable accounts |\n| `google_ads_list_accounts` | Every account the credentials can reach |\n| `google_ads_get_account_details` | Currency, timezone, status, account settings |\n| `google_ads_get_account_hierarchy` | The MCC tree above and below an account |\n\n### Structure and settings\n| Tool | Purpose |\n|---|---|\n| `google_ads_get_campaigns` / `google_ads_get_adgroups` | List entities and their settings |\n| `google_ads_get_budgets` / `google_ads_get_bidding_strategies` | Budgets and bidding configuration |\n| `google_ads_get_conversion_actions` | Conversion actions and their settings |\n| `google_ads_get_change_events` | Change history: who changed what, and when |\n\n### Performance\n| Tool | Purpose |\n|---|---|\n| `google_ads_get_insights` | The main reporting tool. Named metrics, no GAQL required |\n| `google_ads_validate_query` | Check a metric and dimension combination *before* running it |\n| `google_ads_get_keyword_performance` / `google_ads_get_search_terms` | Keyword and query performance |\n| `google_ads_get_landing_pages` | Landing page performance |\n| `google_ads_get_paid_organic_search_terms` | Paid and organic side by side |\n| `google_ads_get_simulations` | Bid and budget simulations |\n| `google_ads_get_recommendations` | Google's own recommendations for the account |\n\n### Performance Max and Shopping\n| Tool | Purpose |\n|---|---|\n| `google_ads_get_pmax_assets` / `google_ads_get_pmax_asset_diagnostics` | Asset groups, assets and their issues |\n| `google_ads_get_pmax_placements` | Where Performance Max actually served |\n| `google_ads_get_shopping_performance` / `google_ads_get_shopping_products` | Shopping performance and product data |\n\n### Keyword Planner\n| Tool | Purpose |\n|---|---|\n| `google_ads_generate_keyword_ideas` | Keyword ideas from seeds or a URL |\n| `google_ads_generate_keyword_historical_metrics` | Volumes, competition, trends |\n| `google_ads_generate_keyword_forecast_metrics` | Forecast clicks, cost and conversions |\n| `google_ads_generate_ad_group_themes` | Suggested ad group groupings |\n| `google_ads_suggest_geo_targets` | Resolve place names to geo target constants |\n\n### Escape hatches\n| Tool | Purpose |\n|---|---|\n| `google_ads_run_gaql` | Run a raw read-only GAQL SELECT |\n| `google_ads_run_readonly_rpc` | Call an allowlisted non-GAQL read service: Reach Planner, audience insights, benchmarks |\n| `google_ads_search_fields` | Search the API field schema |\n\nThese exist so a new field or service doesn't require a new release. Only read-only\nstatements and an allowlist of services are accepted.\n\n</details>\n\n<details>\n<summary><b>5 resources</b></summary>\n\n| URI | Contents |\n|---|---|\n| `google-ads://manifest` | What this server exposes, and which tool to run first |\n| `google-ads://metrics` | All 130 metrics with categories and formats |\n| `google-ads://dimensions` | All 84 dimensions and where they are valid |\n| `google-ads://compatibility` | The compatibility matrix |\n| `google-ads://recipes` | 11 step-by-step workflows |\n\n</details>\n\n---\n\n## Security\n\nThis server holds a refresh token that never expires, a client secret and a developer token.\nConcretely:\n\n- **None of the four credentials is ever logged**, at any log level, or written to disk.\n- **The access token is cached in memory** until a minute before expiry, rather than\n  re-requested on every call.\n- **Two hosts are contacted, and only two**: `googleads.googleapis.com` and\n  `oauth2.googleapis.com`. *A test fails the build if a third host appears in the source.*\n- **No fetch follows a redirect.** Every outbound call sets `redirect: \"error\"`, so a redirect\n  cannot forward a bearer token or client secret to another host. *A test fails the build if\n  any fetch omits this.*\n- **No telemetry.** The server makes no network call other than to Google.\n\nFull policy and reporting instructions: [SECURITY.md](SECURITY.md).\n\n---\n\n## Looking for a managed, multi-platform version?\n\nThis server does one platform, on your machine, with your credentials. That is on purpose.\n\nIf you'd rather not run it yourself, or you need Google Ads **alongside Meta Ads, TikTok Ads,\nPinterest Ads, GA4 and Search Console** behind one endpoint, with hosted OAuth and\ncross-platform reporting, that's what we build at **[getmcpads.com](https://www.getmcpads.com)**.\n\nSame philosophy, less plumbing. This project stays open source and independently useful\neither way.\n\n---\n\n## Contributing\n\nIssues and pull requests are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md).\nPlease read [SECURITY.md](SECURITY.md) before reporting anything security-related.\n\n## Licence\n\n[Apache License 2.0](LICENSE). See also [NOTICE](NOTICE).\n\nGoogle, Google Ads and the Google Ads API are trademarks of Google LLC.\n**This project is not affiliated with, endorsed by, or sponsored by Google LLC.**\nIt is an independent client of a public API.\n",
  "bytes": 16501,
  "sha": "9520d1c1df7569d52cea7687bc1837244a9611d9d74620da5b3559a9295da129",
  "repo_slug": "getmcpads-com/google-ads-mcp-server",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_com_getmcpads_google_ads_e775ab89/readme"
}