Paid media audits, tracking checks and reviewed changes.
Quick start · Example output · Tests · Releases · Contributing
A Python toolkit for investigating Google Ads accounts and preparing changes for review. Use individual adapters from a terminal, or use the specialist agents and /gads skills in an agent runtime. API responses are structured JSON; the audit driver combines them into reports.
| Area | Included capabilities |
|---|---|
| Campaigns | Search, Performance Max, App, Display, Demand Gen, Shopping and YouTube analysis |
| Measurement | Conversion-action health and Google tag checks |
| Optimization | Search-term mining, negative candidates, recommendations, Quality Score and bid-strategy fit |
| Delivery | Budget pacing, anomalies, placement classification, demographic and geographic breakdowns |
| Assets | RSA strength, PMax linked asset inventory, creative briefs and asset workflows |
| Account operations | Per-MCC auth profiles, saved audit history and multi-account audits |
| Reviewed changes | PAUSED Search, Demand Gen and App campaigns, App targets, negatives, placements, Display targeting, image and YouTube video assets, and Video/Display ad edits with JSON review, confirmation and validation |
Requires Python 3.10+. Live queries also require Google Ads account access, an approved OAuth Cloud project, and Google Cloud SDK (gcloud) for the default authentication path.
git clone https://github.com/arcbaslow/google-ads-agents.git
cd google-ads-agents
python -m venv .venvActivate the environment with source .venv/bin/activate on macOS/Linux or .venv\Scripts\Activate.ps1 in Windows PowerShell. Then:
python -m pip install -e ".[dev]"Prefer uv? Run uv venv, uv pip install -e ".[dev]", then prefix Python commands with uv run.
First print and run the Google sign-in command, then register a manager-account profile:
python scripts/gads_auth.py --adc
# Run the gcloud command printed above, then configure your profile:
python scripts/gads_auth.py --add-profile demo --login-customer-id YOUR_MCC_ID
python scripts/gads_auth.py --use-profile demo
python scripts/gads_auth.py --check
python scripts/gads_auth.py --customersReplace the example customer ID below with an account returned by --customers:
python scripts/gads_audit.py --customer 1234567890 --days 28 --output audit.json
python scripts/gads_report.py --input audit.json --format md --output audit.mdAdd --site https://example.com to include the website tag check, and --save-history to retain a snapshot. The local session expires after 24 hours. For multiple MCCs, add profiles and switch with --use-profile. For an OAuth-client fallback, see setup.
Developer tokens are optional legacy configuration. API access belongs to the OAuth Cloud project; see setup for approval and authentication instructions.
The screenshot shows the actual Markdown report, rendered for documentation, using synthetic data. Reproduce it locally without Google credentials:
python scripts/gads_report.py --input examples/demo/audit.json --format md --output audit.md
python scripts/gads_report.py --input examples/demo/audit.json --format html --output audit.htmlRead the generated report or inspect the input fixture.
python scripts/gads_search.py --customer 1234567890 --days 28 --negative-candidates --json
python scripts/gads_demandgen.py --customer 1234567890 --days 28 --json
python scripts/gads_placements.py --customer 1234567890 --days 28 --json
python scripts/gads_recommendations.py --customer 1234567890 --json
python scripts/gads_anomalies.py --customer 1234567890 --days 30 --baseline-days 14 --z 2.0 --json
python scripts/gads_history.py --customer 1234567890 --changes --days 7 --json
python scripts/gads_audit.py --all-customers --days 28 --save-history --output audits.jsonUse --help on an adapter for its complete flags. Most read commands print a compact summary; --json selects machine-readable output. The audit driver always emits JSON.
The router exposes commands such as:
/gads audit 1234567890
/gads search 1234567890
/gads pmax 1234567890
/gads conversions 1234567890
/gads pacing 1234567890
/gads quality 1234567890
The repository includes plugin metadata, specialist agent definitions and skills. Other runtimes can follow AGENTS.md and call the same Python adapters. The audit skill runs the standalone driver, then interprets conversion checks and tag-scan limitations before wider analysis. Raw adapter outputs differ; failed blocks and missing fields are not a clean bill of health.
Supported write commands print the operation JSON to stderr and require an explicit y at a y/N prompt. --apply validates the same operations before applying them; --validate-only stops after validation. The flags are mutually exclusive. EOF or unavailable input cancels the request. Do not pipe an automatic approval into these commands.
# Produce a campaign planning draft without calling the API.
python scripts/gads_creation.py --customer 1234567890 --context-file context.json --json
# Validate proposed negatives without applying them.
python scripts/gads_apply.py --customer 1234567890 negatives --input negatives.json --validate-only --jsonCampaign context produces a planning draft and does not verify measurement health. Separate strict --search-spec, --demand-gen-spec and --app-spec files create PAUSED campaigns atomically after review and validation; Video campaigns cannot be created through the API. See bounded writes for the required fields and limits.
The hooks guide covers the session-expiry guard and opt-in Telegram notifications. The separate FastAPI service in webapp/ supports hosted sign-in; it is not required to run local audits.
scripts/gads_mcp.py exposes six read-only tools to an MCP client. Run it as a standalone stdio server, or import it in a host FastMCP server and call register(server, prefix="", provider_factory=None), which returns the number of tools added.
python -m pip install -e ".[mcp]"
gads-mcp| Tool | Returns | limit default / max |
|---|---|---|
list_accounts |
Accounts under the profile's manager account: ID, name, level, currency, time zone and status. Without a manager account, the customer IDs the credentials can access directly. | 200 / 500 |
run_gaql |
Rows for one GAQL SELECT against a customer ID. Only a single statement is accepted, optionally ending in one LIMIT n, without PARAMETERS, comments or semicolons. Rows are bounded by the smaller of that LIMIT and limit. |
100 / 500 |
resource_metadata |
GAQL resources, or the fields under a resource or prefix, with selectable, filterable and sortable flags. detail=true adds enum values and the resources, metrics and segments a name can be selected with. |
200 / 500 |
account_audit |
Status and summary of every read-only audit agent, plus the top findings by severity. Raw agent data, the website tag scan and saved snapshots are not included. | 50 / 200 |
anomalies_and_pacing |
Day-level metric anomalies and month-to-date budget pacing, together or separately. | 50 / 200 per list |
change_history |
Recent change_event entries over up to 30 days. Actor emails are reduced to their domain. |
50 / 200 |
Every tool is annotated read-only. The tools call only GoogleAdsService search, CustomerService.ListAccessibleCustomers and GoogleAdsFieldService search. They do not write to an account, save audit snapshots, send notifications or change local credential files. Bounded results include rows_returned and complete; complete: false means rows were cut by limit, or an audit agent failed. Failures return {"error": "<category>", "hint": "..."}, where the category is auth_required, permission_denied, quota_exceeded, invalid_argument, not_found or upstream_error. Provider error messages are not passed through.
Authentication. Every tool accepts profile. The standalone server uses the active local profile from gads_auth.py, including the 24-hour session cap. It never switches profiles: naming a different profile returns invalid_argument with the --use-profile command to run locally. A host can pass provider_factory(profile), which returns a gads_provider.CredentialProvider, to supply its own per-profile credentials. A developer token is optional. credentials_present() reports whether a local credentials file, a GOOGLE_APPLICATION_CREDENTIALS file or the gcloud application-default credentials file exists. It does not open these files or make a network call.
Quotas. Each request counts against the Google Ads API quota of the OAuth Cloud project. account_audit sends 19 search requests. The other tools send one request, or two for anomalies_and_pacing with check="both". When the API reports a quota or rate limit, the tool returns quota_exceeded; retry later or narrow the request.
python -m pytest scripts/ -q
python -m ruff check scripts/ hooks/ webapp/
# Optional hosted sign-in service: install its dependencies, then test it.
python -m pip install -r webapp/requirements.txt
python -m pytest webapp/tests/ -qThe suites use mocks and temporary credential stores. They cover auth profiles and expiry, GAQL, placement rules, campaign validation, report rendering, audit history, optimization heuristics, hooks, OAuth, sessions and the web API. No live Google Ads account is needed. CI runs the adapter and webapp suites on Python 3.10–3.13; see the verification record for the release run.
| Path | Purpose |
|---|---|
| scripts/ | API adapters, report rendering and unit tests |
| agents/ · skills/ | Specialist instructions and /gads routing |
| hooks/ | Session guard and Telegram notifications |
| webapp/ | Optional hosted sign-in service and tests |
| examples/demo/ | Reproducible report with synthetic data |
| docs/ | Setup, hooks, release and verification guides |
v0.6.1 — see the release notes for this release and the changelog for project history.
GitHub Releases include downloadable artifacts and checksums. Package-registry publication is a separate, opt-in workflow; a GitHub release does not imply that the same version is available on PyPI or npm. Maintainers can follow the release guide.
Read CONTRIBUTING.md, run the checks above, and include a minimal reproduction for bugs. Report vulnerabilities through SECURITY.md.
| Project | Use it for |
|---|---|
| Google Analytics Agent | GA4 data quality, funnels and property management. |
| Search Console Agent | Search performance, indexing and page experience. |
| Meta Ads Agents | Campaign performance, creative fatigue and event health. |
| GTM Diff | Review the changes in your Google Tag Manager exports. |
| Figma Taxonomy Gen | Turn interactive designs into a reviewable tracking plan. |
Maintained by Good Labs — measurement implementation, tracking plans and analytics audits.
MIT © Dilshat Rakhimov. This is an independent project; it is not an official product of the platform vendors.
Read-only GAQL and saved multi-account audit exports are documented in REPORTING.md. Local monitoring output does not refresh credentials or schedule new account reads.
See read-only interoperability for query and export handoffs, and offline evaluation for safety task fixtures.
