This list is generated from the server's own tools/list response. WRITE marks a tool that changes something outside the server (an ad account, a git file, the approval queue or an IndexNow ping). Every account change still goes through the one door: committed state file, adsops_plan, adsops_apply.
Which tools can change an ad account, and how?
adsops_plan
Diff the committed desired-state file against live (budget, status, end date, negatives, and URL fields: ad-group url_custom_parameters, ad final_urls, final_url_suffix). No writes. Returns a plan_id that adsops_apply commit=true must quote (single use, expires).
Arguments: campaign
adsops_apply
Apply the desired-state file. Validate-only unless commit=true (needs a clean, committed state file and commit_policy.allow_commit).
Arguments: campaign, commit, plan_id
adsops_set
Change budget / status / end date / negatives. Checked against the state file's guards and the live account, written to the state file and committed to git with your reason. apply=true then pushes it live (validateOnly first). dry_run=true previews without writing.
Arguments: apply, campaign, daily_budget_usd, dry_run, end_date, negatives_add, plan_id, reason, status
adsops_guard
Spend guard: PAUSE the campaign if a daily or lifetime cap is crossed. Never enables. Validate-only unless commit=true (pausing is always permitted).
Arguments: campaign, commit
adsops_history
Read-only. Git history of the campaign's desired-state file: every change agents or lanes made, newest first.
Arguments: campaign, limit
adsops_rollback
Undo: build the desired state as of an earlier commit (guards, account and campaign ids are never reverted, and negatives are never removed). With commit=true it writes and git-commits the state file; then run adsops_plan and adsops_apply as usual. Nothing reaches the ad account from this tool.
Arguments: campaign, commit, to_commit
Which tools find wasted spend and broken tracking?
adsops_campaigns
List the campaigns this server may operate (keys, accounts, state files).
Arguments: none
adsops_status
Live read: status, end date, daily budget, spend today/lifetime, negative count; plus URL fields (campaign suffix, ad-group custom parameters, ad final URLs) when the state file manages them.
Arguments: campaign
adsops_terms
Clicked search terms over the last N days (term, matched keyword, clicks, cost).
Arguments: campaign, days
adsops_negatives_suggest
Read-only. Classify the campaign's recent search terms (renter, job, HOA/condo, vacation, DIY/software, out-of-area, competitor brand) with deterministic rules plus an optional local hook, and propose PHRASE negatives with cost/click evidence. Skips terms and phrases already covered by existing negatives, never suggests protected brand/core-service words. Returns a negatives_add patch and a basis note to paste into the desired-state file; it changes nothing.
Arguments: campaign, days, min_cost
adsops_competitors_report
Read-only. The AdRails Intel weekly report from the FREE sources: Auction Insights already imported into the local database, the cached Transparency Center data, and our own Google Ads stats snapshots. Returns markdown. Makes no network call and spends nothing.
Arguments: none
adsops_auction_insights_import
Import a Google Ads Auction Insights export (CSV/TSV text) or a pasted table into the local intel database, replacing rows for the same date range. Writes only the local SQLite file.
Arguments: campaign, level, range, text
adsops_lp_diagnose
Read-only. Per ad group: Google's quality-score components (expected CTR, ad relevance, landing page experience) plus a plain HTTP check of each final URL (status, response time, bytes, whether the title/H1 echo the ad group's keywords and town). Returns plain-English findings, worst first. No browser, no JavaScript; changes nothing.
Arguments: campaign, max_urls, towns
adsops_conv_audit
Read-only. Audit conversion tracking for the campaign's account: primary goals, dead tags, double counting, auto-tagging, lead counting, smart bidding without enough conversions. Returns a 0-100 score, grade, and ranked findings with fixes. Run this before trusting any CPA or optimising toward conversions.
Arguments: campaign, days
adsops_diagnostics
Read-only PPC diagnostics bundle for one campaign: wasted spend (zero-conversion search terms), impression share lost to budget vs rank, cost-weighted quality score with weak components, and day-over-baseline anomalies (z-score). Returns a ranked headline list plus details.
Arguments: campaign, days
adsops_rsa_validate
Pure check, no account access. Validate a Responsive Search Ad draft against Google's limits and common disapproval causes (lengths incl. double-width chars, pins, duplicates, caps, punctuation, phone numbers, unsubstantiated superlatives, banned phrases) before any write. Returns errors, warnings and fixes.
Arguments: ad, policy
adsops_keyword_ideas
Read-only. Keyword Planner ideas (searches, competition, top-of-page bid range) for seed keywords and/or a URL, clustered by theme with an intent label. Needs a Basic-access developer token.
Arguments: campaign, seeds, url
adsops_offline_conv_plan
Build (never send) an offline / enhanced conversion upload from CRM rows. Emails, phones and names are normalised and SHA-256 hashed LOCALLY, so raw PII never leaves this machine. Returns a redacted preview and counts; validate_only stays true.
Arguments: conversion_action, currency, rows
Which tools watch campaigns and propose fixes?
adsops_rules_check
Read-only. Evaluate the automation rules in the campaign's POLICY file (founder-owned, agents can't edit it) against live metrics. Returns PROPOSALS and a desired-state patch; nothing is applied. Rules can only pause, add negatives, alert, or move budget inside the policy caps.
Arguments: campaign, days
adsops_monitor_check
Read-only. Run monitors (CPA spike, pacing over/under, month forecast, zero impressions, disapprovals, budget-limited) over live snapshots of every configured campaign (or one). New alerts are de-duplicated for 24 h; with deliver=true they are posted to the webhook named in config alerts.webhook_env.
Arguments: campaign, deliver
adsops_brief
Read-only. A short markdown brief across every configured campaign: spend today, conversions, blended CPA and the top issues from the monitors. Built for a daily Slack/email post.
Arguments: none
adsops_fleet
Read-only. Fleet view across every configured account and campaign: spend, budget, conversions and CPA by account and platform, plus the AGGREGATE cap check (config fleet_caps), which assumes platforms may deliver up to 2x the daily budget.
Arguments: none
adsops_realloc_suggest
Read-only. Recommend moving daily budget from weak campaigns to budget-limited strong ones inside each policy's caps. The total never rises. Returns moves plus per-campaign desired-state patches to review.
Arguments: none
adsops_update_check
Is a newer AdRails out? Running vs latest version, release notes and the one upgrade command (owner's OK first). Checks PyPI at most once a day; sends no account or usage data; off with ADRAILS_NO_UPDATE_CHECK=1.
Arguments: force
Which tools give security and finance teams control?
adsops_usage
Per-tool usage counts from the metering ledger (billing-ready, no prices).
Arguments: since
adsops_drift
Read-only. Who changed the account outside AdRails? Reads Google's change history for the last N days (max 30) and flags out-of-band edits (UI, scripts, auto-applied recommendations), highlighting budget, status and bidding changes.
Arguments: campaign, days
adsops_approval_request
Ask a human to approve a plan before it can be committed (when config approvals.mode is on). Returns approve/reject tokens to send to the approver; the tokens are HMAC-signed and expire.
Arguments: campaign, plan_id, risk, summary
adsops_approval_decide
Record a human decision using a signed approve/reject token. Forged, expired or reused tokens are refused.
Arguments: decided_by, token
adsops_approvals
List approval requests (newest first), optionally by status.
Arguments: status
adsops_audit_verify
Verify the tamper-evident audit chain of every mutating call (hash-linked entries). Returns ok, entry count, the first bad entry if any, and a head digest to publish so later truncation is detectable.
Arguments: none
adsops_audit_tail
The last N audit-chain entries (redacted), newest first.
Arguments: event, n
adsops_sbom
Supply-chain manifest of this AdRails install: a CycloneDX 1.5 SBOM and a SHA-256 manifest of every package file, so you can verify the code you run is the code that was released.
Arguments: verify_against
adsops_whoami
This server's identity and controls: version, principal and roles (RBAC), approval mode, audit chain path, and whether a guard heartbeat is configured.
Arguments: none
Which tools get a site cited by AI answer engines?
aeo_site_audit
Read-only. Can AI answer engines reach this site? Checks robots.txt rules for 18 AI and search crawlers (GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, PerplexityBot, Google-Extended, Bingbot, Applebot...), llms.txt, the sitemap, and the homepage's noindex/canonical/body-text signals. Returns a 0-100 score and ranked fixes.
Arguments: url
aeo_page_audit
Read-only. Answer-readiness of one page: answer-first paragraph, question headings, FAQ, structured data, specifics, freshness, citations, scannability, plus a JSON-LD audit (required/recommended fields per type) and crawler directives. Returns scores, extractable answer blocks, and missing questions.
Arguments: brand, questions, url
aeo_llms_txt
Read-only. Validate a site's /llms.txt (llmstxt.org format), or build one: pass pages [{url,title,description,section}] with title and summary and it returns a ready file that passes validation.
Arguments: pages, summary, title, url
aeo_schema_generate
Pure. Generate valid JSON-LD for a page: kind = faq (qas [[q,a]...]), software (name,url,description,price), org (name,url,logo,same_as) or breadcrumbs (trail [[name,url]...]). Returns the object, its own audit, and a ready <script> tag.
Arguments: data, kind
aeo_visibility_record
Record an AI share-of-answer panel. YOU (the calling agent) ask each engine the prompts and pass the answers here [{engine,prompt,text,citations}]; AdRails scores mentions, rank vs competitors, citations and sentiment, stores the run, and returns the score plus the change since the last run.
Arguments: answers, brand, competitors, run_id
aeo_indexnow
Tell Bing, Yandex, Seznam and Naver (IndexNow) that URLs changed. Checks the key file at https://host/<key>.txt first. submit=false (default) only validates. Optionally pass sitemap_since (ISO date) to send every sitemap URL modified since then.
Arguments: host, key, sitemap_since, submit, urls
aeo_ai_traffic
Read-only. Measure AI-driven traffic from a local web-server log (nginx combined or JSON lines): referrals from ChatGPT, Perplexity, Claude, Gemini and Copilot with landing pages, and AI crawler fetches split into verified / unverified / spoofed (by the providers' published IP ranges and scanner paths).
Arguments: format, log_path, max_lines, ranges_file, site
aeo_content_gaps
Read-only. The ads-to-answers bridge: turn the campaign's real paid search terms into the questions people ask, check which of your pages already answer them, and return content briefs for the biggest gaps (facts only from site_facts, never invented).
Arguments: campaign, city, days, pages, site_facts, top
adsops_playbook
The tested strategy behind AdRails, written for the agent to execute: 'aeo' (getting recommended by ChatGPT, Perplexity, Gemini and Google AI answers) and 'local-leads' (speed-to-lead, Local Services Ads, Google Business Profile, reviews, follow-up). Every step names the tool that does it and a done-check.
Arguments: name, section
Which tools put postcards on the same ruler as ads?
mail_list_clean
Clean a mailing list before you pay to print and post it: normalises addresses (USPS abbreviations, ZIP+4), drops foreign and incomplete addresses, institutional owners (banks, REITs, housing authorities; plain LLCs and trusts are kept), your own properties, anyone on your client / lead / do-not-mail lists, and duplicates. Labels are wrapped, never truncated. Writes the kept list as CSV in the mail workdir and returns counts by reason.
Arguments: allow_foreign, csv_path, out_name, own_addresses_csv, records, suppress
mail_codes_assign
Give every mail piece a unique tracking code (no 0/1/I/L/O/U, with a check character that catches every single typo and swapped pair when a caller reads it back) and a tracking URL with UTM tags. Writes a CSV ready for labels or a print vendor.
Arguments: base_url, campaign, csv_path, existing_codes_csv, out_name, param, records
mail_labels
Print-exact label sheets (Avery 5160/8160, 5163, 5164, 5167) as HTML that prints to PDF from any browser, with an optional QR per label, plus a vendor CSV. SAMPLE watermark is ON by default; pass sample=false only for the real print run (that call is recorded in the audit chain).
Arguments: csv_path, out_name, qr, sample, template
mail_qr
Make a QR code for any URL (pure-Python encoder, verified against an independent decoder). Returns SVG text and writes a PNG in the mail workdir.
Arguments: ecc, out_name, url
mail_scans
Count real scans of your mail tracking codes from your own web-server access logs: unique visitors per code, first-scan delay, and scan rate by batch/segment. Drops bots and link previewers, your own IPs, unknown codes, and any hit before that piece was mailed (your own testing). Stores hashed visitor ids only.
Arguments: format, log_paths, own_cidrs, own_ips, param, pieces_csv
mail_response
Honest direct-mail response rates by any column (batch, segment, variant...): scans, leads, clients, with 95% intervals and a verdict that says 'too early' or 'no signal yet: could still be up to X%' instead of a misleading zero.
Arguments: by, leads_csv, min_days, outcomes, pieces_csv
mail_holdout_plan
How many pieces (and how big a no-mail holdout) you need to prove direct mail works: sample size for a base response rate and the lift you want to detect, at 95% confidence and 80% power.
Arguments: base_rate, lift, ratio
mail_compare
Is variant A really better than B? Two-proportion test with a difference interval (e.g. two postcard designs, or mailed vs holdout).
Arguments: k1, k2, n1, n2
channel_cac
Cost per lead and per client across every channel on ONE ruler: Google Ads, ChatGPT Ads, direct mail, lead vendors, referrals. Attribution order: tracking code, then UTM, then what the lead said, then referrer. Optionally pulls live Google Ads spend for a campaign. Small numbers are labelled 'too few to judge'.
Arguments: client_value, costs_csv, google_campaign, leads_csv, pieces_csv, since, until
mail_breakeven
Unit economics of a mail piece: cost per piece (print + postage + other) and the response rate you need to break even for a given lead-to-client rate and client value.
Arguments: client_value, lead_to_client, other, postage, print_cost, quantity
Which tools run ChatGPT Ads safely?
adsops_openai_account
OpenAI Ads: verify the account's API key (GET /ad_account) and show names, status, currency, timezone and brand/integrity review state. Read-only.
Arguments: account
adsops_openai_status
OpenAI Ads: live campaign, ad groups, ads (with review status and serving issues), spend today/lifetime, the caps and the guard's pause point. Read-only.
Arguments: campaign
adsops_openai_insights
OpenAI Ads: daily impressions/clicks/spend for the last N days (1-90) at campaign, ad_group or ad level. Read-only.
Arguments: campaign, days, level
adsops_openai_geo_lookup
OpenAI Ads: search targetable locations (countries, regions, markets) and get their ids for the state file's targeting.location_ids. Read-only.
Arguments: account, limit, q
adsops_openai_plan
OpenAI Ads: diff the committed desired-state file against live. No writes. Shows ops, notes, exposure increases, spend-gate blockers, and a single-use plan_id.
Arguments: campaign
adsops_openai_apply
OpenAI Ads: apply the desired-state file. Validate-only unless commit=true (needs mode=live, commit_policy.allow_commit, committed state+policy files, the plan_id, and for activation the spend gate). New resources are always created paused.
Arguments: campaign, commit, plan_id
adsops_openai_guard
OpenAI Ads spend guard: PAUSE the campaign if lifetime spend reaches the pause point (cap minus 2x-overdelivery headroom), today's spend is anomalous, or live budgets/bids exceed the policy. Never activates or raises anything. Validate-only unless commit=true.
Arguments: campaign, commit
adsops_openai_upload_image
OpenAI Ads: check and upload a local PNG/JPEG/WebP (ad_image >= 640x640, account_favicon >= 256x256) and return its file_id. Checks only unless commit=true.
Arguments: account, commit, path, purpose
adsops_openai_brand_update
OpenAI Ads: set the advertiser icon (favicon_file_id), website url and/or brand_name. WARNING: brand changes can pause ALL delivery until OpenAI re-reviews the account. Preview unless commit=true and acknowledge_delivery_pause=true.
Arguments: account, acknowledge_delivery_pause, brand_name, commit, favicon_file_id, url
adsops_openai_conversions_setup
OpenAI Ads: make sure a web pixel and a lead_created conversion event setting exist (reuses ones with the same names). Optionally creates a Conversions API key and writes it to the config's capi key file (chmod 600, never returned). Preview unless commit=true.
Arguments: account, commit, create_capi_key, event_name, pixel_name
adsops_openai_test_event
OpenAI Ads: send ONE lead_created test event to the Conversions API with validate_only=true (never saved, never counted). Needs the account's Conversions API key.
Arguments: account, pixel_id, source_url
adsops_openai_ad_check
ChatGPT Ads: check chat_card ads before submitting them: OpenAI's limits (title 3-50, body <=100, https URL <=2048, 1 or 4-6 images), allowed domains and required UTM tags from the campaign policy, duplicates across an A/B set, and best-practice warnings (caps, superlatives, phone numbers). Pure check, no account access.
Arguments: ads, campaign, policy
adsops_openai_draft_campaign
ChatGPT Ads: turn a business brief (account, landing page, offer, budget, lifetime cap, context hints people ask ChatGPT, agent-written ads) into a desired-state file and a policy file that the AdRails engine accepts: everything paused, conservative caps, UTM-tagged URLs, activation off until a human approves. Returns both documents and next steps; with write=true saves them as drafts beside the config (never commits, never touches the account).
Arguments: brief, write
adsops_openai_ab_report
ChatGPT Ads: which ad is winning? Per-ad CTR (and conversion rate when available) with 95% intervals, a leader, Bonferroni-corrected comparisons and a pause recommendation only for ads significantly worse. Reads the campaign's ad-level insights, or takes rows you pass. Read-only.
Arguments: campaign, days, metric, min_clicks, min_impressions, rows
adsops_openai_send_conversions
ChatGPT Ads: send real conversions (CRM leads, qualified leads, sales) to the OpenAI Conversions API so ChatGPT Ads can optimise toward them. Emails, phones and names are normalised and SHA-256 hashed locally; events older than 7 days are skipped; event ids are deterministic so re-sends dedupe. Validate-only unless commit=true.
Arguments: account, commit, csv_path, event_type, pixel_id, rows
adsops_openai_audience
ChatGPT Ads custom audiences from a customer list (CSV or rows): emails/phones are hashed locally into the documented email_sha256/phone_number_sha256 file. op=create|add|remove|replace. Returns the plan and counts; commit=true uploads the hashed file and creates/updates the audience (mode=live accounts only). Use it to exclude current clients or target look-alike customer lists.
Arguments: account, audience_id, commit, csv_path, name, op, rows
Which tools get a local business leads from Google LSA and AI answers?
adsops_local_profile
Local business: read or save the business profile everything else is built from (trade, city, service area, services, phone, website, Google Business Profile status, reviews, LSA eligibility, budget, average job value, close rate, goals, competitors). action=questions lists what to ask the owner; action=set merges fields and returns what is still missing plus the lead economics (max cost per lead the business can afford).
Arguments: action, fields
adsops_local_plan
Local business: the 90-day growth plan for getting leads from Google (LSA, Search, Maps) and AI assistants. action=build makes it from the saved profile (generic plan, customised: skips what is done, organic-only with no budget, LSA only when eligible); action=progress marks tasks done and returns what is next and overdue; action=markdown returns the owner-readable checklist. Every task names the AdRails tool that does it.
Arguments: action, start_date, done, rebuild
adsops_leads
Lead book (local CRM in a JSON file beside the config): action=add (any channel; dedupes by source id, phone or email), move (stage: new, contacted, quoted, booked, won, lost, spam; won needs value, lost needs reason), note (with optional follow_up date or +Nd), get, find (stage/source/text/since/until), import (rows + source + column mapping), export (CSV), pipeline (counts, win rate and value by source, median first-contact minutes), conversions (won jobs with a gclid, ready for adsops_offline_conv_plan).
Arguments: action, lead, id, stage, value, lost_reason, note, follow_up, source, text, since, until, limit, rows, mapping
adsops_leads_due
Speed-to-lead check (run it every morning and after lunch): new leads still waiting for a first contact (oldest first, minutes waiting), follow-ups overdue, and follow-ups due today. Leads answered within 5 minutes book far more often, and Google ranks responsive LSA advertisers higher.
Arguments: none
adsops_local_schema
Local business: generate LocalBusiness JSON-LD (the right schema.org type for the trade, service areas, services, hours, license, profile links) ready to paste into the website head, with warnings. Uses the saved profile unless business is passed. Never emits self-serving review stars.
Arguments: business
adsops_local_nap
Local business: check that name, address and phone match exactly across listing pages (Google, Bing, Apple, Yelp, BBB, Facebook, directories) — inconsistent NAP costs Maps and AI-assistant visibility. Pass urls to fetch (or pages with text). action=citations returns the prioritised listing-site checklist instead.
Arguments: action, urls, pages, canonical
adsops_local_area_page
Local business: brief for ONE service x area page (title, meta, H1, outline, the questions people ask ChatGPT/Gemini about that service there, what to include and what to avoid). The agent then writes the page from it; publish, then ping aeo_indexnow.
Arguments: service, area, competitors
adsops_reviews
Reviews engine (reviews drive LSA and Maps ranking): action=link (Google write-a-review link from the Place ID), request (SMS/email request DRAFTS for a customer; AdRails never sends them), reply (reply draft for a review, flags ones the owner must handle personally), velocity (pace, average, reviews needed to hit 4.5/4.8, gap vs competitors). Policy built in: ask every customer, no gating, no incentives.
Arguments: action, place_id, customer_first_name, service, channel, tone, review, reviews, gbp_reviews, competitors
adsops_lsa_leads
Google Local Services Ads: pull leads (calls, messages, bookings) with their conversation history, who answered and how fast, charge and credit status, and junk flags (spam, solicitation, duplicate, wrong area, wrong job). sync=true (default) adds them to the lead book so every lead lives in one place. Read-only on Google's side.
Arguments: account, days, sync, include_contact
adsops_lsa_report
Google Local Services Ads report: spend, cost per charged lead vs the max the business can afford (from the profile), credits pending/issued, lead mix, booking rate, answer rate and missed calls (missed calls hurt LSA ranking), first-response time, leads by hour and weekday, and plain-English advice. Read-only.
Arguments: account, days
adsops_lsa_dispute
Google Local Services Ads lead feedback (how you get credit for junk leads and teach Google which leads you want): with no decisions it SUGGESTS ratings from the junk flags (spam, solicitation, duplicate, wrong area, wrong job -> dissatisfied; booked -> very satisfied). Pass decisions [{lead_id, answer, reason, comment}] to plan them; commit=true submits via ProvideLeadFeedback (once per lead, inside the window). Returns Google's credit decision.
Arguments: account, days, decisions, commit
adsops_lsa_readiness
Google Local Services Ads readiness: verification status for license, insurance, background check and business registration (with rejection reasons and expiry warnings) plus the profile signals Google ranks on (reviews, rating, response time, photos, hours, messaging, bio). Read-only; the fixes are listed in plain English.
Arguments: account
adsops_results
Before-and-after results: leads, jobs won, cost per lead by channel, first-response time, AI share of answer, reviews and plan progress, vs the month before AdRails. Missing data is a named gap, never a zero. action=case_study returns a privacy-safe summary (trade and city; name only with permission; no customer data).
Arguments: action, baseline_days, current_days, started_using, spend, baseline_spend, reviews, quote, permission
adsops_gbp
Google Business Profile to 100: score a profile snapshot with ranked fixes and warnings (category stuffing, URL in description, address shown on a service-area business), check a description against Google's rules, and plan two posts a week. Read-only: the owner edits the profile.
Arguments: action, snapshot, text, business_name, services, weeks, per_week, cta_url
Straight answers.
How many tools does AdRails have?
AdRails 0.8.0 has 82 MCP tools. The list on this page is generated from the server's own tools/list response, so it always matches the code you install. Run python3 -m adsops --selftest to check every module offline.
Which AdRails tools can change an ad account?
Only adsops_apply, adsops_set and adsops_guard reach the ad account, and adsops_guard can only pause. adsops_rollback edits the desired-state file in git, which then goes through adsops_plan and adsops_apply like any other change. Everything else is read-only or writes local files such as the approval queue and audit chain.
Do the AEO tools need an ads account?
No. aeo_site_audit, aeo_page_audit, aeo_llms_txt, aeo_schema_generate, aeo_visibility_record, aeo_indexnow and aeo_ai_traffic work on any website. Only aeo_content_gaps reads a campaign, because it turns that campaign's paid search terms into content gaps.