io.github.SnipMCP/gadschain β Google Ads MCP Server
The io.github.SnipMCP/gadschain MCP server provides an AI layer for interacting with a Google Ads account. It covers campaign listing, search-term review, budget tuning, pause/enable actions, and negative-keyword grooming. Responses are returned as strict Pydantic models.
π οΈ Key Features
Campaign listing
Search-term review
Budget tuning
Pause/enable campaigns
Add negative keywords
Strict Pydantic model responses (no raw protobuf sent to the agent)
π Use Cases
Review campaign and search-term performance
Tune budgets as part of daily operations
Temporarily pause or enable campaigns
Maintain keyword hygiene by adding negative keywords
β‘ Developer Benefits
Structured outputs via strict Pydantic models
Can run locally using your own API keys for production workflows
β οΈ Limitations
Described as βsix toolsβ covering a daily-ops loop; no additional capabilities are specified in the provided material.
The AI layer between your Google Ads account and your marketing decisions.
Battle-tested. Six tools cover the daily-ops loop β campaign listing, search-term review, budget tuning, pause/enable, and negative-keyword grooming. All responses are strict Pydantic models. No raw protobuf reaches the agent.
GadsChain Demo
βοΈ Moving to production?
The open-source server runs locally with your own API keys.
For hosted infrastructure with multi-account failover, SLA guarantees,
and webhook alerts β join the managed cloud waitlist.
The Problem
Raw Google Ads API returns thousands of rows. One bad campaign structure bleeds budget silently. GadsChain reads, sanitizes, and acts on your ad data before waste compounds.
Three example prompts to send to Claude (or any MCP-compatible agent):
Use get_campaigns to show me which campaigns are bleeding budget this month
Run get_search_terms for the last 30 days and tell me which queries are wasting spend
Add "free", "cheap", "jobs" as negative keywords to campaign 12345
Run it in two terminals
bash
# Tab 1 β start the MCP server
python -m gadschain.server
bash
# Tab 2 β call a tool from a Python shell or your MCP client# Tool signatures:# get_campaigns(customer_id=None)# get_search_terms(customer_id=None, days=30, campaign_id=None)# update_budget(campaign_id, new_budget_dollars, customer_id=None)# pause_campaign(campaign_id, customer_id=None)# enable_campaign(campaign_id, customer_id=None)# add_negative_keywords(campaign_id, keywords, match_type="BROAD", customer_id=None)
How it works
Three layers between raw Google Ads output and your model:
code
Google Ads API β [Fetch] β [Transform] β [Act] β MCP Tool β AI Agent
GAQL microsβ$ safe
queries enumβstr mutations
CTRβ% shared-budget guard
Fetch: Targeted GAQL queries β only the columns the daily-ops loop actually needs. No SELECT *, no protobuf pagination footguns.
Transform: Currency micros divided to dollars, CTR scaled to percent, enums to human strings, every nested attribute lookup tolerates missing fields without crashing.
Act: Mutations route through guard rails β REMOVED blocked on status changes, shared budgets refused (shared_budget_refused), match types validated before any mutate call. The agent never gets an exception; it gets a structured {"error": ..., "message": ...} it can reason about.
Real numbers from a live Franka Pizzeria account (28-day window)
code
RAW GOOGLE ADS PAYLOAD GADSCHAIN OUTPUT
βββββββββββββββββββββββββββββββββββββββββββββββββ
Impressions: 3,389 Spend (28d): $51.41
Clicks: 163 Conversions: 3 ($17.14 each)
CTR: 4.81% Conv. rate: 1.84%
Cost/click: $0.32 avg Surface: Display Network waste
identified on Fridays
($0.11 CPC vs $0.44 avg)
In one read of a real account, GadsChain surfaced $51.41 spent over 28 days for 3 conversions at $17.14 each β a 1.84% conversion rate hidden inside a 4.81% CTR that looks healthy on paper. The Display Network was the silent culprit, with Friday clicks averaging $0.11 CPC vs the $0.44 search-side average β cheap junk traffic inflating CTR while contributing nothing to conversions. The agent saw it because the transformed payload made channel attribution legible instead of buried in protobuf.