What does AdRails do, in one page?
82 MCP tools in 8 groups, running on your machine with your credentials. Nothing is proxied through a hosted server.
One door for every change
Budget, status, end date, negatives and URL fields move the same way: a committed desired-state file, adsops_plan, a validate-only adsops_apply, then a commit with a single-use plan_id. selftest: approvals
Caps the agent cannot edit
Daily and lifetime caps, max bids, allowed domains and required UTM tags sit in a policy file that tools cannot write. Exposure increases fail closed when the guard heartbeat is stale. selftest: fleet
Every write is on the record
Each mutating call, including refused ones, is appended to a SHA-256 hash-linked audit chain with secrets redacted. adsops_audit_verify detects edited, deleted or reordered entries. selftest: auditchain
Group counts: Guarded changes 6, Diagnostics and research 12, Automation and monitoring 6, Enterprise controls 9, AEO toolkit 9, Direct mail 10, ChatGPT Ads 16. Released as 0.5.0; adrails --selftest runs 2,704 checks, ALL PASS.
Which AdRails tools can change a live account?
Six tools. All of them write to a git-backed state file first, and exactly one pushes to Google Ads.
The six
- adsops_plan Diffs the committed state file against live — budget, status, end date, negatives, ad-group custom parameters, final URLs and suffix. No writes; returns a plan_id. selftest: approvals
- adsops_apply Pushes that plan. Validate-only unless commit=true, which needs a clean committed state file and commit_policy.allow_commit. selftest: auditchain
- adsops_set Changes budget, status, end date or negatives, checked against the state file's guards and the live account, then git-committed with your reason.
- adsops_guard Spend guard: pauses the campaign when a daily or lifetime cap is crossed. Never enables anything; pausing is always permitted.
- adsops_history Git history of the desired-state file, newest first, with the reason each change was made.
- adsops_rollback Rebuilds the state as of an earlier commit. Policy caps, account IDs and campaign IDs are never reverted and negatives are never removed. selftest: rollback
Holds on every write
- Single-use plan_id. A plan expires and cannot be replayed for a second commit. selftest: approvals
- Validate-only first. A dry run is the default; committing is an explicit flag, never a default. selftest: enterprise_tools
- No blind retries. A failed call is reported, not re-sent until something lands.
- Fail closed. With a stale guard heartbeat, anything raising exposure is refused.
What can AdRails tell you before you spend anything?
Twelve read-only tools that read live accounts and local files without writing to Google Ads.
Account and search terms
adsops_campaigns lists campaigns this server may operate; adsops_status reads live budget, spend today and lifetime, negative count and URL fields; adsops_terms returns clicked terms with matched keyword, clicks and cost.
Conversion tracking audit
adsops_conv_audit scores tracking 0-100 and grades it: no primary goal, tracking off, auto-tagging off, a primary action with zero conversions, double counting, short lookback, spend with zero conversions, smart bidding under 15 conversions. selftest: conv_audit
Waste and quality
adsops_diagnostics bundles wasted spend on zero-conversion terms, impression share lost to budget versus rank, cost-weighted quality score with weak components, and day-over-baseline anomalies. selftest: diagnostics
Negatives and competitors
adsops_negatives_suggest classifies recent terms — renter, job, HOA, vacation, DIY, out-of-area, competitor — and proposes phrase negatives. adsops_auction_insights_import and adsops_competitors_report turn Auction Insights exports into a weekly intel report.
Ads and landing pages
adsops_rsa_validate checks an RSA draft against Google's limits, counts double-width characters as two, and flags pins, duplicates, caps, punctuation, phone numbers and unsubstantiated superlatives. adsops_lp_diagnose pairs quality-score components with an HTTP check of each final URL. selftest: rsa_validator
Research and CRM prep
adsops_keyword_ideas clusters Keyword Planner ideas by theme with intent labels, needing Basic developer-token access. adsops_offline_conv_plan builds — never sends — an enhanced-conversion upload, hashing emails, phones and names locally. selftest: kwplan selftest: offline_conv
Can AdRails change bids and budgets on its own?
No. The rules engine and monitors produce proposals and desired-state patches for review; nothing here applies.
Rules you own
adsops_rules_check evaluates JSON conditions in the founder-owned policy file — all/any/not, cost, conversions, CPA, CTR, impression share, 1-90 day windows, cooldowns. Actions: pause, add negative, budget step within caps (20% per step by default), alert. Rules can never enable anything. selftest: rules
Monitors
adsops_monitor_check watches CPA spikes, pacing over and under, month-end forecast, zero impressions, disapprovals, budget-limited campaigns and no conversions for N days. Alerts de-duplicate for 24 hours, escalations always fire, and delivery goes to a webhook such as Slack. selftest: monitors
Daily brief
adsops_brief posts a short markdown summary — spend today, conversions, blended CPA, top monitor issues — across every configured campaign. selftest: monitors
Fleet view
adsops_fleet shows spend, budget, conversions and CPA by account and platform, never sums across currencies, and checks an aggregate cap assuming platforms may deliver up to 2x the daily budget. selftest: fleet
Budget reallocation
adsops_realloc_suggest recommends moving daily budget from weak campaigns to budget-limited strong ones inside each policy's caps. The total never rises, and it will not add budget to a campaign losing more share to rank than to budget. selftest: budget_realloc
What stops an agent from going too far?
Nine controls, all off by default except the audit chain; you enable them in config. Details sit on the enterprise page.
The nine
- adsops_whoami Version, principal, roles, approval mode, audit-chain path and whether a guard heartbeat is configured.
- adsops_approval_request, adsops_approval_decide, adsops_approvals A human approval queue. The agent requests approval for a plan_id; the approver gets HMAC-SHA256-signed tokens that expire after 24 hours by default. Forged, expired, reused or cross-plan tokens are refused, the secret never hits disk, and the queue file is 0600. selftest: approvals
- adsops_audit_verify, adsops_audit_tail Verify and read the tamper-evident chain; a published head digest makes truncation detectable. selftest: auditchain
- adsops_drift Reads Google Ads change history for the last 30 days and flags edits made outside AdRails, highlighting budget, status and bidding changes. selftest: change_history
- adsops_usage Per-tool counts from the metering ledger, billing-ready and with no prices. selftest: enterprise_tools
- adsops_sbom CycloneDX 1.5 SBOM plus a SHA-256 manifest of every package file, so you can verify the code you run. selftest: sbom
Honest limits
- Platform overdelivery. AdRails does not bound what Google delivers; a daily budget can still spend up to 2x, and the fleet cap assumes it. selftest: fleet
- Same OS user. An agent with shell access as the same OS user can bypass local rails unless you run the hardened install with a separate OS user. The privilege-boundary item is still open in the threat model.
Role-based access is deny-by-default once enabled: viewer, operator, approver, guard, admin. A refused call has zero side effects. selftest: rbac
What does AdRails do for answer engines?
Eight answer-engine tools, read-only except IndexNow submission. The full walkthrough is on the AEO page.
Crawler access
aeo_site_audit checks robots.txt with RFC 9309 longest-match for 18 crawlers, including GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, PerplexityBot, Google-Extended and Applebot-Extended, plus llms.txt, sitemap, noindex, canonical and body-text checks. Returns a 0-100 score. selftest: aeo.crawl_audit
Page readiness and schema
aeo_page_audit scores answer-first paragraphs, question headings, FAQ, specifics, freshness, citations and scannability, and suggests extractable answer blocks. aeo_schema_generate writes JSON-LD for FAQ, software, organisation or breadcrumbs that passes its own audit. selftest: aeo.page_audit selftest: aeo.schema_audit
llms.txt
aeo_llms_txt validates a site's /llms.txt against the llmstxt.org format or builds one from a page list, returning a file that passes validation. selftest: aeo.llms_txt
Share of answer
aeo_visibility_record stores a panel: your agent asks ChatGPT, Claude and Perplexity the prompts and passes the answers back. AdRails scores mentions, rank against competitors, citations, sentiment and the change since the last run. It makes no LLM calls itself. selftest: aeo.visibility
IndexNow and AI traffic
aeo_indexnow submits to Bing, Yandex, Seznam and Naver after checking the key file, validating by default. aeo_ai_traffic splits referrals and AI crawler fetches from your own logs into verified, unverified and spoofed. selftest: aeo.indexnow selftest: aeo.ai_traffic
Ads to answers
aeo_content_gaps turns your real paid search terms into the questions people ask, checks which pages answer them, and writes briefs for the gaps using only facts you supply. Host fetches go through an SSRF-safe fetcher. selftest: aeo.ads_to_aeo selftest: aeo_tools
Why does a paid-ads tool do direct mail?
Because cost per client is the only number that compares a postcard to a search campaign. Ten offline-channel tools on the same ruler.
List hygiene
mail_list_clean normalises USPS abbreviations and ZIP+4, drops foreign and incomplete addresses, institutional owners (banks, REITs, housing authorities; plain LLCs and trusts stay), your own properties, clients, do-not-mail entries and duplicates. Labels wrap and never truncate, and an empty client suppression list raises a warning. selftest: mail.hygiene
Codes and QR
mail_codes_assign issues codes with no 0/1/I/L/O/U plus a check character proven to catch every single wrong character and every swapped adjacent pair: 0 misses in 4,060,000 substitutions, where standard Luhn mod 30 missed 47 adjacent swaps. mail_qr encodes QR versions 1-10 with all four ECC levels; 557 of 557 test symbols decoded. selftest: mail.codes selftest: mail.qr
Print-ready labels
mail_labels produces print-exact Avery 5160/8160, 5163, 5164 and 5167 sheets as HTML that prints to PDF from any browser, with an optional QR per label and a vendor CSV. SAMPLE watermark is on by default; a real run is written to the audit chain. selftest: mail.labels
Measurement
mail_scans counts unique human scans from your own logs, dropping bots, link previewers, your own IPs and pre-mail hits, storing hashed visitor IDs and re-running idempotently. mail_response, mail_compare and mail_holdout_plan give 95% Wilson intervals, a two-proportion test and a holdout size within 3% of the textbook formula. selftest: mail.scans selftest: mail.response
Money
channel_cac puts cost per lead and per client for Google Ads, ChatGPT Ads, direct mail, lead vendors and referrals on one ruler, attributing tracking code over UTM over what the lead said over referrer, and labelling small numbers as too few to judge. mail_breakeven gives the response rate you need. selftest: mail.cac
Nothing in the direct-mail tools sends mail, buys postage or contacts anyone.
Which ChatGPT Ads tools shipped in 0.5.0?
Sixteen adsops_openai_* tools for the OpenAI Ads API. The guide is on the ChatGPT Ads page.
Read
adsops_openai_account verifies the key and shows status, currency, timezone and review state. adsops_openai_status reads campaigns, ad groups, ads, spend and the guard's pause point. adsops_openai_insights returns 1-90 days of daily performance. adsops_openai_geo_lookup finds location IDs for targeting.
Write path and guard
adsops_openai_plan diffs the state file against live and returns a single-use plan_id. adsops_openai_apply is validate-only unless commit=true, which needs mode=live, allow_commit, committed files and that plan_id. adsops_openai_guard pauses on the lifetime pause point, anomalous daily spend or out-of-policy budgets and bids; it never activates or raises anything. selftest: qa_openai_ads
Creative and brand
adsops_openai_upload_image checks and uploads a PNG, JPEG or WebP at 640x640 or larger. adsops_openai_brand_update sets icon, website and brand name, warning that brand changes can pause all delivery until re-review. adsops_openai_ad_check enforces chat_card limits, policy domains, required UTM tags and duplicates. selftest: qa_openai_suite
Growth
adsops_openai_draft_campaign turns a brief into a paused, capped desired state the engine accepts. adsops_openai_ab_report names a leader with 95% intervals and Bonferroni-corrected comparisons. adsops_openai_conversions_setup, adsops_openai_test_event, adsops_openai_send_conversions and adsops_openai_audience handle pixels, one validate-only test event, hashed conversions and hashed customer lists.
What was verified live, and what wasn't
Read paths, live spend reads, the guard and validation ran against a real OpenAI Ads account in read-only mode on 2026-11-06; that live run found and fixed an insights rule the offline mock missed. Creates, image upload, activation and the conversion/audience commits are tested offline but have NOT yet run against a live account. selftest: qa_openai_ads 160/0 selftest: qa_openai_suite 24/0
trakkr or AdRails?
trakkr's OpenAI Ads MCP is released, MIT-licensed, with 27 tools in 8 groups and a hosted read-only endpoint; it has broader tool coverage. AdRails 0.5.0 ships 16 tools with the spend-governance layer: approval to activate, cumulative caps and a pause-only guard. Both are open source and can run side by side. See the trakkr comparison.
How do you check these claims yourself?
Every claim on this page traces to a selftest module you can run offline.
Run the suite
adrails --selftest runs 2,704 checks, ALL PASS on 2026-11-06. Alongside it, 35 independent black-box suites pass, 22 hand-written aggressive tests pass, and the OpenAI Ads suites report 160/0 and 24/0.
Check the code you run
adsops_sbom writes a CycloneDX 1.5 SBOM and a SHA-256 manifest of every package file. Source is at github.com/antonioac1/adrails under Apache-2.0, Python 3.11+ with the standard library only apart from one optional google-auth import.
Straight answers.
Is AdRails a hosted service?
No. AdRails is an open-source Apache-2.0 MCP server that runs on your machine with your credentials, inside Claude Code, Claude Desktop, Cursor, Grok CLI or another MCP client. Calls go from your machine to Google Ads or the OpenAI Ads API directly. The only thing that leaves is what you choose to send, such as monitor alerts to a webhook.
How many tools does AdRails ship?
82 tools in 8 groups as of 0.8.0: Guarded changes 6, Diagnostics and research 12, Automation and monitoring 6, Enterprise controls 9, AEO toolkit 9, Direct mail 10, ChatGPT Ads 16 and Local business and LSA 14. The selftest runs 2,704 checks and all pass. The full list lives in the tools documentation.
Is the ChatGPT Ads support live-tested?
Partly, and the split matters. Read paths, live spend reads, the guard and validation ran against a real OpenAI Ads account in read-only mode on 2026-11-06; that live run found and fixed an insights rule the offline mock missed. Creates, image upload, activation and the conversion/audience commits are tested offline but have NOT yet run against a live account.
Can an agent change budgets without a human?
Only along the rails you configure. Apply is validate-only by default; a commit needs a clean, committed state file, commit_policy.allow_commit and a single-use plan_id. Caps live in a policy file tools cannot write. With role-based access enabled, calls are deny-by-default, and the approval queue can require a signed human token before a plan is committed.
What does the AEO toolkit do?
Eight read-only tools mostly: crawler access for 18 AI and search crawlers, page answer-readiness scoring, JSON-LD audit and generators, llms.txt validation and building, share-of-answer recording where your agent asks the engines and AdRails scores the replies, IndexNow submission that validates by default, AI traffic split from your own logs, and ads-to-answers content briefs.
Does AdRails do direct mail?
Yes, 10 tools: list cleaning, unique tracking codes with a check character, QR generation, print-exact Avery labels, scan counting from your own server logs, Wilson-interval response rates, holdout sizing, two-variant comparison, cost per lead across channels and break-even maths. Nothing in the direct-mail group sends mail, buys postage or contacts anyone.