Process

I Stopped Managing Google Ads Manually. Here's What I Built Instead.

Anyone running serious Google Ads accounts knows the math doesn’t work anymore. The accounts are too big. The reports are too long. As one industry report recently put it, the complexity has outgrown human bandwidth. That tracks with my experience. Dozens of campaigns, hundreds of ad groups, thousands of keywords, and a constant stream of search term reports, quality scores, and conversion events to interpret and act on. The manual loop of logging in, building reports, exporting CSVs, analyzing, deciding, and implementing changes was eating hours I didn’t have, and I knew I was missing things even with the hours I was putting in.

Most marketers I know have tried to point AI at this. The problem is that almost all of those workflows still treat AI as a smarter notepad. You export the data, paste it into a chat window, ask for analysis. The mechanical work hasn’t actually gone anywhere, and the AI only ever sees what you remembered to bring it.

A few months ago I built something that changed that. Here is what it looks like, including the part where I had to build a piece of it myself, and what I think it means for how marketing teams get staffed.

You Claude + Cowork Persistent project workspace Google Ads Read MCP Vendor-supplied, read-only Google Ads Write MCP Custom-built Semrush MCP Keyword research Manager Account (MCC) Required gateway for API access Semrush data Volume, difficulty, gaps Business Unit 1 Business Unit 2 Business Unit 3

The setup, in plain English

Three pieces to start.

The first is the Google Ads API itself. Google has long offered a full programmatic interface to advertiser accounts, exposing everything from campaign settings and keyword lists to search term reports and conversion events. It supports both reads and writes. Most marketers never touch it because the cost of building against it directly is high.

Worth flagging upfront: API access requires a Google Ads Manager Account, which Google calls an MCC. The MCC sits above one or more individual ad accounts and routes all programmatic calls through it. If you only run a single account today, you still need to set up the MCC to get a developer token. For anyone managing campaigns across multiple business units, brands, or regions, that same MCC structure becomes the seam that makes the whole setup scale.

The second is an MCP server. Model Context Protocol is an open standard Anthropic released in late 2024 and donated to the Linux Foundation’s Agentic AI Foundation in December 2025. It is the layer that lets AI agents call APIs as live tools mid-conversation. Adoption has been quick: WorkOS reports that the Python and TypeScript SDKs alone see roughly 97 million monthly downloads, and a recent industry survey found that 78% of enterprise AI teams have at least one MCP-backed agent in production. Google maintains an open-source MCP server for Google Ads that lets Claude query the account as a live tool, running any read query you can write in Google’s query language and returning structured results. Setting it up takes some patience: a developer token, OAuth credentials, a config file. It is a one-time cost. Once it runs, it covers every account in the portfolio.

The third is Anthropic’s Cowork product, which gives the AI a persistent project workspace on disk. Each account has its own folder, with a plain-text file holding the standing context: account ID, primary KPI, current campaign structure, naming conventions, recent decisions, open questions. The AI reads it at the start of every session. I never re-explain the same thing twice.

Layered together, this gives an AI that already knows the account before you say a word, can query live data on demand, and remembers what happened in your last conversation. No exports, no uploads, no spreadsheet detour.

A note on the tooling. I’m running this on Claude today because the model handles the analytical work well and it takes a variable out of the system while I’m building out the workflow. The architecture itself is model-agnostic. MCP is an open standard, which means the same setup runs against any LLM that supports it. As the workflow matures, I’m planning to move it onto a self-hosted runtime like OpenClaw for two reasons: to stay portable across model providers, and to give other people easy access without each of them rebuilding the pipes themselves.

Claude requesting permission to run a search tool from the google-ads MCP server.

Why I had to build my own write layer

There’s a gap in this setup that took me a beat to discover. The vendor MCP server for Google Ads is useful, but it is read-only. It will run any query you can write in GAQL. It will return campaign performance, ad group data, search term reports, conversion events. What it will not do is change anything in the account. No creating campaigns. No editing keywords. No pausing ads. It also will not pull keyword research data, which is why SEMrush carries that piece.

That was a real moment for me. I had assumed that if the AI could read the account, it could act on it. It cannot. Reading and writing are different surfaces in the Google Ads API, with different risk profiles, and the off-the-shelf connector simply does not expose the write tools.

The natural next move was to look for an off-the-shelf write connector. There is one called Adspirer, which advertises a much wider tool set spanning Google Ads, Meta, TikTok, and LinkedIn. It has a campaigns:write scope. I installed it.

The problem turned out to be architectural. Adspirer’s OAuth flow rejects manager accounts. The error message says it plainly: do not connect a manager account, those are umbrella accounts and don’t contain campaign data. Adspirer is designed for an in-house team that authenticates directly against the child account they operate. For anyone running a portfolio through an MCC, which is the entire point of the manager account structure, Adspirer cannot authenticate. The architecture is the wrong shape for the work.

That left two options. Use the read MCP for analysis and export the changes to make manually. Or build a write layer myself.

So I built one. The connector is a custom MCP server, written and refined in Claude Code over a handful of sessions, scoped to operate against my manager account so a single credential reaches any child under it. It has tools for the obvious things: create campaigns, ad groups, responsive search ads, keywords, negatives. Adjust budgets, bids, ad URLs, statuses. Roughly ten tools covering the full lifecycle of managing a Search campaign.

The interesting part of building it was not the tools. It was the safety design.

When you give an AI agent write access to live ad spend, the constraints are the product. Four mattered enough to be hard-coded into the design.

First, every tool call requires an explicit account ID. There is no default. If a command does not specify which account it is operating on, it fails loudly rather than silently writing to the wrong one. Cross-account contamination is the nightmare scenario for anyone managing more than one account, and the connector is built to make it impossible by accident.

Second, every new entity is created paused. Campaigns, ad groups, ads. Nothing serves until a human reviews it in the Google Ads UI and explicitly flips it on. “Create” and “go live” are kept as separate, human-gated steps.

Third, every operation supports a dry-run mode. Google’s API has a validate-only flag that lets you submit a full request, get back a complete validation response, and commit nothing. We use it to rehearse builds before executing them. On the first real campaign build, the dry-run caught a newly required field for EU political advertising disclosure that would otherwise have failed the build halfway through. The safety pattern earned its place on day one.

Fourth, every write is logged with a timestamp, the tool that ran, and the target account. There is a record of what the agent did to whom.

None of this was clean magic. The build hit a wrong API enum name and had to be patched. A reference implementation from an earlier project had API secrets sitting in plaintext, which had to be locked down before we used it. The local machine’s antivirus actively blocked the connector’s file writes for a stretch, which took real diagnosis to work around. This is what engineering against a live system looks like.

But here is the part I keep coming back to. Five years ago, building a custom MCP server with safety guardrails for a niche workflow would have been a months-long project requiring a developer hire. With Claude Code, it took a handful of sessions. The thing that didn’t exist now exists. That shift is not specific to Google Ads. It is the broader thing happening underneath everything: when the tool you need is not on the shelf, you build it.

Building a campaign now looks completely different

With all three MCPs running (read, write, SEMrush), what used to be a day of work becomes a single focused session.

The old workflow is familiar to anyone who has done this professionally. Open the Keyword Planner. Brainstorm seed terms. Expand manually. Export to a spreadsheet. Cluster by intent. Decide on match types. Write the RSA copy. Build the campaign in the UI. Create each ad group, add keywords, write ads, set bids, double-check the conversion tracking, launch. A full day, often more.

The new workflow is a conversation.

I describe the campaign goal to Claude, with the audience, offer, market, and budget. Claude helps develop the messaging architecture and proposes a keyword strategy.

For the research, I reach for SEMrush. The MCP returns search volume, keyword difficulty, CPC ranges, related terms, and competitive SERP data straight into the conversation. Claude clusters everything by intent and ranks it by opportunity, no exports, no tab switching. The research also catches the kind of pollution traps a seed list will not show you on its own. On a recent project, expanding the term “CRO tools” pulled results dominated by clinical research organizations and an unrelated waste-management product. “Product page optimization” pulled Apple App Store Optimization. Claude flagged all of it and added the offending terms to the campaign-level negative list before the build began.

Then the write connector takes over. Claude drafts the RSA copy, builds the campaign structure, creates the ad groups, populates the keyword lists with per-keyword max-CPC bids, and pushes everything to the Google Ads account. Every entity is created paused by design. Nothing serves until I review it in the Google Ads UI and explicitly enable it.

A handful of campaign settings still live entirely in the UI: geo targeting, the Search Partners toggle, RSA headline pins. For those, I either set them by hand or use Playwright, a browser automation library that drives the UI for the parts of the platform Google has not yet exposed to the API.

The result is a campaign that comes together in one focused session instead of a day. And it is more rigorous on the way out the door, because the keyword research is grounded in real data, the negative list has been pre-cleaned against the pollution the SERPs actually return, the ad copy has been tested against the brief, and the structure has been designed with intent clustering from the start.

Running the account is where the real time comes back

Building is one thing. Ongoing management is where most of the manual hours actually live.

Anyone running a serious account knows the weekly grind. Check performance by campaign. Dig into ad groups that are underperforming. Review the search term report for waste and opportunity. Audit quality scores. Watch the conversion tracking. Look for budget inefficiencies. Multiply that across multiple accounts, and you can fill a week just staying current. One industry analysis estimates marketers spend around 20 hours per week on hands-on campaign management when they do it properly.

With Cowork running scheduled tasks against the read MCP, that grind becomes something else.

Every week, the system pulls live performance data across active campaigns and produces a structured report. Not a generic dashboard. A reasoned analysis that already knows the account’s goals, history, and strategy, because that context lives in the project files. It flags what is working, what is not, and specifically what to do about it.

Because the write connector is part of the same setup, the recommendations do not just sit in a document. Ones that clear my review threshold can be executed in the same session: pause this keyword, add these negatives, shift budget from this campaign to that one, expand this winning ad group. Analysis and action in one loop, with every change going through the paused-by-default safety pattern.

The point isn’t speed

There is a temptation to frame this as a productivity story. Same work, less time. That framing misses what actually changed.

When pulling and interpreting data costs almost nothing, you ask more questions. You investigate what you would have skipped because the cost of investigation was higher than the expected value. You notice patterns earlier and act on them faster. That is not a productivity gain. It is a capability shift.

And the part I care about most is where the reclaimed hours go. The time that used to disappear into exports and reformatting now goes into roadmaps, into strategy debates, into the slow human conversations where a team actually decides what to do next. The mechanical work was never the valuable part. It was the tax you paid to reach the valuable part. Automating it doesn’t make the work less human. It clears room for the part that was always going to need a human in the first place.

Harvard Business Review has been making a version of this argument for years. The real opportunity in AI is augmented intelligence, where AI handles the analytical heavy lifting and humans focus on judgment. Kasparov made the same point after losing to Deep Blue: the strongest player is not the strongest human or the strongest machine. It is a competent human with the right process.

Paid media has been waiting for the right process.

What this does to the org chart

This is the part that should concern anyone building a marketing team, and it is why I bothered writing any of the above down.

Google is signaling the direction openly. AI Max for Search, which is replacing Dynamic Search Ads this year, is built on the assumption that campaign management is collaborative: human-set goals and creative direction, AI-driven execution. The platform is moving toward agentic management as a default, and it is moving faster than most agencies and in-house teams are prepared for.

Which means the job called “campaign manager,” defined primarily as the person who does the operational work, is going to compress. Not disappear. Compress. The hours that justified the headcount were mechanical hours, and mechanical hours are exactly what this setup absorbs. A team that is structured around people executing changes in a UI is structured around a task that is being automated out from under it.

What replaces it is a different and harder hire. Someone fluent enough with AI agents to direct them against a commercial outcome, skeptical enough to catch a confident wrong answer before it reaches live spend, and technical enough to extend the toolchain when the off-the-shelf falls short. That last part matters more than it sounds. The most useful thing I did in this whole project was notice that the tool I needed did not exist and build it anyway. A year ago that would have been a developer request with a queue in front of it.

There is a real gap forming between marketers working against live data and marketers still exporting it, and it is compounding now, in real accounts. The teams that restructure around this in the next eighteen months will be operating at a depth the ones that don’t cannot match. Same platforms, same budgets, different output.

The playbook is replicable. The window to use it as an edge is not infinite.