1. Why Connect Google Ads to LLMs via MCP?
Traditional search marketing optimization workflows are notoriously manual. Media buyers spend hours pulling Search Query Reports (SQRs), building pivot tables in spreadsheets, and manually uploading negative keyword lists. Beyond the time lost, standard Google Ads automated rules operate in silos—they lack contextual awareness of broader marketing objectives, cross-channel performance benchmarks, and real-time semantic intent.
By connecting the official Google Ads API directly to Claude using the Model Context Protocol (MCP), you transform Claude into an autonomous search marketing analyst with live, programmatic access to your ad accounts. Discover how our Google Ads management services leverage this modern technical foundation.
Core Advantage: With a direct claude desktop google ads mcp server, you eliminate manual CSV exports and interact with live campaign datasets using natural language while maintaining strict read-only safety.
2. Understanding Claude Desktop Google Ads MCP Server Architecture
The integration adheres to Anthropic's Model Context Protocol client-host specification operating over standard input/output (stdio):
│ Claude Desktop │
│ (MCP Client / Reasoning Host) │
└───────────────────────────┬────────────────────────────┘
│ JSON-RPC (stdio)
▼
┌────────────────────────────────────────────────────────┐
│ Google Ads MCP Server (Python) │
│ - Tool Registry (query_gaql, get_keyword_ideas) │
│ - Read-Only Validation & Truncation Safeguards │
│ - Google Ads API Client Wrapper │
└───────────────────────────┬────────────────────────────┘
│ REST / gRPC (OAuth 2.0)
▼
┌────────────────────────────────────────────────────────┐
│ Google Ads API │
│ (Reporting Service & KeywordPlanIdeaService) │
└────────────────────────────────────────────────────────┘
- Claude Desktop (MCP Client): Formulates user queries into structured tool calls, analyzes returned campaign payloads, and generates strategic recommendations.
- Local Python Daemon (MCP Server): Receives JSON-RPC commands from Claude, handles OAuth2 token refreshing, communicates securely with Google APIs, and enforces strict read-only boundaries.
- Google Ads API: The official Google infrastructure providing live GAQL performance metrics and KeywordPlanIdeaService forecasting.
3. Prerequisites: Google Ads API Credentials & Authentication
Before connecting Claude, you must configure OAuth 2.0 authentication in the Google Cloud Console and obtain an active Developer Token from Google.
3.1 Configure Google Cloud OAuth 2.0
- Open the Google Cloud Console and create a new project.
- Enable the Google Ads API under APIs & Services.
- Configure the OAuth Consent Screen (add scope
https://www.googleapis.com/auth/adwordsand add your Google account as a Test User). - Navigate to Google Cloud Credentials and create an OAuth Client ID (Application Type: Desktop App).
3.2 Generating a Google Ads API OAuth2 Refresh Token in Python
To authorize Claude without repeated manual logins, run the official OAuth handshake script using the Google Ads Python SDK:
from google_auth_oauthlib.flow import InstalledAppFlow
CLIENT_CONFIG = {
"installed": {
"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"client_secret": "YOUR_CLIENT_SECRET",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
}
}
SCOPES = ["https://www.googleapis.com/auth/adwords"]
def get_refresh_token():
flow = InstalledAppFlow.from_client_config(CLIENT_CONFIG, scopes=SCOPES)
credentials = flow.run_local_server(port=8080, prompt="consent", access_type="offline")
print(f"\nRefresh Token: {credentials.refresh_token}")
if __name__ == "__main__":
get_refresh_token()
3.3 Developer Token Access Levels
| Access Level | Operations / Day | Keyword Planner Access | Status |
|---|---|---|---|
| Explorer Access | Unlimited (Test Accounts) / Live GAQL | Mock data only | Instant provision upon MCC creation |
| Basic Access | 15,000 ops / day | Full live search volume & CPC bids | Standard production review (24-48 hrs) |
| Standard Access | Unlimited | Full production enterprise volume | Requires Google compliance review |
For more details on managing robust API integrations, explore our conversion tracking and analytics services.
4. Configuring claude_desktop_config.json for Google Ads MCP
With credentials in place, build your FastMCP Python server script and register it in Claude Desktop.
import os, json
from mcp.server.fastmcp import FastMCP
from google.ads.googleads.client import GoogleAdsClient
mcp = FastMCP("Google Ads MCP Server")
def get_google_ads_client():
credentials = {
"developer_token": os.environ["GOOGLE_ADS_DEVELOPER_TOKEN"],
"client_id": os.environ["GOOGLE_ADS_CLIENT_ID"],
"client_secret": os.environ["GOOGLE_ADS_CLIENT_SECRET"],
"refresh_token": os.environ["GOOGLE_ADS_REFRESH_TOKEN"],
"use_proto_plus": True
}
if os.environ.get("GOOGLE_ADS_LOGIN_CUSTOMER_ID"):
credentials["login_customer_id"] = os.environ["GOOGLE_ADS_LOGIN_CUSTOMER_ID"]
return GoogleAdsClient.load_from_dict(credentials)
@mcp.tool()
def execute_gaql_query(customer_id: str, query: str) -> str:
"""Executes a read-only GAQL SELECT query against the specified Google Ads customer_id."""
clean = query.strip()
if not clean.upper().startswith("SELECT"):
return json.dumps({"error": "Safety violation: Only SELECT queries are permitted."})
client = get_google_ads_client()
ga_service = client.get_service("GoogleAdsService")
try:
response = ga_service.search_stream(customer_id=customer_id.replace("-", ""), query=clean)
results = []
for batch in response:
for row in batch.results:
results.append(row._pb.to_dict() if hasattr(row, "_pb") else str(row))
if len(results) >= 100: break
if len(results) >= 100: break
return json.dumps({"count": len(results), "data": results}, default=str)
except Exception as e:
return json.dumps({"error": str(e)})
if __name__ == "__main__":
mcp.run()
Add the server configuration to your claude_desktop_config.json file according to the Anthropic MCP Documentation:
{
"mcpServers": {
"google-ads": {
"command": "/usr/local/bin/python3",
"args": ["/path/to/google_ads_mcp.py"],
"env": {
"GOOGLE_ADS_DEVELOPER_TOKEN": "YOUR_DEV_TOKEN",
"GOOGLE_ADS_CLIENT_ID": "YOUR_CLIENT_ID.apps.googleusercontent.com",
"GOOGLE_ADS_CLIENT_SECRET": "YOUR_CLIENT_SECRET",
"GOOGLE_ADS_REFRESH_TOKEN": "1//YOUR_REFRESH_TOKEN",
"GOOGLE_ADS_LOGIN_CUSTOMER_ID": "1234567890"
}
}
}
}
5. Auditing Campaigns & Generating GAQL with Claude Desktop
Once connected, you can prompt Claude to audit performance, diagnose CPA spikes, and harvest negative keywords dynamically.
5.1 Negative Keyword Mining Prompt
Prompt for Claude: "Audit search terms for Customer ID 123-456-7890 over the last 30 days. Identify terms with over 20 clicks and 0 conversions, and construct a categorized negative keyword list."
SELECT
search_term_view.search_term,
search_term_view.status,
campaign.name,
ad_group.name,
metrics.impressions,
metrics.clicks,
metrics.cost_micros,
metrics.conversions
FROM search_term_view
WHERE segments.date DURING LAST_30_DAYS
AND metrics.clicks > 20
AND metrics.conversions = 0
ORDER BY metrics.cost_micros DESC
LIMIT 100
Learn more about implementing custom AI agents and automated marketing pipelines across your tech stack.
6. Automating Keyword Research with Claude and Google Ads API
By adding Google's KeywordPlanIdeaService to your FastMCP server, Claude can pull live search volume, competition indexes, and top-of-page CPC bid ranges during campaign planning sprints.
@mcp.tool()
def get_keyword_ideas(customer_id: str, keywords: list[str], location_id: str = "2840", language_id: str = "1000") -> str:
"""Fetches keyword search volume, CPC estimates, and related terms from Google Keyword Planner."""
client = get_google_ads_client()
kp_service = client.get_service("KeywordPlanIdeaService")
request = client.get_type("GenerateKeywordIdeasRequest")
request.customer_id = customer_id.replace("-", "")
request.language = f"languageConstants/{language_id}"
request.geo_target_constants.append(f"geoTargetConstants/{location_id}")
request.keyword_plan_network = client.enums.KeywordPlanNetworkEnum.GOOGLE_SEARCH
request.keyword_seed.keywords.extend(keywords)
response = kp_service.generate_keyword_ideas(request=request)
ideas = []
for idea in response:
m = idea.keyword_idea_metrics
ideas.append({
"keyword": idea.text,
"monthly_searches": m.avg_monthly_searches,
"competition": m.competition.name,
"low_bid": (m.low_top_of_page_bid_micros or 0) / 1_000_000,
"high_bid": (m.high_top_of_page_bid_micros or 0) / 1_000_000
})
if len(ideas) >= 50: break
return json.dumps({"ideas": ideas})
Cross-Platform Note: While Claude uses the Model Context Protocol natively, you can connect Google Keyword Planner to ChatGPT using OpenAI Function Calling or Custom Actions pointing to this identical API structure.
7. Frequently Asked Questions (FAQ)
Can Claude make accidental budget or bidding changes to my Google Ads account via MCP?
No, if configured with an MCP Google Ads read-only setup. By restricting the server to SELECT queries only and omitting mutation endpoints, Claude Desktop acts strictly as an analytical auditor with zero write permissions.
What Google Ads API developer access level is required for Claude MCP?
Basic Access for your Google Ads Developer Token is required to fetch live search volume and CPC data via KeywordPlanIdeaService. Explorer Access is sufficient for running GAQL reporting queries and sandbox validation.
Can I connect Google Keyword Planner to ChatGPT using a similar approach?
Yes. While Claude Desktop utilizes the open Model Context Protocol (MCP), ChatGPT can be integrated via OpenAI Custom Actions (OpenAPI specification) or Python-based tool runners calling the identical Google Ads API endpoints.
How does Claude analyze search terms for negative keyword mining?
Claude queries the search_term_view table via GAQL, compares actual user search queries against conversion milestones, and identifies zero-converting terms to automatically construct a categorized negative keyword list.