Skip to main content
Glama
kLOsk

AdLoop: Google Ads, Reddit Ads & GA4

AdLoop

The AI command center for Google Ads, Reddit Ads, GA4, and tracking code.

PyPI License: MIT Python 3.11+ MCP Compatible Google Ads API GA4 Data API GitHub stars Smithery

An MCP server that gives your AI assistant read + write access to Google Ads, Reddit Ads and GA4 — with safety guardrails that prevent accidental spend.

☁️ Skip the setup — use AdLoop Cloud (free plan, no card)  ·  or self-host: pip install adloop

TIP

AdLoop Cloud is the hosted version of this project, with a free plan that needs no credit card. Connect Google in two clicks and use the full toolset from claude.ai, ChatGPT, Claude Code, Cursor, or Gemini. No Google Cloud project, no API access application, no OAuth verification wait. EU-hosted, GDPR-first, DPA included.

📚 Documentation: docs.getadloop.com — setup guides per AI client, toolsets, the safety model, and troubleshooting for both editions.


Cloud or Self-Hosted?

Both versions run the same tools with the same safety model. The difference is who handles the plumbing:

☁️ AdLoop Cloud

🛠️ Self-hosted (this repo)

Setup

Connect Google in two clicks

~5 min: own Google Cloud project + adloop init

Google Cloud project

Not needed

Required (free)

Ads API access

Not needed

Granted to your Cloud project (no developer token, no MCC since Sept 2026)

Works with

claude.ai, ChatGPT, Claude Code, Cursor, Gemini

Claude Code, Cursor, Claude Desktop, any local MCP client

Where your data flows

EU servers (Germany), GDPR-first, DPA included

100% your machine — nothing leaves it

Updates

Automatic

pip install -U adloop

Price

Free plan, no card; paid plans for more accounts and volume

Free forever (MIT)

Not sure? Start with Cloud — it's the fastest way to see what AdLoop can do, and it's the only way to use AdLoop from claude.ai or ChatGPT. Self-host when you want everything on your own machine or need to modify the code. And if you're here to hack on AdLoop itself: welcome, keep scrolling.

Related MCP server: Google MCP Server

What It Solves

AdLoop exists because managing Google Ads alongside your code is a mess. These are the specific problems it handles:

  • "My conversions dropped and I don't know why." AdLoop cross-references Ads clicks, GA4 sessions, and conversion events in one query. It detects whether the gap is from GDPR consent rejection, broken tracking, or an actual landing page problem — before you waste hours checking each dashboard separately.

  • "I'm wasting ad spend on irrelevant searches." Pull your search terms report, identify the junk, and add negative keywords — all from a single conversation in your IDE. No context-switching to the Ads UI.

  • "Is my tracking even working?" Compare the event names in your actual codebase against what GA4 is receiving. Find the mismatches: events you fire that GA4 never sees, events GA4 records that you didn't know about.

  • "I need to create ads but the Google Ads UI is hostile." Draft responsive search ads, create campaigns, add keywords — all through natural language. Every change shows a preview first. Nothing goes live without your explicit confirmation: in Claude, ChatGPT and VS Code the preview is an approval card, and only your click on Apply changes the account (the AI cannot press it). New ads and campaigns start paused.

  • "My landing page gets paid traffic but nobody converts." AdLoop joins your ad final URLs with GA4 page-level data. See which pages get clicks but no conversions, which have high bounce rates, and which ones are orphaned from any ad campaign.

  • "Are conversions even being tagged on every page?" AdLoop reads your live Google Tag Manager container, joins it against the events in your codebase and the events firing in GA4, and tells you exactly which conversions are being captured, which tags are paused, which page-scope filters are too narrow, and which codebase events have no tag at all — the kind of three-way audit GTM Preview can't give you in a single view.

  • "I don't know if my EU consent setup is causing data gaps." In Europe, 30-70% of users reject analytics cookies. AdLoop accounts for this automatically — it won't diagnose a normal GDPR consent gap as broken tracking.

Built From Real Usage

Every tool exists because of an actual problem hit while running real Google Ads campaigns. The cross-reference tools exist because we kept manually asking the AI to "get Ads data, then get GA4 data, then compare them" — so we automated the join. The Broad Match + Manual CPC safety rule exists because the AI once created that exact combination and wasted budget. The GDPR consent awareness exists because the AI kept diagnosing normal EU cookie rejection as broken tracking.

The best features come from real workflows. If you're using AdLoop and find yourself wishing it could do something it can't, open an issue describing your situation — not just "add feature X" but "I was trying to do Y and couldn't because Z." The context matters more than the request.

All Tools

Quick start: pip install adloop or git clone https://github.com/kLOsk/adloop.git && cd adloop && uv sync && uv run adloop init — or zero setup on AdLoop Cloud

Diagnostics

Tool

What It Does

health_check

Test OAuth, GA4, and Ads connectivity in one call — actionable error messages if anything is broken. Also reports the pinned Google Ads API version and warns if a newer version is available.

GA4 Read Tools

Tool

What It Does

get_account_summaries

List GA4 accounts and properties

run_ga4_report

Custom reports: sessions, users, key events, page performance. Optional dimension and metric filters, ordering, paging, and a comparison period

run_realtime_report

Live data — verify tracking fires after deploys

get_tracking_events

All configured events and their volume

list_key_events

The property's key events (conversions) with counting method, create time and whether they can be deleted

list_ga4_dimensions_and_metrics

Every dimension and metric the property can report on, including custom ones, with search

Google Ads Read Tools

Tool

What It Does

list_accounts

Discover accessible Ads accounts

get_campaign_performance

Campaign metrics: impressions, clicks, cost, conversions, CPA, Search impression share and share lost to budget/rank

get_ad_performance

Ad copy analysis: headlines, descriptions, CTR, policy approval status and topics

get_keyword_performance

Keywords — quality scores, competitive metrics

get_search_terms

What users actually searched before clicking

get_negative_keywords

List direct campaign-level negative keywords

get_negative_keyword_lists

List all shared negative keyword lists (SharedSets) — names, IDs, status, keyword count

get_negative_keyword_list_keywords

List the keywords inside a specific shared negative keyword list

get_negative_keyword_list_campaigns

List which campaigns a shared negative keyword list is attached to

get_recommendations

Google's auto-generated recommendations with type, estimated impact, and campaign context

get_pmax_performance

Performance Max campaign metrics with network breakdown + asset group ad strength

get_pmax_assets

Per-asset details for PMax — field type, serving status, content

get_asset_group_signals

A PMax asset group's search themes and audience signal, plus the audiences available for it

get_detailed_asset_performance

Top-performing asset combinations — which headline+description+image combos Google selects most

get_audience_performance

Audience segment performance — remarketing, in-market, affinity, demographics

get_shopping_product_performance

Spend, conversions, CPA and ROAS per product across Shopping and Performance Max, plus products that spent without converting

get_change_history

What changed before the drop: who changed what and when, through which client (UI, API, scripts, auto-applied recommendations), last 30 days

get_demographic_targeting

List demographic criteria (age/gender/parental status/income) on an ad group or campaign

get_audience_lists

The account's remarketing and customer lists (size, eligibility, open/closed), custom and combined segments

search_audience_segments

Find Google's in-market and affinity segments by name

get_audience_targeting

Audiences and audience exclusions on a campaign or ad group, plus the audience mode (observation or targeting)

suggest_brands

Resolve a brand name to the brands Google recognizes — brand ID, name, state, URLs

check_brand_names

Check a shortlist of brand names against Google's brand knowledge graph (max 25 per call)

get_brand_lists

List brand lists (SharedSets of type BRANDS) — ID, name, status, member count

get_brand_list_brands

List the brands inside a list, with the Commercial KG MID and the criterion ID for removals

get_brand_list_campaigns

Which campaigns a brand list is attached to, and whether each attachment excludes or targets

get_ai_max_settings

AI Max knobs per campaign and ad group — enable_ai_max, bundling_required, the full asset_automation_settings list and each ad group's disable_search_term_matching

get_custom_conversion_goals

Custom conversion goals with their actions, plus one campaign's goal config

run_gaql

Arbitrary GAQL queries for anything else

Brand lists — a list is a SharedSet of type BRANDS; attaching it to a campaign is a CampaignCriterion.brand_list (negative=true excludes, false restricts), not a CampaignSharedSet like negative keyword lists. remove_from_brand_list and detach_brand_list_from_campaigns remove for real — SharedCriterion has no status field.

Brand targeting — brand criteria (brand lists, brand exclusions) target a brand's Commercial Knowledge Graph ID, not its display name. Use suggest_brands for a single name or check_brand_names for a shortlist to get the ID; exact_match marks a candidate whose name matches apart from case and punctuation, everything else is a Google suggestion.

AI Max is the container for Search brand exclusions — Google rejects a brand list on a plain Search campaign with "For search advertising channel, brand lists can only be applied to exclusive targeting, broad match campaigns for inclusive targeting or PMax generated campaigns." draft_prepare_brand_exclusions sets the state that makes the exclusion usable without handing Google the automations: AI Max on, search term matching off per ad group, text and final-URL automation opted out. draft_ai_max_settings is the general form when only parts of that state should change — it refuses a plan that would leave an automation on unnoticed, and asks for a second confirmation when that automation was requested explicitly.

Custom conversion goals — a named set of conversion actions that a campaign can be pointed at. get_custom_conversion_goals shows the goals with their actions and a campaign's current goal config; draft_custom_conversion_goal creates a set, draft_update_custom_conversion_goal renames or replaces its actions, draft_assign_custom_conversion_goal points a campaign at it and draft_clear_custom_conversion_goal puts the campaign back on the account-level goals. Only the goal and the campaign's goal config are touched — conversion actions, bidding and budgets stay as they are.

Compact mode — get_campaign_performance, get_keyword_performance, get_search_terms, and get_ad_performance accept compact=true: account totals, breakdowns, top-10 rows, and pre-computed offender lists (zero-conversion spenders, low-QS keywords, negative-keyword candidates, thin RSAs) instead of every row. ~90% smaller responses — built for account audits so raw tables don't flood your AI's context.

Cross-Reference Tools (GA4 + Ads Combined)

These tools call both APIs internally and return unified results with auto-generated insights. They're the core of what makes AdLoop different from having separate GA4 and Ads tools.

Tool

What It Does

analyze_campaign_conversions

Maps Ads clicks → GA4 sessions → conversions per campaign. Detects GDPR consent gaps, computes real CPA, compares paid vs organic channels.

landing_page_analysis

Joins ad final URLs with GA4 page data. Shows conversion rate, bounce rate, and engagement per landing page. Flags pages with paid traffic but zero conversions.

attribution_check

Compares Ads-reported conversions vs GA4 events. Diagnoses whether discrepancies are from GDPR consent, attribution windows, or broken tracking.

Tracking Tools

Tool

What It Does

validate_tracking

Compare event names found in your codebase against what GA4 actually records. Returns matched, missing, and unexpected events with diagnostics.

generate_tracking_code

Generate ready-to-paste GA4 gtag JavaScript for any event, with recommended parameters for well-known events (sign_up, purchase, etc.) and optional trigger wrappers.

Google Tag Manager Tools

These tools read the live GTM container and join it with the codebase + GA4 to find tracking gaps that pure GA4 inspection can't catch — page-scoped triggers, paused tags, dynamic event names, brittle CSS selectors, and codebase events with no tag wired up at all.

Tool

What It Does

audit_event_coverage

The flagship. Three-way join: codebase events ↔ GTM tags ↔ GA4 actual fires. For each event name in expected_events, returns one of 10 statuses (ok, no_tag_no_fire, tag_paused, tag_active_but_not_firing, gtm_only_firing, ga4_only, etc.) plus auto-generated insights for the gaps.

list_gtm_accounts

Discover accessible GTM accounts

list_gtm_containers

List containers under an account — returns numeric container_id (needed by other tools), public GTM-XXXXXXX ID, and usage context (web/iOS/Android/server)

list_gtm_tags

Every tag in the live container with parsed event names and resolved firing/blocking trigger names. Pass workspace_id to read a workspace's unpublished state instead, so a just-drafted tag is visible (also on get_gtm_tag, list_gtm_triggers, get_gtm_trigger, list_gtm_variables)

get_gtm_tag

Full raw config for a single tag — every parameter, firing/blocking triggers with filter conditions, priority, pause status, sampling

list_gtm_triggers

Every trigger with filter conditions parsed to readable text (e.g. {{Page Path}} contains service-promotions, {{Form ID}} NOT contains wf-form-...). Renders the negate flag explicitly.

get_gtm_trigger

Full trigger config + reverse lookup of every tag that uses it. Includes parsed element_visibility block (selector, on-screen ratio, firing frequency) for elementVisibility triggers and group_member_trigger_ids for triggerGroup types

list_gtm_variables

Custom variables (data layer, constants, JS) plus enabled built-in variables

list_gtm_workspaces

List drafts (workspaces) under a container — workspace IDs are needed by get_gtm_workspace_diff

get_gtm_workspace_diff

Drafted-but-not-published changes — common cause of "I edited a tag but nothing happened". Returns is_clean: true when nothing is pending.

list_gtm_versions

Version history, newest first, with version IDs and entity counts. The Tag Manager API returns no timestamps or author for versions.

get_gtm_version

Name, notes and tag/trigger names for a single historical container version

get_gtm_version_diff

What a publish changed: added, removed and changed tags, triggers and variables with the changed fields, plus built-in variables enabled or disabled. Defaults to the live version against the one before it; two or three API calls.

GTM write tools (opt-in)

Off by default. Set gtm.write_enabled: true in ~/.adloop/config.yaml and restart; the next call asks you to re-consent with the Tag Manager edit + publish scopes, which are never part of the default grant. Everything follows the usual draft → preview → confirm_and_apply flow, and tag/trigger edits only touch a workspace until you publish it.

Tool

What It Does

draft_gtm_tag

Create a tag, or update one by tag_id. Updates are a read-modify-write: parameters merge by key and every field you don't pass (priority, consent settings, firing options, schedule, folder, …) is preserved. Tag types are canonical GTM template IDs (googtag, gaawe, awct, sp, gclidw, …) or cvt_<id> gallery templates.

draft_gtm_trigger

Create a trigger, or update one by trigger_id (type is immutable). custom_event_name wires a customEvent trigger to a dataLayer event.

draft_gtm_variable

Create or update variables, e.g. Data Layer Variables for GA4 ecommerce values; renaming a referenced variable is refused, Custom JavaScript is gated

draft_delete_gtm_entity

Delete a workspace tag, trigger or variable. Triggers and variables still in use are refused up front, with the references listed.

draft_publish_gtm_workspace

Publish a workspace live. The preview lists every pending change, including edits other people made in the GTM UI.

draft_rollback_gtm_version

Republish an older container version live. The preview is the diff from the live version to the target; the plan pins the live version, so apply refuses if someone publishes in between. Workspaces are left as they are.

Safety gates specific to GTM:

  • Custom HTML runs arbitrary JavaScript on your site, so creating or editing an html tag — or publishing a workspace that adds or changes one — is refused unless gtm.allow_custom_html: true is also set. Pausing or deleting one is always allowed.

  • No stale writes. Updates and deletes pin the entity's fingerprint from the preview, and publish pins the workspace's pending changes; if someone edits the container in between, apply refuses and you re-draft.

  • Publishing stops on merge conflicts or GTM compiler errors. The dry run runs a Tag Manager quick preview first (Tag Manager has no validate-only mode), so compiler errors surface before a version is even created. That preview is a POST and stores a preview version in the container — nothing is published and no live tag changes; the rest of the dry run only reads.

  • The publish and rollback results name the version they replaced (previous_live_version_id), so rolling back is one step: draft_rollback_gtm_version with that id. If the version was created but publishing it failed, the error carries both the created version id and the still-live one.

  • Per-operation names for safety.blocked_operations: gtm_create_tag, gtm_update_tag, gtm_delete_tag, gtm_create_trigger, gtm_update_trigger, gtm_delete_trigger, gtm_publish_workspace, gtm_rollback_version.

The Google account also needs Edit permission on the container (and Publish to publish) under Admin → User Management.

Setup for GTM tools — Enable the Tag Manager API v2 in your GCP project, then add your AdLoop credentials' email (the OAuth user, or the service account email if using a service account) as a Read user on the GTM container under Admin → User Management. Service accounts pick up access on the next call. OAuth users upgrading from an earlier AdLoop version must re-authorize once: the GTM scope is new, so delete ~/.adloop/token.json and run any tool to re-consent — until then GTM tools return a permissions error.

Search Console Tools

Tool

What It Does

list_gsc_sites

List Search Console properties the connected account can access

run_gsc_report

Organic search analytics: clicks, impressions, CTR, position by query/page/country/device/date/searchAppearance/hour. Supports fresh data (data_state="all"), aggregation_type, and paging past 25,000 rows with start_row

Web Performance Tools

Tool

What It Does

analyze_page_speed

PageSpeed Insights for landing pages: Lighthouse score, Core Web Vitals, real-user CrUX data (falls back to origin-wide data, labelled as such, when the page has too little traffic), top fixes. No OAuth needed (optional API key).

Merchant Center Tools

Tool

What It Does

list_merchant_accounts

Discover accessible Merchant Center accounts

get_merchant_feed_health

Feed health — approved/pending/disapproved counts per reporting context, top product issues with docs, account-level issues. Disapprovals silently starve Shopping/PMax.

get_merchant_product_issues

The products behind the feed-health counts: which are disapproved, limited or pending, and each issue with its attribute and affected countries

Setup for Merchant Center tools — Enable the Merchant API in your GCP project (the Content API for Shopping is deprecated). The Merchant API has no read-only scope; AdLoop uses it strictly read-only. Upgrading OAuth users re-authorize once.

Setup for GSC tools — Enable the Search Console API in your GCP project. Upgrading OAuth users must re-authorize once for the new scope (delete ~/.adloop/token.json, run any tool). The killer combo: cross-reference organic queries with get_keyword_performance to find paid/organic cannibalization and untapped keyword opportunities.

Reddit Ads Tools

A second ad platform, same safety model. Reddit is a separate connection: its own developer app, its own OAuth, no developer token and no approval process. Every tool takes ad_account_id (defaults to reddit.ad_account_id).

Tool

What It Does

list_reddit_accounts

Discover businesses and ad accounts (currency, time zone, approval state)

list_reddit_funding_instruments

Billing instruments and posting profiles — prerequisites for creating campaigns and ads

get_reddit_campaigns / get_reddit_ad_groups / get_reddit_ads

Structure with configured vs effective status, budgets, bids, pixel, targeting, weekly schedule, rejection reasons; include_copy returns each ad's post (headline, body, destination, media)

get_reddit_performance

Spend, clicks, CTR, CPC, conversions, CPA, ROAS per account/campaign/ad group/ad, optional breakdown (date, country, community, keyword, placement, …), compact mode with insights

run_reddit_report

Raw reports endpoint for any metric (REACH, video, per-event conversions)

get_reddit_pixels

Pixels and when each event last fired — flags ad groups optimizing for events the pixel never sent

get_reddit_audiences

Custom and saved audiences with status, size and source, plus the ad groups that target or exclude each

search_reddit_targeting

Communities, interests, geolocations, languages, keyword suggestions, and Reddit's related-community suggestions (by seed communities or website)

get_reddit_account_history

Who changed what and when: field, before/after, member

estimate_reddit_ad_group

Audience size, delivery estimate and suggested bid range for a planned ad group (Reddit's counterpart of estimate_budget)

pause_reddit_entity / enable_reddit_entity / remove_reddit_entity

Status changes through the preview gate (remove = ARCHIVE, irreversible, double-confirmed)

update_reddit_campaign / update_reddit_ad_group / update_reddit_ad

Budget, bid, run dates, weekly schedule (day names, viewer-local hours), targeting, placements and audiences to target or exclude (validated with Reddit at draft time), landing URL and comment changes with old → new previews, budget cap and bid-increase guards

draft_reddit_campaign / draft_reddit_ad_group / draft_reddit_ad

Create campaign → ad group (pixel + targeting required) → post + ad (text, image, video or a 2–6 card carousel, media by URL), or promote an existing post with post_id. Everything is created PAUSED.

draft_reddit_custom_audience

Retargeting audiences from website visitors (pixel events) or people who engaged with your campaigns. No customer-list uploads.

Setup for Reddit Ads tools — In Reddit Ads Manager open Business Manager → Developer Application → Create app (business admins only; no approval wait). Register the redirect URL exactly as http://localhost:8765/callback, then run adloop init and complete the Reddit Ads step: it opens Reddit's consent page (scopes adsread + adsedit, permanent grant), stores the refresh token at ~/.adloop/reddit_token.json, and lets you pick the default ad account. Reddit rate-limits per user (reporting: 60 requests/min) and requires a descriptive User-Agent, which AdLoop builds from your app id and Reddit username. Reddit has no validate-only mode, so confirm_and_apply(dry_run=true) re-reads the target and re-checks the safety caps instead.

Image Uploads

An image on your computer, or one you attached in the chat, has no public URL, and an AI app cannot hand the file to a tool. upload_images gives it a way in.

Tool

What It Does

upload_images

Shows an upload card in apps with MCP Apps (drop PNG, JPEG or GIF up to 5 MB); on AdLoop Cloud in other apps it returns a one-time upload link, which a coding agent can also use with curl -T

list_uploads

The uploads that have not expired yet (kept 24 hours), with id, dimensions and size

The upload ids go into draft_image_assets(upload_ids=[...]), or as upload:<id> into the image fields of draft_reddit_ad on AdLoop Cloud.

Planning Tools

Tool

What It Does

discover_keywords

Discover new keyword ideas from seed keywords and/or a URL — with optional per-month search history + seasonality insights (include_monthly_volumes) using Google Ads Keyword Planner. Returns avg monthly searches, competition level, and top-of-page bid range.

estimate_budget

Forecast clicks, cost, and conversions for a set of keywords using Google Ads Keyword Planner. Supports geo/language targeting. Essential for budget planning before launching campaigns.

Google Ads Write Tools

All write operations follow a draft → preview → confirm workflow. Nothing executes without explicit approval.

Tool

What It Does

draft_campaign

Create a full campaign structure — budget + campaign (PAUSED) + ad group + optional keywords. Supports Search partners, display expansion, and max_cpc for either MANUAL_CPC initial ad-group bids or TARGET_SPEND (Maximize Clicks) CPC caps.

draft_shopping_campaign

Create a Standard Shopping campaign for a linked Merchant Center feed — budget, campaign (PAUSED), product ad group, Shopping ad and an "All products" group in one atomic request. Manual CPC, Maximize clicks or target ROAS.

draft_asset_group_assets

Add and remove Performance Max assets (text, images incl. uploads, YouTube videos) in one change, so replacing an asset never drops a group below Google's minimums

draft_asset_group_signals

Add search themes or set the audience signal of a PMax asset group

draft_pmax_product_exclusions

Exclude products from a retail PMax asset group by item id, brand or custom label

update_campaign

Modify existing campaign settings — bidding, budget, geo/language targeting, Search partners, display expansion, and TARGET_SPEND (Maximize Clicks) max_cpc caps.

draft_ad_group

Create a paused SEARCH_STANDARD ad group inside an existing campaign, with optional MANUAL_CPC max_cpc.

update_ad_group

Update an ad group name and/or MANUAL_CPC max_cpc. Use pause_entity / enable_entity for ad-group status changes.

draft_responsive_search_ad

Create RSA preview (3-15 headlines ≤30 chars, 2-4 descriptions ≤90 chars). Warns if headline/description count is below best practice.

draft_callouts

Create campaign callout assets from 1-25 character text snippets.

draft_structured_snippets

Create campaign structured snippet assets using official header values and 3-10 snippet values.

draft_image_assets

Create campaign image assets from local files, public image URLs or uploads (PNG, JPEG, or GIF).

draft_keywords

Propose keyword additions with match types. Proactively checks bidding strategy — flags BROAD match on campaigns without Smart Bidding as dangerous in the preview.

add_negative_keywords

Propose negative keywords directly on a campaign

add_negative_locations

Propose negative geo exclusions on a campaign — exclude cities/regions while keeping broader positive targets

draft_key_event

Mark a GA4 event as a key event (conversion) — the fix for "fires but isn't tracked as a conversion"

draft_delete_key_event

Remove a GA4 key event. The event keeps firing but no longer counts as a conversion, for future data only

draft_demographic_targeting

Propose demographic criteria (age, gender, parental status, income) — exclusions by default

draft_audience_attachment

Attach audiences as observation (default), targeting (double confirmation) or exclusion; refuses pairings Google doesn't allow and Search lists too small to target

propose_negative_keyword_list

Draft a shared negative keyword list (SharedSet) and attach it to a campaign — reusable across multiple campaigns

propose_brand_list

Draft a brand list (SharedSet of type BRANDS) from Commercial KG MIDs and optionally attach it to campaigns — negative=true (default) excludes the brands, false restricts targeting to them

add_to_brand_list

Draft adding brands to an existing brand list

remove_from_brand_list

Draft removing brands from a list (SharedCriteria have no status — removal is the only way; asks for a second confirmation)

attach_brand_list_to_campaigns

Draft attaching an existing brand list to campaigns as CampaignCriterion.brand_list

detach_brand_list_from_campaigns

Draft detaching a brand list from campaigns (removes only the criterion, the list stays)

draft_ai_max_settings

Draft AI Max controls for a Search campaign: enable_ai_max, per-ad-group disable_search_term_matching, plus text and final-URL asset automation (each OPTED_IN / OPTED_OUT / UNCHANGED)

draft_prepare_brand_exclusions

Draft the safe standard state in one step: AI Max on, search term matching off for every non-removed ad group, text and final-URL automation opted out. Touches nothing else

draft_custom_conversion_goal

Create a custom conversion goal (a named set of conversion actions)

draft_update_custom_conversion_goal

Rename a custom conversion goal and/or replace its action list (list replace, not append)

draft_assign_custom_conversion_goal

Point a campaign at a custom conversion goal (goal_config_level = CAMPAIGN)

draft_clear_custom_conversion_goal

Put a campaign back on the account-level goals (rollback)

pause_entity

Pause a campaign, ad group, ad, keyword or PMax asset group

enable_entity

Re-enable a paused entity

remove_entity

Permanently remove an entity (irreversible — prefers pause). Supports keywords, negative keywords, ads, ad groups, campaigns.

confirm_and_apply

Execute a previously previewed change

Orchestration Rules

AdLoop ships with orchestration rules that teach the AI how to combine these tools — marketing workflows, GAQL syntax, safety protocols, GDPR awareness, and best practices. Without rules, the AI has tools but doesn't know the playbook.

  • Cursor: .cursor/rules/adloop.mdc (canonical source)

  • Claude Code: .claude/rules/adloop.md (synced from Cursor rules via scripts/sync-rules.py)

The rules include:

  • Orchestration patterns for common workflows (performance review, conversion diagnosis, campaign creation, negative keyword hygiene, keyword discovery, tracking validation, budget planning, landing page analysis)

  • GAQL quick reference with syntax, common queries, and gotchas

  • Safety rules including Broad Match + Manual CPC prevention and pre-write validation

  • Ad copy character limit guidance (30-char headlines are shorter than you think)

  • GDPR consent awareness to prevent false tracking diagnoses in EU markets

Slash Commands (Claude Code)

AdLoop includes pre-built slash commands in .claude/commands/ for common workflows:

Command

What It Does

/analyze-performance

Full performance review across Google Ads + GA4

/create-ad

Create a responsive search ad with safety checks

/diagnose-tracking

Diagnose tracking and conversion issues

/optimize-campaign

Full optimization checklist for a campaign

/create-campaign

Create a new search campaign with budget estimation

/budget-plan

Estimate budget for keywords via Keyword Planner

Safety Model

AdLoop manages real ad spend, so safety is not optional.

  • Approval cards. In apps that show MCP Apps (Claude, ChatGPT, VS Code and others), every change appears as a card with Test run and Apply. Only the click applies it: the AI's own confirm_and_apply(dry_run=false) is refused with APPROVE_ON_CARD, whatever it was told in the chat.

  • Confirmation dialogs. Apps without cards that support elicitation (Claude Code, for example) get a dialog from AdLoop itself before every real change. The AI cannot answer it; declining changes nothing.

  • Two-step writes. Every mutation returns a preview first. A separate confirm_and_apply call is required to execute.

  • Dry-run by default. Even confirm_and_apply defaults to dry_run=true. Real changes require explicit dry_run=false.

  • Two-phase apply (optional). With safety.two_phase_apply: true, confirm_and_apply refuses dry_run=false until the plan has completed one dry-run pass — preview-then-apply becomes server-enforced instead of a convention.

  • Budget caps. Configurable maximum daily budget — the server rejects anything above the cap.

  • Audit log. Every operation (including dry runs) is logged to ~/.adloop/audit.log.

  • New campaigns and ads are PAUSED. Nothing goes live without manual enablement.

  • Destructive ops are flagged for double confirmation. Removing entities or large budget increases come back with extra warnings, and the AI is instructed to confirm twice.

  • Broad Match without Smart Bidding caught. The #1 cause of wasted ad spend: draft_campaign refuses BROAD keywords unless the campaign uses Smart Bidding, and draft_keywords / draft_ad_group mark them as dangerous in the preview, so the AI has to raise it before anything is applied.

  • Pre-write validation. Before any write, the AI checks bidding strategy, conversion tracking status, and quality scores. If the campaign is fundamentally broken, AdLoop warns you instead of making things worse.

  • Structured error handling. All tools return actionable error messages with hints instead of raw exceptions. Auth errors include specific re-authorization steps.

  • API version pinning. The Google Ads API version is pinned to prevent silent breaking changes from library updates. health_check warns when a newer version is available.

  • Ask mode compatibility. Read tools declare readOnlyHint so they work in Cursor's Ask mode without switching to Agent mode.

Setup

AdLoop uses your own (free) Google Cloud project for OAuth. The adloop init wizard walks you through it — a one-time setup of about 5 minutes, with no shared user caps and no waiting on anyone's verification review. AdLoop does not ship built-in OAuth credentials.

Prefer zero setup? AdLoop Cloud is the hosted version: connect Google in two clicks — no Cloud project, no API access application, EU-hosted.

(Upgrading from ≤0.9 with built-in credentials? Those sign-ins were retired in 0.10 — run adloop init once to switch to your own project.)

IMPORTANT

Seeing deleted_client: The OAuth client was deleted. or invalid_client? The shared Google Cloud project behind AdLoop ≤0.9's bundled credentials has been shut down, so its stored sign-ins no longer refresh. Two ways forward: AdLoop Cloud (connect Google in two clicks, nothing to configure) or stay self-hosted with pip install -U adloop && adloop init to set up your own free Google Cloud project. Details in the pinned issue (#49).

Install

From PyPI:

pip install adloop
adloop init

From source:

git clone https://github.com/kLOsk/adloop.git
cd adloop
uv sync
uv run adloop init

What adloop init does

The wizard first asks whether to set up Google. Answer no to run AdLoop on Reddit Ads alone: it skips steps 1 to 6 and goes straight to the Reddit step. Otherwise it walks you through:

  1. Google Cloud setup — creates a project, enables the three APIs, generates an OAuth client (see Custom Google Cloud Project Setup below for the exact steps the wizard refers you to)

  2. Google Ads API access — applied for on your Cloud project's Google Ads API Overview page; the legacy developer-token prompt can be left empty

  3. MCC Account ID — optional, only if you reach several accounts through a Manager Account

  4. OAuth sign-in — opens a browser to sign in with Google (or prints a URL for headless servers)

  5. Auto-discovers your accounts — finds your GA4 properties and Ads accounts automatically

  6. Optional services — pin a GTM container, a Search Console property (both auto-discovered too), and a PageSpeed API key; skip any of them with Enter

  7. Reddit Ads — optional next to Google, required without it: your own Reddit developer app, sign-in, and the default ad account

  8. Safety defaults — budget cap and dry-run preference

  9. Toolsets — optionally expose only part of the tool catalog to your AI client (see Toolsets)

  10. Editor config snippets — prints MCP configuration for both Cursor and Claude Code, including your toolset selection

Requirements

  • Python 3.11+

  • A Google Ads account (a Manager Account is optional; you only need one to reach several accounts through one login)

  • Google Ads API access on your Google Cloud project (see below)

Google Ads API access

Since 9 September 2026, Google Ads API access belongs to the Google Cloud project that owns your OAuth client. Developer tokens are sunset: the API ignores the header, the wizard's token prompt is optional, and you no longer need a Manager Account to get access.

Apply on your project's Google Ads API Overview page in the Cloud Console:

Level

How to get it

What it allows

Test

Automatic when you enable the Google Ads API

Test accounts only, not production accounts. CLOUD_PROJECT_NOT_APPROVED_FOR_PRODUCTION (or DEVELOPER_TOKEN_NOT_APPROVED on older API versions) means you are here.

Explorer

"Upgrade access level" → apply; usually granted automatically

2,880 operations/day on production accounts. Enough to get started.

Basic

Apply; reviewed automatically within minutes once the project is brand-verified (OAuth consent screen set to External and published "In production")

15,000 operations/day.

Standard

Apply; manual review, about ten business days

Higher limits; Google's RMF policy applies

Projects on a Cloud free trial or with billing disabled are refused Explorer and Basic; use a project with billing set up.

Getting CLOUD_PROJECT_NOT_APPROVED_FOR_PRODUCTION? Your project is at Test level. Open the Overview page above and apply for Explorer access.

Headless Servers

Running on a server without a browser (VMs, Docker, SSH)? The wizard automatically detects this and falls back to a manual flow: it prints an authorization URL you can open on any device, then you paste the redirect URL back into the terminal.

Custom Google Cloud Project Setup

The wizard refers to these steps — do them in your browser before running adloop init (or while it waits at the OAuth prompt).

Step 1 — Google Cloud Project

  1. Go to console.cloud.google.com and create a new project

  2. Enable these three APIs (search for each in the API Library):

    • Google Analytics Data API — for GA4 reports and events

    • Google Analytics Admin API — for listing GA4 properties

    • Google Ads API — for all ads operations

Step 2 — OAuth Credentials

  1. In your Google Cloud project, go to APIs & Services → Credentials

  2. Click Create Credentials → OAuth client ID

  3. Select Desktop app as the application type, give it any name

  4. Download the JSON file and save it as ~/.adloop/credentials.json

Service accounts are also supported — just place the service account key JSON at the same credentials_path. AdLoop detects the file type automatically.

Step 3 — Connect to Your Editor

Cursor — Add to your project's .cursor/mcp.json:

{
  "mcpServers": {
    "adloop": {
      "command": "/absolute/path/to/adloop/.venv/bin/python",
      "args": ["-m", "adloop"]
    }
  }
}

Then copy .cursor/rules/adloop.mdc from this repo into your project's .cursor/rules/ directory.

Claude Code — Run:

claude mcp add --transport stdio adloop -- /absolute/path/to/adloop/.venv/bin/python -m adloop

Or add to your project's .mcp.json:

{
  "mcpServers": {
    "adloop": {
      "command": "/absolute/path/to/adloop/.venv/bin/python",
      "args": ["-m", "adloop"]
    }
  }
}

Then install the orchestration rules + slash commands globally so every Claude Code session inherits them:

adloop install-rules

This writes a managed block to ~/.claude/CLAUDE.md and copies the slash commands (prefixed adloop-*) into ~/.claude/commands/. The block is delimited by sentinel comments so it's safe to run multiple times — re-running just refreshes the content. Two install modes:

  • inline (default) — full rules embedded in ~/.claude/CLAUDE.md. Reliable but adds ~10K tokens to every Claude Code session.

  • lazy (adloop install-rules --lazy) — small directive in CLAUDE.md pointing at ~/.claude/rules/adloop.md. Cheaper baseline cost; the LLM reads the rules file only when AdLoop tools are in scope.

To refresh after upgrading AdLoop: adloop update-rules. To remove cleanly: adloop uninstall-rules — only the managed block and adloop-* commands are touched, never your own content.

If you'd rather manage things by hand instead, copy .claude/rules/adloop.md and .claude/commands/ from this repo into your project's .claude/ directory.

Claude Desktop / claude.ai has no programmatic rules location. Run adloop install-rules and it will print the rules content for you to paste into Project settings → Custom instructions on claude.ai.

Use It

Ask your AI assistant things like:

  • "How are my Google Ads campaigns performing this month?"

  • "Which search terms are wasting budget? Add them as negative keywords."

  • "My sign-up conversions dropped — check GA4 and Ads to find out why."

  • "Draft a new responsive search ad for my main campaign."

  • "Which landing pages get paid traffic but don't convert?"

  • "Is my tracking set up correctly? Compare my codebase events against GA4."

  • "Audit my Google Tag Manager container — which conversions are being captured and where are the gaps?"

  • "What keywords should I target for [product]? Find ideas and estimate the budget."

  • "How much budget would I need for these keywords in Germany?"

  • "Create a new search campaign for [product feature] with a €20/day budget."

Configuration Reference

All configuration lives in ~/.adloop/config.yaml. See config.yaml.example for a documented template.

Section

Key

Default

Description

google

project_id

(empty)

Google Cloud project ID (only needed with custom credentials)

google

credentials_path

(empty)

Path to OAuth client JSON or service account key. Empty = ~/.adloop/credentials.json, else Application Default Credentials.

google

token_path

~/.adloop/token.json

Where to store the OAuth token (auto-created)

ga4

property_id

—

Your GA4 property ID (auto-discovered by adloop init)

ads

developer_token

—

Legacy, optional: API access belongs to your Cloud project since Sept 2026

ads

customer_id

—

Default Google Ads customer ID (auto-discovered by adloop init)

ads

login_customer_id

—

Your MCC account ID

reddit

client_id / client_secret

(empty)

Your Reddit developer app (Business Manager → Developer Application)

reddit

ad_account_id

(empty)

Default Reddit ad account for every Reddit tool (picked by adloop init)

reddit

username

(empty)

Your Reddit username, used only in the User-Agent Reddit requires

reddit

token_path

~/.adloop/reddit_token.json

Where the Reddit refresh token is stored

safety

max_daily_budget

50.00

Maximum allowed daily budget per campaign

safety

require_dry_run

true

Force all writes to dry-run mode

safety

two_phase_apply

false

Refuse real applies until the plan had a dry-run pass

safety

blocked_operations

[]

Operations to block entirely

Toolsets — trim the context footprint

Most MCP clients (claude.ai, ChatGPT, Cursor, …) load every tool schema into the model's context at the start of every conversation. With AdLoop's full catalog that's a noticeable share of the context window, paid before you type a word. If you only use part of AdLoop, expose a subset with the ADLOOP_TOOLSETS environment variable in your MCP client's env block (the adloop init wizard offers this and writes it into the snippets for you):

"env": { "ADLOOP_TOOLSETS": "ads,ga4" }

Toolset

Covers

ads

Google Ads reads, writes, and planning (Keyword Planner)

ga4

Google Analytics reports, realtime, key events

tracking

Cross-channel attribution + tracking code generation

gtm

Google Tag Manager audits, reads, and opt-in writes

gsc

Search Console reads

web

PageSpeed / Core Web Vitals

merchant

Merchant Center feed health

reddit

Reddit Ads reads, writes, and planning

Google Ads can be narrowed further. Use one of these instead of ads:

Subset

Covers

ads:read

Ads reports, GAQL, and the Ads/Analytics cross-checks (attribution_check, analyze_campaign_conversions, landing_page_analysis)

ads:write

Ads drafts and changes; turns on ads:read too, because a draft needs the reads first (IDs, bidding strategy)

ads:plan

Keyword ideas and budget forecasts (discover_keywords, estimate_budget)

health_check and confirm_and_apply are always included, whatever you select. Unset = the full catalog; unknown names fail at startup with the valid list. The effect is real: ads:read,ga4 costs about 40% of ads,ga4 for audits and diagnosis, and an ads:plan-only client for keyword research pays about 5% of the full catalog. Toolsets are per client, not per install: one AdLoop config can serve a trimmed Cursor and a full-catalog Claude Code side by side.

On AdLoop Cloud, the same feature is per API key: pick toolsets when creating a key in the dashboard, and that key's tools/list is trimmed server-side for whichever AI client uses it.

Project Structure

src/adloop/
├── __init__.py        # Entry point — routes 'adloop init' to wizard, otherwise starts MCP server
├── server.py          # FastMCP server — every tool registration with safety annotations and toolset tags
├── config.py          # Config loader (~/.adloop/config.yaml)
├── auth.py            # OAuth 2.0 flow (user-supplied credentials, headless fallback) + service accounts; GA4 / Ads / GTM scopes
├── cli.py             # Interactive 'adloop init' setup wizard
├── crossref.py        # Cross-reference tools (GA4 + Ads + GTM combined analysis)
├── tracking.py        # Tracking validation + code generation tools
├── ga4/
│   ├── client.py      # GA4 Data + Admin API clients
│   ├── reports.py     # Account summaries, reports, realtime
│   └── tracking.py    # Event discovery
├── ads/
│   ├── client.py      # Google Ads API client (version-pinned) + retry/backoff for rate limits
│   ├── gaql.py        # GAQL query execution with human-readable error parsing
│   ├── read.py        # Campaign, ad, keyword, search term, negative keyword, shared sets, recommendations, audience reads
│   ├── pmax.py        # Performance Max tools — campaign/asset group performance, asset labels, top combinations
│   ├── write.py       # Draft campaign, RSA, keywords; pause, enable, remove, confirm
│   └── forecast.py    # Budget estimation + keyword discovery via Keyword Planner API
├── gtm/
│   ├── client.py      # Google Tag Manager API v2 client
│   └── read.py        # Live container fetching, tag/trigger/variable parsing, workspace diff, version history
├── reddit/
│   ├── auth.py        # Reddit OAuth2 (own app, permanent refresh token, loopback flow for adloop init)
│   ├── client.py      # Reddit Ads API v3 REST client — bearer refresh, per-user rate limits, pagination
│   ├── read.py        # Accounts, campaigns, ad groups, ads, performance reports, pixels, targeting lookups
│   └── write.py       # Draft/preflight/apply for status, budget, bid, targeting, and PAUSED creation
└── safety/
    ├── guards.py      # Budget caps, bid limits, blocked operations, Broad Match safety
    ├── preview.py     # Change plans and previews
    └── audit.py       # Mutation audit logging

Roadmap

What's been shipped and what's next:

  • GA4 read tools ✓

  • Google Ads read + write tools with safety layer ✓

  • Cross-reference intelligence (campaign→conversion mapping, landing page analysis, attribution comparison) ✓

  • Tracking utilities (validate events against GA4, generate gtag code) ✓

  • Budget estimation + keyword discovery via Keyword Planner ✓

  • Shared negative keyword lists (SharedSet API) ✓

  • Retry/backoff for API rate limits ✓

  • Setup wizard (adloop init) ✓

  • Claude Code support ✓ — CLAUDE.md, .mcp.json, .claude/rules/, .claude/commands/, CLI wizard snippets

  • Claude Desktop one-click install — adloop install claude-desktop (and/or a .dxt extension bundle) that writes the AdLoop MCP entry into claude_desktop_config.json automatically, so Claude Desktop + Cowork users don't have to hand-edit JSON

  • PyPI package ✓ — pip install adloop

  • AdLoop Cloud ✓ — the hosted version: no Google Cloud project, no API access application, connect Google in two clicks (EU-hosted, GDPR-first)

  • Headless server support ✓ — manual URL copy-paste flow for servers without a browser

  • Behavioral eval suites ✓ — prompt-and-expectation tests in tests/evals/ covering read, write, tracking, and planning workflows

  • Google Tag Manager integration ✓ — read tools for tags, triggers, variables, workspaces, and version history, plus the audit_event_coverage three-way join across codebase events, GTM tags, and GA4 actual fires

  • Community launch — HN, Indie Hackers, r/cursor, Twitter

  • Video walkthrough

Contributing

See CONTRIBUTING.md for guidelines. The short version: open an issue describing your situation first, then submit a PR if you want to build it.

License

MIT — see LICENSE.

Privacy

The open-source version runs entirely on your machine. No data is collected, stored, or transmitted to any server. See PRIVACY.md for the full privacy policy. AdLoop Cloud has its own privacy policy and DPA.


If AdLoop helps you run Google Ads, GA4, and tracking code from one place — give it a star or try the hosted version.

Made by @kLOsk | AdLoop Cloud | Privacy Policy

Available Tools

138 tools
add_negative_keywordsDraft negative keywordsAInspect

Draft negative keyword additions — returns a PREVIEW.

Negative keywords prevent your ads from showing for irrelevant searches. They are added at campaign level. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesNegative keyword texts; at least one is required. All share the same match_type.
match_typeNo"EXACT" (default), "PHRASE", or "BROAD".EXACT
campaign_idYesNumeric ID of the campaign that gets the negatives.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations flag readOnlyHint=false and destructiveHint=false, and the description usefully clarifies that this is a non-mutating draft returning a plan_id that only takes effect after confirm_and_apply. That resolves the ambiguity of a write-flagged tool that does not actually change anything.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and the PREVIEW caveat in the first sentence, which is the most decision-relevant information. The explanatory sentence about what negative keywords do is somewhat generic filler but does not derail the structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not explain return values, yet it still names the plan_id handoff to confirm_and_apply. The preview-then-confirm workflow is fully described; only the routing versus sibling draft tools is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (keywords, match_type, campaign_id, customer_id) are already documented with types and defaults. The description adds only the campaign-level placement context and nothing about keyword syntax or match_type semantics, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft negative keyword additions') and immediately scopes it as a preview. The phrase 'added at campaign level' distinguishes it from the list-based siblings like add_to_negative_keyword_list, though it never names them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The two-step workflow ('nothing changes until confirm_and_apply applies it') gives implied usage, but there is no explicit statement of when to prefer this over add_to_negative_keyword_list or propose_negative_keyword_list, nor any when-not condition.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_negative_locationsDraft negative locationsAInspect

Draft negative geo location additions — returns a PREVIEW.

Excludes cities/regions from a campaign while keeping broader positive targets such as State of Sao Paulo. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idYesNumeric ID of the campaign to add the location exclusions to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
geo_target_idsYesNumeric Google geo target constant IDs to exclude (e.g. "1001773"). Duplicates are collapsed; non-numeric IDs are rejected.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false, destructiveHint=false and openWorldHint=true, but do not convey the two-phase behavior. The description adds genuinely useful context: the call produces a PREVIEW with a plan_id and mutates nothing until confirm_and_apply is invoked.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the most important fact ('returns a PREVIEW') and keeps the body tight across three short segments. The trailing Google Ads API URL is marginally useful reference rather than wasted space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not detail return values, and annotations cover the safety profile. Combined with the preview/confirm workflow it explains, the agent has enough to invoke it correctly; only sibling differentiation is left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents campaign_id, customer_id and geo_target_ids in detail. The description reinforces the geo-exclusion concept but adds no syntax or format detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft negative geo location additions') and clarifies the scope with a concrete example (excluding cities/regions while keeping 'State of Sao Paulo'). The 'negative geo' qualifier distinguishes it from other draft_* siblings, though it does not explicitly name an alternative tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the draft workflow clearly: it returns a preview and 'nothing changes until confirm_and_apply applies it', which tells the agent when this tool is the right step and what must follow. It does not name explicit exclusions or competing siblings, but the context is sufficient to route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_to_brand_listDraft additions to a brand listAInspect

Append brands to an EXISTING brand list — returns a PREVIEW.

For a list that already exists and only needs more brands (propose_brand_list creates a new list instead). The shared_set_id comes from get_brand_lists; get_brand_list_brands shows the brands already in the list, which makes a brand that would be added twice visible.

Returns a preview with a plan_id; nothing changes until the returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
brand_idsYesCommercial Knowledge Graph MIDs from suggest_brands.
customer_idNoAds account ID. Defaults to the configured account.
shared_set_idYesNumeric list ID from get_brand_lists.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, so the safety profile is partly covered, but the description adds genuinely non-obvious behavior: the call returns a PREVIEW with a plan_id and 'nothing changes until the returned plan_id is applied with confirm_and_apply'. That two-phase commit contract is the key operational fact an agent needs and is not in the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core action and preview caveat are front-loaded in the first line, then supporting routing and workflow details follow in short paragraphs. Every sentence earns its place; the trailing API docs link is the only filler and is minor.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not explain return values, yet it still flags the plan_id preview, the confirm_and_apply dependency, the sibling alternative, and where the required IDs come from. An agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so brand_ids, customer_id, and shared_set_id are already documented at field level, and the description largely echoes the schema's provenance notes. The dedup hint tied to get_brand_list_brands adds a little meaning but no format or constraint detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Append brands to an EXISTING brand list') and immediately disambiguates from the closest sibling, propose_brand_list, which 'creates a new list instead'. An agent can pick this over its sibling without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use ('a list that already exists and only needs more brands'), an explicit when-not (propose_brand_list for new lists), and prerequisite routing for both required params: shared_set_id from get_brand_lists and get_brand_list_brands for duplicate detection. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

add_to_negative_keyword_listDraft additions to a negative keyword listAInspect

Append keywords to an EXISTING shared negative keyword list — returns a PREVIEW.

Adds terms to a list that already exists (propose_negative_keyword_list creates a new list instead); get_negative_keyword_list_keywords shows the terms already in a list. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesKeyword strings to append. Blank entries are dropped and duplicates in the input list are collapsed (case-insensitive).
match_typeNoMatch type applied to every keyword: "EXACT" (default), "PHRASE", or "BROAD" (case-insensitive).EXACT
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
shared_set_idYesNumeric ID of the list (shared_set.id from get_negative_keyword_lists).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false, destructiveHint=false, openWorldHint=true, which leaves the draft-vs-commit semantics ambiguous. The description supplies that missing context: the call is non-mutating, returns a preview with a plan_id, and requires confirm_and_apply before anything changes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and its preview nature in one sentence, followed by sibling routing and commit semantics. The API doc link is short and placed last; no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists so return-value detail is unnecessary, and the description still explains the plan_id concept. Combined with full schema coverage and covered sibling routing, an agent has everything needed to call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents match_type defaults, customer_id fallback, and blank/duplicate handling for keywords. The description adds only the notion of the target being an existing list, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (append), resource (keywords in a shared negative keyword list), and hard scope constraint (EXISTING list, returns a PREVIEW). The agent can distinguish this from propose_negative_keyword_list and add_negative_keywords without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes between siblings: propose_negative_keyword_list for creating a new list, get_negative_keyword_list_keywords for inspecting existing terms, and confirm_and_apply to actually commit the change. Both when-to-use and the required follow-up are stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

analyze_campaign_conversionsCampaign conversions against AnalyticsA
Read-only
Inspect

Campaign clicks → GA4 conversions mapping — the real cost-per-conversion.

Combines Google Ads campaign metrics with GA4 session/conversion data to reveal click-to-session ratios (GDPR indicator), compare Ads-reported vs GA4-reported conversions, and compute cost-per-GA4-conversion. Also returns non-paid channel conversion rates for comparison context. GA4 conversions are the property's key events (GA4 metric keyEvents).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
campaign_nameNoOptional case-insensitive substring; only campaigns whose name contains it are included. Empty = all campaigns.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: the click-to-session ratio acts as a GDPR indicator, GA4 conversions map to the property's keyEvents, and non-paid channels are returned as comparison context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first line as a headline, followed by concrete analytical outputs. It is appropriately sized, though the trailing API documentation links are somewhat marginal and not strictly necessary for invocation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, and the readOnly/openWorld annotations cover trust signals. The description supplies enough cross-source context (what is combined and why) for an agent to call the tool correctly, with only when-to-use routing left unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter (customer_id, property_id, campaign_name, date ranges) is already documented in the schema, including defaults and the 'last 30 days' fallback. The description adds no parameter-level detail beyond what the schema provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource (Campaign clicks → GA4 conversions mapping) and enumerates concrete outputs: click-to-session ratios, Ads-vs-GA4 conversion comparison, cost-per-GA4-conversion, and non-paid channel rates. It clearly distinguishes itself as a cross-source Ads+GA4 tool, though it never names a sibling to compare against.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the specific analysis described (real cost-per-conversion across Ads and GA4), but there is no explicit when-to-use guidance and no named alternatives among siblings like attribution_check or get_campaign_performance. The agent can infer the scenario but receives no routing help.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

analyze_page_speedPageSpeed analysisA
Read-only
Inspect

Run PageSpeed Insights for a landing page — Lighthouse + real-user data.

Returns the performance score (0-100), lab Core Web Vitals (LCP, CLS, TBT, FCP), CrUX field data from real Chrome users where available (p75 LCP/INP/CLS/FCP/TTFB + FAST/AVERAGE/SLOW ratings), and the top improvement opportunities with estimated savings. When the page itself has too little traffic for field data, the origin-wide field data is returned instead, marked field.scope="origin".

Typical input is an ad final_url: slow landing pages depress Quality Score and waste paid clicks. Takes 10-30s; that is normal for a Lighthouse run.

PageSpeed Insights API: https://developers.google.com/speed/docs/insights/v5/about

ParametersJSON Schema
NameRequiredDescriptionDefault
urlYesFull URL of the page to analyze, e.g. an ad's final_url ("https://example.com/landing").
strategyNo"mobile" (default — most paid traffic) or "desktop".mobile

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld annotations, the description discloses material behavior: the 10-30s latency, and the important fallback that origin-wide field data is substituted when the page lacks traffic, marked field.scope="origin". That fallback semantics is exactly the kind of non-obvious trait annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return payload, then usage context, then the API reference link. Every sentence carries information, though the multi-clause return enumeration is dense.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Though an output schema exists, the description still orients the agent on what comes back and the origin-scope caveat. Combined with the latency note and input guidance, nothing needed to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents both url and strategy (including the mobile default and the paid-traffic rationale). The description's mention of ad final_url adds no meaning beyond the schema's own example.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource (run PageSpeed Insights for a landing page) and enumerates what it returns — score, lab CWV, CrUX field data, opportunities. However, it never distinguishes itself from the sibling tool landing_page_analysis, which an agent could easily confuse it with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear context for use (typical input is an ad final_url, slow pages hurt Quality Score and waste clicks) and discloses expected runtime of 10-30s. It stops short of stating when NOT to use it or naming an alternative over landing_page_analysis.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

attach_brand_list_to_campaignsDraft attaching a brand listAInspect

Attach an existing brand list to one or more campaigns — returns a PREVIEW.

Creates a CampaignCriterion.brand_list per campaign. This is NOT the CampaignSharedSet linkage used for negative keyword lists — brand lists are criteria, and negative decides the role. The shared_set_id comes from get_brand_lists; get_brand_list_campaigns lists existing attachments.

Returns a preview with a plan_id; nothing changes until the returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
negativeNoTrue (default) excludes the brands from those campaigns; False restricts targeting to them instead.
customer_idNoAds account ID. Defaults to the configured account.
campaign_idsYesNumeric campaign IDs to attach the list to.
shared_set_idYesNumeric list ID from get_brand_lists.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give the generic write/non-destructive/open-world profile; the description adds substantial context beyond that: it creates a CampaignCriterion.brand_list per campaign, returns a preview with a plan_id, and nothing mutates until confirm_and_apply is called. That two-phase draft/apply behavior is essential and not derivable from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and the PREVIEW nature of the result, then layers the sibling distinction and prerequisite flow. Each sentence carries a distinct piece of information; the API doc link is the only disposable element and is minimal.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given four params, a full schema, an output schema, and a preview/apply workflow, the description supplies everything an agent needs: input provenance, mutation semantics, downstream confirmation step, and the criterion-vs-shared-set distinction. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds meaning by explaining that `negative` decides the role (criteria vs. exclusion) and that shared_set_id originates from get_brand_lists. It stops short of documenting customer_id behavior, but the schema already covers the parameters.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (attach an existing brand list to campaigns) and immediately distinguishes it from the nearest sibling by declaring it is NOT the CampaignSharedSet linkage used for negative keyword lists. An agent can tell it apart from attach_shared_set_to_campaigns without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent: shared_set_id comes from get_brand_lists, get_brand_list_campaigns lists existing attachments, and the result must be applied via confirm_and_apply. It also clarifies the negative-vs-exclusion semantic split, leaving no inference needed about when to use this vs. the shared-set tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

attach_shared_set_to_campaignsDraft attaching a shared setAInspect

Attach an existing shared set to one or more campaigns — returns a PREVIEW.

Creates CampaignSharedSet linkages so the campaigns inherit the shared set's criteria (e.g. negative keywords). Most commonly used to attach a shared negative keyword list to newly-built campaigns; get_negative_keyword_list_campaigns lists existing attachments. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
campaign_idsYesNumeric campaign IDs to attach the set to (at least one). Blank entries are dropped and duplicates collapsed.
shared_set_idYesNumeric ID of the shared set (from get_negative_keyword_lists).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, destructiveHint=false, openWorldHint=true, which alone would leave the agent unsure whether this mutates state. The description resolves that by explaining it returns a PREVIEW with a plan_id and that nothing changes until confirm_and_apply applies it — a two-phase workflow annotations cannot express.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the preview caveat, then the mechanism, use case, and apply step. Efficient overall, though the trailing Google Ads API documentation URL is low-value filler for an agent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need no explanation, and the description covers the key workflow context (preview -> confirm_and_apply) that an agent needs to call this correctly. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents shared_set_id, campaign_ids, and customer_id (including dedup behavior). The description adds conceptual context ('campaigns inherit the shared set's criteria') but no parameter-level detail beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Attach an existing shared set to one or more campaigns') and immediately scopes it as a preview. It is clearly distinguishable from detach_shared_set_from_campaigns and get_negative_keyword_list_campaigns, both named or implied in siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete primary use case ('attach a shared negative keyword list to newly-built campaigns') and points to get_negative_keyword_list_campaigns for inspecting existing attachments. It does not explicitly state when not to use it (e.g. vs attach_brand_list_to_campaigns), but the context is clear enough to route correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

attribution_checkAttribution checkA
Read-only
Inspect

Compare Ads-reported conversions vs GA4 — find tracking discrepancies.

Checks whether conversions reported by Google Ads match what GA4 records, diagnoses GDPR consent gaps, attribution model differences, and missing conversion event configuration. Returns both sides' totals with the discrepancy and diagnostic insights. GA4 conversions are the property's key events (GA4 metric keyEvents).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.
conversion_eventsNoOptional list of GA4 event names to specifically check (e.g. ["sign_up", "purchase"]). If omitted, compares aggregate totals only.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered; the description adds genuinely useful behavior — it cross-references two datasets, names the specific diagnoses it performs (consent gaps, attribution model differences, missing conversion event config), and clarifies the metric semantics ('GA4 conversions are the property's key events / keyEvents'). It doesn't mention auth requirements or rate/cost constraints for the two API calls it makes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The comparison purpose is front-loaded in the first clause, followed by diagnoses and return shape; nothing is padded or repeated. The trailing pair of documentation URLs is arguably filler for an agent that already has the tool, but it is a single compact sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool has an output schema, so the brief mention of return contents ('both sides' totals with the discrepancy and diagnostic insights') is sufficient without enumerating fields. With 100% schema coverage and no required parameters, the definition supplies what an agent needs to call it, though it never explains how this cross-source analysis differs from validate_tracking or analyze_campaign_conversions.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each of the five optional parameters documented (defaults, formats, the 'both dates must be set else last 30 days' rule, and conversion_events semantics), so the baseline is 3. The description adds only the tangential note that GA4 conversions are keyEvents and no direct parameter guidance beyond that.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and two resources ('Compare Ads-reported conversions vs GA4 — find tracking discrepancies') and enumerates the diagnostic categories it covers, so an agent can tell what it computes. It stops short of distinguishing itself from close siblings such as validate_tracking, audit_event_coverage, or analyze_campaign_conversions, which an agent browsing this large toolset would still have to disambiguate by opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose ('find tracking discrepancies', 'diagnoses GDPR consent gaps'), so it is reasonably clear when an agent would reach for it. However, there is no explicit when-to-use/when-not statement and no mention of the nearly overlapping alternatives (validate_tracking, audit_event_coverage, analyze_campaign_conversions), leaving the agent to infer selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

audit_event_coverageTracking coverage auditA
Read-only
Inspect

Three-way audit: codebase events ↔ GTM tags ↔ GA4 actual fires.

Fetches the LIVE GTM container, joins it against GA4 event counts for the date range, and returns a per-event matrix with one of these statuses: ok — tag active and event firing ok_auto_collected — GA4 Enhanced Measurement event, no tag needed no_tag_no_fire — codebase event, no GTM tag, never fires tag_paused — GTM tag exists but is paused tag_active_but_not_firing — tag is active but no GA4 hits gtm_only_firing — GA4 event from a tag, not in codebase gtm_paused_but_firing — only paused tag(s), not in codebase, yet GA4 still fires (event comes from elsewhere) gtm_only_not_firing — tag exists, not in codebase, no fires ga4_only — fires in GA4, no tag, no codebase ref ga4_fires_no_tag — codebase event firing without a GTM tag auto_event_only — Enhanced Measurement event with no codebase ref

The result also lists dynamic-event tags ({{Event}} variables) and Custom HTML tags that the audit cannot interpret automatically.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
property_idNoGA4 property as "properties/123456789". Empty uses the default from config.
date_range_endNoEnd date "YYYY-MM-DD". Empty (or an empty date_range_start) means the last 30 days.
gtm_account_idNoNumeric GTM account ID (Tag Manager UI → Admin → Container Settings, or list_gtm_accounts). Empty uses gtm.account_id from the config.
expected_eventsYesDistinct event names found in the codebase's gtag('event', ...) and dataLayer.push({event: ...}) calls.
date_range_startNoStart date "YYYY-MM-DD". Empty (or an empty date_range_end) means the last 30 days.
gtm_container_idNoNumeric GTM container ID (not the GTM-XXXXXXX public ID; see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true. The description adds meaningful behavioral context beyond that: it fetches the LIVE container, joins against GA4 counts, returns a per-event status matrix, and notes that dynamic-event and Custom HTML tags cannot be interpreted automatically. It does not cover authentication, rate limits, or error behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with a one-line summary and then structured status definitions. The long status enumeration is informative, though some of it may overlap with the output schema and could be trimmed if the schema is similarly complete.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's complexity and the presence of an output schema, the description is largely complete: it explains the audit logic, the status meanings, and its interpretability limits. It could still mention prerequisites such as required GTM/GA4 access, but the core behavioral picture is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters including defaults and required expected_events. The description adds no additional parameter meaning beyond what the schema provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: a three-way audit joining codebase events, GTM tags, and GA4 fires. It is clear what the tool does, but it does not explicitly distinguish itself from nearby siblings like list_gtm_tags or get_tracking_events.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use statement or identification of alternatives. An agent can infer the tool is for coverage auditing, but the description provides no guidance about when this audit should be selected over other tracking or GTM tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

check_brand_namesCheck brand namesA
Read-only
Inspect

Check a list of brand names against Google's brand knowledge graph.

One SuggestBrands call per name, for the case where a shortlist has to be triaged instead of a single name resolved: which of these brands does Google know at all, and what is the ID of each?

Returns checked / matched / no_match counts and one result per name with status "matched" (with a best-match brand plus all candidates) or "no_match" (empty candidate list — a normal answer, not an error). exact_match marks a candidate whose name matches the query apart from case and punctuation; anything else is a Google suggestion, not a guarantee.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
brand_namesYesThe names to triage, at most 25 per call — the API resolves one prefix per request, so longer lists take several calls.
customer_idNoAds account ID. Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds real behavioral context beyond that: it explains the per-name call pattern, that 'no_match' is a normal answer rather than an error, and that non-exact candidates are Google suggestions, not guarantees.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then escalates into return semantics in a logical order. It is slightly longer than necessary and the return-format detail partially overlaps the output schema, but every sentence carries substantive information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations, a fully covered input schema, and an output schema present, the definition is largely complete. It goes further than required by describing result statuses, which is helpful even if partly redundant with the output schema; the only minor gap is that the per-name API cost implied by the batching is stated but not fully quantified.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already documents both parameters, including the 'at most 25 per call' limit. The description adds the rationale (one API prefix resolution per request) but no new syntax or formatting detail, so the baseline 3 for schema-driven parameters is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Check a list of brand names against Google's brand knowledge graph') and explicitly frames the batch-triage case versus the single-name resolution done by SuggestBrands, which is a sibling tool. An agent can distinguish this from suggest_brands without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly states when to use it: 'for the case where a shortlist has to be triaged instead of a single name resolved.' That is a clear when-to-use condition and it implicitly routes the single-name case to the suggest_brands sibling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

confirm_and_applyApply a previewed changeA
Destructive
Inspect

Execute a previously previewed change.

IMPORTANT: Defaults to dry_run=True (validate only). Only an explicit dry_run=false applies the change to the ad account (Google Ads or Reddit Ads — the plan knows which platform it targets).

Forced dry runs: when real changes are switched off (live changes off for the workspace in AdLoop Cloud, or safety.require_dry_run in a self-hosted config), dry_run=false is IGNORED and the result is still DRY_RUN_SUCCESS, with 'dry_run_forced_by' and 'remediation' fields. 'remediation' says how the user switches that setting; until it is changed, repeated calls with dry_run=false change nothing.

Two-phase apply: if 'safety.two_phase_apply: true' is set (always on for AdLoop Cloud tenants), dry_run=false is REFUSED with status DRY_RUN_REQUIRED until this plan_id has completed one dry_run=true pass. The sequence is: dry run, review of its result, then the real apply.

Google Ads plans: the dry run sends the exact mutates to Google with validate_only=True, so Google checks the change and executes nothing (checks counts the validated calls). Steps that build on an object an earlier step would create cannot be validated and are counted as skipped.

Reddit plans: Reddit has no validate-only mode, so the dry run re-reads the target entity and re-checks the safety caps (returned as checks).

A DRY_RUN_FAILED result means the change does not go through as previewed. The real apply fails the same way, unless Google rejected only part of the request: then it carries out the rest and reports those operations again.

Returns a status with the plan_id and operation: DRY_RUN_SUCCESS, DRY_RUN_FAILED, DRY_RUN_REQUIRED, APPLIED, PARTIAL_UPLOAD or APPLY_IN_PROGRESS. APPLIED results carry the created or changed resource names under 'result'. PARTIAL_UPLOAD belongs to the upload tools: the batches it lists are already in the account, so the plan is retired. 'sent_total', 'accepted_total', 'rejected_total' and 'resume_from_line' say how far the upload got and at which CSV line a new draft continues; when a batch's fate is unknown, 'unknown_status', 'uncertain_lines' and 'row_errors' name the rows whose outcome has to be checked first. APPLY_IN_PROGRESS means an earlier call claimed this plan first, so this call executed nothing.

Approval cards: in AI apps that show AdLoop's approval card with the preview, dry_run=false is REFUSED with status APPROVE_ON_CARD, because only the user's click on the card applies the change. Dry runs still work. The workspace owner can allow approval in chat as well.

Confirmation dialogs: in apps that show dialogs instead, dry_run=false first asks the user in a dialog. A declined dialog returns NOT_CONFIRMED; an app that receives the dialog but never answers it gets CONFIRMATION_UNANSWERED on the next call, with the ways out.

Google Ads API: https://developers.google.com/google-ads/api/docs/start, Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
dry_runNoTrue (default) validates without changing anything; false applies the change for real.
plan_idYesThe plan_id returned by a prior draft_*, update_*, add_*, pause/enable/remove or other preview tool call. An unknown or expired plan_id returns an error.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations: it discloses the dry_run default, forced-dry-run behavior with 'dry_run_forced_by'/'remediation', two-phase gating, platform-specific dry-run semantics for Google vs Reddit, partial-upload continuation via 'resume_from_line', and concurrency via APPLY_IN_PROGRESS. The destructive/openWorld hints are backed with concrete consequences and recovery paths.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Well front-loaded (the dry_run default is stated first) and organized under bold headers, but it is very long. Much of the status enumeration duplicates the output schema that already exists, and the trailing Google/Reddit API documentation links add little for tool selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given a two-parameter mutation tool with safety gating, approval flows, and multi-platform behavior, the description leaves nothing an agent needs unstated. Output schema exists, yet the status semantics are still explained, making it complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are already documented, but the description adds behavioral meaning beyond the schema — notably that dry_run=false can be ignored or refused depending on workspace settings, and that an unknown/expired plan_id errors. This is meaningful context layered on top of the field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Execute a previously previewed change') and makes clear it is the apply step that consumes a plan_id produced by the draft_*/update_* preview tools. An agent can distinguish it from the many draft_* siblings without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly covers when to use it (after a preview, following the dry-run/review/apply sequence), when real application is refused (forced dry runs, two-phase apply, approval cards, confirmation dialogs), and what to do next in each case. This is a model of routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detach_brand_list_from_campaignsDraft detaching a brand listA
Destructive
Inspect

Detach a brand list from one or more campaigns — returns a PREVIEW.

Removes the CampaignCriterion rows linking the list to those campaigns; the list itself and its brands are unchanged. get_brand_list_campaigns lists the existing attachments.

Returns a preview with a plan_id; nothing changes until the returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.
campaign_idsYesNumeric campaign IDs to detach the list from. Campaigns that do not carry the list are reported as `not_attached` in the apply result instead of failing the batch.
shared_set_idYesNumeric list ID from get_brand_lists.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, destructiveHint=true, openWorldHint=true. The description adds the crucial nuance that the call itself is non-mutating: it returns a preview with a plan_id and nothing changes until apply. It also scopes what is destroyed (CampaignCriterion rows) versus what survives (the list and its brands), which an agent cannot infer from the annotation flags alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads the action and the preview caveat, and the remaining sentences are short and purposeful. 'Returns a PREVIEW' is slightly restated by the later 'Returns a preview with a plan_id', and the bare API docs link is marginal, but overall it is tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Return values are covered by the output schema, safety posture by the annotations, and the description fills the remaining gap: the draft/apply workflow, the scope of removal, and the sibling used to inspect current attachments. Nothing needed to invoke this correctly in a two-step mutation flow is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the parameters are already well documented there, including the not_attached batch behavior for campaigns. The description only echoes 'one or more campaigns' and does not add format or constraint detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Detach a brand list from one or more campaigns') and immediately defines the scope of the change ('Removes the CampaignCriterion rows linking the list to those campaigns; the list itself and its brands are unchanged'). That level of precision lets an agent distinguish it from the attach counterpart and from the generic shared-set detach without reading either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Routes the agent to a concrete alternative for the read side ('get_brand_list_campaigns lists the existing attachments') and explains the required follow-up ('nothing changes until the returned plan_id is applied with confirm_and_apply'). It stops short of naming attach_brand_list_to_campaigns or detach_shared_set_from_campaigns as the inverse/analogue, so selection between near-identical siblings is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

detach_shared_set_from_campaignsDraft detaching a shared setAInspect

Detach a shared set from one or more campaigns — returns a PREVIEW.

Removes CampaignSharedSet linkages so the campaigns no longer inherit the shared set's criteria. The shared set itself is unchanged; only the per-campaign attachment is removed. get_negative_keyword_list_campaigns lists the existing attachments. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
campaign_idsYesNumeric campaign IDs to detach the set from (at least one). Blank entries are dropped and duplicates collapsed.
shared_set_idYesNumeric ID of the shared set (from get_negative_keyword_lists).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Despite annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true), the description adds substantial non-obvious context: it is a draft/preview that changes nothing, returns a plan_id, leaves the shared set itself intact, and removes only per-campaign linkages. This clarifies why a 'detach' is non-destructive, which the annotations alone do not explain.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the essential scope and PREVIEW behavior in the first line, followed by supporting detail. Well-organized, though the trailing Google Ads API URL is boilerplate that doesn't earn much space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a draft-mutation tool with an output schema and annotations, this description is complete: it covers the linkage semantics, the preview/plan_id lifecycle, the confirm step, and the discovery sibling. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are already documented in the schema. The description adds only that the detachment targets 'one or more campaigns,' which is marginally beyond what the schema states. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Detach a shared set from one or more campaigns') and immediately flags that it returns a PREVIEW, which distinguishes it from the actual-apply sibling confirm_and_apply. An agent can tell exactly what the tool does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides the workflow: get_negative_keyword_list_campaigns lists existing attachments (discovery), this tool produces a plan_id preview, and confirm_and_apply executes it. Clear context for when to use it, though it does not state explicit when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

discover_keywordsKeyword ideasA
Read-only
Inspect

Discover new keyword ideas using Google Ads Keyword Planner.

Mirrors the "Discover new keywords" UI in Keyword Planner: start with keywords (seed_keywords), start with a website (url), or both together for more targeted ideas. At least one of seed_keywords or url is required.

Returns keyword ideas sorted by avg monthly search volume, with competition level (LOW/MEDIUM/HIGH) and top-of-page bid range, plus the seeds used and insights.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
urlNoA landing page or site URL to extract ideas from, e.g. "https://example.com/products".
page_sizeNoMax keyword ideas to return (default 50, clamped to 1-1000).
customer_idNoGoogle Ads customer ID (digits, dashes allowed). Defaults to the configured account.
language_idNoLanguage constant ID (1000=English, 1001=German, 1002=French). Defaults to 1000.1000
geo_target_idNoGeo target constant ID (2276=Germany, 2840=USA, 2826=UK). Defaults to 2276.2276
seed_keywordsNoSeed terms, e.g. ["running shoes", "trail running"].
include_monthly_volumesNotrue adds per-month search history (last 24 months, top-20 ideas) plus a seasonality insight — relevant to questions about demand trends, seasonality, or "when should I ramp budget".

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the practical validation constraint ('at least one of seed_keywords or url is required') that the schema does not enforce (required=0), which is genuinely useful. Return-format details are somewhat redundant given the output schema, and it omits rate-limit/account requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by entry modes, the requirement, and the return shape. Every sentence carries information, though the return-value sentence overlaps with the output schema and could be trimmed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 7-parameter tool with full schema coverage and an output schema, the description supplies the essential constraint and usage modes. It could still note account/auth expectations for customer_id and does not contrast with keyword-performance siblings, but nothing critical for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds combination semantics beyond the schema by explaining that seed_keywords and url can be combined 'for more targeted ideas' and that one is mandatory — meaning not conveyed by the raw property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('discover') and resource ('new keyword ideas') via Google Ads Keyword Planner, and clearly disambiguates its scope from sibling research tools like get_keyword_performance (existing keywords) and draft_keywords (writing). The three seed/url entry modes make the tool's role unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the three input modes (seed keywords, website url, or both) and the gating condition that at least one of seed_keywords or url is required. It does not, however, explicitly contrast when to pick this over siblings such as get_search_terms or suggest_brands, so it falls short of a full when/when-not/alternatives statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_ad_groupDraft an ad groupAInspect

Draft a new ad group within an existing campaign — returns a PREVIEW, does NOT create.

Creates an ad group (ENABLED, type SEARCH_STANDARD) in the specified campaign, optionally with keywords in the same atomic operation. Only SEARCH campaigns are supported. Ads are not included, so the ad group cannot serve until one of its ads is created and enabled.

Returns a preview with a plan_id plus warnings (BROAD keywords on a non-Smart-Bidding campaign, a duplicate ad group name, a CPC bid that Smart Bidding ignores); nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsNoOptional list of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD"}.
campaign_idYesThe campaign to add the ad group to (numeric ID as returned by get_campaign_performance).
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
ad_group_nameYesName for the new ad group.
cpc_bid_microsNoOptional ad group CPC bid in micros (1,000,000 = one unit of the account's currency); only used by MANUAL_CPC campaigns. 0 means no ad-group bid; must not be negative.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare non-readonly, non-destructive, open-world, but the description goes further: it specifies what gets created (ENABLED, SEARCH_STANDARD), that keywords can be added atomically, that ads are omitted so it can't serve, and that a plan_id plus warnings (BROAD keywords, duplicate names, ignored CPC bid) are returned with no side effects until applied. This is rich behavioral context beyond annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the key 'PREVIEW, does NOT create' distinction in the first line, followed by tightly organized behavior details. The trailing API documentation URL is somewhat expendable, keeping it just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema covering the return (plan_id, warnings) and annotations covering the safety profile, the description fills the remaining gaps: scope limits (SEARCH only), atomicity, and the confirm workflow. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real meaning: it explains the atomic keyword creation, the CPC-bid-ignored-by-Smart-Bidding warning, and the duplicate-name warning context. It does not fully restate the micros/customer_id semantics already in the schema, but the warning behavior adds value.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft a new ad group within an existing campaign') and immediately disambiguates with 'returns a PREVIEW, does NOT create.' An agent can distinguish this from sibling mutation tools like draft_campaign, draft_keywords, and confirm_and_apply without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit about scope ('Only SEARCH campaigns are supported'), preconditions (campaign must exist, ads needed before serving), and the workflow boundary ('nothing changes until confirm_and_apply applies it'). The when-to-use and the alternative (confirm_and_apply) are both named.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_ai_max_settingsDraft AI Max settingsAInspect

Draft AI Max controls for a Search campaign — returns a PREVIEW.

AI Max is the container that makes brand exclusions usable in Search: Google rejects a brand list on a plain Search campaign ("For search advertising channel, brand lists can only be applied to exclusive targeting, broad match campaigns for inclusive targeting or PMax generated campaigns"). Turning AI Max on while leaving its automations running is the trap, so both belong to the same plan. An automation the caller never mentioned is refused outright (the plan says which switch to pass); one named explicitly (disable_search_term_matching=False, text_asset_automation="OPTED_IN") is planned with requires_double_confirm=True, because switching to AI Max with its automations is a real configuration some accounts want.

Reads the campaign and its ad groups first, so the preview names concrete ad groups and shows current values per knob. Returns a preview with a plan_id; nothing is written until confirm_and_apply runs.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idYesNumeric ID of the Search campaign to prepare.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
ad_group_idsNoExplicit ad group IDs. Empty means every non-removed ad group of the campaign.
enable_ai_maxNoValue for campaign.ai_max_setting.enable_ai_max. When omitted, it stays untouched.
final_url_expansionNoOPTED_IN, OPTED_OUT or UNCHANGED (default) for FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION (the v25 field name for final URL expansion).UNCHANGED
text_asset_automationNoOPTED_IN, OPTED_OUT or UNCHANGED (default) for TEXT_ASSET_AUTOMATION.UNCHANGED
include_paused_ad_groupsNoDefault true — paused groups are set as well, so re-enabling one later cannot silently restore search term matching. REMOVED ad groups are never touched.
disable_search_term_matchingNoValue for ad_group.ai_max_ad_group_setting.disable_search_term_matching on the selected ad groups. When omitted, they stay untouched.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as a non-readonly, non-destructive, open-world operation, and the description adds substantial extra behavior: preview-only writes gated behind a plan_id, refusal of automations the caller never mentioned, requires_double_confirm for explicitly named automations, and the fact that campaign/ad group state is read before planning. This is far beyond what the annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The preview-scope statement is front-loaded and most sentences carry behavioral payload, but the quoted Google brand-list rejection message and the background about AI Max being the container for brand exclusions drift toward context that belongs with draft_prepare_brand_exclusions. Slightly long for the task, though not wasteful enough to obscure the core message.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex 8-parameter draft tool this is well covered: the write-gating behavior, plan_id handoff, automation interactions, and paused-ad-group default are all explained, and an output schema exists so return values need not be described. Nothing critical for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real semantic value beyond the schema: it explains the interaction between the automation knobs (an unmentioned automation is refused, an explicit value like disable_search_term_matching=False or text_asset_automation="OPTED_IN" triggers requires_double_confirm) and frames include_paused_ad_groups behavior as protecting against silent search-term restoration.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence states a specific verb (Draft), resource (AI Max controls), scope (Search campaign), and output modality (returns a PREVIEW), which cleanly separates it from siblings like get_ai_max_settings and confirm_and_apply. An agent can identify the tool's role in the draft/confirm pipeline without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description makes the workflow explicit: nothing is written until confirm_and_apply runs, and the tool reads the campaign/ad groups itself so a prior getter call is unnecessary. It does not explicitly name get_ai_max_settings as the read-only alternative, so routing is strong but not fully spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_asset_group_assetsDraft Performance Max asset changesAInspect

Draft adding and/or removing assets of a Performance Max asset group — returns a PREVIEW.

Adds new text, image and YouTube assets and unlinks existing ones in one atomic request, so an asset is replaced without the group dropping below Google's minimums (3 headlines, 1 long headline, 2 descriptions, one of them at most 60 characters). Texts already in the group are skipped. Images are checked and sorted by aspect ratio; removed assets stay in the account's asset library. The preview lists the asset counts per type after the change. Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
imagesNoImages to add, each {"url": "..."} or {"upload_id": "up_..."} with an optional "role": "marketing" (default; landscape 1.91:1, square 1:1 or portrait 4:5 by aspect ratio), "logo" (1:1) or "landscape_logo" (4:1). PNG, JPEG or GIF up to 5120 KB.
headlinesNoHeadlines to add, at most 30 characters each (up to 15 in the group).
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
descriptionsNoDescriptions to add, at most 90 characters (up to 5).
business_nameNoBusiness name to add, at most 25 characters (one per group).
asset_group_idYesNumeric asset group id (from get_pmax_performance or get_pmax_assets).
long_headlinesNoLong headlines to add, at most 90 characters (up to 5).
remove_asset_idsNoAsset ids to unlink from the group (from get_pmax_assets).
youtube_video_idsNoYouTube video ids to add (the 11 characters after "v=" in the URL), up to 5 per group.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (which only cover readOnly=false, destructive=false, openWorld=true). It discloses atomicity, Google minimums that must be preserved, that already-present texts are skipped, aspect-ratio sorting of images, that removed assets remain in the library, that the preview lists per-type counts, and that nothing mutates until confirm_and_apply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and the PREVIEW outcome, then dense but useful constraint detail. Every sentence carries information; slightly long but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 9-parameter mutation-drafting tool with an output schema covering the preview, the description supplies the workflow, constraints, and side-effect profile an agent needs. Nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds constraint semantics not in the schema: the group minimums (3 headlines, 1 long headline, 2 descriptions, one within 60 chars) and image role/aspect-ratio handling. This meaningfully enriches parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft adding/removing) plus resource (Performance Max asset group assets) and immediately flags the PREVIEW nature. An agent can distinguish it from siblings like draft_image_assets or draft_asset_group_signals without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to confirm_and_apply for actually applying the plan_id, establishing the two-step draft/apply workflow. The 'one atomic request' framing also signals when to prefer this over piecemeal single-asset tools, though no explicit when-not or exclusion is stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_asset_group_signalsDraft Performance Max signal changesAInspect

Draft adding search themes or an audience signal to a Performance Max asset group, or removing signals — PREVIEW.

Signals are hints that steer Performance Max, not targeting. A group has at most one audience signal and up to 50 search themes; replacing the audience means removing the current one in the same draft. Themes already on the group are skipped. Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
audience_idNoAudience to set as the group's audience signal (from get_asset_group_signals available_audiences).
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
asset_group_idYesNumeric asset group id (from get_pmax_performance).
add_search_themesNoSearch themes to add, short phrases people search for (at most 80 characters each).
remove_signal_idsNoSignals to remove (signal_id from get_asset_group_signals).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true) by disclosing that signals are hints rather than targeting, the cardinality limits (one audience signal, up to 50 search themes), the skip-if-present behavior, and the deferred-apply/dry-run validation model.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then layered with constraints and lifecycle in dense, non-redundant sentences. Every sentence earns its place; the API link is terse reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, and the description covers the mutation lifecycle, cardinality rules, and validation path. Nothing material to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds interaction semantics the schema lacks: replacing the audience requires removing the current one in the same draft, and already-present themes are skipped. This meaningfully clarifies how audience_id and remove_signal_ids relate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Draft adding/removing) on a specific resource (search themes / audience signal on a Performance Max asset group), distinguishing it cleanly from the read-side sibling get_asset_group_signals. An agent can pick it out without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the draft-then-apply workflow ('Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it'), which routes the agent to the correct next tool. It stops short of an explicit when-not-to-use or a named read alternative, but the usage context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_assign_custom_conversion_goalDraft assigning a custom conversion goalAInspect

Point a campaign at a custom conversion goal — returns a PREVIEW.

Sets goal_config_level=CAMPAIGN and the goal on that campaign's conversion goal config. Nothing else changes: conversion actions, bidding, budgets and the account-level goals stay as they are.

A campaign must have at least one goal configured when it switches to campaign level — Google answers EMPTY_CONVERSION_GOALS otherwise. That is why this tool assigns a goal instead of clearing goals; draft_clear_custom_conversion_goal goes back to the account level.

If the campaign already uses exactly this goal, nothing is planned and the result says already_configured. The preview carries a note that changing what a campaign optimises for restarts its Smart Bidding learning period.

The returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idYesNumeric campaign ID to configure.
customer_idNoAds account ID. Defaults to the configured account.
custom_conversion_goal_idYesNumeric goal ID from get_custom_conversion_goals.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=false and destructiveHint=false, but the description goes further: it discloses the idempotency behavior ('already_configured' when the goal is unchanged), the blast radius ('nothing else changes'), and the side effect that changing optimisation restarts the Smart Bidding learning period. This is exactly the extra behavioral context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return type, then supporting constraints. Dense and mostly waste-free, though the Google Ads API link and multi-sentence constraint block are slightly more verbose than strictly needed.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema covering the preview/plan_id return and annotations covering the safety profile, the description fills the remaining gaps: edge-case behavior, side effects, and the confirm_and_apply workflow. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all three parameters are already documented with descriptions (campaign_id, customer_id default, custom_conversion_goal_id sourced from get_custom_conversion_goals). The description adds no syntax or format detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (assign) and resource (custom conversion goal), specifies it returns a PREVIEW, and disambiguates from siblings like draft_clear_custom_conversion_goal and draft_update_custom_conversion_goal. An agent can identify the tool's intent without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative (draft_clear_custom_conversion_goal goes back to account level), gives the precondition that triggers the tool's error (campaign must have a goal or Google answers EMPTY_CONVERSION_GOALS), and points to confirm_and_apply for applying the returned plan_id. Full when/when-not/alternative coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_audience_attachmentDraft audience attachmentAInspect

Draft attaching audiences to a campaign or ad group as observation, targeting or exclusion: returns a PREVIEW.

Observation (the default) keeps the reach: the audiences adjust bids and show up in reports. Targeting narrows delivery to the audiences and needs a double confirmation. Exclusions keep the people out and leave the mode alone. The draft refuses combinations Google does not allow (custom segments on Search, combined segments outside Search, audiences at both campaign and ad group level) and lists that cannot serve; Performance Max is refused with a pointer to draft_asset_group_signals. Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
modeNo"observation" (default) or "targeting". Ignored for exclusions.observation
excludeNoTrue to exclude the audiences instead of adding them.
ad_group_idNoNumeric ad group id. Pass this or campaign_id.
campaign_idNoNumeric campaign id. Pass this or ad_group_id.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
segment_idsNoIn-market or affinity segments (segment_id from search_audience_segments).
user_list_idsNoRemarketing or customer lists (user_list_id from get_audience_lists).
custom_audience_idsNoCustom segments (custom_audience_id from get_audience_lists); Display and Video only.
combined_audience_idsNoCombined segments (combined_audience_id from get_audience_lists); Search only.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true) by disclosing that it returns only a PREVIEW, that nothing changes until confirm_and_apply applies the plan_id, that a dry run has Google validate it, and that specific Google-invalid combinations are refused. This is exactly the behavioral context an agent needs before invoking.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and preview/draft semantics are front-loaded in the first sentence, and the rest is organized by mode and validation rule. It is dense but every clause carries meaning, though it could be tightened slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering the safety profile, the description fills the remaining gaps: the draft/confirm lifecycle, mode semantics, and validation refusals. Nothing essential to correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all nine parameters are already documented in the schema. The description reinforces the mode/exclude interaction but adds little syntax or format detail beyond what the schema already provides; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence states a specific verb (draft attaching audiences), the resource (audiences), and the target scope (campaign or ad group), plus the three modes. It clearly distinguishes itself from the apply-oriented sibling confirm_and_apply and from draft_asset_group_signals.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly explains when each mode applies (observation default, targeting narrows delivery and needs double confirmation, exclusions leave mode alone) and when the tool is the wrong choice (Performance Max is refused with a pointer to draft_asset_group_signals). It also clarifies the draft-then-confirm workflow that gates all changes.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_calloutsDraft calloutsAInspect

Draft campaign callout assets — returns a PREVIEW.

Creates callout assets and links them to the campaign. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
calloutsYesCallout texts (at least one), each non-empty and at most 25 characters after trimming.
campaign_idYesNumeric ID of the campaign to attach the callouts to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations already declaring readOnly=false and destructive=false, the description adds meaningful context: this is a staged write that produces a plan_id and mutates nothing until confirm_and_apply runs. That two-phase behavior is not derivable from the annotations alone and is exactly what an agent needs to avoid assuming an immediate mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the preview semantics in the first sentence, then explains the plan_id/confirm mechanism. Slightly padded by the trailing Google Ads API documentation link, which adds little for an agent already invoking this tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value details need not be described, and the description still covers the crucial plan_id/preview contract. The preview-then-confirm workflow plus the 25-character callout constraint already in the schema makes this sufficient for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so campaign_id, callouts, and customer_id are fully documented in the schema. The description adds no additional parameter meaning beyond what the schema provides, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft campaign callout assets') and immediately clarifies it returns a preview rather than applying changes. It does not name which sibling to use instead (e.g., draft_sitelinks, draft_structured_snippets), but the resource noun makes it distinguishable from the other draft_* asset tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly routes the agent to the follow-up tool: 'nothing changes until confirm_and_apply applies it', which tells the agent both when this is used and what the next step is. No explicit exclusions or when-not-to-use conditions, but the staged workflow is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_campaignDraft a campaignAInspect

Draft a full campaign structure — returns a PREVIEW, does NOT create anything.

Creates: CampaignBudget + Campaign (PAUSED) + AdGroup + optional Keywords

  • geo targeting + language targeting. Ads are NOT included — draft_responsive_search_ad adds them once the campaign exists. Only SEARCH campaigns can be created: Performance Max needs an asset group with all its assets in one request, and DISPLAY, SHOPPING and VIDEO need channel-specific settings and ad group types, so the draft refuses them.

Returns a preview with a plan_id plus any warnings (e.g. a daily budget below 5x target CPA, MANUAL_CPC); nothing changes until confirm_and_apply applies the returned plan_id.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
max_cpcNoIn the account's currency: the manual CPC bid for the initial ad group when bidding_strategy is MANUAL_CPC, or the Maximize Clicks CPC cap when bidding_strategy is TARGET_SPEND. Not allowed with other strategies; 0 means none.
keywordsNoOptional list of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD"} added to the initial ad group.
target_cpaNoTarget cost per acquisition in the account's currency; required if bidding_strategy is TARGET_CPA, optional target for MAXIMIZE_CONVERSIONS. 0 means none.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
target_roasNoTarget return on ad spend as a ratio (e.g. 4.0 = 400%); required if bidding_strategy is TARGET_ROAS, optional target for MAXIMIZE_CONVERSION_VALUE. 0 means none.
channel_typeNoSEARCH (default). DISPLAY, SHOPPING, VIDEO and PERFORMANCE_MAX are refused with the reason (see above).SEARCH
daily_budgetYesDaily budget in the account's currency (not micros); must be greater than 0 and at most the config's max_daily_budget.
language_idsYesREQUIRED list of language constant IDs. Common: "1001" German, "1000" English, "1002" French, "1003" Spanish, "1004" Italian, "1014" Portuguese. Full list: Google Ads API language constants.
ad_group_nameNoName of the initial ad group. Empty uses campaign_name.
campaign_nameYesName of the new campaign.
geo_target_idsYesREQUIRED list of geo target constant IDs. Common: "2276" Germany, "2040" Austria, "2756" Switzerland, "2840" USA, "2826" UK, "2250" France. Full list: Google Ads API geo target constants.
bidding_strategyYesMAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC. BROAD keywords require a Smart Bidding strategy (MAXIMIZE_CONVERSIONS, MAXIMIZE_CONVERSION_VALUE, TARGET_CPA, TARGET_ROAS).
display_network_enabledNoEnable Search campaign display expansion (SEARCH campaigns only). Defaults to off.
search_partners_enabledNoInclude ads on Search partners (SEARCH campaigns only).
display_expansion_enabledNoAlias for display_network_enabled; both must match when both are given.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: explains that nothing mutates until confirm_and_apply, that the campaign is created PAUSED, that the return is a preview with a plan_id and warnings (e.g. budget below 5x target CPA, MANUAL_CPC). This is rich side-effect disclosure that the readOnlyHint/destructiveHint flags alone cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the most important fact (preview, no creation) in the first sentence, then layers created entities, exclusions, and the return/apply flow in tight, purposeful sentences. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 15-parameter drafting tool with an output schema, the description covers everything needed to call it correctly: scope, channel restrictions, downstream dependencies, and the apply workflow, while the output schema handles return-value detail.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all 15 parameters in detail; the description adds mostly structural context rather than new per-parameter meaning. Baseline 3 is appropriate when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft) and resource (campaign) and immediately clarifies it returns a PREVIEW and creates nothing, which distinguishes it from real mutation tools like confirm_and_apply. The enumeration of what gets drafted (budget, paused campaign, ad group, keywords, geo/language) makes the output scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit when-to-use (SEARCH campaigns only) and when-not (PMax/DISPLAY/SHOPPING/VIDEO refused, with reasons). Names the alternative for ads (draft_responsive_search_ad) and the follow-up tool (confirm_and_apply), leaving nothing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_clear_custom_conversion_goalDraft clearing a custom conversion goalAInspect

Put a campaign back on the account-level goals — returns a PREVIEW.

Sets goal_config_level=CUSTOMER and clears the custom goal: the rollback for draft_assign_custom_conversion_goal. The account-level goals themselves are not touched.

The returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idYesNumeric campaign ID to reset.
customer_idNoAds account ID. Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=false), the description discloses that nothing is mutated yet — it returns a preview whose plan_id is later applied via confirm_and_apply — and scopes exactly what changes (custom goal cleared, account-level goals untouched). This meaningfully clarifies the draft/apply lifecycle, though it doesn't address permissions or any limits.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and preview status, then the mechanism, the rollback relationship, and the plan_id handoff. Each sentence carries weight; the trailing API reference link is mild filler but low-cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation, and the description covers the mutation scope, preview semantics, and the confirm_and_apply workflow. It is complete for correct invocation, with only minor room to say when this should not be chosen over other goal-config tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented in the schema. The description explains the effect on the campaign but adds no syntax, format, or edge-case detail beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (put a campaign back on account-level goals), the mechanism (sets goal_config_level=CUSTOMER and clears the custom goal), and frames it as a PREVIEW. It explicitly names the sibling it reverses (draft_assign_custom_conversion_goal), so an agent can distinguish it from the surrounding draft_* conversion-goal tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The rollback framing gives clear context for when to use it, and it names the follow-up tool (confirm_and_apply) that applies the plan_id. It does not spell out an explicit 'when not to use' or compare against other custom-conversion-goal siblings, so it falls just short of the top band.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_create_conversion_actionDraft a conversion actionAInspect

Draft a new Google Ads ConversionAction — returns a PREVIEW.

Returns a preview with a plan_id (plus warnings where relevant); nothing changes until confirm_and_apply applies it. SMART_CAMPAIGN_* and GOOGLE_HOSTED types are auto-managed by Google and rejected with MUTATE_NOT_ALLOWED.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesConversion action name as it appears in Google Ads. Required.
type_YesConversionActionType enum value, e.g. AD_CALL, WEBSITE_CALL, WEBPAGE, WEBPAGE_CODELESS, GOOGLE_ANALYTICS_4_CUSTOM, GOOGLE_ANALYTICS_4_PURCHASE, UPLOAD_CALLS, UPLOAD_CLICKS.
categoryNoConversionActionCategory enum value, e.g. PHONE_CALL_LEAD, SUBMIT_LEAD_FORM, PURCHASE, ... (default DEFAULT).DEFAULT
customer_idNoGoogle Ads customer ID (digits, dashes allowed). Defaults to the configured account.
counting_typeNoONE_PER_CLICK (default; one conversion per click, typical for lead gen) or MANY_PER_CLICK (every conversion counts, typical for ecommerce).ONE_PER_CLICK
currency_codeNo3-letter ISO 4217 currency code for default_value (default USD).USD
default_valueNoValue attributed to each conversion, in currency_code units (not micros). Must be >= 0. A positive default_value with always_use_default_value=False is a legal "fallback" config: the preview warns but does NOT flip the flag.
primary_for_goalNoTrue (default) makes it a Primary action that Smart Bidding optimizes toward; False makes it Secondary (recorded only).
attribution_modelNoAttributionModel enum value, e.g. GOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN. Empty leaves Google's default.
always_use_default_valueNoTrue ignores transaction values from the tag/import and always uses default_value; False uses default_value only as a fallback when no value is supplied.
view_through_window_daysNoView-through attribution window in days, 1-30. 0 leaves Google's default.
click_through_window_daysNoClick-through attribution window in days, 1-90. 0 leaves Google's default.
phone_call_duration_secondsNoMinimum call length in seconds for a call to count; only meaningful for call conversions (PHONE_CALL_LEAD category). 0 leaves Google's default.
include_in_conversions_metricNoIMMUTABLE on create — Google derives it from the category, so this value is not sent; change it later via draft_update_conversion_action.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial behavior beyond the annotations: the preview semantics, that a plan_id is returned, that warnings may accompany it, and the specific MUTATE_NOT_ALLOWED rejection for auto-managed types. The annotations only declare safety hints, so this description carries real operational detail.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core purpose and the preview/rejection facts before the URL. Efficient overall; the trailing Google Ads API link is mildly extraneous but harmless.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema exists and annotations cover the safety profile, the description needn't explain return values — yet it still usefully notes plan_id and warnings. The full draft-then-confirm workflow plus the rejection rule makes it complete for this 14-param mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all 14 parameters are already well documented in the schema. The description adds no parameter-level detail beyond that, which matches the baseline for a fully-covered schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft a new Google Ads ConversionAction') and immediately clarifies the operation is a preview, not a committed write. This distinguishes it from draft_update_conversion_action and draft_remove_conversion_action among the siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the two-step workflow ('nothing changes until confirm_and_apply applies it'), which tells the agent this is the front half of a draft→apply pair. It also names the condition under which the call is rejected (SMART_CAMPAIGN_* and GOOGLE_HOSTED), but it does not explicitly point to sibling update/remove tools for modifying an existing action.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_custom_conversion_goalDraft a custom conversion goalAInspect

Create a custom conversion goal — returns a PREVIEW.

The goal bundles conversion actions into a named set that campaigns can then be pointed at with draft_assign_custom_conversion_goal. Only the goal is created: conversion actions are read for validation and never modified. It is always created ENABLED — a goal created as REMOVED would be invisible to every other tool, so there is nothing to plan.

If a goal with the same name and exactly the same conversion actions already exists, nothing is planned and the result says already_exists with that goal's ID (REMOVED goals do not count). A name that exists with different actions is changed with draft_update_custom_conversion_goal.

The returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesName for the new goal, e.g. "OHL | Kauf + qualifizierte Anrufe".
customer_idNoAds account ID. Defaults to the configured account.
conversion_action_idsYesNumeric conversion action IDs. Duplicates are collapsed; unknown or REMOVED actions are refused.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses that conversion actions are read-only during validation, that the goal is always created ENABLED, the exact dedup rule for name+actions, the `already_exists` result, and that REMOVED goals do not count. This is exactly the mutation-planning context the annotations cannot convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the key fact (PREVIEW) in the first sentence and orders the rest logically: bundling/read-only behavior, the ENABLED rationale, then dedup handling. Dense but every sentence earns its place; the trailing API documentation link is minor filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a draft/plan tool with an output schema (so return values need not be explained), the description covers creation scope, side effects, idempotency, and the confirm step. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents name, customer_id, and conversion_action_ids. The description adds the meaningful name-dedup interaction (same name + same actions → already_exists; different actions → update tool), but little else about the individual parameters. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ("Create a custom conversion goal") and immediately discloses the crucial scope qualifier: it returns a PREVIEW. It distinguishes itself from draft_assign_custom_conversion_goal and draft_update_custom_conversion_goal by naming them and their roles.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing: use draft_assign_custom_conversion_goal to point campaigns at the goal, draft_update_custom_conversion_goal when a name exists with different actions, and confirm_and_apply to apply the returned plan_id. It also states the when-not case (REMOVED is meaningless, so there is "nothing to plan") and the idempotent already_exists path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_delete_gtm_entityDraft deleting a Tag Manager tag, trigger or variableA
Destructive
Inspect

Draft deleting a Tag Manager tag, trigger or variable — returns a PREVIEW.

The entity is removed from a workspace and stays on the site until the workspace is published. A trigger that any tag still references, or a variable that a tag, trigger or other variable uses as {{name}}, is refused up front, with the references named. Refused unless gtm.write_enabled is set. Returns the entity that would be deleted, the resolved workspace and a plan_id.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesNumeric ID of the entity (see list_gtm_tags, list_gtm_triggers and list_gtm_variables).
entity_typeYes"tag", "trigger" or "variable".
workspace_idNoWorkspace to edit (see list_gtm_workspaces). Empty uses the Default Workspace, or the only workspace there is.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare destructiveHint/readOnlyHint/openWorldHint; the description adds substantial context beyond them — that deletion is staged and the entity survives on the site until workspace publish, that referenced triggers/variables are refused with references named, the gtm.write_enabled gate, and the returned payload (entity, workspace, plan_id). This is exactly the extra behavioral disclosure the annotations do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the preview qualifier, then prerequisites and return values in a logical order; every sentence carries information. Slightly long and line-broken, but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive-flagged draft mutation with a full schema and an output schema, the description covers the safety profile, preconditions, refusal behavior, and staging model. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are already documented in the schema, including the entity_type values and the fallback behavior of the empty IDs. The description adds no syntax or format detail beyond that, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a precise verb+resource pair ('Draft deleting a Tag Manager tag, trigger or variable') and immediately qualifies it with the preview semantics, which distinguishes it from the actual mutating siblings like draft_gtm_tag and draft_gtm_trigger. An agent can tell what it does without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: it is a preview/draft operation, it refuses up front when the entity is still referenced, and it requires gtm.write_enabled. It does not explicitly name alternative tools (e.g. the non-delete draft tools) or when-not to use this, so it falls short of a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_delete_key_eventDraft removing an Analytics key eventA
Destructive
Inspect

Draft removing a GA4 key event so the event no longer counts as a conversion, returning a PREVIEW.

The event itself keeps firing and stays in event reports; only its key-event status goes, for future data (key events already recorded are not reclassified). The draft resolves the event name against the property's key events (keyEvents.list), so the preview names the exact key event, its counting method and create time; an unknown name returns the existing key events, and one GA4 marks as not deletable is refused. Returns a preview with a plan_id and warnings; nothing changes until confirm_and_apply applies it (GA4 Admin API keyEvents.delete).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
event_nameYesEvent name of the key event to remove, exactly as listed by list_key_events (e.g. "sign_up"). Required.
property_idNoNumeric GA4 property ID, with or without the "properties/" prefix. If empty, uses the default from config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare destructiveHint=true and readOnlyHint=false, yet the description adds substantial non-obvious behavior: the event keeps firing and stays in event reports, only future key-event status is removed, historical key events are not reclassified, the preview names the exact event/counting method/create time, and resolution runs against keyEvents.list.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core verb and PREVIEW outcome, then lays out effects and error behavior. Dense but each sentence carries distinct information; the API URL tail is the only low-value addition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering safety, the description is complete: it covers intent, side effects, resolution behavior, and the confirm/apply gate. An agent would need nothing further to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds resolution semantics beyond the schema: event_name is matched against the property's key events and an unknown name returns the existing key events rather than erroring. That meaningfully supplements the schema's field descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource+scope: drafting the removal of a GA4 key event, returning a PREVIEW. It clearly distinguishes itself from sibling draft_key_event (likely create/update) and from confirm_and_apply, which the description names as the applying counterpart.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explains the draft-then-confirm workflow ('nothing changes until confirm_and_apply applies it'), and describes edge conditions: unknown names return existing key events, and non-deletable events are refused. It does not explicitly name when to prefer this over alternatives like draft_key_event or list_key_events, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_demographic_targetingDraft demographic targetingAInspect

Draft demographic targeting (age/gender/parental status/income) — returns a PREVIEW.

By default, Google Ads serves to all demographic segments. This tool adds criteria that EXCLUDE a segment (negative=True, default) or NARROW targeting to it (negative=False — uncommon). Takes exactly one of ad_group_id or campaign_id, and at least one of the four demographic lists must contain a value.

Returns a preview with a plan_id, plus warnings when the change narrows targeting, excludes 'undetermined' users, or excludes nearly a whole dimension; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
gendersNo'female', 'male', 'undetermined'.
negativeNoTrue (default) excludes the listed segments; False adds positive criteria that narrow an ad group's targeting to them.
age_rangesNoAge buckets '18-24', '25-34', '35-44', '45-54', '55-64', '65+', 'undetermined' (or canonical names such as AGE_RANGE_18_24). Google's buckets are FIXED — 'Exclude 23-35' has no exact mapping and needs a choice of buckets.
ad_group_idNoNumeric ad group ID to add the criteria to. Mutually exclusive with campaign_id.
campaign_idNoNumeric campaign ID to add the criteria to. Mutually exclusive with ad_group_id; campaign-level criteria can only be exclusions (negative=True).
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
income_rangesNoPERCENTILES (not currency): 'top-10', '11-20', '21-30', '31-40', '41-50', 'lower-50', 'undetermined'. Available in select countries only (US, AU, JP, etc.).
parental_statusesNo'parent', 'not_a_parent', 'undetermined'.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: Google serves to all segments by default, the call is non-mutating until confirmed, the response carries a plan_id and specific warning classes (narrowing, excluding 'undetermined', excluding a near-total dimension). This is exactly the kind of side-effect and failure-mode disclosure annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the most important fact (it is a preview) and proceeds through semantics, constraints, and warnings without much fat. The density is high but each sentence carries distinct information; the API doc link is the only padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description still covers prerequisites, default behavior, mutation semantics, warning cases, and the confirm step. Nothing an agent needs to invoke this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is already 100%, so the baseline is 3. The description nonetheless adds cross-parameter constraints not stated as such in the schema — 'at least one of the four demographic lists must contain a value' and the default-negative semantics — earning above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft demographic targeting') and enumerates the four dimensions it covers (age/gender/parental status/income). The 'returns a PREVIEW' framing cleanly distinguishes it from the read-side sibling get_demographic_targeting and the write-side confirm_and_apply.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the key branch decision (negative=True excludes by default, negative=False narrows and is uncommon) and states prerequisites: exactly one of ad_group_id/campaign_id and at least one populated demographic list. It routes the agent to confirm_and_apply for the actual change, but does not name the read sibling for inspecting existing targeting or state explicit when-not conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_gtm_tagDraft a Tag Manager tagAInspect

Draft creating or updating a Tag Manager tag — returns a PREVIEW.

Without tag_id this creates a tag in a workspace; with tag_id it updates the existing tag. The edit lands in the workspace and changes nothing on the site until the workspace is published. Refused unless gtm.write_enabled is set, and Custom HTML (html) is refused as well unless gtm.allow_custom_html is set. Returns the resolved workspace, the tag type, the fields that would change and a plan_id.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoTag name, 1-200 characters. Required when creating a tag.
notesNoFree-form note stored on the tag. None keeps the current note.
pausedNoTrue stores the tag paused instead of deleting it. None keeps the current state.
tag_idNoExisting tag ID to update (see list_gtm_tags). Empty creates a new tag.
tag_typeNoTag type, required when creating a tag because GTM cannot change a tag's type later: googtag, gaawe (GA4 event), awct (Ads conversion), awcc, awud, sp (Ads remarketing), gclidw, flc, fls, img, html (Custom HTML) or cvt_<id> for a Community Gallery template.
parametersNoGTM parameter dicts with at least "type" and "key", for example gaawe [{"type": "TEMPLATE", "key": "eventName", "value": "form_submit"}] or awct [{"type": "TEMPLATE", "key": "conversionId", "value": "123456789"}, {"type": "TEMPLATE", "key": "conversionLabel", "value": "AbC-dEf"}]. On update they merge by key: passed keys replace, other keys stay.
workspace_idNoWorkspace to edit (see list_gtm_workspaces). Empty uses the Default Workspace, or the only workspace there is.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.
firing_trigger_idsNoTrigger IDs that fire the tag (see list_gtm_triggers). The built-in All Pages trigger is "2147479553".
blocking_trigger_idsNoTrigger IDs that must not fire the tag.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (which only say destructiveHint=false): it discloses that the call returns a PREVIEW, that nothing changes on the live site until the workspace is published, the two feature-flag preconditions that cause refusal, and the exact return payload (workspace, tag type, changed fields, plan_id). This is exactly the extra context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The preview and create/update rules come first, followed by gating and return contract, with an API doc link last. Every sentence is load-bearing and nothing is padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a preview-oriented draft tool with full annotation coverage, a complete 11-param schema and an output schema, the description supplies everything an agent needs: gating preconditions, mutation scope, and return shape. No gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so each of the 11 parameters is already documented in the schema. The description only adds the tag_id create/update semantics, which is already echoed in the schema, so it does not meaningfully extend parameter meaning. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft creating or updating a Tag Manager tag') and immediately pins the scope with the tag_id create-vs-update split. This clearly separates it from sibling draft tools like draft_gtm_trigger, draft_delete_gtm_entity and draft_publish_gtm_workspace.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly tells the agent that omitting tag_id creates and supplying tag_id updates, and states the gating conditions (gtm.write_enabled, gtm.allow_custom_html) under which the call is refused. It does not, however, name when to prefer this over sibling drafters, so it stops short of full when/when-not routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_gtm_triggerDraft a Tag Manager triggerAInspect

Draft creating or updating a Tag Manager trigger — returns a PREVIEW.

Without trigger_id this creates a trigger in a workspace; with trigger_id it updates the existing one. The edit lands in the workspace and changes nothing on the site until the workspace is published. Refused unless gtm.write_enabled is set. Returns the resolved workspace, the trigger fields that would change and a plan_id.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoTrigger name, 1-200 characters. Required when creating a trigger.
notesNoFree-form note stored on the trigger. None keeps the current note.
filtersNoGTM conditions, each a dict with "type" (EQUALS, CONTAINS, MATCH_REGEX, ...) and "parameter" (arg0 = variable, arg1 = value), for example clicks on tel: links [{"type": "CONTAINS", "parameter": [{"type": "TEMPLATE", "key": "arg0", "value": "{{Click URL}}"}, {"type": "TEMPLATE", "key": "arg1", "value": "tel:"}]}]. On update the list replaces the existing one.
parametersNoGTM parameter dicts with at least "type" and "key". On update they merge by key: passed keys replace, other keys stay.
trigger_idNoExisting trigger ID to update (see list_gtm_triggers). Empty creates a new trigger.
trigger_typeNoTrigger type, required when creating a trigger and rejected on an existing one, because GTM cannot change it later: pageview, domReady, windowLoaded, click, linkClick, formSubmission, customEvent, elementVisibility, scrollDepth, youTubeVideo, historyChange, timer, jsError or triggerGroup.
workspace_idNoWorkspace to edit (see list_gtm_workspaces). Empty uses the Default Workspace, or the only workspace there is.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.
custom_event_nameNoThe dataLayer event name. Required for trigger type customEvent, rejected for every other type, and rejected on an existing trigger, where the event name sits in its custom event filter.
auto_event_filtersNoConditions on automatic event parameters, same shape as filters. On update the list replaces the existing one.
custom_event_filtersNoConditions on custom event parameters, same shape as filters. On update the list replaces the existing one.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false and destructiveHint=false; the description goes well beyond by disclosing that this is a preview-only write, that nothing hits the site until publish, the config gate (gtm.write_enabled), and the returned plan_id/change set. That is the exact behavioral context an agent needs before invoking a draft mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the key fact (preview, no site change) and keeps four short sentences, each carrying a distinct behavioral fact. Slightly over-resolved given the publisher/config gate is repeated in concept, but no wasted clauses.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter draft mutation with an output schema, the description covers the create/update branch, the preview semantics, the publish dependency, the auth/config gate, and points to the API doc. Return values are handled by the output schema, so nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so every parameter including trigger_id, trigger_type and custom_event_name is already documented in the schema. The description's trigger_id create/update note duplicates that coverage rather than adding new syntax or format meaning, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft creating or updating a Tag Manager trigger') and immediately clarifies it returns a PREVIEW rather than applying changes. The create-vs-update branching on trigger_id distinguishes it from sibling readers like get_gtm_trigger and from draft_gtm_tag.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly routes between create (no trigger_id) and update (with trigger_id), and states the precondition 'Refused unless gtm.write_enabled is set' plus the fact that the edit is inert until the workspace is published. It never names whitelisted alternatives such as draft_gtm_tag or the confirm_and_apply follow-up, so 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_gtm_variableDraft a Tag Manager variableAInspect

Draft creating or updating a Tag Manager variable: returns a PREVIEW.

Without variable_id this creates a variable in a workspace; with variable_id it updates the existing one. Data Layer Variables, the usual source for GA4 ecommerce values, take data_layer_key (e.g. "ecommerce.value") instead of raw parameters. Tags and triggers use a variable as {{name}}; renaming one they reference is refused, because the references would break (the GTM UI renames safely). Custom JavaScript variables run code on the site and are refused unless gtm.allow_custom_html is set. The edit lands in the workspace and changes nothing on the site until the workspace is published. Refused unless gtm.write_enabled is set.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoVariable name, 1-200 characters without curly braces. Required when creating a variable.
notesNoFree-form note stored on the variable. None keeps the current note.
parametersNoGTM parameter dicts with at least "type" and "key" for the other types, e.g. a Constant's [{"type": "TEMPLATE", "key": "value", "value": "G-ABC123"}]. On update they merge by key.
variable_idNoExisting variable ID to update (see list_gtm_variables). Empty creates a new variable.
workspace_idNoWorkspace to edit (see list_gtm_workspaces). Empty uses the Default Workspace, or the only workspace there is.
default_valueNoFor Data Layer Variables: the value when the key is missing. None sets no default.
variable_typeNoRequired when creating, fixed afterwards: v (Data Layer Variable), c (Constant), u (URL), k (1st-party cookie), j (JavaScript Variable, reads a global), aev (Auto-Event Variable), d (DOM element), f (HTTP referrer), e (Custom event), smm (Lookup table), remm (RegEx table), jsm (Custom JavaScript, gated) or cvt_<id> for a custom template.
data_layer_keyNoFor Data Layer Variables: the dataLayer key to read, dot notation for nested values, e.g. "ecommerce.transaction_id".
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give readOnly=false, destructive=false, openWorld=true, so the description carries real weight. It discloses that edits stay in the workspace until published, that referenced-variable renames are refused, that Custom JavaScript is gated, and that update parameters merge by key — all behavioral traits beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical statement (draft + returns a PREVIEW) is front-loaded and each subsequent sentence covers a distinct concern (create/update, data layer, references, gating, publish semantics, write gate). Slightly dense but no padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be described, and the description covers the create/update decision, refusal conditions, and workspace-vs-published semantics. For a 10-param, gated mutation tool this is essentially complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds genuine meaning: it explains that Data Layer Variables take data_layer_key instead of raw parameters, names the {{name}} reference convention, and clarifies workspace_id / variable_id fallback behavior that the schema alone doesn't tie together.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft creating or updating a Tag Manager variable') and immediately flags the PREVIEW return, which distinguishes it from get_gtm_variable and list_gtm_variables siblings. It also disambiguates create vs update via variable_id in the same breath.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains the two modes (without variable_id = create in a workspace; with variable_id = update) and names the prerequisite gates (gtm.write_enabled, gtm.allow_custom_html). It doesn't explicitly route to sibling alternatives like draft_gtm_tag or draft_gtm_trigger, but the create/update conditions are unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_image_assetsDraft image assetsAInspect

Draft campaign image assets from local files, public image URLs or uploads — returns a PREVIEW.

At least one image in total is required across image_paths, image_urls and upload_ids. Images must be PNG, JPEG or GIF and at most 5120 KB (Google's limit). URL images are downloaded now and checked; applying re-downloads them and refuses if the image changed since the preview. Returns a preview with a plan_id and a per-image summary; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
image_urlsNoPublic http(s) URLs of PNG/JPEG/GIF images. Links to private, local or internal addresses are refused.
upload_idsNoIds of images the user uploaded (up_..., from upload_images or list_uploads). The way to use an image that has no public URL.
campaign_idYesNumeric ID of the campaign to attach the images to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
image_pathsNoLocal PNG/JPEG/GIF file paths on the machine running AdLoop. Not available on a hosted server, where image_urls applies instead.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses real behavioral traits: nothing mutates until confirm_and_apply runs, the return is a preview with plan_id and a per-image summary, URL images are fetched and validated at draft time, and apply re-downloads and refuses if the image drifted. It also states format and 5120 KB size limits, none of which annotations carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence front-loads purpose and the preview guarantee, and the constraint sentences are compact. The trailing Google Ads API documentation link and line-broken constraint bullets add mild bulk without new information, but nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't detail return fields, yet it still names the preview payload (plan_id, per-image summary). Combined with source selection, validation rules, and the apply handoff, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents each parameter, making 3 the baseline. The description adds value beyond that with the cross-parameter constraint (at least one image across the three source fields) and the explicit 5120 KB ceiling, which the schema does not state.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource ('Draft campaign image assets'), enumerates the three input sources, and makes the preview-only nature explicit. It clearly separates itself from siblings such as upload_images (which supplies upload_ids) and confirm_and_apply (which performs the mutation).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a concrete precondition ('At least one image in total is required across image_paths, image_urls and upload_ids') and routes the agent on source choice (upload_ids for images with no public URL; image_paths unavailable on a hosted server). It implies the draft-then-apply flow via confirm_and_apply but never states explicit when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_key_eventDraft an Analytics key eventAInspect

Draft marking a GA4 event as a key event (conversion) — returns a PREVIEW.

The fix for "the event fires but isn't tracked as a conversion": attribution_check / validate_tracking diagnose it, this closes the loop. Applies to future data only. Returns a preview with a plan_id and warnings; nothing changes until confirm_and_apply applies it.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
event_nameYesName of the GA4 event to mark as a key event, exactly as it fires (e.g. "sign_up", "purchase"). Required.
property_idNoNumeric GA4 property ID, with or without the "properties/" prefix. If empty, uses the default from config.
counting_methodNoONCE_PER_EVENT (counts every occurrence, e.g. purchases) or ONCE_PER_SESSION (counts once per session, e.g. sign-ups). Defaults to ONCE_PER_EVENT.ONCE_PER_EVENT

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, destructiveHint=false, openWorldHint=true. The description goes well beyond that: it discloses that the call returns a PREVIEW with a plan_id and warnings, that nothing changes until confirm_and_apply runs, and that the effect is limited to future data. These are the exact traits an agent needs to avoid treating this as an immediate mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded purpose, then the workflow context, then the scope constraint, then the preview/confirm mechanics. Each sentence earns its place; the emphasis on PREVIEW is well placed for an agent skimming. The trailing documentation links are the only mild padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and full parameter coverage, the description needn't explain return values — yet it usefully adds plan_id/warnings and the confirm gate. The staged draft/confirm contract, scope limitation, and diagnostic loop are all covered; permission requirements are the only notable omission and are not critical here.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with all three parameters (event_name, property_id, counting_method) fully documented including defaults and prefix handling. The description adds no parameter-level detail beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: drafting the marking of a GA4 event as a key event (conversion). It is clearly distinguishable from siblings like list_key_events, draft_delete_key_event, and draft_create_conversion_action (which targets Google Ads conversion actions, not GA4 key events).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly situates the tool in a workflow: attribution_check and validate_tracking diagnose the problem, this 'closes the loop', and confirm_and_apply is required to apply it. It also notes the change applies to future data only. It doesn't differentiate against near siblings like draft_update_custom_conversion_goal, but the when/when-not context is otherwise strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_keywordsDraft keywordsAInspect

Draft keyword additions — returns a PREVIEW, does NOT add keywords.

Returns a preview with a plan_id, plus a warning when BROAD keywords go into a campaign without Smart Bidding; nothing changes until confirm_and_apply applies the returned plan_id.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesList of {"text": "keyword phrase", "match_type": "EXACT|PHRASE|BROAD"}; at least one is required.
ad_group_idYesNumeric ID of the ad group that gets the keywords.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true), the description discloses the return shape (preview with plan_id), the non-mutating phase semantics, and a conditional warning surfaced when BROAD keywords land in a campaign without Smart Bidding. That is substantive behavioral context the annotations do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The preview/non-mutation guarantee is front-loaded, followed by the plan_id mechanics and warning condition. Three tight sentences, each earning its place, with no restatement of the name or schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The output schema exists and the description still flags the salient return elements (plan_id, BROAD/Smart Bidding warning), and the confirm_and_apply handoff closes the loop. An agent has everything needed to call it and act on the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents ad_group_id, keywords (with text/match_type shape), and customer_id. The description adds no parameter-level detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource (draft keyword additions) and immediately clarifies the two-phase intent: it returns a PREVIEW and does NOT add keywords. This distinguishes it cleanly from the mutation siblings like add_negative_keywords and confirm_and_apply.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly states the follow-up path — 'nothing changes until confirm_and_apply applies the returned plan_id' — which tells the agent how the draft fits into the workflow. It stops short of naming when to prefer this over alternatives such as discover_keywords or add_negative_keywords, so no explicit exclusion is given.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_pmax_product_exclusionsDraft Performance Max product exclusionsAInspect

Draft which products a retail Performance Max asset group excludes — returns a PREVIEW.

Sets the full list of excluded values on one product dimension (item id, brand or a custom label); everything else stays included. Pass the complete list each time: values left out are included again, and an empty list includes all products. Works on asset groups that advertise all products or are already split on that one dimension; more complex product filters are refused and stay a job for Google Ads. The filter is rebuilt in one atomic request. Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
dimensionNo"item_id" (default), "brand", or "custom_label_0" to "custom_label_4".item_id
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
asset_group_idYesNumeric asset group id of a Performance Max campaign with a Merchant Center feed (from get_pmax_performance).
exclude_valuesYesEvery value to exclude, e.g. item ids from the feed, brand names or custom label values. [] removes all exclusions.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true), which only say the call is non-destructive and touches an open system. The description discloses the replace-not-merge semantics ('Pass the complete list each time: values left out are included again'), the empty-list behavior, the single-dimension atomic rebuild, and that Google-side validation occurs on the dry run.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the preview nature of the call, then organized into scope, semantics, and the confirm step. Efficient overall, though 'a dry run has Google validate it' and the PREVIEW warning overlap slightly in intent.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With full schema coverage, an output schema present, and annotations covering the safety profile, the description still supplies the pieces an agent needs: preview-vs-apply workflow, list replacement semantics, dimension constraints, and the confirm_and_apply handoff. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning: exclude_values is a full replacement list rather than an incremental addition, and dimension is constrained to one allowed dimension at a time. It doesn't restate enum-like details that the schema already carries, but the replacement semantics are genuinely additive.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft) and resource (Performance Max asset group product exclusions) and immediately flags that it produces a PREVIEW, not an applied change. This distinguishes it from sibling draft_* tools and especially from confirm_and_apply, which the description names explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly bounds applicability: works on asset groups that advertise all products or are already split on that one dimension, while more complex product filters are refused. It also states the prerequisite for effect ('Nothing changes until confirm_and_apply applies the plan_id') and that a dry run has Google validate it.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_prepare_brand_exclusionsPrepare a campaign for brand exclusionsAInspect

Draft the safe standard state for brand exclusions — returns a PREVIEW.

Exactly one combination, nothing else: enable_ai_max = true, disable_search_term_matching = true (all non-removed ad groups), TEXT_ASSET_AUTOMATION = OPTED_OUT and FINAL_URL_EXPANSION_TEXT_ASSET_AUTOMATION = OPTED_OUT.

No bidding, keyword, match type, ad, URL or budget change, and no brand list is attached — attaching stays a separate step with propose_brand_list / attach_brand_list_to_campaigns once this state is verified in the account.

Returns a preview with a plan_id (purpose brand_exclusions); nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idYesNumeric ID of the Search campaign to prepare.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
include_paused_ad_groupsNoDefault true — paused ad groups are set too, so re-enabling one later cannot silently restore search term matching.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (readOnlyHint=false, destructiveHint=false), the description discloses the exact mutation set (enable_ai_max, disable_search_term_matching across non-removed ad groups, both TEXT_ASSET_AUTOMATION opt-outs), what is deliberately NOT touched (bidding, keywords, match type, ads, URLs, budget), and that output is a preview with a plan_id requiring confirm_and_apply. That is rich behavioral context an agent cannot get from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose and the PREVIEW guarantee, then the exact settings and the no-other-changes list. Slightly verbose in the settings block, but each sentence (including the API doc link line) carries information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a draft/preview tool with an output schema present, the description supplies everything needed: what changes, what does not, that output is a plan_id preview, and the confirm_and_apply follow-up. Return-value detail is correctly delegated to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents campaign_id, customer_id, and include_paused_ad_groups thoroughly. The description reinforces the scope ('all non-removed ad groups') but adds no syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource (drafting the brand-exclusion preparation state for a campaign) and enumerates the exact settings it writes, so an agent can distinguish it from sibling drafters like draft_ai_max_settings or draft_campaign. It also explicitly separates itself from the attach step, making the scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly routes the agent: attach 'stays a separate step with propose_brand_list / attach_brand_list_to_campaigns once this state is verified', and nothing applies until confirm_and_apply. It gives sequencing and named alternatives, though it does not spell out explicit when-not-to-use conditions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_publish_gtm_workspaceDraft publishing a Tag Manager workspaceA
Destructive
Inspect

Draft publishing a Tag Manager workspace LIVE — returns a PREVIEW.

Every pending change in the workspace goes live, including changes other people made in the GTM UI; the preview lists them all. Apply refuses when the workspace changed after the preview, has merge conflicts, or reports compiler errors in a quick preview, and it refuses a Custom HTML tag being added or changed while gtm.allow_custom_html is off. Refused unless gtm.write_enabled is set. Returns the pending changes, the version that is live now (for a one-step rollback), the version name that would be created and a plan_id. That gate matches the tag type html; a Custom JavaScript variable or a custom template tag (cvt_…), which can inject a script, is not covered and needs review in the GTM UI.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
version_nameNoName of the container version created by the publish. Empty uses "AdLoop publish <UTC timestamp>".
workspace_idNoWorkspace to publish (see list_gtm_workspaces). Empty uses the Default Workspace, or the only workspace there is.
version_notesNoNotes stored on the created version. Empty leaves them out.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Well beyond the annotations, it enumerates refusal conditions, the gtm.write_enabled prerequisite, the allow_custom_html gate, and critically discloses the coverage gap (cvt_ custom templates and Custom JavaScript variables are not covered and need UI review). It also names the returned values — pending changes, current live version, prospective version name, plan_id — including the rollback affordance.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the key fact (preview, not apply) and dense with substantive constraints rather than filler. Slightly long and the trailing API URL plus the inline 'LIVE — returns a PREVIEW' phrasing add mild reading friction, but no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive, open-world publish-preview tool with an output schema, this covers prerequisites, refusal semantics, return contents, and the one known blind spot. Nothing an agent needs to call it safely is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters (including workspace_id, version_name, version_notes, account/container IDs) are already documented in the schema. The description adds no parameter-level meaning on top of it, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening states a specific verb and resource ('Draft publishing a Tag Manager workspace') and immediately pins the output ('returns a PREVIEW'), so the agent knows this is the preview half of a two-phase flow. It also names the counterpart step ('Apply'), letting it be distinguished from confirm_and_apply without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The preview-then-Apply workflow and the conditions under which Apply refuses (changed workspace, merge conflicts, compiler errors, custom HTML gate) give clear context for when this call is used. However, it never explicitly tells the agent to call this before confirm_and_apply, nor does it exclude any alternative, so routing is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_reddit_adDraft a Reddit adAInspect

Draft a Reddit ad: creates a post on the profile, then the ad (PAUSED) — PREVIEW.

click_url and the media URLs are checked before drafting, so ads do not point at unverified pages and Reddit gets real image and video files. Comments are public on Reddit ads. With post_id an EXISTING post is promoted instead, keeping its upvotes and comments: no post is created and the copy arguments are ignored. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it. Once enabled, the ad goes through Reddit policy review (PENDING_APPROVAL).

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
bodyNoPost body text, up to 40,000 characters. Optional for media posts.
ad_nameNoAd name; empty uses the headline. Truncated to 200 characters.
post_idNoExisting post to promote (t3_...); headline, body, the media arguments, call_to_action and display_url are then ignored. Empty creates a new post.
headlineNoPost headline, required for a new post, at most 300 characters.
click_urlNoLanding page (http:// or https://). Required for a new post. TEXT posts open themselves, so the full click_url must also appear in body. With post_id, TEXT posts take no click_url and media posts default it to the post's destination.
image_urlNoPublicly reachable image URL, required for IMAGE posts.
post_typeNoTEXT (headline + optional body; default), IMAGE (public image_url), VIDEO (public video_url + thumbnail_url) or CAROUSEL (2 to 6 carousel_cards).TEXT
video_urlNoDirect link to the video file (MP4 or MOV, up to 1 GB), required for VIDEO posts. Reddit downloads it when the post is created; a page that embeds the video does not work.
profile_idNoReddit profile that authors the post, from list_reddit_funding_instruments (profiles). Required for a new post; with post_id it defaults to the post's.
ad_group_idYesReddit ad group id (from get_reddit_ad_groups).
display_urlNoOptional display URL shown with media posts; must be on the click_url's domain.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
thumbnail_urlNoPublicly reachable image Reddit shows before the video plays, required for VIDEO posts.
allow_commentsNoWhether Redditors can comment publicly on the ad (default true); false disables them.
call_to_actionNoOne of Reddit's fixed labels for media posts: Apply Now, Book Now, Buy Tickets, Contact Us, Donate Now, Download, Get a Quote, Get Directions, Get Showtimes, Install, Learn More, Listen Now, Order Now, Play Now, Pre-order Now, Read More, Remind Me, See Menu, Shop Now, Sign Up, Subscribe, View More, Visit Store, Watch Now. On a carousel it is the default for every card.
carousel_cardsNoFor CAROUSEL posts, 2 to 6 cards, each {"image_url": "...", "caption": "...", "click_url": "...", "call_to_action": "..."}. Only image_url is required; caption is at most 180 characters, click_url and call_to_action default to the ad's.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations (which only declare non-readOnly, non-destructive, openWorld), the description discloses that this is a no-op preview until confirm_and_apply, that click_url and media URLs are validated up front, that the ad enters Reddit policy review (PENDING_APPROVAL), and that comments are public. That is substantial behavioral context the annotations do not carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the essential preview/no-op semantics, then the post_id branch and the API link. Dense but each sentence carries information; the multi-line wrapping makes it slightly harder to scan but nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 16-parameter mutation tool with an output schema and full annotation coverage, the description covers the preview lifecycle, the post_id branch, validation, and policy review. Since an output schema exists, it need not explain return values, and it still mentions the plan_id preview result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real cross-parameter meaning the schema does not: post_id suppresses post creation and makes the copy arguments ignored while preserving upvotes/comments, and media/landing URLs are verified before drafting. It does not restate the field enumerations, which the schema already handles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence gives a specific verb+resource (draft a Reddit ad) and immediately explains the two-step mechanics: create a post, then a PAUSED ad as a PREVIEW. This clearly separates it from siblings like draft_reddit_campaign, draft_reddit_ad_group and draft_reddit_custom_audience, and the preview/plan_id framing separates it from update_reddit_ad.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit context for the two operating modes: with post_id an existing post is promoted (copy args ignored), without it a new post is created, and it states nothing changes until confirm_and_apply. It stops short of naming a sibling alternative (e.g. update_reddit_ad) for the edit-existing-ad case, so it stops at 4.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_reddit_ad_groupDraft a Reddit ad groupAInspect

Draft a new Reddit ad group (created PAUSED) — returns a PREVIEW.

Required: campaign_id, ad_group_name, conversion_pixel_id and at least one targeting list (geolocations, communities, interests or keywords — ids/names from search_reddit_targeting). For non-CBO campaigns also daily_budget (or lifetime_budget + end_time), bid_strategy and bid_type. Budgets are checked against max_daily_budget; keywords and geolocations are pre-validated with Reddit. Returns a preview with a plan_id, the payload and warnings; nothing changes until confirm_and_apply applies it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
genderNoFEMALE or MALE; empty means all genders.
devicesNoDevice targets, objects like {"type": "MOBILE", "os": "IOS", "min_version": "16"} (type DESKTOP or MOBILE; optional os ANDROID or IOS, major OS versions with iOS at least 14, and label_map {make: [models]} with makes/models from search_reddit_targeting kind "devices"). Omitted means every device; APP_INSTALLS campaigns take exactly one.
bid_typeNoCPC, CPM, CPV, CPV6 or CPV15. Required for non-CBO campaigns.
carriersNoMobile carrier ids (from search_reddit_targeting kind "carriers", e.g. "O2_DEUTSCHLAND"), checked against Reddit's carrier list. Omitted means every carrier.
end_timeNoEnd, same formats as start_time.
keywordsNoKeywords to target; Reddit refuses keywords that are not brand-safe.
scheduleNoWeekly delivery windows ("time of day" in Ads Manager), a list of blocks like {"days": "MON-FRI", "start_hour": 13, "end_hour": 23} (day names, hours 0-23, end_hour inclusive) or the native {"start_day": "FRI", "start_hour": 22, "end_day": "SAT", "end_hour": 3}. Omitted means delivery at any time. Hours apply in each viewer's local time, not the account time zone. Not allowed in CBO campaigns, whose schedule overrides every ad group.
bid_valueNoBid in account currency; MANUAL_BIDDING and TARGET_CPX (target cost per result) need it.
interestsNoInterest ids to target.
languagesNoLanguage codes (ISO 639-1, upper-cased automatically, e.g. "DE"). Empty means every language.
locationsNoPlacements, FEED and/or COMMENTS_PAGE (conversation pages); cannot be an empty list.
platformsNoALL, DESKTOP, DESKTOP_LEGACY, MOBILE_NATIVE, MOBILE_WEB, MOBILE_WEB_3X or SHREDTOP.
start_timeNoStart, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare YYYY-MM-DD means 00:00 UTC that day. Empty means now.
view_modesNoFeed layouts: ALL, CARD, CLASSIC, COMPACT or IMMERSIVE. Omitted uses Reddit's default.
campaign_idYesReddit campaign id (from get_reddit_campaigns).
communitiesNoCommunity (subreddit) names to target.
bid_strategyNoBIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX. Required for non-CBO campaigns; in CBO campaigns it must match the campaign's.
daily_budgetNoDaily budget in account currency (positive). Required for non-CBO campaigns unless lifetime_budget is given; not allowed in CBO campaigns. Mutually exclusive with lifetime_budget.
geolocationsNoGeolocation ids to target (e.g. "DE" or "DE:2874225").
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
ad_group_nameYesName of the new ad group.
lifetime_budgetNoLifetime budget in account currency (positive); requires end_time and is compared to max_daily_budget by its per-day share.
expand_targetingNoWhether Reddit may expand delivery beyond the targeting; omitted uses Reddit's default.
excluded_keywordsNoKeywords to exclude.
optimization_goalNoThe pixel event to optimize for (PURCHASE, SIGN_UP, LEAD, PAGE_VISIT, ...). Empty in a CBO campaign inherits the campaign's.
excluded_interestsNoInterest ids to exclude (Reddit marks this field deprecated).
conversion_pixel_idYesPixel id (Reddit rule; from get_reddit_pixels).
custom_audience_idsNoCustom audiences to target (from get_reddit_audiences), e.g. website visitors for retargeting.
excluded_communitiesNoCommunity names to exclude.
excluded_geolocationsNoGeolocation ids to exclude.
excluded_custom_audience_idsNoCustom audiences to exclude, e.g. people who already bought.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, destructiveHint=false and openWorldHint=true. The description goes well beyond that by disclosing the PAUSED initial state, the preview/plan_id/warnings return, the fact that nothing mutates until confirm_and_apply, and that keywords/geolocations are pre-validated against Reddit. That is exactly the non-destructive-but-not-read-only behavioral nuance an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the essential facts (draft, PAUSED, preview) in the first sentence, then layers requirements and the mutation caveat. Dense but every clause carries information for a 31-parameter tool; the trailing API doc link is the only marginal element.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a large, conditional schema plus an output schema and a two-phase draft/apply workflow, the description covers the required inputs, conditional branches, validation behavior, and the confirm_and_apply gate. An agent has everything needed to call it and understand what happens next.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so per-parameter meaning is already documented and the baseline is 3. The description adds a cross-parameter rule that the schema does not express per-field: at least one targeting list (geolocations, communities, interests or keywords) must be supplied, plus the budget/bid_strategy/bid_type combination for non-CBO campaigns.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Draft a new Reddit ad group') and immediately discloses the two distinguishing traits: it is created PAUSED and returns a preview rather than a live entity. This cleanly separates it from siblings like update_reddit_ad_group and draft_reddit_campaign without needing to open any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete usage context: required inputs, the conditional requirements for non-CBO campaigns, the budget check against max_daily_budget, and the pointer to search_reddit_targeting for ids. It also names the follow-up step (confirm_and_apply). It never explicitly contrasts itself with update_reddit_ad_group for modifying existing groups, so it stops short of full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_reddit_campaignDraft a Reddit campaignAInspect

Draft a new Reddit campaign (created PAUSED) — returns a PREVIEW.

By default the budget lives on the ad groups; campaign_budget_optimization holds it on the campaign. Budgets are checked against max_daily_budget. Ad groups are added with draft_reddit_ad_group. Returns a preview with a plan_id, the payload and warnings; nothing changes until confirm_and_apply applies it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
bid_typeNoCPC, CPM, CPV, CPV6 or CPV15 (CBO only).
end_timeNoEnd, same formats as start_time.
scheduleNoWeekly delivery windows ("time of day" in Ads Manager; CBO only), a list of blocks like {"days": "MON-FRI", "start_hour": 13, "end_hour": 23} (day names, hours 0-23, end_hour inclusive) or the native {"start_day": "FRI", "start_hour": 22, "end_day": "SAT", "end_hour": 3}. [] clears it (deliver at any time). Hours apply in each viewer's local time, not the account time zone. A campaign schedule replaces every ad group's.
bid_valueNoBid in account currency (CBO only).
objectiveYesCLICKS, CONVERSIONS, IMPRESSIONS, LEAD_GENERATION, APP_INSTALLS, CATALOG_SALES or VIDEO_VIEWABLE_IMPRESSIONS. Other values only produce a warning, since Reddit is rolling out new objective enums.
spend_capNoCampaign spend cap in account currency; 0 or empty means none.
start_timeNoStart, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare YYYY-MM-DD means 00:00 UTC that day.
bid_strategyNoBIDLESS, MAXIMIZE_VOLUME or TARGET_CPX (CBO only).
daily_budgetNoDaily budget in account currency (positive; CBO only). Mutually exclusive with lifetime_budget.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
campaign_nameYesName of the new campaign.
lifetime_budgetNoLifetime budget in account currency (positive; CBO only); requires end_time and is compared to max_daily_budget by its per-day share.
optimization_goalNoPixel event to optimize for (PURCHASE, SIGN_UP, LEAD, PAGE_VISIT, ...); used with CBO only.
conversion_pixel_idNoPixel id from get_reddit_pixels; required with CBO, optional otherwise.
funding_instrument_idYesServable funding instrument id from list_reddit_funding_instruments.
campaign_budget_optimizationNotrue holds the budget on the campaign (then daily_budget or lifetime_budget, bid_strategy, bid_type and conversion_pixel_id are required). false (default) leaves budget and bids to the ad groups, and none of the budget or bid parameters may be passed.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare the safety profile (destructiveHint=false, openWorldHint=true); the description goes well beyond them by disclosing that nothing is mutated until confirm_and_apply, that a campaign is created PAUSED, that a plan_id/payload/warnings preview is returned, and that budgets are checked against max_daily_budget. That is exactly the behavioral context an agent needs before invoking a draft tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core identity (what it drafts, PAUSED, preview) before the budget model and follow-up tooling. Dense but every sentence carries real information; the trailing API docs URL is the only mild filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the description need not explain return values, yet it still summarizes them, and it covers the draft/confirm lifecycle plus the CBO budget model for a 16-parameter tool whose schema is fully documented. Nothing needed to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3. The description still adds meaning beyond the schema by explaining the budget-location model (ad groups by default vs. campaign_budget_optimization) and the max_daily_budget validation rule, which is not spelled out in the property descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft a new Reddit campaign') plus two critical traits up front: it is created PAUSED and returns a PREVIEW. This clearly separates it from the read/update siblings and from confirm_and_apply, which does the actual write.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the workflow context well: budget defaults to ad groups, campaign_budget_optimization moves it to the campaign, budgets are validated against max_daily_budget, and ad groups are added via draft_reddit_ad_group. It names the follow-up tool (confirm_and_apply) but never states an explicit when-not-to-use or a direct alternative to choose between.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_reddit_custom_audienceDraft a Reddit retargeting audienceAInspect

Draft a Reddit retargeting audience (website visitors or engaged people) — PREVIEW.

Builds the audience from data Reddit already has: people the pixel saw on the website, or people who saw or engaged with the account's campaigns. No personal data is uploaded. Nothing changes until confirm_and_apply applies the plan_id; Reddit then fills the audience (status PENDING, up to a day), and an ad group uses it through update_reddit_ad_group custom_audience_ids (target) or excluded_custom_audience_ids (exclude).

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
nameYesAudience name, 3 to 500 characters.
eventsNoWebsite audiences: the pixel events that qualify, any of PAGE_VISIT (default), VIEW_CONTENT, SEARCH, ADD_TO_CART, ADD_TO_WISHLIST, PURCHASE, LEAD, SIGN_UP, CUSTOM.
pixel_idNoPixel to build a website audience from (get_reddit_pixels).
engagementsNoEngagement audiences: what people did, any of CLICKS (default), IMPRESSIONS, UPVOTES, COMMENT_SUBMISSIONS, VIDEO_STARTED, VIDEO_WATCHED_50_PERCENT, VIDEO_WATCHED_100_PERCENT.
campaign_idsNoEngagement audiences: the campaigns whose audience to reuse (get_reddit_campaigns).
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
audience_typeYesPIXEL_RETARGETING (website visitors, from the pixel) or ENGAGEMENT_RETARGETING (people who saw or engaged with campaigns).
custom_eventsNoWebsite audiences: custom pixel event names to include (adds CUSTOM to events), at most 50.
lookback_window_daysNoHow far back an action counts: 1 to 90 days for website audiences (default 30), 1 to 180 for engagement audiences (default 90).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnly=false, destructive=false, openWorld=true) by disclosing that nothing is mutated until confirm_and_apply, that Reddit then asynchronously fills the audience (status PENDING, up to a day), and that no personal data is uploaded. These are exactly the operational facts an agent needs for a preview tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the essential fact (PREVIEW) and orders the rest as source -> safety -> lifecycle. Every sentence carries information, though the doc link and some phrasing are marginally verbose.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description still covers the full lifecycle (draft -> confirm -> PENDING fill -> ad-group usage). Nothing critical is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all nine parameters including the two audience_type values and get_reddit_pixels/get_reddit_campaigns sourcing hints. The description reinforces the website-vs-engagement split but adds no syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft) plus resource (Reddit retargeting audience) and immediately scopes it to the two audience kinds: website visitors and engaged people. An agent can tell it apart from sibling `draft_audience_attachment` or `search_audience_segments` without reading the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the workflow context clearly: it only produces a preview, nothing changes until `confirm_and_apply` applies the plan_id, and the result is consumed via `update_reddit_ad_group` custom_audience_ids/excluded_custom_audience_ids. It names the relevant downstream tools but does not explicitly contrast with alternative audience-creation paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_remove_conversion_actionDraft removing a conversion actionAInspect

Draft a REMOVAL of a ConversionAction — returns a PREVIEW.

Removal stops counting and drops the action from goal lists; historical data is preserved but the action is irreversible. SMART_CAMPAIGN_* and GOOGLE_HOSTED types reject removal with MUTATE_NOT_ALLOWED. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID (digits, dashes allowed). Defaults to the configured account.
conversion_action_idYesNumeric ConversionAction ID, e.g. from SELECT conversion_action.id, conversion_action.name FROM conversion_action.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

This is a case where the description carries far more than the annotations: it discloses that removal stops counting, drops the action from goal lists, preserves historical data while being irreversible, that SMART_CAMPAIGN_* and GOOGLE_HOSTED types are rejected with MUTATE_NOT_ALLOWED, and that a plan_id preview is returned. Annotations (destructiveHint=false, readOnlyHint=false) only say the draft itself is a safe non-write, which the description's preview semantics corroborate rather than contradict.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in a single bolded line, follow-on sentences each add a distinct constraint (irreversibility, type restrictions, preview/apply flow) with no filler. The trailing Google Ads API documentation link is boilerplate that doesn't earn its place, keeping this just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema covering the plan_id preview and annotations covering the safety profile, the description supplies everything else an agent needs: the irreversibility caveat, the rejecting conversion-action types, and the required confirm_and_apply follow-up.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (customer_id and conversion_action_id, including the GAQL hint for obtaining the ID) are already fully documented in structured data. The description adds nothing about parameter format or defaults, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The lead sentence gives a specific verb and resource ('Draft a REMOVAL of a ConversionAction') plus the critical qualifier that it returns a PREVIEW, which cleanly separates it from draft_create_conversion_action, draft_update_conversion_action, and the direct remove_entity sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the two-phase workflow explicitly ('nothing changes until confirm_and_apply applies it') and names the sibling that completes the operation, which is strong routing guidance. It does not, however, contrast this draft path against the direct remove_entity tool in the sibling list, leaving that choice to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_responsive_search_adDraft a responsive search adAInspect

Draft a Responsive Search Ad — returns a PREVIEW, does NOT create the ad.

The preview shows exactly what will be created; confirm_and_apply executes the returned plan_id. The ad is created PAUSED. final_url is checked for reachability first and an unreachable URL is refused. Several headlines may pin to the same position (Google rotates them there) as long as every position stays fillable, by an asset pinned to it or by a distinct unpinned one. Mixed plain-string and dict entries are allowed within a single call (e.g. brand pinned to HEADLINE_1, the rest unpinned). Warnings note fewer than 8 headlines or 3 descriptions.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
path1NoOptional first display-URL path segment (Google allows up to 15 chars).
path2NoOptional second display-URL path segment (Google allows up to 15 chars).
final_urlYesLanding page URL the ad links to; must be reachable.
headlinesYes3-15 headlines, max 30 chars each. Each entry is a plain string (unpinned) or {"text": "...", "pinned_field": "HEADLINE_1"}; valid pins are HEADLINE_1, HEADLINE_2, HEADLINE_3. Keyword or location insertion such as {KeyWord:Drain Cleaning} counts as its default text, which is required.
ad_group_idYesNumeric ID of the ad group that gets the ad.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
descriptionsYes2-4 descriptions, max 90 chars each. Each entry is a plain string (unpinned) or {"text": "...", "pinned_field": "DESCRIPTION_1"}; valid pins are DESCRIPTION_1, DESCRIPTION_2. Insertion tags count as their default text, as for headlines.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses that the ad is created PAUSED, that final_url is reachability-checked and unreachable URLs are refused, the pinning/fillability validation rule, and that warnings fire below 8 headlines or 3 descriptions. This is exactly the kind of write-behavior and validation context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The critical scope statement ('PREVIEW, does NOT create') is front-loaded, and the remaining sentences carry non-obvious behavioral rules. It is dense and slightly long, but essentially every sentence adds actionable information rather than restating structured fields.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description still covers the confirmation workflow, mutation side effects, URL validation, and pinning constraints. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% (baseline 3), and the description adds real meaning: mixed plain-string/dict entries are permitted in one call, insertion tags count as their default text, and the same position may hold multiple pinned assets. That exceeds what the schema alone conveys, though the schema already documents char limits and pin fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening line names a specific verb and resource ('Draft a Responsive Search Ad') and immediately disambiguates from actual creation ('returns a PREVIEW, does NOT create the ad'). An agent can distinguish it from update_responsive_search_ad and confirm_and_apply without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent to the follow-up step: 'confirm_and_apply executes the returned plan_id', making the draft-then-confirm workflow clear. It stops short of naming when to prefer this over update_responsive_search_ad or other draft tools, so it is clear context without full alternatives coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_rollback_gtm_versionDraft rolling back Tag Manager to a versionA
Destructive
Inspect

Draft republishing an older Tag Manager version LIVE; returns a PREVIEW.

A rollback publishes an existing container version again. The preview diffs the live version against the target, so it lists every tag, trigger and variable that changes on the site, and it pins the live version: apply refuses when another version went live after the preview, or when the target was modified or archived. Workspaces are not changed. Refused unless gtm.write_enabled is set, and refused when the target adds or changes a Custom HTML tag while gtm.allow_custom_html is off. Returns the diff, previous_live_version_id (the version that restores today's state), the target version and a plan_id.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
version_idYesContainer version ID to make live again (see list_gtm_versions and get_gtm_version_diff).
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Far exceeds the annotations: it discloses the version pinning, that apply will refuse if another version went live, that workspaces are untouched, the gtm.write_enabled and gtm.allow_custom_html preconditions, and the returned artifacts (diff, previous_live_version_id, plan_id). This is unusually rich behavioral context for a destructive draft operation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the crucial insight (drafts a live rollback and returns a preview) in the first sentence. Dense but nearly every sentence carries distinct value; a couple of long compound sentences could be trimmed slightly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Even with an output schema present, the description covers preconditions, refusal behavior, side effects and return contents, making it complete for a complex destructive mutation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters with cross-references. The description adds conceptual framing of the target version but no syntax or format detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: "Draft republishing an older Tag Manager version LIVE; returns a PREVIEW." The second sentence explicitly defines rollback semantics, distinguishing it from sibling publish/version tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the rollback context and names related tools (list_gtm_versions, get_gtm_version_diff) for the target version. It does not explicitly contrast with draft_publish_gtm_workspace or state when-not-to-use, but the rollback-vs-publish concept is clearly conveyed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_shopping_campaignDraft a Shopping campaignAInspect

Draft a Standard Shopping campaign that advertises a Merchant Center feed — returns a PREVIEW.

Creates the budget, the campaign (PAUSED), a product ad group with its Shopping ad, and one "All products" product group, in one atomic request. The Merchant Center account must be linked to the Google Ads account; the draft checks that. Shopping campaigns take no keywords and no language targeting (the feed's language applies). Nothing changes until confirm_and_apply applies the plan_id; a dry run has Google validate it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
max_cpcNoOptional CPC ceiling for TARGET_SPEND, in account currency.
feed_labelNoOptional feed label to limit the campaign to one feed of the Merchant Center account.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
merchant_idYesNumeric Merchant Center id (from list_merchant_accounts) whose products the campaign advertises.
product_bidYesCPC bid of the "All products" group in account currency. Google requires it even when the bid strategy sets bids.
target_roasNoTarget return on ad spend for TARGET_ROAS, e.g. 4.0 for 400%.
daily_budgetYesDaily budget in account currency, checked against the max_daily_budget safety cap.
ad_group_nameNoOptional ad group name; defaults to "<campaign> - All products".
campaign_nameYesName of the new campaign.
geo_target_idsYesCountries or regions as geo target constant ids, e.g. ["2276"] for Germany. Required.
bidding_strategyNoMANUAL_CPC (default), TARGET_SPEND (Maximize clicks) or TARGET_ROAS.MANUAL_CPC
campaign_priorityNoLOW (default), MEDIUM or HIGH. With several Shopping campaigns on the same products, the higher priority serves first.LOW
search_partners_enabledNoAlso serve on Google search partners.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say readOnlyHint=false, destructiveHint=false, openWorldHint=true. The description goes well beyond them: it discloses the atomicity of the request, that the campaign is created PAUSED, that the result is a preview/draft that changes nothing until confirm_and_apply, and that a dry run has Google validate it. That is exactly the behavioral context an agent needs for a multi-entity create tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and PREVIEW nature are front-loaded in the first sentence, followed by a compact block covering what is created, the prerequisite, the Shopping-specific constraints, and the confirm step. No sentence is filler; the API doc link is the only extra.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 13-parameter, output-schema-backed draft tool, the definition covers everything an agent must know before calling: the required Merchant Center link, the PAUSED draft state, atomic creation of all sub-entities, and the confirm_and_apply handoff. Return-value detail is unnecessary because an output schema exists.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% across 13 parameters, so the schema already carries per-parameter meaning (defaults, currency, enum-like strategy values). The description adds little parameter-level detail beyond noting the feed and the mandatory 'All products' group bid, so this sits at the baseline for a fully documented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb+resource+scope: 'Draft a Standard Shopping campaign that advertises a Merchant Center feed — returns a PREVIEW.' The Shopping-specific detail plus the enumeration of what gets created (budget, PAUSED campaign, product ad group, Shopping ad, 'All products' product group) clearly separates it from draft_campaign, draft_pmax_product_exclusions, and the Reddit draft siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Strong on prerequisites and constraints ('Merchant Center account must be linked', 'no keywords and no language targeting') and it names the follow-up path ('Nothing changes until confirm_and_apply applies the plan_id'). It does not explicitly say when to prefer this over the generic draft_campaign or draft_pmax siblings, so routing guidance is implied by campaign type rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_structured_snippetsDraft structured snippetsAInspect

Draft campaign structured snippet assets — returns a PREVIEW.

Creates structured snippet assets and links them to the campaign. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
snippetsYesAt least one dict with "header" and "values". header is one of Amenities, Brands, Courses, Degree programs, Destinations, Featured Hotels, Insurance coverage, Models, Neighborhoods, Services, Shows, Styles, Types (exact spelling). values is a list of 3-10 non-empty strings, each at most 25 characters.
campaign_idYesNumeric ID of the campaign to attach the snippets to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only give the generic safety flags (readOnlyHint=false, destructiveHint=false, openWorldHint=true); the description adds the non-obvious commit model — returns a plan_id preview and nothing changes until confirm_and_apply. That is genuine behavioral context beyond the structured fields, though it omits auth/permission requirements.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short paragraphs, front-loaded with the purpose and the PREVIEW behavior. The trailing Google Ads API documentation link is mildly filler and doesn't earn as much space as the rest, but overall it is tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and 100% schema coverage, the description need not restate return fields; it still usefully names plan_id. Annotations cover the safety profile and the description covers the draft/apply workflow, leaving nothing an agent needs missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents campaign_id, customer_id, and the header/values constraints of snippets. The description adds no parameter detail over the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft campaign structured snippet assets') plus a scope qualifier ('returns a PREVIEW'). The resource name itself distinguishes it from sibling asset drafts like draft_callouts, draft_sitelinks, and draft_image_assets, so an agent can select it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly frames the two-phase workflow by naming confirm_and_apply as the step that actually applies changes, which tells the agent when this tool fits. It stops short of explicitly excluding alternatives (e.g., when to prefer a direct update over drafting), so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_update_conversion_actionDraft conversion action changesAInspect

Draft a partial UPDATE of an existing ConversionAction — returns PREVIEW.

Only parameters passed non-empty/non-default are sent to the API. Covers renaming, demoting a Primary to Secondary, changing value, adjusting the call-duration threshold, or changing attribution. SMART_CAMPAIGN_* and GOOGLE_HOSTED types reject mutations with MUTATE_NOT_ALLOWED at apply time. Returns a preview with a plan_id (plus warnings where relevant); nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew name. Empty keeps the current name.
customer_idNoGoogle Ads customer ID (digits, dashes allowed). Defaults to the configured account.
counting_typeNoONE_PER_CLICK or MANY_PER_CLICK. Empty leaves it unchanged.
currency_codeNoNew 3-letter ISO 4217 currency code. Empty leaves it unchanged.
default_valueNoNew default value in the action's currency (not micros), >= 0. 0 leaves it unchanged.
primary_for_goalNoTrue makes it Primary (Smart Bidding optimizes toward it); False demotes it to Secondary. Omit to leave unchanged.
attribution_modelNoAttributionModel enum value, e.g. GOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN. Empty leaves it unchanged.
conversion_action_idYesNumeric ConversionAction ID. It comes from: SELECT conversion_action.id, conversion_action.name FROM conversion_action.
always_use_default_valueNoTrue always uses default_value; False uses it only as a fallback when the tag/import supplies no value (the preview warns when combined with a positive default_value). Omit to leave unchanged.
view_through_window_daysNoView-through attribution window in days, 1-30. 0 leaves it unchanged.
click_through_window_daysNoClick-through attribution window in days, 1-90. 0 leaves it unchanged.
phone_call_duration_secondsNoMinimum call length in seconds for a call to count. 0 leaves it unchanged.
include_in_conversions_metricNoTrue shows the action in the "Conversions" column; False in "All conversions" only. Mutable here (unlike on create). Omit to leave unchanged.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare readOnlyHint=false, destructiveHint=false, openWorldHint=true, leaving the description to carry real behavioral weight. It does so: partial-update semantics ('only parameters passed non-empty/non-default are sent'), a hard failure mode (SMART_CAMPAIGN_* and GOOGLE_HOSTED reject with MUTATE_NOT_ALLOWED at apply time), and the non-mutating guarantee (nothing changes until confirm_and_apply). This is exactly the kind of context annotations cannot supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Every sentence is load-bearing: purpose, partial-update rule, mutation coverage, failure mode, and return/apply contract. The preview semantics and the destructive-free guarantee are front-loaded before the API doc link, so an agent gets the essentials in the first two lines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value detail is not needed, and annotations cover the safety profile. The description fills the remaining gaps — workflow sequencing to confirm_and_apply, partial-update behavior, and type-based rejection — so an agent can call this correctly without further inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 and the schema already documents each field. The description adds a valuable cross-parameter rule — that only non-empty/non-default values are transmitted — which explains the default-suppression pattern shared by all 13 params and cannot be inferred from any single field description. The enumerated change categories add minor confirmation but little new syntax.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft a partial UPDATE of an existing ConversionAction') and immediately qualifies scope with 'partial' and 'existing', which cleanly separates it from the sibling draft_create_conversion_action and draft_remove_conversion_action. The preview-only nature is front-loaded in the first line.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes the draft-then-apply workflow and names confirm_and_apply as the terminal step, which effectively routes the agent to the correct follow-up tool. It also enumerates the mutation categories it handles (rename, demote Primary, value, call-duration, attribution), giving clear usage context. It stops short of explicit when-not-to-use guidance versus the create/remove siblings, so not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_update_custom_conversion_goalDraft changes to a custom conversion goalAInspect

Rename and/or re-scope an existing custom conversion goal — PREVIEW.

conversion_action_ids REPLACES the whole action list, it does not append. An empty parameter stays unchanged. The preview shows the action list before and after.

The returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew name. Empty leaves the name unchanged.
customer_idNoAds account ID. Defaults to the configured account.
conversion_action_idsNoThe complete new action list. Empty leaves the actions unchanged.
custom_conversion_goal_idYesNumeric goal ID from get_custom_conversion_goals.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnly=false, destructive=false, openWorld=true); the description adds genuinely useful behavior: the preview shows the action list before and after, empty parameters are no-ops, and the result must be confirmed. It still doesn't quantify side effects beyond the goal's action list.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action, then the replace warning, then the preview/apply contract. Efficient overall; the trailing API documentation URL is the only element that doesn't earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 4-parameter draft-mutation tool with full schema coverage, an output schema, and annotations covering safety, the description covers purpose, preview behavior, and the confirm step. Complete enough to invoke correctly, missing only edge-case handling (e.g., invalid IDs, name collisions).

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds the critical replace-vs-append semantics for conversion_action_ids and reinforces the empty-means-unchanged convention, which is exactly the kind of trap an agent would otherwise fall into.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Rename and/or re-scope an existing custom conversion goal') and flags that it is a PREVIEW, which cleanly separates it from the create-oriented draft_custom_conversion_goal and the draft_clear_custom_conversion_goal siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the follow-up path: 'The returned plan_id is applied with confirm_and_apply.' That gives clear workflow context, though it does not state when to prefer this over direct update paths or list any prerequisites/exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

draft_upload_call_conversionsDraft call conversion uploadInspect

Draft an offline CALL-conversion upload from a CSV — returns a PREVIEW.

Uploads call conversions via ConversionUploadService.UploadCallConversions, matching the call against the ad click by the caller's phone number. The CSV must have columns: Caller's Phone Number, Call Start Time, Conversion Name, Conversion Time, Conversion Value, Conversion Currency. The Conversion Name must match an existing UPLOAD_CALLS-type conversion action — verified against the account while drafting, so a typo fails here rather than after the upload. Optional Ad User Data and Ad Personalization columns carry consent per row.

The CSV comes from csv_path (a file on the machine running AdLoop) or from upload_id (a file uploaded with upload_conversion_csv, the only way on AdLoop Cloud). An uploaded file is deleted once the draft has read it.

PII: the caller phone number is required RAW by Google (it cannot be hashed), so it lives in the plan's apply-only payload — the preview shows redacted ids and counts, the audit log and plan.changes show neither. Apply uploads exactly what you previewed (no CSV re-read).

Phone numbers are normalized with libphonenumber semantics: a number carries no country code needs default_region, an extension is dropped, and the German trunk marker in "+49 (0)89 …" is handled. Rows whose number stays unusable are skipped and reported in skipped_rows instead of being uploaded to no effect.

Rows that repeat inside one file are named in dedup_warnings. A call upload has no dedup key at Google, so each of them still goes out as its own conversion — the warning is the only place that says so.

Returns a preview with a plan_id, the row counts, the consent the rows actually carry (consent_summary) and the skipped rows; nothing is uploaded until that preview is confirmed.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
consentNoConsent signals for GDPR/EEA, as an object with "ad_user_data" and/or "ad_personalization", each "GRANTED", "DENIED" or "UNSPECIFIED". None sends UNSPECIFIED. A row whose own "Ad User Data" / "Ad Personalization" columns are filled in overrides this for that row; empty cells fall back to it.
csv_pathNoPath of the CSV file holding the upload rows, read on the machine that runs AdLoop. Refused on the hosted server; use upload_id there.
upload_idNoId of a CSV uploaded with upload_conversion_csv (up_...), instead of csv_path.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
default_regionNoISO 3166-1 alpha-2 country assumed for phone numbers that carry no country code, e.g. "DE" for "0151 12345678". Empty leaves such numbers unusable and the row is skipped.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

draft_upload_enhanced_conversions_for_leadsDraft enhanced conversions uploadInspect

Draft an Enhanced Conversions for LEADS upload from a CSV — PREVIEW.

Uploads lead conversions via ConversionUploadService.UploadClickConversions with user_identifiers, matching hashed customer PII back to the Google users who clicked the ads. The CSV holds RAW PII in columns: Email, Phone Number, First Name, Last Name (plus Conversion Name, Conversion Time, Conversion Value, Conversion Currency; optional Order ID dedup key, and optional Ad User Data / Ad Personalization consent columns).

PII is normalized and SHA-256-hashed AT PREVIEW TIME — only the hashes are stored in the plan. Raw email/phone/name never land in the plan or the audit log. The target conversion action must be UPLOAD_CLICKS-type.

An Order ID column makes re-uploads dedup instead of double-counting.

Rows that repeat inside one file are named in dedup_warnings. Rows sharing an Order ID count once at Google; two rows with different Order IDs are two real orders and are not reported.

The CSV comes from csv_path (a file on the machine running AdLoop) or from upload_id (a file uploaded with upload_conversion_csv, the only way on AdLoop Cloud). An uploaded file is deleted once the draft has read it.

Returns a preview with a plan_id, the row counts, the consent the rows actually carry (consent_summary) and the skipped rows; nothing is uploaded until that preview is confirmed.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
consentNoConsent signals for GDPR/EEA, as an object with "ad_user_data" and/or "ad_personalization", each "GRANTED", "DENIED" or "UNSPECIFIED". None sends UNSPECIFIED. A row whose own "Ad User Data" / "Ad Personalization" columns are filled in overrides this for that row; empty cells fall back to it.
csv_pathNoPath of the CSV file holding the upload rows, read on the machine that runs AdLoop. Refused on the hosted server; use upload_id there.
upload_idNoId of a CSV uploaded with upload_conversion_csv (up_...), instead of csv_path.
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
default_regionNoISO 3166-1 alpha-2 country assumed for phone numbers that carry no country code, e.g. "DE" for "0151 12345678". Empty leaves such numbers unusable; the row still uploads when its email or its complete address identifies the lead.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

enable_entityDraft enabling an entityAInspect

Draft enabling a paused campaign, ad group, ad, or keyword — returns a PREVIEW.

Returns a preview with a plan_id (target status ENABLED); nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesID in the format for its type. campaign: campaign ID (e.g. "12345678"); ad_group: ad group ID (e.g. "12345678"); ad: "adGroupId~adId" (e.g. "12345678~987654"; a bare ad ID is resolved to its ad group at apply time); keyword: "adGroupId~criterionId" (e.g. "12345678~987654").
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
entity_typeYes"campaign", "ad_group", "ad", "keyword" or "asset_group" (Performance Max).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as non-read-only, non-destructive, open-world. The description adds meaningful context beyond them: the call produces only a preview with a plan_id, no state changes occur, and confirm_and_apply is the required follow-up. That resolves the otherwise ambiguous mutation-with-destructiveHint=false combination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: purpose and preview semantics first, then the confirmation dependency. The API doc link is the only extra and is legitimately useful. Nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value explanation is unnecessary, and the description covers the safety-relevant draft/confirm behavior. The only gap is the missing asset_group mention, which leaves a minor mismatch between the described scope and the schema's accepted values.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so entity_id formatting, customer_id defaulting, and entity_type values are already fully documented. The description adds no parameter-level detail and notably omits asset_group from its entity list while the schema includes it. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (enable) and resource set (paused campaign, ad group, ad, or keyword) and immediately frames it as a draft returning a PREVIEW. The agent can distinguish it from confirm_and_apply, pause_entity, and remove_entity without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly signals the two-step workflow: this tool only previews, and nothing changes until confirm_and_apply applies the plan. It does not explicitly say when to prefer this over siblings like pause_entity or remove_entity, but the draft-then-confirm context is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

enable_reddit_entityDraft enabling a Reddit entityAInspect

Draft enabling (configured_status=ACTIVE) a Reddit campaign, ad group or ad — PREVIEW.

Enabling a new ad sends it to Reddit policy review (PENDING_APPROVAL). Returns a preview with a plan_id, the current and target status and warnings (e.g. an effective_status of REJECTED or PENDING_BILLING_INFO that keeps it from serving); nothing changes until confirm_and_apply applies the plan_id.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesReddit id of the entity, from the read tools (get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads).
entity_typeYes"campaign", "ad_group" or "ad".
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true) by disclosing that the call is non-mutating until confirmed, that enabling a new ad triggers Reddit policy review (PENDING_APPROVAL), and that warnings can be returned for statuses like REJECTED or PENDING_BILLING_INFO. This is exactly the kind of side-effect and edge-case context an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with verb, resource and the PREVIEW qualifier, followed by tightly ordered sentences on side effects, return shape, and the confirm step. The trailing API docs link and some parenthetical detail add minor length but no real waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a three-parameter draft tool with an output schema, this covers everything needed: the draft/confirm contract, the policy-review consequence, warning semantics, and where the entity IDs come from. Nothing required to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema already documents entity_id (with source read tools), entity_type values, and ad_account_id default behavior. The description adds no parameter-level syntax or format detail beyond that, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (enable), the resource (a Reddit campaign, ad group or ad), and the crucial scope qualifier that this is a PREVIEW that only drafts the change. It is immediately distinguishable from pause_reddit_entity, remove_reddit_entity, and the Google-side enable_entity sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the two-step workflow clearly: this drafts, and nothing changes until confirm_and_apply applies the plan_id. It also notes the policy-review side effect for new ads. It does not explicitly state when to prefer this over alternatives, but the draft-vs-apply routing is spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimate_budgetBudget forecastA
Read-only
Inspect

Forecast clicks, cost, and conversions for a set of keywords.

Uses Google Ads Keyword Planner to estimate campaign performance without creating anything. Essential for budget planning before launching campaigns. Per-keyword max_cpc values are collapsed to a campaign-level manual CPC cap (the highest one) — the Ads API forecast takes no per-keyword bids. Returns estimated clicks, cost, avg CPC, conversions and avg CPA for the forecast period, daily estimates, and insights.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesList of {"text": "keyword", "match_type": "EXACT|PHRASE|BROAD", "max_cpc": 1.50}. match_type defaults to BROAD; max_cpc is optional (defaults to 1.00 in account currency, not micros). At least one keyword is required.
customer_idNoGoogle Ads customer ID (digits, dashes allowed). Defaults to the configured account.
language_idNoLanguage constant ID (1000=English, 1001=German, 1002=French, 1003=Spanish). Defaults to 1000.1000
daily_budgetNoDaily budget in account currency. If provided, insights will show what % of traffic the budget captures. 0 = no budget comparison.
forecast_daysNoForecast horizon in days, starting tomorrow (default 30).
geo_target_idNoGeo target constant ID (2276=Germany, 2840=USA, 2826=UK, 2250=France). Defaults to 2276.2276

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: it discloses the Keyword Planner data source, the read-only non-creating behavior, and a non-obvious semantic quirk (per-keyword max_cpc values are collapsed to the highest value as a campaign-level manual CPC cap because the forecast API takes no per-keyword bids). It also names what is returned, which is genuinely useful.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose, then covers mechanism, constraints, and returns in cleanly separated sentences. The trailing Google Ads API documentation link is filler, but the rest of the text earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, open-world forecast tool with annotations covering the safety profile and an output schema covering return shape, the description supplies everything else an agent needs: data source, bid-collapsing caveat, and output granularity. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds real meaning by explaining how the max_cpc input is actually consumed (collapsed to the highest per-keyword value). It does not, however, clarify the interaction of daily_budget or forecast_days beyond what the schema already states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (forecast) and resources (clicks, cost, conversions) scoped to keywords, and explicitly disclaims side effects ('without creating anything'), which cleanly separates it from the many draft_* siblings. An agent can identify the tool's job without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context — 'essential for budget planning before launching campaigns' — which tells the agent when this tool fits. It does not, however, name an alternative (e.g. using actual performance tools like get_keyword_performance once campaigns exist), so the when-not case is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

estimate_reddit_ad_groupEstimate a Reddit ad groupA
Read-only
Inspect

Audience size, delivery estimate and Reddit's suggested bid for a planned ad group — read-only.

Reddit's counterpart of estimate_budget: takes the same targeting and budget as draft_reddit_ad_group, ahead of drafting. Returns the reachable and targetable audience (fixed 30-day basis), estimated impressions/clicks/reach for the schedule, the minimum/suggested bid range for bid_type in account currency, and insights (audience under 10,000 people, bid_value below the suggested minimum). Nothing is created. At least one of geolocations, communities, interests or keywords is required.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
genderNoFEMALE or MALE; empty means all genders.
devicesNoDevice targets, objects like {"type": "MOBILE", "os": "IOS", "min_version": "16"} (type DESKTOP or MOBILE; optional os ANDROID or IOS, major OS versions, and label_map {make: [models]} with makes/models from search_reddit_targeting kind "devices"). Empty means every device.
bid_typeNoCPC (default), CPM, CPV, CPV6 or CPV15; the bid suggestion is for this bid type.CPC
carriersNoMobile carrier ids (from search_reddit_targeting kind "carriers", e.g. "O2_DEUTSCHLAND"). Empty means every carrier.
end_timeNoSchedule end, ISO 8601. Empty means 30 days after the default start.
keywordsNoKeywords to target.
bid_valueNoPlanned bid in account currency; compared with Reddit's suggested minimum.
interestsNoInterest ids to target (from search_reddit_targeting kind "interests").
languagesNoLanguage codes (ISO 639-1, upper-cased automatically, e.g. "DE"). Empty means all languages.
objectiveNoCampaign objective the estimate assumes, e.g. CLICKS (default), CONVERSIONS, IMPRESSIONS, LEAD_GENERATION, APP_INSTALLS, CATALOG_SALES or VIDEO_VIEWABLE_IMPRESSIONS.CLICKS
platformsNoPlatforms to target, e.g. ALL, DESKTOP, MOBILE_NATIVE, MOBILE_WEB. Empty means no platform restriction.
start_timeNoSchedule start, ISO 8601 (e.g. 2026-10-01T00:00:00Z). Empty means tomorrow 00:00 UTC.
communitiesNoCommunity (subreddit) names to target.
bid_strategyNoBIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX. Empty means BIDLESS.
daily_budgetNoDaily budget in account currency (positive). One of daily_budget or lifetime_budget is required; daily_budget wins when both are given.
geolocationsNoGeolocation ids to target (e.g. "DE" or "DE:2874225", from search_reddit_targeting kind "geolocations").
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
lifetime_budgetNoLifetime budget in account currency (positive), used when daily_budget is not given.
optimization_goalNoPixel event to optimize for (PURCHASE, SIGN_UP, LEAD, PAGE_VISIT, ...). Empty means none.
excluded_communitiesNoCommunity names to exclude.
excluded_geolocationsNoGeolocation ids to exclude.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so 'read-only'/'Nothing is created' is partly redundant. The description still adds real behavioral context beyond the annotations: the fixed 30-day basis, the insight triggers (audience under 10,000, bid_value below suggested minimum), and the requirement that at least one of geolocations/communities/interests/keywords be supplied.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose in the first clause, then layers in workflow context, return contents, constraints, and a docs link. It is dense but each sentence carries information; the only slight slack is restating read-only twice ('read-only' and 'Nothing is created').

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 21-parameter, no-required-field estimation tool with an output schema and full annotations, the description supplies the missing pieces: workflow placement, the at-least-one-targeting constraint, and the meaning of the returned insights. Nothing an agent needs to invoke it correctly is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema documents all 21 parameters and the baseline is 3. The description adds meaning the schema cannot convey: the cross-parameter constraint that at least one targeting dimension is required, and that the bid suggestion is tied specifically to bid_type in account currency.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (estimate a Reddit ad group) and explicitly frames it as the read-only counterpart of estimate_budget, distinguishing it from the sibling draft_reddit_ad_group. The returned artifacts (audience size, delivery estimate, suggested bid) are named up front.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly places the tool in the workflow: it takes the same targeting and budget as draft_reddit_ad_group and is used 'ahead of drafting.' It also names its GA-side analogue (estimate_budget), so an agent can route correctly between the estimate and the draft.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

generate_tracking_codeGenerate tracking codeA
Read-only
Inspect

Generate a GA4 event tracking JavaScript snippet.

Produces ready-to-paste gtag code for the specified event. Includes recommended parameters for well-known GA4 events (sign_up, purchase, etc.). Optionally checks GA4 to warn if the event already fires. Returns the javascript snippet, already_exists / existing_count from GA4, and notes (duplicates, marking it as a key event, GDPR consent).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
triggerNo"form_submit", "button_click", or "page_load" — wraps the gtag call in an appropriate event listener (with a YOUR_SELECTOR placeholder for forms and buttons). Empty = bare gtag call.
event_nameYesGA4 event name for the snippet, e.g. "sign_up" or "generate_lead".
property_idNoGA4 property as "properties/123456789" used for the existing-event check. If empty, uses the default from config.
event_paramsNoEvent parameters as a name-to-value object, e.g. {"method": "email"}. Missing recommended parameters for well-known events are added as typed placeholders.
check_existingNoWhen true (default), looks up the last 28 days of GA4 events to report whether this event already fires.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds genuine behavioral context beyond them: the GA4 lookup window behavior, the automatic placeholder insertion for well-known events, and the consent/key-event/GDPR notes returned alongside the snippet.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose in the first sentence, then a compact paragraph on behavior and outputs. The trailing Google Analytics Data API / Google Ads API documentation links are irrelevant to invoking this tool and are the only wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists and annotations cover the safety profile, so the description needn't explain return values — yet it usefully summarizes them (snippet, already_exists, existing_count, notes). What remains missing is guidance on when to prefer this over the sibling tracking-validation tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are already documented in the schema, making 3 the baseline. The description restates the existing-event check and the recommended-parameter behavior but adds no syntax or format detail beyond what the schema properties already say.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Generate a GA4 event tracking JavaScript snippet' with ready-to-paste gtag code. The output and scope are clear, but it never distinguishes itself from nearby siblings such as validate_tracking, get_tracking_events, or audit_event_coverage, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the phrases 'for the specified event' and 'Optionally checks GA4 to warn if the event already fires', which maps to the check_existing parameter. There is no explicit when-not guidance and no named alternative tool, so routing between this and validate_tracking/audit_event_coverage is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_account_summariesList Analytics propertiesA
Read-only
Inspect

List all GA4 accounts and properties accessible by the authenticated user.

Serves as the discovery step for which GA4 properties are available. Returns account names, property names, and property IDs.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds genuine context beyond that: results are scoped to what the 'authenticated user' can access, and it frames the call as a prerequisite discovery step rather than a standalone report.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by role and return scope. The two external API documentation links at the end are marginal for tool selection but short and clearly optional, so the definition stays tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only discovery tool with rich annotations and an output schema, the description supplies everything an agent needs: what it returns, whose data it covers, and when in a workflow to call it. Return-value detail is duplicated from the output schema but does no harm.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so per the baseline there is nothing to document and no gap for the description to fill. No parameter detail is expected or missing.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all GA4 accounts and properties') scoped to GA4, which separates it from the sibling list_accounts (Ads) and the various list_gtm_*/list_reddit_* tools. An agent can identify this as the GA4 discovery tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Serves as the discovery step for which GA4 properties are available' gives clear usage context and position in a workflow. However, it never names an alternative or an exclusion (e.g. distinguishing it from list_accounts or list_gsc_sites), so routing between the several list_* siblings is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ad_performanceAd performanceB
Read-only
Inspect

Get ad-level performance data including headlines, descriptions, and metrics.

Returns ad type, headlines, descriptions, final URL, impressions, clicks, CTR, conversions, cost for each ad, plus its policy approval status, review status and policy topic names. Disapproved and limited-by-policy ads are listed under policy_issues with their spend.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
compactNoWhen true (for audits/overviews), returns totals, the top-10 ads with headline/description COUNTS instead of full asset lists, plus incomplete-RSA, single-ad ad-group and policy findings with approval-status counts (~90% smaller).
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds useful behavioral context by noting that disapproved and limited-by-policy ads surface under policy_issues with their spend, which tells the agent what to expect from the result.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by the returned fields and policy handling. The trailing Google Ads API URL is marginally useful documentation but slightly extraneous to the task of invoking the tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety and an output schema present, the description need not explain return values, yet it does so thoroughly and adds the policy_issues behavior. Everything needed to call the tool correctly is present, with mild redundancy against the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents all four parameters. The description adds no parameter-level syntax or format detail beyond what the schema provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Get) and resource (ad-level performance data) and enumerates the fields returned (headlines, impressions, CTR, conversions, etc.). It is clearly distinguishable from get_campaign_performance and get_keyword_performance by scope, though it never names those siblings explicitly for differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives no when-to-use guidance or exclusions; it never says when to prefer this over get_detailed_asset_performance or get_campaign_performance. The only usage hint (audits/overviews) lives inside the compact parameter schema, not the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_ai_max_settingsAI Max settingsA
Read-only
Inspect

Read the AI Max controls of Search campaigns, per campaign and ad group.

Returns for every campaign: id, name, status, advertising channel type, campaign.ai_max_setting.enable_ai_max, campaign.ai_max_setting.bundling_required (output only) and the full campaign.asset_automation_settings list. Each campaign also carries its non-REMOVED ad groups with ad_group.ai_max_ad_group_setting.disable_search_term_matching.

Shows the current state ahead of draft_ai_max_settings, and what the account actually looks like after confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoNumeric campaign ID. When omitted, every non-removed Search campaign in the account is listed.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds one genuine behavioral trait (only non-REMOVED ad groups are returned) but otherwise spends its words enumerating return fields, which the output schema already provides.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and workflow placement are front-loaded, but the long enumeration of returned fields is redundant given an output schema and dilutes the signal. It is efficient overall but not maximally tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers purpose, scope, workflow position, and links the Google Ads API docs; with an output schema present it need not explain returns. It could note filtering limits or pagination behavior for large accounts, but nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are documented there (campaign_id filtering, customer_id default). The description adds nothing beyond the schema about parameter semantics, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('Read') and resource ('AI Max controls of Search campaigns'), scoped per campaign and ad group. No sibling in the list reads AI Max settings, so the tool is immediately distinguishable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly positions the tool in the workflow: use it to see current state 'ahead of draft_ai_max_settings' and after 'confirm_and_apply'. The agent knows both the alternatives and when each applies.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_asset_group_signalsAsset group signalsB
Read-only
Inspect

Search themes and the audience signal of a Performance Max asset group, plus the account's audiences.

Returns each search theme and audience signal with its signal_id and approval status, the enabled audiences of the account that can become the group's audience signal (audience_id, name), and insights when a group has no themes or no audience signal.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
asset_group_idYesNumeric asset group id (from get_pmax_performance).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds real context beyond that: it enumerates what comes back (signal_id, approval status, enabled account audiences, empty-state insights). It does not cover permissions, rate limits, or any pagination/truncation behavior, so it sits at the baseline-plus level rather than rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence and the second paragraph is a compact enumeration of returned fields. It is slightly wasteful because return-value detail largely duplicates the output schema, but there is no filler or hedging.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and annotations carry the safety profile; the schema carries parameter docs. What remains missing is only the usage/routing context relative to siblings like draft_asset_group_signals and get_audience_lists, which is a modest gap for a two-parameter read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (customer_id, asset_group_id) are already documented in the schema, including the useful 'from get_pmax_performance' provenance hint. The description adds no parameter-level meaning at all, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource: 'Search themes and the audience signal of a Performance Max asset group, plus the account's audiences.' An agent can tell this is a read of PMax signal state, distinct from most siblings. It does not, however, name its closest sibling (draft_asset_group_signals), which is the mutating counterpart an agent would need to disambiguate against.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not-to-use guidance. Nothing tells the agent whether to call this before draft_asset_group_signals, or how it relates to get_audience_lists / get_pmax_performance, which return overlapping data. The only hint is the mention of 'insights when a group has no themes or no audience signal', which is behavioral, not usage guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_audience_listsAudience listsA
Read-only
Inspect

The account's own audiences: remarketing and customer lists, custom segments, combined segments.

Each user list comes with its type, membership status (OPEN or CLOSED), size for Search and Display, eligibility and membership duration; custom and combined segments with their id and description. Insights flag lists below the 1,000 users Search needs and closed lists. Use the ids with draft_audience_attachment; for Google's in-market and affinity segments use search_audience_segments.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, non-destructive, openWorld), so the bar is lower. The description adds genuine behavioral value by describing what each record carries (type, OPEN/CLOSED status, size scope, eligibility, membership duration) and the Insights flagging behavior for sub-1,000-user and closed lists. It omits pagination/result-size behavior, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the resource definition, then details on returned fields, then routing. Dense but every clause earns its place. The trailing Google Ads API doc link is boilerplate rather than tool guidance.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not required, yet the description still caps what to expect from returned lists. Combined with explicit sibling routing, an agent has enough to select and invoke it. Only minor gaps (pagination, result limits) remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% for the single customer_id parameter, and the schema already documents the digits/dashes format and default-account fallback. The description implies default-account behavior via 'The account's own audiences' but adds no syntax or format detail, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (the account's own audiences: remarketing/customer lists, custom segments, combined segments) and even enumerates the subtypes returned. It explicitly distinguishes itself from the sibling search_audience_segments by scoping to 'the account's own' versus Google's in-market/affinity segments.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Routes the agent explicitly: use the returned ids with draft_audience_attachment, and defer Google's in-market/affinity segments to search_audience_segments. This gives both the downstream-use case and the sibling-alternative condition, leaving little inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_audience_performanceAudience performanceA
Read-only
Inspect

Get audience segment performance metrics.

Returns performance by audience type — remarketing lists (USER_LIST), in-market segments (USER_INTEREST), affinity, demographics (AGE_RANGE, GENDER), etc. Shows display_name, impressions, clicks, cost, conversions, CTR, and CPC for each audience.

Works for campaigns with explicit audience targeting (Search, Display). PMax audience targeting is automatic and may not appear in this report.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoOptional numeric ID to filter to a single campaign.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, openWorldHint=true, so the safety profile is covered. The description adds real, non-obvious behavior: which audience categories appear, the per-row metrics returned, and the important caveat that PMax audiences may be missing entirely. No auth or rate-limit detail, but the PMax data-coverage caveat is the kind of trait an agent needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then returned fields, then the applicability caveat — a sensible ordering with little waste. The trailing 'Google Ads API: https://...' link is filler that doesn't help an agent select or invoke the tool, keeping it short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values need not be explained, yet the description still names key metrics; all four parameters are fully documented in-schema and the PMax limitation is disclosed. Complete enough for correct invocation, with only the sibling-boundary question against get_demographic_targeting left open.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including the date-range default behavior ('last 30 days if either is empty') and customer_id fallback, so the schema carries the parameter burden. The description adds no parameter-level meaning beyond what the schema already states, making 3 the correct baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: 'Get audience segment performance metrics', with the granularity (audience type) and returned fields spelled out. It distinguishes itself from generic performance tools by naming the audience-type dimension (USER_LIST, USER_INTEREST, AGE_RANGE, GENDER), but it never names the nearest-looking sibling, get_demographic_targeting, leaving some ambiguity between a performance report and a targeting-settings tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear scope: 'Works for campaigns with explicit audience targeting (Search, Display)', and an explicit when-not: PMax audience targeting is automatic and 'may not appear in this report'. It stops short of routing the agent to an alternative tool for the PMax case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_audience_targetingAudience targetingA
Read-only
Inspect

Audiences attached to one campaign or ad group, its exclusions, and the audience mode.

audience_mode is "observation" (audiences only adjust bids and report), "targeting" (ads only reach the audiences) or "not set". Every audience and exclusion carries a remove_id for remove_entity (entity_type "campaign_criterion" or "ad_group_criterion").

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_group_idNoNumeric ad group id. Pass this or campaign_id.
campaign_idNoNumeric campaign id. Pass this or ad_group_id.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe-read profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true). The description adds real value beyond them by decoding the audience_mode values (observation vs targeting vs not set) and disclosing that every audience/exclusion carries a remove_id for remove_entity, which links this read to a specific mutation path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the resource definition, then two dense sentences that each carry information (mode semantics, remove_id cross-reference). The trailing API doc link is mild filler but the rest is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be spelled out. The description covers the key non-obvious domain concept (audience_mode) and the cross-tool removal linkage, leaving only sibling differentiation as a gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so ad_group_id, campaign_id, and customer_id are already fully documented, including the either/or relationship. The description adds no parameter-level syntax or format detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource and scope: audiences attached to one campaign or ad group, plus exclusions and the audience mode. An agent can distinguish it from get_audience_lists and get_demographic_targeting by the 'attached to a campaign/ad group' framing, but it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied rather than stated — the tool clearly reads existing targeting config, and the remove_id/remove_entity note hints at the adjacent removal workflow. There is no explicit when-to-use guidance or condition selecting this over get_demographic_targeting or get_audience_lists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_brand_list_brandsBrands in a brand listA
Read-only
Inspect

List the brands inside a brand list.

Returns the brands and their total. Each entry carries brand.entity_id (the Commercial KG MID that suggest_brands returns as id), the display name, primary URL, status and a criterion_id — the latter is what remove_from_brand_list needs.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.
shared_set_idYesNumeric list ID from get_brand_lists (shared_set.id).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds real value beyond that by enumerating the return shape (entity_id, display name, primary URL, status, criterion_id) and the cross-tool identity of entity_id. It says nothing about pagination or limits, but against these annotations that is a minor gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose is front-loaded in the first sentence, followed by tightly packed return-field detail and a link. Every sentence carries information an agent needs; nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter read tool with full schema coverage, an output schema, and safety annotations, the description supplies the remaining workflow context (field meanings and the link to remove_from_brand_list). Nothing needed to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented in the schema, including that shared_set_id comes from get_brand_lists. The description adds no format, syntax, or defaulting detail beyond that, so the baseline 3 is correct.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List the brands inside a brand list') and implicitly distinguishes itself from the sibling get_brand_lists, which lists the lists themselves. It also ties the returned brand.entity_id back to suggest_brands' id, so an agent can place it precisely in the brand-list workflow.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Context is clear through cross-references: criterion_id is flagged as what remove_from_brand_list needs, and shared_set_id is sourced from get_brand_lists, giving an agent natural use conditions. It stops short of an explicit when-to-use/when-not statement or naming alternatives as choices, so it does not reach full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_brand_list_campaignsCampaigns using a brand listA
Read-only
Inspect

List which campaigns a brand list is attached to.

Brand lists attach as CampaignCriterion rows of type BRAND_LIST (not as CampaignSharedSet like negative keyword lists). Returns each attachment's campaign ID, name and status, the criterion, and role: "excluded" when the criterion is negative, "targeted" when it restricts targeting to the list.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.
shared_set_idNoNumeric list ID from get_brand_lists. When omitted, all brand-list attachments in the account are returned.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint true, destructiveHint false, openWorldHint true). The description goes beyond them by disclosing the row type behind the result (CampaignCriterion / BRAND_LIST) and decoding the `role` field semantics ('excluded' vs 'targeted'), which is real behavioral context an agent would not otherwise infer.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the one-line purpose before the technical detail, and the CampaignCriterion clarification earns its place. The trailing 'Google Ads API' URL is boilerplate padding that adds little, but the rest is tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be explained, yet the description helpfully clarifies the non-obvious `role` semantics. Combined with annotations and full schema coverage, an agent has what it needs to call it correctly; only pagination/volume behavior is left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and both parameters are documented in the schema itself (customer_id default, shared_set_id default-omitted behavior). The description's field list (campaign ID, name, status, criterion, role) describes outputs, not inputs, so it adds no parameter meaning beyond the schema. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('List which campaigns a brand list is attached to'), and it actively distinguishes itself from the sibling family by contrasting the attachment mechanism (CampaignCriterion of type BRAND_LIST vs CampaignSharedSet used by negative keyword lists). An agent can separate this from get_negative_keyword_list_campaigns and get_brand_lists without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage context is clear: it reveals the reverse-lookup purpose (list -> campaigns), and notes that omitting the list ID returns all brand-list attachments in the account. It does not name an explicit alternative or a when-not-to-use case, but the surrounding detail about attachment semantics gives the agent enough to place it correctly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_brand_listsList brand listsA
Read-only
Inspect

List all brand lists (SharedSets of type BRANDS) in the account.

Returns each list's ID, name, status, and member count, plus the total — the basis for reusing an existing list with add_to_brand_list instead of duplicating it with propose_brand_list.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds useful resource-type context ('SharedSets of type BRANDS') and the fact that it returns a total alongside per-list rows, but return-shape detail is largely redundant given an output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the reuse-vs-duplicate rationale are front-loaded in two tight sentences. The trailing Google Ads API documentation link is boilerplate that does not help tool selection, keeping this from a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering the safety profile and an output schema covering return values, the description supplies what is needed: scope, resource type, and the reuse workflow. It omits any note on result limits or pagination, which is a minor gap for a 'list all' tool on an account that may hold many shared sets.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single customer_id parameter is fully documented in the schema, including its default behavior. The description adds no syntax, format, or defaulting information beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all brand lists') and disambiguates the resource by naming its underlying type ('SharedSets of type BRANDS'), which no sibling tool does. It also names the sibling tools it relates to (add_to_brand_list, propose_brand_list), so an agent can distinguish it from get_brand_list_brands and get_brand_list_campaigns without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the tool as the lookup step before reusing a list with add_to_brand_list rather than duplicating it with propose_brand_list, which gives clear routing guidance to alternatives. It stops short of stating exclusions (e.g., use get_brand_list_brands when you need the members themselves), so it is clear context rather than full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_campaign_performanceCampaign performanceA
Read-only
Inspect

Get campaign-level performance metrics for a date range.

Returns campaign name, status, type, impressions, clicks, cost, conversions, CPA, ROAS, CTR for each campaign, plus Search impression share and the share lost to budget and to ad rank (fractions with matching *_pct percentages; null for campaigns that do not serve on Search or had no impressions). Insights flag converting campaigns that lose a significant share of impressions to budget.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
compactNoWhen true (for audits/overviews on large accounts), returns account totals, status/type breakdowns, the top-10 spenders, zero-conversion offenders and budget-limited converters instead of every row (~90% smaller).
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description still adds real behavioral context: which fields are returned, that impression-share values are paired fractions with matching *_pct percentages, that they are null for non-Search or zero-impression campaigns, and that an insights flag calls out budget-limited converters.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, followed by return details and a reference link. The prose is dense but largely earns its place; the trailing API documentation URL is boilerplate but short.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, yet the description still enumerates them usefully along with the null and insights semantics. Combined with complete annotation and schema coverage, an agent has enough to invoke it correctly; only explicit sibling routing is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters including date defaults, the customer_id format, and the compact flag. The description adds no parameter syntax or constraints beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (get), resource (campaign-level performance metrics), and scope (for a date range). The campaign-level framing distinguishes it from siblings like get_ad_performance, get_keyword_performance, and get_pmax_performance without needing to open any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied by the tool name and the date-range scope; there is no explicit 'use this when' guidance and no routing to or away from the many sibling performance tools (get_ad_performance, get_pmax_performance, get_audience_performance). The compact parameter's purpose is explained in the schema rather than the description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_change_historyChange historyA
Read-only
Inspect

List recent account changes: who changed what, when, and through which tool.

Answers "what changed before the drop?". Returns each change newest first with its time, the user's email, the client it came through (Google Ads UI, API, Google Ads scripts, Editor, automated rules, auto-applied recommendations, ...), the changed resource type, the operation (CREATE, UPDATE, REMOVE), the changed field paths, and the campaign and ad group names. Also returns counts by resource type, client, user and day, plus insights on auto-applied recommendations and budget or bidding changes. Google Ads keeps change history for 30 days, so older start dates are moved to the earliest available day.

Reads the change_event resource: https://developers.google.com/google-ads/api/docs/change-event

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of changes returned, newest first (1 to 10000; default 1000). The response is marked truncated when the limit is reached.
campaign_idNoOptional numeric campaign ID; only changes attributed to that campaign are returned.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive). Empty means today.
resource_typesNoOptional filter of ChangeEventResourceType names, e.g. ["CAMPAIGN", "CAMPAIGN_BUDGET", "AD_GROUP_AD", "AD_GROUP_CRITERION"]. Empty = all types.
date_range_startNoStart date as "YYYY-MM-DD", at most 30 days back. Empty starts at the oldest day Google Ads still keeps.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/openWorld/non-destructive, and the description adds real behavioral context beyond them: the 30-day retention window, the clamping of older start dates to the earliest available day, and the shape of aggregated output (counts by resource type/client/user/day, auto-applied recommendation insights). These are constraints an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and scope are front-loaded in the first sentence, followed by return-shape detail and the retention caveat. The enumeration of clients and the resource URL add some length, but each segment carries useful selection or interpretation value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only audit tool with an output schema present, the description covers what is returned, the retention bound, the aggregation summary, and the underlying resource. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description explains the date_range_start behavior that the schema alone doesn't (older start dates are moved to the earliest available day), which is the one non-obvious parameter interaction. Other parameters are left to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb + resource ('List recent account changes: who changed what, when, and through which tool') and grounds it in a concrete API resource (change_event), which clearly separates it from the performance/reporting siblings like get_campaign_performance or run_gaql.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear use context ('what changed before the drop?') that signals the diagnostic/audit scenario, which no sibling covers. It does not explicitly name an alternative tool or state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_custom_conversion_goalsCustom conversion goalsA
Read-only
Inspect

Read the custom conversion goals and the campaign goal configuration.

Returns every custom goal with its name, status and conversion actions, plus — optionally for one campaign — the goal config the campaign uses (goal_config_level CUSTOMER or CAMPAIGN and the assigned custom goal).

A custom conversion goal bundles conversion actions into a named set that a campaign can be pointed at. Ahead of drafting, this shows which goals exist, which actions they contain and what a campaign currently uses.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoNumeric campaign ID. When omitted, the campaign config is skipped.
customer_idNoAds account ID. Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so the safety profile is covered. The description adds value beyond that by disclosing the conditional behavior (campaign config only returned when campaign_id is supplied) and by explaining the domain concept of a custom conversion goal. No auth or rate-limit context, so not a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return contents, followed by a useful definition of the resource. Slightly verbose in the third paragraph (the 'bundles conversion actions into a named set' explanation is context, not operation), but every sentence carries information and nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be described, yet the description gives an accurate summary of the payload. For a two-optional-parameter read tool with full annotations, the definition covers purpose, usage context and conditional behavior adequately; only explicit sibling routing is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters are already documented (campaign_id optional, customer_id defaults to configured account). The description reinforces the optional campaign behavior and names goal_config_level enum values, but adds little syntax beyond the schema. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: 'Read the custom conversion goals and the campaign goal configuration.' It enumerates exactly what is returned (name, status, conversion actions, plus optional goal config levels). An agent can distinguish this read tool from the many draft_*custom_conversion_goal* siblings without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear usage context: 'Ahead of drafting, this shows which goals exist, which actions they contain and what a campaign currently uses,' which positions it as a pre-flight read before the draft_* tools. However, it does not explicitly name alternatives or state when-not to use it, so it falls short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_demographic_targetingDemographic targetingA
Read-only
Inspect

List demographic targeting criteria (age, gender, parental status, income).

Takes exactly one of ad_group_id or campaign_id. Returns each criterion's value, whether it's negative (excluded) or positive (narrowing), status, and a remove_id (composite resource ID) that can be passed directly to remove_entity with entity_type='ad_group_criterion' or 'campaign_criterion'.

By default, Google Ads serves ads to ALL demographic segments — a criterion only appears here once a segment has been actively excluded or narrowed.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_group_idNoNumeric ad group ID. Mutually exclusive with campaign_id.
campaign_idNoNumeric campaign ID. Mutually exclusive with ad_group_id.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/safe/open-world, but the description adds genuinely new behavior: the default 'serves ads to ALL demographic segments' model and the fact that a criterion only materializes after exclusion or narrowing. It also describes return content (value, negative vs positive, status, remove_id) and the composite-ID handoff to remove_entity, none of which annotations convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then parameter constraint, then return contract, then the important default-behavior caveat. Slightly redundant in re-explaining mutual exclusivity already in the schema, but every sentence carries useful weight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still correctly summarizes the salient return fields and the cross-tool remove_id workflow. Combined with full schema coverage and annotations, an agent has everything needed to call and act on results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so mutual exclusivity and IDs are already documented. The description restates the one-of constraint and adds the Google Ads default-behavior nuance, but adds no format details beyond the schema, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb (List) plus the exact resource and its enumerated segments (age, gender, parental status, income). An agent can immediately distinguish this read tool from sibling draft_demographic_targeting without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

States the 'exactly one of ad_group_id or campaign_id' selection rule and explains that a criterion only appears once it has been actively excluded or narrowed, which sets expectations for when the tool returns meaningful data. It also routes the agent onward (remove_id → remove_entity). It stops short of naming alternatives like draft_demographic_targeting explicitly.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_detailed_asset_performancePerformance Max asset combinationsB
Read-only
Inspect

Get top-performing asset combinations for Performance Max campaigns.

Shows which headline + description + image combinations Google selects most often. Returns each combination with the assets used and their field types. This data helps identify which creative elements work well together.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoOptional numeric ID to filter to a single PMax campaign.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered and the description only needs to add context. It does add useful framing about what is returned ('each combination with the assets used and their field types'), but discloses nothing about pagination, ranking cutoffs, or any scope limits on 'top-performing'.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and kept to four tight sentences. The trailing Google Ads API documentation link adds little selection value, but otherwise there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations carrying the safety profile, the description only needs to orient the agent, which it does. The remaining gap is routing guidance against the other PMax read tools, which no structured field supplies.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are fully documented, so the baseline is 3. The description adds no parameter-level meaning such as date-range scoping for the performance data, which a 'top-performing' tool would plausibly need.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get top-performing asset combinations for Performance Max campaigns') and clarifies the granularity is combinations, not raw assets. This naturally separates it from siblings like get_pmax_assets and get_pmax_performance, but it never names those alternatives, so the differentiation is inferential rather than explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what the data is good for ('helps identify which creative elements work well together') but gives no when-to-use guidance and no comparison to the closely related get_pmax_assets, get_pmax_performance, or get_asset_group_signals siblings. An agent must guess which of the four to call.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gtm_tagTag Manager tag detailsA
Read-only
Inspect

Get the full RAW configuration for a single GTM tag.

Includes every parameter, firing/blocking triggers (with their filter conditions resolved to text), priority, pause status, sampling, and monitoring metadata. Suited to inspecting a tag flagged by audit_event_coverage. An unknown tag_id returns an error with the available tag IDs. Reads the live container, or a workspace's unpublished state when workspace_id is set.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
tag_idYesNumeric GTM tag ID, as listed by list_gtm_tags.
workspace_idNoWorkspace to read (see list_gtm_workspaces), which includes drafted changes that are not published yet. Empty reads the live (published) container version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnly/openWorld/non-destructive. The description adds real context beyond them: the error behavior for an unknown tag_id (returns available tag IDs) and the live-container vs. workspace-unpublished read routing when workspace_id is set. It does not mention rate limits or auth scopes, keeping it at a solid 4 rather than 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, with payload contents, use-case, error behavior, and workspace routing following in a tight block. Every sentence carries information; the API doc link is the only mildly extraneous element.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need no explanation, and the description still covers scope, contents, error handling, and workspace vs. live reads. Nothing an agent needs to invoke the tool correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all four parameters. The description restates the workspace_id behavior (live vs. draft state) but adds no syntax or format beyond what the schema provides, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Starts with a specific verb+resource+scope ('Get the full RAW configuration for a single GTM tag') and then enumerates the exact payload contents. An agent can distinguish it from list_gtm_tags (list vs. single-get) and get_gtm_trigger (different resource) without opening the schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Suited to inspecting a tag flagged by audit_event_coverage' supplies a concrete when-to-use workflow, and the schema cross-references list_gtm_tags for discovery. It stops short of naming an explicit alternative or when-not-to-use condition, so it is clear context but not fully prescriptive routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gtm_triggerTag Manager trigger detailsA
Read-only
Inspect

Get the full RAW configuration for a single GTM trigger.

Includes filters, auto-event filters, custom-event filters, validation settings, and a list of every tag that uses this trigger. Helps diagnose why a tag with a specific trigger ID does or doesn't fire. An unknown trigger_id returns an error with the available trigger IDs. Reads the live container, or a workspace's unpublished state when workspace_id is set.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
trigger_idYesNumeric GTM trigger ID, as listed by list_gtm_triggers or a tag's firing/blocking triggers.
workspace_idNoWorkspace to read (see list_gtm_workspaces), which includes drafted changes that are not published yet. Empty reads the live (published) container version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered; the description adds real value beyond that by disclosing the error behavior for an unknown trigger_id and the live-vs-workspace read semantics. It does not cover auth requirements or rate limits, which are the only notable gaps.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then layered with payload contents, diagnostic purpose, and error behavior in short sentences. The enumerated field list is slightly long but each item earns its place by telling the agent what will come back.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be explained, and the description still covers the key operational facts: read scope, error on bad ID, and what the config includes. Nothing critical is missing for a single-resource read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and every parameter is already documented in-schema, so the baseline is 3. The description's note about workspace_id reading unpublished state largely restates the schema text rather than adding new syntax or format guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Get the full RAW configuration for a single GTM trigger') and enumerates the payload contents (filters, auto-event filters, custom-event filters, validation settings, referencing tags). It is clearly distinguishable from siblings like list_gtm_triggers, get_gtm_tag, and get_gtm_workspace_diff.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case ('Helps diagnose why a tag with a specific trigger ID does or doesn't fire') and clarifies the read scope (live container vs. unpublished workspace state). It does not explicitly name alternatives such as get_gtm_tag or list_gtm_triggers, nor state when not to use it, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gtm_versionTag Manager version detailsA
Read-only
Inspect

Get metadata + entity counts for a single GTM container version.

Returns name, description (the version notes), fingerprint, and lists of tag/trigger/variable names at that point in time. The API returns no timestamps or author for a version.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.
container_version_idYesNumeric container version ID from list_gtm_versions.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true/openWorldHint=true, and the description goes beyond them with a genuinely useful disclosure: the API returns no timestamps or author for a version, which stops an agent from requesting fields that do not exist. It also enumerates the returned entity kinds, though it says nothing about permissions or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then the return content, then the limitation note; each sentence carries information. The trailing API documentation URL is slightly expendable but harmless.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description does not need to enumerate return values, yet it summarizes them helpfully and flags the version's data limitations. Nothing critical for a correct one-shot call appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters (account ID, container ID, container version ID) are already documented with fallback behavior and cross-references. The description adds no additional parameter meaning, which is the expected baseline when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Get metadata + entity counts for a single GTM container version') and lists concrete returned fields, so the tool's purpose is unambiguous. It does not, however, explicitly distinguish itself from close siblings such as list_gtm_versions or get_gtm_version_diff beyond the word 'single'.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: 'single GTM container version' hints this is the detail lookup versus the list tool, but there is no explicit when-to-use, when-not-to-use, or pointer to get_gtm_version_diff for comparisons. An agent must infer the selection rule from sibling names.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gtm_version_diffTag Manager version diffA
Read-only
Inspect

Compare two GTM container versions: what a publish changed.

Returns added, removed and changed tags, triggers and variables (with names, types and the changed fields; parameters and trigger conditions are diffed key by key), plus built-in variables enabled or disabled. By default compares the live version with the version created before it. The Tag Manager API does not mark which versions were published, so that default "before" version may never have been live. Makes two or three Tag Manager API calls.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
to_version_idNoNewer version ID. Empty uses the live (published) version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
from_version_idNoOlder version ID (see list_gtm_versions). Empty uses the newest non-archived version created before to_version_id.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/openWorld/non-destructive, and the description adds genuinely new behavior: it enumerates what the diff covers (tags/triggers/variables key-by-key, plus built-in variables), discloses the API cost ('two or three Tag Manager API calls'), and flags the reliability caveat that GTM does not mark which versions were published.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the single-sentence purpose, then layered detail on the diff contents, defaults, and caveats. Every sentence carries distinct information; nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value detail is optional, yet the description still covers diff scope, defaults, caveats, and API-call cost. An agent has everything needed to select and invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the baseline is 3, but the description reinforces and explains the defaults ('compares the live version with the version created before it') and ties the caveat to why from_version_id may need to be set explicitly, adding meaning beyond the raw schema defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Compare two GTM container versions') plus the scope ('what a publish changed'), which is far more precise than a bare name restatement. The version-scoped framing naturally separates it from the workspace-level sibling get_gtm_workspace_diff.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context for use (post-publish change inspection), explains the default comparison behavior, and warns that the default 'before' version may never have been live. It stops short of naming the alternative tool for workspace diffs, so the agent must infer that routing.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_gtm_workspace_diffTag Manager workspace changesA
Read-only
Inspect

Show drafted-but-not-published changes in a GTM workspace.

Returns the list of entities (tags, triggers, variables) added, modified, or deleted relative to the live published version, plus any merge conflicts. Common cause of "I edited a tag but nothing happened" — the workspace was never published. is_clean=true means no pending changes and no conflicts.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
workspace_idYesNumeric GTM workspace ID from list_gtm_workspaces.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds real beyond-annotation context: the return set (added/modified/deleted tags, triggers, variables), merge conflicts, and the meaning of is_clean=true.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, then useful return-shape and diagnostic context, ending with the API reference. The 'Common cause of...' sentence earns its place by clarifying usage, though the definition runs slightly long.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values are largely documented structurally, yet the description still summarizes the key fields and is_clean semantics. Combined with annotations covering safety, the definition is essentially complete for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so workspace_id, gtm_account_id, and gtm_container_id are already documented with defaults and cross-references. The description adds no parameter-level detail, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear specific verb+resource: 'Show drafted-but-not-published changes in a GTM workspace,' with scope pinned to 'relative to the live published version.' An agent can tell it is a workspace-diff reader. It does not name its closest sibling (get_gtm_version_diff), so it stops short of full differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides a concrete diagnostic scenario ('I edited a tag but nothing happened') that cues when to reach for this tool. It gives clear context but no explicit exclusions or named alternatives against get_gtm_version_diff.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_keyword_performanceKeyword performanceB
Read-only
Inspect

Get keyword metrics including quality scores and competitive data.

Returns keyword text, match type, quality score, impressions, clicks, CTR, CPC, conversions for each keyword.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
compactNoWhen true (for audits/overviews), returns totals, match-type distribution, the top-10 spenders, low-quality-score keywords, and zero-conversion spenders instead of every row (~90% smaller).
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the content scope (quality scores and competitive data) but says nothing about pagination, rate limits, or auth requirements beyond the doc link, so it adds only modest context on top of the structured data.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose in the opening clause, followed by a compact return-value list and a doc link. Every sentence is short and earns its place, though the field enumeration is partly redundant given an output schema exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the return-value listing is not strictly necessary, and annotations cover safety; full schema coverage handles the parameters. The only real gap is the absence of sibling differentiation, which the description does not address.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (compact, customer_id, date_range_start/end) are fully documented in the schema, including the compact-mode behavior and the 30-day default. The description adds no parameter detail; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ("Get keyword metrics including quality scores and competitive data") and enumerates the returned fields (keyword text, match type, quality score, impressions, clicks, CTR, CPC, conversions). It is clearly keyword-level reporting, though it never explicitly contrasts itself with siblings like get_search_terms or get_campaign_performance, so the distinction is inferred rather than stated.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No when-to-use statement, no prerequisites, and no routing to or from alternatives such as get_search_terms, get_campaign_performance, or get_ad_performance. Usage is only implied by the topic, leaving the agent to guess which performance tool to pick.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merchant_feed_healthMerchant Center feed healthA
Read-only
Inspect

Merchant Center feed health — disapproved products + account issues.

Disapproved feed items silently starve Shopping and Performance Max campaigns; this reports approved/pending/disapproved counts per reporting context (Shopping ads, free listings, ...), the top product issues by affected products (with documentation links), and account-level issues — CRITICAL ones stop offers serving entirely. Product-status data lags reality by ~30 minutes.

Merchant API: https://developers.google.com/merchant/api/overview

ParametersJSON Schema
NameRequiredDescriptionDefault
account_idNoNumeric Merchant Center ID from list_merchant_accounts. Defaults to merchant.account_id in the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, and the description is consistent with them ('this reports...'). Beyond that it adds genuinely useful behavior: product-status data lags reality by ~30 minutes and CRITICAL account issues halt offer serving entirely — freshness and severity semantics an agent cannot get from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then impact, then report contents, then latency caveat — a logical order with no filler sentences. The dense em-dash style makes it slightly heavy for its length, but each clause carries real information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't enumerate return fields, yet it still previews the payload shape and severity semantics. Combined with a single optional parameter, rich annotations, and the API reference link, an agent has everything needed to call and interpret this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

One optional parameter at 100% schema description coverage; the schema already documents that account_id comes from list_merchant_accounts and defaults to merchant.account_id in config. The description adds nothing about the parameter, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('reports' Merchant Center feed health) and enumerates exactly what is returned: approved/pending/disapproved counts per reporting context, top product issues with doc links, and account-level issues. This is clearly distinguishable from sibling list_merchant_accounts (which yields IDs) and from generic reporting tools like run_gaql.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives strong context for when this matters ('disapproved feed items silently starve Shopping and Performance Max campaigns' and 'CRITICAL ones stop offers serving entirely'), which frames it as a diagnostic tool. It does not, however, name an alternative sibling or state explicit exclusions, so the routing guidance stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_merchant_product_issuesMerchant Center product issuesA
Read-only
Inspect

The products behind the feed-health counts, each with its issues.

Lists products by status with offer id, title, brand, click potential and every item issue: its code, the attribute it concerns, severity per reporting context with the affected countries, and whether the merchant has to act or Google is still processing. Products with high click potential come first, because fixing them recovers the most traffic. issues_by_code counts the products per issue. Data lags feed changes by about 30 minutes.

Merchant API: https://developers.google.com/merchant/api/overview

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of products to return (1-200, default 50).
statusNo"disapproved" (default, not serving), "limited" (serving with restrictions), "pending" (still in review) or "any" (every product with at least one issue).disapproved
account_idNoNumeric Merchant Center ID from list_merchant_accounts. Defaults to merchant.account_id in the config.
issue_codeNoOnly products with this issue code (from issues_by_code or get_merchant_feed_health).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations establish the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), so the description needn't cover that. It adds genuinely useful undisclosed traits: the result ordering by click potential, the ~30-minute data lag behind feed changes, and the per-issue severity/actionability detail. Missing pagination/cursor behavior keeps it from 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and structure, then elaborates. Densely informative but each clause (sorting rationale, issues_by_code, data lag) earns its place; the trailing Merchant API link is marginally useful. Slightly long but not padded.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values needn't be spelled out, and the description still usefully signals sorting, latency and issue fields. For a 4-param read tool with full schema coverage and annotations, it is essentially complete; only pagination behavior is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so baseline is 3. The description reinforces semantics (statuses, issue codes sourced from issues_by_code) but adds no syntax or format detail beyond what the schema already documents.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (lists) and resource (products with issues), and explicitly positions itself relative to the sibling get_merchant_feed_health by describing it as 'the products behind the feed-health counts'. An agent can distinguish this drill-down tool from the summary tool without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides strong context: it lists by status, points to issues_by_code and get_merchant_feed_health as sources for the issue_code filter, and explains the prioritization (high click potential first, because fixing them recovers traffic). It stops short of explicit when-not-to-use guidance or naming a contrasting sibling directly, so not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_negative_keyword_list_campaignsCampaigns using a negative keyword listB
Read-only
Inspect

List which campaigns a shared negative keyword list is attached to.

Returns each list-to-campaign attachment with the list and campaign IDs and names.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
shared_set_idNoNumeric ID from get_negative_keyword_lists. When omitted, returns all list-to-campaign attachments across the account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description adds that the result is raw list-to-campaign attachment records (IDs and names) rather than campaign objects, which is modestly useful context beyond the annotations and the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded first sentence answers the core question, followed by a brief return-value note; nothing redundant. The trailing Google Ads API documentation link is largely filler for an agent that already has the schema and output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only lookup with both parameters optional, an output schema, and no nested objects, the description covers purpose and returned fields adequately. Minor omissions (pagination behavior, or that an empty result is expected when the list is unattached) do not impede correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (customer_id default behavior, shared_set_id source and omit-meaning) are already fully documented in the schema. The description adds no parameter syntax or format details, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (list) and a precise resource (which campaigns a shared negative keyword list is attached to), which is naturally distinguishable from get_negative_keyword_lists and get_negative_keyword_list_keywords. It never names those siblings explicitly, so an agent gets no direct differentiation beyond the topic wording.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no when-to-use guidance, no prerequisite (e.g. needing a shared_set_id from get_negative_keyword_lists), and no alternatives. The only usage hint - that omitting shared_set_id returns everything - lives in the input schema, not here.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_negative_keyword_list_keywordsKeywords in a negative keyword listB
Read-only
Inspect

List the keywords inside a shared negative keyword list.

Returns each negative keyword's text, match type, and a resource_id ("sharedSetId~criterionId"), with the total keyword count.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
shared_set_idYesNumeric ID from get_negative_keyword_lists (shared_set.id).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds the returned fields and the resource_id format, which is mild extra context, but it omits pagination behavior and any rate-limit or auth caveats. With annotations carrying the safety profile, a 3 is appropriate.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the action and resource, then return shape. The trailing Google Ads API link is minor filler but not disruptive.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not explain return values, and annotations cover safety; parameters are fully documented in the schema. The only real gap is the absence of usage/routing guidance, which is not strictly required to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both parameters (customer_id and shared_set_id) are already documented in the schema, including the pointer to get_negative_keyword_lists for the ID. The description adds no parameter detail beyond that, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("List the keywords inside a shared negative keyword list") and specifies scope precisely. It is distinguishable from get_negative_keyword_lists and get_negative_keyword_list_campaigns by the "keywords inside" phrasing, though it never names those siblings explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description says what the tool does but never says when to use it versus get_negative_keyword_lists or get_negative_keyword_list_campaigns, nor does it state prerequisites (e.g., that a valid shared_set_id must first come from get_negative_keyword_lists). No when/when-not guidance is present.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_negative_keyword_listsList shared negative keyword listsA
Read-only
Inspect

List all shared negative keyword lists (SharedSets) in the account.

Returns each list's ID, name, status, and keyword count. Useful before propose_negative_keyword_list: a suitable list may already exist and just need attaching to a campaign.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is covered. The description adds the shape of the response (ID, name, status, keyword count), but with an output schema present this is largely redundant and no additional behavioral traits (pagination, rate limits, auth) are disclosed.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, followed by return contents and then usage context. Three short sentences that each carry information; the API documentation link is mildly extraneous but not harmful.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With rich annotations, full schema coverage, and an output schema, the description supplies enough for an agent to select and invoke the tool correctly, plus useful routing context toward propose_negative_keyword_list. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single customer_id parameter is fully documented in the schema, including the default fallback to ads.customer_id. The description adds no parameter-level meaning, which is the expected baseline when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all shared negative keyword lists (SharedSets) in the account') with clear scope. It also names the returned fields, which reinforces what the tool produces. It does not explicitly distinguish itself from siblings like get_negative_keyword_list_keywords or get_negative_keyword_list_campaigns, though the scope makes the distinction inferable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use scenario ('Useful before propose_negative_keyword_list: a suitable list may already exist and just need attaching to a campaign') and names the alternative. There are no when-not-to-use exclusions, but the guidance is concrete and actionable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_negative_keywordsList negative keywordsA
Read-only
Inspect

List existing negative keywords for a campaign or all campaigns.

Shows the existing negatives, which reveals duplicates before new negative keywords are added. Returns each negative's campaign, keyword text, match type, and a resource_id ("campaignId~criterionId") as taken by remove_entity, plus the total count.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoNumeric campaign ID to filter by. If empty, returns negatives across all campaigns.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered and the description is not burdened with it. What the description adds beyond structured data is the cross-tool contract: the returned resource_id format ('campaignId~criterionId') is explicitly the value accepted by remove_entity, which is genuinely useful linking behavior not encoded in the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then return shape, then a reference link; no sentence is redundant. The trailing Google Ads API URL is marginal filler but short enough not to dilute the structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be enumerated in prose (though the description helpfully does), and both parameters are fully described in the schema. The only meaningful gap is explicit disambiguation from the negative-keyword-list tools that share the same domain vocabulary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% for both optional parameters (campaign_id, customer_id), so the schema fully documents filtering and defaulting behavior. The description adds nothing about parameter syntax or empty-value semantics beyond what the schema states, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List existing negative keywords') plus scope ('for a campaign or all campaigns'), so an agent knows what it returns. It does not, however, distinguish itself from the nearby negative-keyword-list siblings (get_negative_keyword_list_keywords, get_negative_keyword_list_campaigns), which address a different resource (shared sets) and could plausibly be confused with this one.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The line 'reveals duplicates before new negative keywords are added' implies the check-before-write workflow with add_negative_keywords, which is real but indirect guidance. There is no explicit when-to-use/when-not and no sibling is named as an alternative, leaving the choice to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pmax_assetsPerformance Max assetsA
Read-only
Inspect

List the assets of Performance Max campaigns with type, status and content.

Returns each asset's field_type (HEADLINE, DESCRIPTION, MARKETING_IMAGE, YOUTUBE_VIDEO, etc.), primary_status (ELIGIBLE, NOT_ELIGIBLE, PAUSED, PENDING), and content (text or image URL), plus by_status and by_field_type summaries.

Per-asset performance labels (BEST/GOOD/LOW) are not available for PMax assets in the Google Ads API. get_detailed_asset_performance reports which asset combinations Google selects most — the closest proxy for individual asset quality.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoOptional numeric ID to filter to a single PMax campaign.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so the safety profile is covered. The description adds genuine behavioral value beyond that by listing the concrete status enums returned and by disclosing a real limitation of the Google Ads API (no BEST/GOOD/LOW labels for PMax assets), which prevents a wrong tool choice.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The definition is front-loaded: the core action and returned fields lead, followed by the limitation and alternative. It is slightly long due to the enum recitations and a bare documentation URL, but every section carries useful information for tool selection.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the return format need not be spelled out, and the annotations cover the safety profile, so the description only needs to establish scope and boundaries. It does that well, including the closest-proxy alternative for asset quality; a note on result limits or pagination would make it fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% with only two optional parameters, so the schema fully documents campaign_id and customer_id. The description adds no syntax, format, or default-behavior detail beyond what the schema already states, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and resource ('List the assets of Performance Max campaigns') and immediately enumerates the returned fields (type, status, content). It is clearly distinguishable from adjacent PMax tools such as get_pmax_performance or get_detailed_asset_performance, which the description explicitly frames as a different concern.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent that per-asset performance labels are unavailable and routes it to get_detailed_asset_performance as the substitute, which is an explicit alternative with a condition. It does not, however, state an explicit 'use this tool when you need X' trigger, so the primary usage is only implied by the resource name.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_pmax_performancePerformance Max performanceA
Read-only
Inspect

Get Performance Max campaign and asset group performance.

Returns two result sets. campaigns: PMax campaign metrics broken down by ad_network_type (SEARCH, CONTENT, YOUTUBE_SEARCH, YOUTUBE_WATCH, MIXED). MIXED is a catch-all that Google uses for most PMax traffic — full channel splits are not available via the API. asset_groups: per-asset-group metrics including ad_strength (EXCELLENT, GOOD, AVERAGE, POOR).

Includes insights flagging weak ad strength, zero-conversion asset groups, and network type distribution.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnlyHint, destructiveHint=false), so the bar is lower, and the description still adds real value: it discloses the two result sets, the API limitation that full channel splits are unavailable (MIXED catch-all), and the insight flags it emits. It does not mention pagination or result caps, which is the only gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the one-line purpose, then the two result sets, then the caveat, then insights — a clean information hierarchy. The trailing Google Ads API doc link is marginally useful but not load-bearing, keeping it just short of a 5.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description explains the shape of both result sets and the MIXED caveat an agent would otherwise misread. For a read-only reporting tool this is complete and self-sufficient.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents customer_id, date_range_start, and date_range_end including defaults and the last-30-days fallback. The description adds nothing further about parameters, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('Get') plus a tightly scoped resource ('Performance Max campaign and asset group performance'), which separates it from the general get_campaign_performance and from the sibling get_pmax_assets that returns assets rather than metrics. The return-structure sentence makes the scope unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when it is useful (you want PMax metrics with a network-type split and asset-group ad strength), but never names an alternative or states when not to use it versus get_campaign_performance, get_pmax_assets, or run_gaql. Usage is inferable rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_recommendationsGoogle Ads recommendationsA
Read-only
Inspect

Retrieve Google's auto-generated recommendations with estimated impact.

Returns each recommendation's type, associated campaign/ad group, current (base) and projected (potential) metrics, and the estimated improvement. Includes insights that flag budget-increase recommendations (their projected gain comes from spending more) and highlight high-impact suggestions.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoOptional numeric campaign ID to scope to a single campaign.
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
recommendation_typesNoOptional filter of Google Ads RecommendationType names, e.g. ["KEYWORD", "TARGET_CPA_OPT_IN", "MAXIMIZE_CONVERSIONS_OPT_IN", "RESPONSIVE_SEARCH_AD"]. Empty = all types.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds genuine behavioral context beyond them: the caveat that budget-increase recommendations derive their projected gain from additional spend, and that high-impact suggestions are flagged, which helps an agent interpret results correctly.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core operation, then a compact enumeration of returned fields. It spends several sentences on return-value detail that an existing output schema already conveys, which is mild redundancy, but the prose is tight and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full output schema and rich annotations, the description is complete enough for correct invocation: it names the resource, the optional scoping filters, and the interpretation caveat. The only gap is the absence of routing guidance against sibling reporting tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and all three parameters (campaign_id, customer_id, recommendation_types) are well documented inline, so the schema carries the load. The description adds no syntax, default, or filtering semantics beyond what the schema states; baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Retrieve Google's auto-generated recommendations with estimated impact'), making the operation clear. However, it never differentiates itself from reporting-oriented siblings such as get_campaign_performance or get_ad_performance, which an agent might reasonably consider an alternative.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description offers no explicit when-to-use guidance and no exclusions relative to the many sibling tools. Nothing tells the agent whether this is preferred over run_gaql or the performance getters when seeking optimization ideas.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_account_historyReddit account change historyA
Read-only
Inspect

Who changed what in the Reddit ad account: field, before/after, member, time.

Returns the changes, most recent first, with changed_at, by, entity type, id and name, field, and before/after values. The first thing to check when performance moves. Child entities are included when filtering by entity. Changes made through AdLoop show under the connected Reddit user, like changes made in Ads Manager. Money fields are in account currency.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of changes returned, clamped to 1-500.
entity_idsNoIds of the entities of entity_type to filter to; required when entity_type is set.
entity_typeNoOptional filter to one entity type: "campaign", "ad_group" or "ad". Requires entity_ids.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
date_range_endNoLast day (inclusive), YYYY-MM-DD (account-local day). Empty means today.
date_range_startNoFirst day, YYYY-MM-DD (account-local day). Empty means 29 days before date_range_end (default window is the last 30 days).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe-read profile (readOnlyHint, destructiveHint=false), so the bar is lower. The description adds real behavioral context beyond that: results are most-recent-first, child entities are included when filtering by entity, AdLoop-made changes are attributed to the connected Reddit user, and money fields are in account currency.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose in the first sentence, and the API link is a useful pointer. There is minor redundancy: the opening phrase lists "field, before/after, member, time" and the next sentence re-lists those same fields, which is wasted text given an output schema already exists.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be re-explained, and the description still covers filtering behavior, currency, attribution quirks, and default windows. Nothing essential for correct invocation is missing, though it never explicitly routes to a sibling history tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description still adds meaning on top of the schema, notably that child entities are pulled in when filtering by entity and that monetary values follow account currency, which shapes how entity_type/entity_ids results should be read.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Who changed what in the Reddit ad account: field, before/after, member, time") and enumerates the returned fields. The "Reddit ad account" scoping clearly distinguishes it from the sibling get_change_history, which covers a different platform.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"The first thing to check when performance moves" gives a clear triggering context for reaching for this tool. It stops short of naming an alternative or stating exclusions, so it is a solid context statement rather than full when/when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_ad_groupsReddit ad groupsA
Read-only
Inspect

List Reddit ad groups (budget, bid, pixel, weekly schedule, targeting summary), optionally per campaign.

Returns the account currency, the ad groups, and insights. Reddit requires conversion_pixel_id on every ad group; insights flag ad groups without one and name ad groups that run on a weekly schedule.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
campaign_idNoReddit campaign id (from get_reddit_campaigns) to limit the list to; empty lists every ad group of the account.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/openWorldHint, so safety is covered. The description adds genuine domain behavior beyond that: Reddit requires conversion_pixel_id on every ad group, and the insights output flags ad groups lacking one and identifies weekly-schedule ad groups. That is real operational context an agent could not derive from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and field list, then behavior, then a doc link. Slight redundancy: the first sentence already mentions pixel and weekly schedule, which the third sentence re-explains, costing a little space.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description still summarizes them (currency, ad groups, insights). Combined with the conversion_pixel_id requirement and insights behavior, an agent has enough to call this correctly; only explicit sibling routing is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so both parameters are fully documented with defaults and sourcing (campaign id, ad account id). The description only echoes the per-campaign filtering idea and adds no syntax or format detail beyond the schema, matching the baseline for a fully documented schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List Reddit ad groups') and enumerates the returned fields (budget, bid, pixel, weekly schedule, targeting summary). The 'optionally per campaign' clause implicitly separates it from get_reddit_campaigns, but no sibling is named explicitly, so differentiation is only partial.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies the common usage ('optionally per campaign') but never states when to use this tool versus get_reddit_campaigns, get_reddit_ads, or update_reddit_ad_group. The parameter descriptions carry the origin hints (from get_reddit_campaigns, from list_reddit_accounts), but that is schema-level, not description-level guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_adsReddit adsB
Read-only
Inspect

List Reddit ads with status, rejection_reason, post and click URL.

Returns the ads and insights: insights flag REJECTED ads (policy review) and ads still PENDING_APPROVAL.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_group_idNoReddit ad group id (from get_reddit_ad_groups) to limit the list to; empty means no ad group filter.
campaign_idNoReddit campaign id (from get_reddit_campaigns) to limit the list to; empty means no campaign filter.
include_copyNoWhen true, adds each ad's post: type (TEXT, IMAGE, VIDEO, CAROUSEL), headline, body, destination and media, one request per distinct post (at most 50 posts per call), so creative can be reviewed without opening Reddit.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the safe read-only profile (readOnlyHint=true, destructiveHint=false), so the description is not carrying the safety burden. It does add useful semantics about the insights flag surfacing REJECTED and PENDING_APPROVAL ads, but stops short of explaining pagination, request cost, or filtering behavior beyond that.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with verb and resource, then the return semantics, in three short lines. The trailing Reddit Ads API URL is minor filler but low cost.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and annotations cover safety. The description completes the picture by clarifying what the list and insights convey. Only the lack of routing guidance against sibling tools keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, with each of the four parameters documented inline (including the per-post request cost of include_copy). The description adds no parameter detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('Reddit ads') plus the salient return fields (status, rejection_reason, post and click URL). It is clearly a read/list tool, but it does not explicitly differentiate itself from sibling readers such as get_reddit_performance or run_reddit_report.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use or when-not guidance, and no alternative sibling is named. The presence of a campaign_id/ad_group_id filter hints at scoped listing, but the agent must infer when this tool beats get_reddit_performance or run_reddit_report.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_audiencesReddit audiencesA
Read-only
Inspect

Reddit custom and saved audiences of the account, and which ad groups use them.

Returns each custom audience's audience_id, name, type (PIXEL_RETARGETING, ENGAGEMENT_RETARGETING, CUSTOMER_LIST, LOOKALIKE, ...), status, estimated size_range, its source (pixel events or campaigns, lookback days) and the ad groups that target or exclude it; saved audiences with their targeting; and insights that flag audiences Reddit cannot use yet or that are too small to deliver. The audience_id goes into custom_audience_ids or excluded_custom_audience_ids on an ad group.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered. The description adds real behavioral context beyond that: it discloses the insight flags for audiences Reddit cannot use yet or that are too small to deliver, which tells the agent results can carry warning state, and it names the downstream field the audience_id is consumed by.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and dense with selection-relevant detail, but the middle paragraph enumerates return fields (audience_id, name, type, status, size_range, source) that largely duplicate the output schema. Slightly over-sized, though no sentence is pure filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only, single-optional-parameter listing tool with an output schema and read-only annotations, the description is more than sufficient: it names the account scope, the two audience classes covered, and the caveat insights. Nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The single ad_account_id parameter is already 100% documented in the schema, including its default and config fallback, so the description adds no parameter-level meaning. Baseline 3 applies when the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('Reddit custom and saved audiences of the account, and which ad groups use them') and pins down scope tightly enough to separate it from siblings like get_audience_lists, get_audience_targeting, and search_audience_segments. An agent knows exactly what object it is retrieving without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no explicit when-to-use / when-not-to-use statement and no sibling is named as an alternative. The one workflow hint – that the returned audience_id feeds custom_audience_ids or excluded_custom_audience_ids on an ad group – is genuinely useful routing information, but it is implied usage rather than a selection rule.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_campaignsReddit campaignsA
Read-only
Inspect

List Reddit campaigns with status, objective, budget mode and bids.

Returns the account currency, the campaigns, and insights for campaigns blocked by account state. Each campaign carries configured_status (what was set) and effective_status (what Reddit computes: PENDING_APPROVAL, REJECTED, PENDING_BILLING_INFO, ...). Money is in account currency. Budgets live on ad groups unless is_campaign_budget_optimization is true.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
include_archivedNoInclude ARCHIVED and DELETED campaigns, which are left out by default.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, so safety is covered; the description goes further and discloses non-obvious data semantics: configured_status vs effective_status, possible effective status values, that money is in account currency, and that budgets sit on ad groups unless is_campaign_budget_optimization is true. Pagination and rate-limit behavior are not mentioned, keeping it short of a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then layered detail about return contents and status semantics. Nearly every sentence earns its place; a dense run of caveats but no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, yet the description still usefully frames what comes back (currency, campaigns, blocked-campaign insights). Complete enough for a read tool, with only the usage routing left implicit.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both ad_account_id and include_archived are already documented in the schema. The description adds no syntax or behavioral detail about these parameters, which is the expected baseline when the schema carries the load.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('List Reddit campaigns') and enumerates the key fields returned (status, objective, budget mode, bids), which cleanly distinguishes it from siblings like get_reddit_ad_groups, get_reddit_ads, and get_reddit_performance.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description implies when the tool is useful (inspecting campaign configuration), but never states when to use it versus the adjacent Reddit read tools (get_reddit_performance, run_reddit_report) or when-not. Usage must be inferred from the resource it lists.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_performanceReddit performanceA
Read-only
Inspect

Reddit Ads performance: spend, impressions, clicks, CTR, CPC, conversions, CPA, ROAS.

Returns rows per entity for the chosen level with names joined, plus totals and insights[] (zero-conversion spenders, rejected ads, empty windows). 'conversions' is the account's key conversion event. Money is in account currency. Data lags up to 6 hours.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
levelNoRow granularity: "account", "campaign" (default), "ad_group" or "ad".campaign
compactNoWhen true, returns totals + top-10 rows by spend + offender lists instead of every row.
breakdownNoOptional extra dimension: "date", "hour", "country", "region", "community", "keyword", "interest", "placement", "gender" or "os_type". Empty means none.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
date_range_endNoLast day (inclusive), YYYY-MM-DD, in the account's time zone. Empty means today.
date_range_startNoFirst day, YYYY-MM-DD, in the account's time zone. Empty means 29 days before date_range_end (a 30-day window).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), so the description carries the remaining behavioral burden and does it well: it discloses result shape (rows per entity plus totals and insights[]), defines semantics of 'conversions' as the key conversion event, states money is in account currency, and warns of up to a 6-hour data lag. These freshness/currency/return-content details are exactly the value-add annotations cannot provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the metric list, then layers return shape, semantics, currency, and lag in short sentences before a reference URL. Mostly waste-free, though the trailing API URL is borderline padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values needn't be spelled out, yet the description still usefully sketches rows/totals/insights. Combined with full-schema param docs and annotations covering safety, an agent has enough to call it correctly; only the sibling-overlap routing is unaddressed.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already fully documents all six parameters including the level/compact/breakdown semantics and date defaults. The description only references 'the chosen level' generically and adds no syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (Reddit Ads performance) and enumerates the metrics returned (spend, impressions, clicks, CTR, CPC, conversions, CPA, ROAS), which is far better than a tautology. However, it never distinguishes itself from the closer sibling run_reddit_report, so the agent must infer the split.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the tool reads as the performance-reporting entry for Reddit Ads, but there is no explicit when-to-use, when-not-to-use, or alternative named despite run_reddit_report and get_ad_performance sitting alongside it. Context is sufficient to guess but not stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_reddit_pixelsReddit pixelsA
Read-only
Inspect

Reddit pixels of the account and when each event (purchase, sign_up, lead, ...) last fired.

Returns each pixel's pixel_id, name, last_fired_at per standard event, custom events and a never_fired flag, plus insights. Relevant before conversion-optimized campaigns: insights flag pixels that never fired and ad groups optimizing for an event their pixel has never sent. Every new ad group needs a conversion_pixel_id from here.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/openWorld/non-destructive, so the bar is lower, and the description still adds real behavioral context: it enumerates returned fields (pixel_id, name, last_fired_at per event, custom events, never_fired) and explains what the 'insights' actually flag (never-fired pixels, mismatched ad group optimization events).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what the tool returns, then the usage rationale, then the API reference. Efficient and well ordered, with only slight redundancy between the field list and the insights sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-format detail is not required, and the description already covers purpose, key fields, and the decision context for conversion-optimized campaigns. Adequate for a single-param read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Only one parameter with 100% schema description coverage, including the empty-string fallback to config, so the schema does the heavy lifting. The description adds no parameter-level info, which is the expected baseline when coverage is this high.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (get) and resource (Reddit pixels) and immediately scopes the payload: 'when each event (purchase, sign_up, lead, ...) last fired.' This clearly separates it from sibling Reddit tools like get_reddit_campaigns or get_reddit_audiences.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit usage context: 'Relevant before conversion-optimized campaigns' and 'Every new ad group needs a conversion_pixel_id from here.' That is a clear when-to-use signal, though it names no alternative tool or exclusion case.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_search_termsSearch terms reportA
Read-only
Inspect

Get search terms report — what users actually typed before clicking your ads.

Critical for finding negative keyword opportunities and understanding user intent. Returns search term, campaign, ad group, impressions, clicks, conversions.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
compactNoWhen true (for audits/overviews), returns totals, the top-10 terms by clicks, ready-made negative-keyword waste candidates (5+ clicks, zero conversions), and top converters (~90% smaller).
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so the safety profile is fully covered. The description adds the returned dimensions (search term, campaign, ad group, impressions, clicks, conversions), but since an output schema exists this is largely redundant; nothing is said about pagination, date defaults, or rate limits. Adequate but thin beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose is front-loaded in the first clause, and the intent/negative-keyword value proposition follows immediately. The trailing Google Ads API URL is marginal filler but does not dilute the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety and an output schema covering return fields, the description supplies the remaining conceptual context (what search terms are, why they matter). It is complete enough to call correctly, missing only explicit sibling routing and behavioral notes like date-default fallback.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, including detailed docs for compact, customer_id, and the date range params, so the schema carries the parameter burden. The description adds no parameter-level meaning beyond what is already documented, which is the expected baseline of 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a clear verb+resource ('Get search terms report') and immediately defines the resource in user terms ('what users actually typed before clicking your ads'), which distinguishes it from report tools like get_keyword_performance. It stops short of naming which sibling to use instead when the agent wants keyword-level rather than query-level data.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a use case ('Critical for finding negative keyword opportunities and understanding user intent') that implies when to reach for it, and the 'find negative keyword opportunities' framing loosely routes toward add_negative_keywords. However, there is no explicit when-not guidance or named alternative, so usage is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_shopping_product_performanceShopping product performanceA
Read-only
Inspect

Spend, clicks, conversions, CPA and ROAS per product across Shopping and Performance Max.

Each product (item id) is summed over the campaigns it ran in. Returns the account totals, the top products by spend, and the products that spent without a conversion, with insights on what to do with them.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of products to return (1-200, default 50).
campaign_idNoOptional numeric campaign id to limit the report to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
date_range_endNoEnd date "YYYY-MM-DD" (inclusive).
date_range_startNoStart date "YYYY-MM-DD". Both dates empty means the last 30 days.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark this as a read-only, non-destructive, open-world query. The description goes beyond that by disclosing the aggregation model ('each product summed over the campaigns it ran in'), the grain (item id), and the three output groupings, which is meaningful behavioral context for interpreting numbers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two short paragraphs with the metric scope front-loaded and the aggregation/return behavior following; the API reference link is the only marginal content and no sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety and an output schema covering the response shape, the remaining burden is scope and semantics, which the description handles. Minor gap: no mention of pagination/limit interaction or how insights are prioritized.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so limit, campaign_id, customer_id and both date fields are already documented. The description only adds a loose reference to date-range and item-id semantics, so the schema does the heavy lifting and the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource (per-product performance), an exact metric set (spend, clicks, conversions, CPA, ROAS), and the channel scope (Shopping and Performance Max), which separates it from siblings like get_pmax_performance or get_campaign_performance. An agent can identify what it returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the promise of 'insights on what to do' with non-converting products suggests a diagnostic/reporting use case, but no alternative tool is named and no when-not condition is given, even though get_pmax_performance and get_campaign_performance overlap in scope.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_tracking_eventsList Analytics eventsA
Read-only
Inspect

List all GA4 events and their volume for the given date range.

Returns every distinct event name with its total event count, sorted by count (highest first). Shows what tracking is configured and active.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
date_range_endNoEnd date, same formats as date_range_start.today
date_range_startNoStart date: "today", "yesterday", "NdaysAgo" (e.g. "28daysAgo"), or "YYYY-MM-DD".28daysAgo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, covering the safety profile. The description adds useful context about the response shape (distinct event names, counts, sorted descending), but discloses no auth requirements, rate limits, or quota behavior beyond linking the API docs. Adequate but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose in the first sentence, followed by return details, and the API references are compact. Slightly redundant since an output schema exists and the return format is described anyway, but overall tight and well-ordered.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain returns (though it does), and all three parameters are fully covered by the schema. The definition gives an agent enough to call the tool correctly; only explicit sibling differentiation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents property_id and both date range parameters thoroughly (formats, defaults, references to get_account_summaries). The description adds nothing param-specific beyond restating 'the given date range', so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Clear specific verb+resource scope: 'List all GA4 events and their volume for the given date range.' It adds what the result represents ('what tracking is configured and active'). However, it does not explicitly distinguish itself from close siblings like list_key_events or audit_event_coverage, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'for the given date range' and the purpose statement, giving the agent enough context to invoke it. But there is no explicit when-to-use/when-not guidance and no named alternatives (e.g. list_key_events for conversions), so it is only minimum viable.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

health_checkConnection health checkA
Read-only
Inspect

Test AdLoop connectivity — checks OAuth token, GA4 API, Google Ads API, and (when configured) the Reddit Ads API.

Returns the status of each service and actionable guidance when something is broken, which makes it the diagnostic for failures in other tools.

Google Ads API: https://developers.google.com/google-ads/api/docs/start, Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint, and non-destructive, so safety is covered. The description adds genuine behavioral context beyond that: the exact services probed, the conditional Reddit check, and that it returns per-service status plus actionable remediation guidance. It does not mention rate limits or auth prerequisites, keeping it out of the 5 band.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and diagnostic framing are front-loaded and the sentences earn their place. However, the three trailing API documentation URLs are long and expend little value for an agent deciding whether to call the tool, slightly diluting an otherwise tight definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not detail return values, and it still summarizes them as per-service status plus remediation guidance. For a zero-parameter diagnostic, everything an agent needs to select and call it correctly is present.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to disambiguate; the 0-param baseline of 4 applies. The description correctly implies no arguments are needed to invoke it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Test AdLoop connectivity') and enumerates exactly what is checked: OAuth token, GA4 API, Google Ads API, and conditionally Reddit Ads API. This distinguishes it cleanly from siblings like validate_tracking or get_merchant_feed_health, which check specific objects rather than overall connectivity.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames itself as 'the diagnostic for failures in other tools,' which tells the agent when to reach for it. It stops short of naming specific alternative tools or stating when-not to use it, so it falls just under the top band.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

landing_page_analysisLanding page analysisB
Read-only
Inspect

Analyze which landing pages convert and which don't.

Combines ad final URLs with GA4 page-level data. Returns paid traffic sessions, conversion rates, bounce rates, and engagement per landing page, and identifies pages that get ad clicks but zero conversions and orphaned URLs.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoGoogle Ads customer ID, digits with or without dashes (e.g. "123-456-7890"). Defaults to the configured ads.customer_id.
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
date_range_endNoEnd date as "YYYY-MM-DD" (inclusive).
date_range_startNoStart date as "YYYY-MM-DD". Both dates must be set to apply a range; if either is empty, the last 30 days are used.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.2/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, and destructiveHint=false, so the safety profile is covered. The description adds a preview of what is computed (sessions, conversion rates, bounce rates, engagement, zero-conversion pages, orphaned URLs), but says nothing about auth requirements, rate limits, or data latency, and much of the return content is already available in the output schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two front-loaded sentences with no filler, stating purpose before output. The trailing API documentation links are somewhat verbose but plausibly useful, keeping this just short of maximum.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 4 optional parameters at 100% schema coverage, an output schema, and clear annotations, the definition gives the agent enough to invoke the tool. The only meaningful gap is the absence of routing guidance against sibling reporting tools, which belongs to usage rather than completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so customer_id, property_id, and both date fields are fully documented in the schema itself, including defaults and the 'both dates or last 30 days' rule. The description adds no parameter meaning beyond that, so the baseline of 3 for schema-driven documentation applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource and analysis goal ('which landing pages convert and which don't') and clarifies the method by naming the two data sources it joins (ad final URLs + GA4 page-level data). It is distinguishable from generic siblings like run_ga4_report by describing the cross-source join, though it never explicitly names a sibling it is not.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explains what the tool does but gives no when-to-use or when-not guidance and names no alternatives, despite sitting alongside closely related tools like run_ga4_report, get_campaign_performance, and analyze_page_speed. An agent must infer the selection conditions from the output description alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_accountsList Google Ads accountsA
Read-only
Inspect

List accessible Google Ads accounts.

Returns account names, IDs, status, and whether each is a manager account. When more accounts exist than limit, the response has 'truncated: true'; a much higher limit (e.g. list_accounts(limit=1000)) returns the full list. Workflows that target a specific account need no enumeration at all: get_campaign_performance, run_gaql, etc. take customer_id directly.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of accounts listed under the manager (MCC) account. The default cap of 200 covers the vast majority of agency MCCs in one call.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so safety is covered. The description adds real behavior the annotations do not: the 'truncated: true' flag, when it appears, and that raising the limit returns the full set. It does not discuss pagination or rate limits, but for a read-only list tool this is strong added context.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the purpose, then truncation behavior, then the alternative workflow, in three tight sentences. The trailing Google Ads API doc link is marginally useful but the rest has zero filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return structure need not be spelled out, yet the description still names the key fields and the truncation contract. Combined with the limit semantics and the guidance that enumeration is often unnecessary, an agent has everything needed to decide whether to call it and how.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the limit parameter's meaning is already documented (baseline 3). The description adds value beyond the schema by tying the parameter to the truncation flag and showing the concrete idiom list_accounts(limit=1000), which explains the practical effect of raising it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List accessible Google Ads accounts') and immediately scopes it to Google Ads, distinguishing it from the sibling list_merchant_accounts, list_reddit_accounts, and list_gsc_sites. The return-fields sentence ('names, IDs, status, and whether each is a manager account') makes the resource unambiguous.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-not guidance: 'Workflows that target a specific account need no enumeration at all' and names the alternative path (get_campaign_performance, run_gaql take customer_id directly). It also explains the escalation path for large lists via a higher limit. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_ga4_dimensions_and_metricsAnalytics dimensions and metricsA
Read-only
Inspect

List the dimensions and metrics a GA4 property can report on, including custom ones.

Returns the exact API names valid in run_ga4_report for this property: each with its UI name, category, whether it is a custom definition (customEvent:..., customUser:...), and deprecated API names; metrics also carry their type and, for calculated metrics, the expression. Reads the GA4 Data API metadata (properties.getMetadata), which uses no report quota.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo"all" (default), "dimensions" or "metrics".all
searchNoCase-insensitive text matched against API name, UI name, category, description and deprecated API names (e.g. "channel", "revenue", or the legacy "conversions", which finds keyEvents). Empty returns everything.
custom_onlyNoTrue returns only the property's custom dimensions and metrics.
property_idNoGA4 property as "properties/123456789" or the bare numeric ID. If empty, uses the default from config.
include_descriptionsNoInclude each field's description. Defaults to true when search is set and false otherwise (the full list is long).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover readOnly/openWorld/non-destructive, but the description adds substantial behavioral context beyond them: it names the underlying API call (properties.getMetadata) and discloses that it consumes no report quota. It also describes the shape of the return (UI name, category, custom prefix markers, deprecated API names, metric type, calculated expression).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose and return details in three efficient sentences. The trailing API documentation URLs add some length but are useful references; the content is well-organized and non-redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given readOnly annotations and a complete output schema, the description covers what an agent still needs: the underlying call, quota implications, return shape, and the relationship to run_ga4_report. Nothing material is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so all five parameters are already documented in the schema with defaults and behavior. The description adds no parameter-level syntax or format detail beyond what the schema provides, which is the expected baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (GA4 dimensions and metrics), and sharply scopes it to what a GA4 property can report on, including custom definitions. The mention of run_ga4_report ('exact API names valid in run_ga4_report') distinguishes it from that sibling by positioning it as the prerequisite lookup.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The link to run_ga4_report makes the usage context clear: call this to find valid field names before running a report. However, it never explicitly states 'use before run_ga4_report' nor excludes alternatives like run_gaql, leaving some inference to the agent.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gsc_sitesList Search Console propertiesA
Read-only
Inspect

List all Google Search Console properties the authenticated user can access.

Serves as the discovery step for the site URLs that search analytics reports (run_gsc_report) take. Returns the site URL and permission level for each property.

Search Console API: https://developers.google.com/webmaster-tools

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint and destructiveHint, so the safety profile is covered. The description adds value beyond that by stating what comes back (site URL and permission level per property) and linking the upstream API docs, though it omits pagination, auth scope details, or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short lines, front-loaded with the purpose, then the usage relationship, then the return contents and a reference link. Every sentence carries distinct information; nothing is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With zero parameters, an output schema present, and rich annotations, the description only needs to cover purpose, discovery role, and result shape — and it does all three. An agent has everything required to select and call this tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes no parameters, so there is nothing for the description to disambiguate and the baseline of 4 applies. The absence of parameters is consistent with the schema and the schema description coverage is 100%.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ("List") and resource ("Google Search Console properties") with an access qualifier ("the authenticated user can access"). It further pins down its role as the discovery step feeding run_gsc_report, clearly separating it from the reporting sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says it "serves as the discovery step for the site URLs that search analytics reports (run_gsc_report) take", naming the exact downstream consumer and the condition for calling it. There is no competing alternative tool, so no exclusion guidance is needed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_accountsList Tag Manager accountsA
Read-only
Inspect

List all GTM accounts the AdLoop service account / OAuth user can read.

The first-time discovery step: provides the account_id that audit_event_coverage takes. Returns each account's ID and name. An empty list means the service account hasn't been added to any GTM container with at least Read permission.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly, non-destructive, openWorld), so the description adds value by disclosing the permission precondition and the meaning of an empty result (service account lacks at least Read permission). It does not describe pagination or result ordering, but the empty-list semantics are genuinely useful context beyond the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the purpose and the discovery-step role before the empty-list caveat and the API reference. Each sentence carries information, though 'Returns each account's ID and name' partially duplicates what the output schema already provides.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool with an output schema and full annotation coverage, the description supplies everything an agent needs: what it returns, why to call it, the downstream consumer, and how to interpret an empty result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing to disambiguate and the baseline of 4 applies. The description appropriately focuses on the return/dependency relationship rather than inventing parameter guidance.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (list GTM accounts) and scopes it to what the service account / OAuth user can read. It also positions itself relative to siblings by naming audit_event_coverage as the downstream consumer, so an agent can distinguish it from list_gtm_containers, list_gtm_tags, etc.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the tool as the first-time discovery step and states that it supplies the account_id needed by audit_event_coverage, giving clear when-to-use context. It stops short of naming alternatives or exclusions, but the downstream dependency makes the usage unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_containersList Tag Manager containersA
Read-only
Inspect

List all containers under a GTM account.

Returns container_id (the numeric ID needed by audit_event_coverage), public_id (the GTM-XXXXXXX string shown in the UI), name, and usage context (web / iOS / Android / amp / server).

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
gtm_account_idNoNumeric GTM account ID from list_gtm_accounts. Empty uses gtm.account_id from the config; the tool errors when neither is set.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=true, so safety is covered. The description adds real behavioral value beyond that by distinguishing container_id (numeric, tool-consumable) from public_id (GTM-XXXXXXX, UI-visible) and enumerating the container_type values returned, which is what an agent needs to pick the right ID downstream.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the action and scope, then the return fields, then a reference link. Every sentence is short and purposeful, though the API documentation URL is marginal payload for selection decisions.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value documentation is not required, and annotations cover the read-only safety profile. The description supplies scope, the account-hierarchy relationship, and ID semantics, which is sufficient; pagination and permission requirements are the only unaddressed gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single parameter already documents its default, the config fallback, and the error condition when neither is set. The description adds no parameter-level detail beyond what the schema provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List all containers under a GTM account') and scopes it to the GTM account hierarchy, which separates it from lookalikes such as list_gtm_accounts, list_gtm_tags, and list_gtm_workspaces. Naming the returned identifiers (container_id, public_id) further pins down what this tool is for.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies usage by noting container_id is the input needed by audit_event_coverage, which is a genuine downstream-routing hint. However, it never states the when-to-use prerequisite chain (call list_gtm_accounts first, or rely on config) nor any exclusions versus the other GTM list tools; that guidance lives only in the schema's parameter description.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_tagsList Tag Manager tagsA
Read-only
Inspect

List every tag in the LIVE GTM container, or in one workspace.

Each tag includes type, status, parsed parameters, the GA4 event name (for GA4 event tags), and resolved firing/blocking trigger names. Complements audit_event_coverage for inspecting specific tags. With workspace_id the list shows that workspace's unpublished state, so a just-drafted tag is visible; source says which state was read.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
workspace_idNoWorkspace to read (see list_gtm_workspaces), which includes drafted changes that are not published yet. Empty reads the live (published) container version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers), not the GTM-XXXXXXX public ID. Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safe-read profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), and the description adds meaningful context beyond them: the exact fields returned per tag (type, status, parsed parameters, GA4 event name, resolved trigger names) and the `source` field that reports which state was read. This is real behavioral disclosure rather than repetition.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with the primary scope statement and each subsequent sentence adds a distinct fact (returned fields, complement tool, workspace behavior). The trailing API URL line is reference material of marginal value but does not bloat the definition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return-value explanation is not required, and the description still covers scope, returned fields, workspace semantics, and the relevant alternative tool. An agent has everything needed to select and call this correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema already documents all three parameters and the 3 baseline applies; the description nonetheless adds value by tying workspace_id to the behavior it triggers (unpublished workspace state becoming visible) and by introducing the `source` companion field. It does not add syntax details, so it is a modest gain over the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb (List) and resource (GTM tags) and scopes it precisely: every tag in the LIVE container or in one workspace. It also distinguishes itself from siblings like get_gtm_tag and list_gtm_triggers by naming the returned fields and the workspace/live distinction.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selection rule for workspace_id (unpublished state, so a just-drafted tag is visible) versus the live container, and names an alternative by noting it 'Complements audit_event_coverage for inspecting specific tags.' It does not explicitly contrast with get_gtm_tag, so it stops short of full when-not guidance, but the context is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_triggersList Tag Manager triggersA
Read-only
Inspect

List every trigger in the LIVE GTM container, or in one workspace.

Each trigger has its filter conditions parsed to readable text (e.g. "{{Page Path}} matches RegExp ^/service-promotions/"). Helps diagnose why a tag fires or doesn't fire on specific pages. With workspace_id the list shows that workspace's unpublished state.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
workspace_idNoWorkspace to read (see list_gtm_workspaces), which includes drafted changes that are not published yet. Empty reads the live (published) container version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/destructive/openWorld, so safety is covered. The description adds real behavioral context beyond them: results are read from the LIVE published container unless a workspace_id is given, in which case unpublished drafted state is shown, and filter conditions are returned as readable text rather than raw objects.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the scope in the first sentence, uses a second only to explain the output shape and the diagnostic value, and closes with a one-line API reference. No filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations covering safety, a 100%-covered schema, and an output schema handling return values, the description supplies everything else an agent needs: read scope, workspace behavior, and the diagnostic intent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters including their sibling references and defaults are already documented. The description restates the workspace_id live-vs-draft semantics but adds no syntax or format detail beyond the schema, making 3 the correct baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('List every trigger') and precisely scopes it to the live container or a single workspace, which cleanly separates it from siblings like get_gtm_trigger and list_gtm_workspaces. It also previews what the output contains (parsed filter conditions).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case (diagnosing why a tag fires or doesn't fire on specific pages) and explains the workspace_id branch's effect. It does not explicitly name alternatives such as get_gtm_trigger for a single trigger, so it stops short of full routing guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_variablesList Tag Manager variablesA
Read-only
Inspect

List GTM variables — both custom and enabled built-in.

Without workspace_id both come from the live container version (the Default Workspace supplies the built-ins only when the live version lists none; built_in_source names where they came from). With workspace_id both come from that workspace's unpublished state. Variables matter because triggers reference them: if a trigger uses {{Form ID}} but Form ID isn't enabled, the trigger never matches.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
workspace_idNoWorkspace to read (see list_gtm_workspaces), which includes drafted changes that are not published yet. Empty reads the live (published) container version.
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish the read-only, non-destructive safety profile, so the description is freed to add behavioral detail it does provide: the live-vs-unpublished source selection, the Default Workspace fallback for built-ins, and the built_in_source field that records provenance. This is meaningful context beyond the annotations, though nothing on rate limits or pagination.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with what is listed, then the conditional source behavior, then the rationale and API reference. Dense but each element earns its place; the parenthetical about the Default Workspace fallback is the only slightly tangled portion.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no exposition, and the description fully covers purpose, source selection, and the trigger-reference rationale an agent needs to call it correctly. Nothing essential is missing for a zero-required-parameter list tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents workspace_id's live-vs-draft behavior and the account/container ID fallbacks. The description adds the built_in_source naming and the 'both come from' scoping, a marginal addition over the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('List GTM variables') and immediately scopes it ('both custom and enabled built-in'), distinguishing it from the sibling list_gtm_tags/list_gtm_triggers tools. The workspace_id conditional further clarifies exactly which dataset is returned.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains the when/when-not of workspace_id: omit it to read the live container, supply it to read a workspace's unpublished state. It also motivates usage by explaining why variables matter (triggers reference them). It stops short of naming sibling alternatives for adjacent resources, so 4 rather than 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_versionsTag Manager version historyA
Read-only
Inspect

List GTM container version headers (newest first).

Version headers include version_id, name, archived flag and entity counts. The Tag Manager API returns no creation or publish time and no author for a version, and does not mark which versions were published; get_gtm_version returns a version's notes and get_gtm_version_diff what changed between two versions.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
page_sizeNoMaximum number of version headers returned (newest first).
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover safety (readOnlyHint, openWorldHint, destructiveHint), but the description adds important behavioral context: the API returns no creation or publish time, no author, and does not mark published versions, plus it enumerates the header fields. This prevents false assumptions about available metadata.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tightly written sentences with the core purpose front-loaded. The subsequent sentences about header contents and API limitations each earn their place, and the API URL is a concise supplementary reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so the description need not enumerate return values, yet it still summarizes version header contents and warns about missing metadata. Together with the annotations and full schema coverage, the definition gives an agent everything needed to call the tool correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all three parameters are fully documented in the schema. The description adds no parameter-specific meaning beyond the 'newest first' ordering already noted in the page_size schema description, so the baseline of 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ('List') and resource ('GTM container version headers'), and explicitly distinguishes the tool from siblings get_gtm_version and get_gtm_version_diff by describing what those alternatives return.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names two sibling alternatives (get_gtm_version and get_gtm_version_diff) and the information each provides ('notes', 'what changed'), giving an agent clear routing guidance for when to use this listing tool versus the detail tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_gtm_workspacesList Tag Manager workspacesA
Read-only
Inspect

List workspaces (drafts) under a GTM container.

Returns each workspace's ID, name and description; the IDs are what get_gtm_workspace_diff takes. Most containers have a single Default Workspace; multiple workspaces appear when the team uses parallel drafts.

Tag Manager API: https://developers.google.com/tag-platform/tag-manager/api/v2

ParametersJSON Schema
NameRequiredDescriptionDefault
gtm_account_idNoNumeric GTM account ID (see list_gtm_accounts). Empty uses gtm.account_id from the config.
gtm_container_idNoNumeric GTM container ID (see list_gtm_containers). Empty uses gtm.container_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds domain behavior the annotations cannot convey: workspaces represent drafts, most containers have a single Default Workspace, and multiple appear only with parallel drafts — real context for interpreting results. It does not mention pagination, permissions, or quota behavior, so it is not exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short lines, front-loaded with the operation and then the payload/routing detail. No filler sentences; the API doc link is a compact reference rather than prose padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Low-complexity read tool with an output schema, so return-shape explanation is not required, yet the description still names the returned fields. Combined with the annotation safety profile and the sibling routing cue, an agent has everything needed to call and interpret it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%: both parameters (gtm_account_id, gtm_container_id) are documented in the schema with their config-fallback default behavior. The description adds nothing about these inputs — it refers to account/container only implicitly through the hierarchy — so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource with scope ('List workspaces (drafts) under a GTM container') and a clarifying gloss on what a workspace is. It also distinguishes itself from the sibling it feeds (get_gtm_workspace_diff) and from list_gtm_accounts/list_gtm_containers, which sit above it in the hierarchy.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It tells the agent what the output enables — 'the IDs are what get_gtm_workspace_diff takes' — which is a clear routing cue to the next tool in the workflow, and it sets expectations that most containers have only a Default Workspace. It stops short of explicit when-not-to-use guidance or alternatives, so a 4 rather than a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_key_eventsList Analytics key eventsB
Read-only
Inspect

List the key events (conversions) configured on a GA4 property.

Returns each key event's event name, counting method (ONCE_PER_EVENT or ONCE_PER_SESSION), create time, whether GA4 allows deleting it, whether it is a custom event, and its resource name, sorted by event name, plus the total. Reads the GA4 Admin API (keyEvents.list).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
property_idNoGA4 property as "properties/123456789" or the bare numeric ID (see get_account_summaries). If empty, uses the default from config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

B3.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=true, openWorldHint=true, destructiveHint=false), so the bar is lower. The description adds real context beyond that: it names the backing call (keyEvents.list / GA4 Admin API) and notes the result is sorted by event name with a total, which helps the agent interpret output ordering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first sentence, good. The second paragraph enumerates return fields in prose, which largely duplicates the existing output schema, and the trailing API doc URLs add bulk without aiding tool selection. Clean but not tight.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given an output schema, a fully documented parameter, and annotations covering safety, the description covers what an agent needs: what is listed, for which resource, and how results are ordered. The only real omission is routing guidance against the mutation siblings.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With a single parameter at 100% schema description coverage, the schema already documents property_id format and the empty-string fallback to config. The description adds nothing about the parameter, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource with scope: 'List the key events (conversions) configured on a GA4 property.' Mapping key events to 'conversions' disambiguates terminology against neighbors like draft_create_conversion_action and get_custom_conversion_goals. It does not, however, explicitly distinguish itself from the write-side sibling draft_key_event.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no when-to-use or when-not-to-use guidance and no named alternative. A read/write pair exists in the sibling list (draft_key_event, draft_delete_key_event), but the description never tells the agent that this is the read path and those are the mutation paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_merchant_accountsList Merchant Center accountsA
Read-only
Inspect

List Google Merchant Center accounts the connected user can access.

Returns each account's numeric ID, name and whether it is a test account. Provides the account_id used by get_merchant_feed_health; not needed when merchant.account_id is set in the config.

Merchant API: https://developers.google.com/merchant/api/overview

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so safety is covered. The description adds real value beyond that: what each account row contains (ID, name, test flag) and the dependency on the merchant.account_id config setting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the primary purpose, then return shape, then the config/downstream caveat. Every sentence earns its place; the trailing Merchant API link is the only marginally expendable element.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a parameterless read tool with an output schema, the description covers everything needed: purpose, platform scope, the account_id linkage to get_merchant_feed_health, and the config condition that makes it unnecessary.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

There are zero parameters, so the baseline of 4 applies. The description correctly describes no inputs, and its mention of the account_id output clarifies the downstream consumption rather than introducing parameter ambiguity.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (Google Merchant Center accounts) with scope ('the connected user can access'). It clearly separates itself from siblings like list_accounts, list_gsc_sites, and list_reddit_accounts by naming the Merchant Center platform.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit conditional guidance: it supplies the account_id used by get_merchant_feed_health, but is 'not needed when merchant.account_id is set in the config.' That is a strong when/when-not statement, though it offers no broader alternatives for enumerating accounts.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reddit_accountsList Reddit ad accountsA
Read-only
Inspect

List Reddit businesses and ad accounts the connected Reddit user can access.

Returns the Reddit username, the businesses, and per ad account the ad_account_id values (plus currency, time zone and approval state) that every other Reddit tool takes. Requires the Reddit Ads connection (adloop init → Reddit step, or Settings → Reddit Ads in Cloud).

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, openWorldHint and destructiveHint=false, so the safety profile is covered. The description adds useful context beyond that: the prerequisite Reddit Ads connection and how to establish it (adloop init / Settings), plus what the payload contains, which a bare read tool would not otherwise reveal.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with what it lists and what it returns before the setup requirement and reference link. The URL and setup note earn their place for a zero-param discovery tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present the return shape need not be spelled out, yet the description still summarizes it, and the annotations plus the auth-connection note cover the safety and prerequisites. Nothing an agent needs to call this correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is no parameter semantics to document and the baseline applies. The description correctly omits any parameter discussion rather than inventing one.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (list Reddit businesses and ad accounts) and enumerates the returned fields: username, businesses, per-account ad_account_id plus currency, time zone and approval state. It also distinguishes itself from the many non-Reddit list siblings by explicitly scoping to the Reddit Ads connection.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Implies the correct usage context strongly by calling out that the ad_account_id values are what 'every other Reddit tool takes', i.e. this is the discovery step to run first. It does not state explicit exclusions or contrast with candidates like list_accounts or list_merchant_accounts, but the routing is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_reddit_funding_instrumentsReddit billing + posting profilesA
Read-only
Inspect

Funding instruments (billing) and posting profiles of a Reddit ad account.

Returns funding_instruments (funding_instrument_id, currency, is_servable, reasons_not_servable, credit limit and billable amount in account currency) and profiles (profile_id, username). draft_reddit_campaign needs a servable funding_instrument_id; draft_reddit_ad needs the profile_id that authors the post. Both come from here.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so the safety profile is covered. The description adds genuine behavioral context beyond that: the servability dimension (is_servable, reasons_not_servable) signals some instruments may be unusable, and the currency/credit-limit fields hint at account-context dependency. It says nothing about auth or rate limits, but the added semantics are real.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Content is front-loaded with the resource and its fields, then the downstream dependency, then a docs link. Every element is informative, though the exhaustive field listing partially duplicates the output schema.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The tool is simple (one optional param, output schema present) and the description covers what it returns and why it matters in the drafting workflow. It is complete enough to invoke correctly; only the absence of any non-servable/pagination handling note keeps it from a 5.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

With a single parameter at 100% schema description coverage, the schema already documents ad_account_id including the empty-string fallback to reddit.ad_account_id in config. The description adds nothing parameter-specific, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (funding instruments/billing and posting profiles of a Reddit ad account) and enumerates the returned fields, so an agent knows exactly what it fetches. The verb is implicit ('Returns ...'), but combined with the list_ prefix the purpose is unambiguous and distinguishable from siblings like get_reddit_campaigns.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly routes the agent: draft_reddit_campaign needs a servable funding_instrument_id and draft_reddit_ad needs the profile_id, and states both come from this tool. That is clear when-to-use context, though it stops short of any when-not-to-use or exclusion guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_uploadsList uploadsA
Read-only
Inspect

List the files the user uploaded to AdLoop that have not expired.

Returns each upload's upload_id, kind (image or csv), name, type, size, dimensions (images) or lines (CSVs) and hours until it expires: images last a day, conversion CSVs two hours or until a draft reads them. The ids of files the user sent through an upload link show up here.

Google Ads API: https://developers.google.com/google-ads/api/docs/start, Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the safety profile (readOnly=true, destructive=false, openWorld=true), and the description goes beyond them with real behavioral context: expiry windows (images one day, conversion CSVs two hours or until read by a draft) and the fact that upload-link files surface here. It does not mention pagination or ordering, so not a full 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and the expiry detail are front-loaded and efficient, but the trailing block of three external API documentation URLs is boilerplate that consumes roughly half the text without helping an agent select or invoke this tool. That bulk dilutes an otherwise tight description.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, read-only listing tool with an output schema already present, the description is largely complete: it explains scope (non-expired), the shape of the results, and the expiry lifetime rules. The only real omission is guidance on when to choose it over sibling read tools.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to clarify; baseline 4 applies. Schema coverage is 100% and the empty parameter object is self-explanatory.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb and resource with a scope qualifier: 'List the files the user uploaded to AdLoop that have not expired.' An agent can immediately distinguish this read-side listing from the sibling write tool upload_images without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by the purpose (retrieve upload ids for files already sent), and the expiry note hints at why an agent would call it, but there is no explicit when-to-use, no when-not-to-use, and no routing to a sibling alternative. Adequate but with a clear gap.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pause_entityDraft pausing an entityAInspect

Draft pausing a campaign, ad group, ad, or keyword — returns a PREVIEW.

Pausing is reversible with enable_entity. Returns a preview with a plan_id (target status PAUSED); nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesID in the format for its type. campaign: campaign ID (e.g. "12345678"); ad_group: ad group ID (e.g. "12345678"); ad: "adGroupId~adId" (e.g. "12345678~987654"; a bare ad ID is resolved to its ad group at apply time); keyword: "adGroupId~criterionId" (e.g. "12345678~987654").
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
entity_typeYes"campaign", "ad_group", "ad", "keyword" or "asset_group" (Performance Max).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond annotations (readOnlyHint=false, destructiveHint=false, openWorldHint=true), the description discloses that the call returns a PREVIEW with a plan_id and a target status of PAUSED, that no changes happen until confirm_and_apply is used, and that the action is reversible. This is exactly the behavioral context an agent needs for a draft/pending mutation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the core action and preview behavior, then follows with the reversibility/apply workflow, then a reference link. Every sentence earns its place; there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema, annotations, and 100% schema coverage, the description supplies the remaining critical context: that this is a preview-only draft operation, how it relates to confirm_and_apply and enable_entity, and the target status. An agent has enough to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the input schema already fully documents entity_id formats, customer_id defaulting, and entity_type values. The description repeats the entity types in prose but adds no parameter-level syntax or constraints beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb+resource: 'Draft pausing a campaign, ad group, ad, or keyword — returns a PREVIEW.' It cleanly distinguishes the tool from direct mutations by emphasizing that it only produces a preview, and it names the follow-up tool (confirm_and_apply) and the reverse action (enable_entity).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It clearly situates the tool in a two-step workflow: nothing changes until confirm_and_apply applies the preview, and pausing is reversible with enable_entity. It doesn't spell out exclusions (e.g., when to use pause_reddit_entity or a direct update instead), but the context for use is unambiguous.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

pause_reddit_entityDraft pausing a Reddit entityAInspect

Draft pausing a Reddit campaign, ad group or ad — returns a PREVIEW.

Returns a preview with a plan_id, the current and target status (PAUSED) and warnings (e.g. already paused); nothing changes until confirm_and_apply applies the plan_id.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesReddit id of the entity, from the read tools (get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads).
entity_typeYes"campaign", "ad_group" or "ad".
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes beyond the annotations (readOnlyHint=false, destructiveHint=false) by disclosing the dry-run contract: a plan_id is returned, target status is PAUSED, warnings such as 'already paused' are surfaced, and no mutation occurs until confirmation. Auth/permission requirements and warning semantics are still unspecified.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short, information-dense blocks: the preview outcome first, the mechanism second, the doc link last. No filler and no repetition of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a preview-generating mutation tool with an output schema present, this covers everything an agent needs: what is produced (plan_id, status, warnings), that no side effect occurs yet, and which tool finishes the job. Return-value detail is correctly deferred to the output schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents entity_id, entity_type, and ad_account_id sources. The description restates the three entity types but adds no format, default, or lookup guidance beyond what the schema provides; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft pausing) plus the exact resources (Reddit campaign, ad group, ad) and immediately flags that it returns a PREVIEW. An agent can distinguish it from the confirm_and_apply and enable_reddit_entity siblings without reading either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly explains the two-step flow: nothing changes until confirm_and_apply applies the plan_id, which tells the agent this is the drafting half of a pair. It does not contrast against enable_reddit_entity or remove_reddit_entity, so the exclusions are not fully enumerated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_brand_listDraft a brand listAInspect

Draft a brand list and optionally attach it to campaigns — returns a PREVIEW.

Creates a SharedSet of type BRANDS, fills it with brands, and — when campaign_ids is given — attaches it to those campaigns.

Returns a preview with a plan_id; nothing changes until the returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
negativeNoTrue (default) excludes the brands from those campaigns; False restricts targeting to them instead.
brand_idsYesCommercial Knowledge Graph MIDs — the `id` field from suggest_brands / check_brand_names, which resolve names; a display name alone cannot be written. Duplicates are dropped.
list_nameYesName for the new list, as it should appear in Google Ads.
customer_idNoAds account ID. Defaults to the configured account.
campaign_idsNoOptional numeric campaign IDs. When omitted, the list is created without being used yet; attach_brand_list_to_campaigns attaches it later.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations mark this as a non-read, non-destructive, open-world mutation; the description crucially discloses the preview-first contract — a plan_id is returned and nothing changes until confirm_and_apply is called. That is non-obvious behavior beyond the annotations. It does not cover permission/auth requirements or duplicate/dedup effects in the prose, keeping it from a 5.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the outcome and the PREVIEW warning, then the mechanics, then the plan/apply contract. The opening 'Draft a brand list and optionally attach it to campaigns' partly restates the title, a small redundancy, but overall it is tight and well-ordered.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With annotations, full schema coverage, and an output schema for the preview, the definition supplies enough to call the tool correctly, including the two-step draft/confirm workflow. Nothing essential is missing, though it could have named the sibling tools it hands off to (attach_brand_list_to_campaigns) more explicitly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents each parameter including the negative default semantics and the MID requirement for brand_ids. The description adds only high-level framing ('fills it with brands', 'optionally attach') and no syntax or format detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (draft a brand list) with scope (optionally attach to campaigns) and even the underlying object (a SharedSet of type BRANDS). It is clear and specific, though it never explicitly names a sibling in the main text, so differentiation from propose_negative_keyword_list / draft_prepare_brand_exclusions is left to inference.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear context: when campaign_ids is supplied the set is attached, otherwise it is created unused and attach_brand_list_to_campaigns is used later. It also states the plan must be applied with confirm_and_apply. No explicit when-not or named-alternative comparison, so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

propose_negative_keyword_listDraft a shared negative keyword listAInspect

Draft a shared negative keyword list and attach it to a campaign — returns a PREVIEW.

Creates a reusable negative keyword list (shared set) that can later be applied to multiple campaigns, whereas add_negative_keywords adds negatives directly to one campaign. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
keywordsYesNegative keyword texts to put in the list (at least one).
list_nameYesName of the new shared negative keyword list.
match_typeNoMatch type applied to every keyword: "EXACT" (default), "PHRASE", or "BROAD" (case-insensitive).EXACT
campaign_idYesNumeric ID of the campaign the new list is attached to.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations declare readOnlyHint=false and destructiveHint=false, but the description adds the crucial non-obvious trait: this is a deferred write that returns a preview with a plan_id and changes nothing until confirm_and_apply. That resolves ambiguity the safety hints alone would leave (an agent could otherwise assume immediate mutation).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with scope, then sibling differentiation, then the preview/confirm workflow. Slightly padded by the bare Google Ads API documentation link, which adds little for an agent already inside this toolset.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be explained, and the description still notes the preview/plan_id shape. Combined with annotations and complete parameter docs, nothing essential to a correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the five parameters are fully documented in the schema (keywords, list_name, match_type, campaign_id, customer_id). The description adds only the conceptual notion of a shared list, no syntax or format detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft a shared negative keyword list') and immediately scopes it against the sibling add_negative_keywords, which adds negatives to one campaign. An agent can distinguish this reusable-shared-set tool from its neighbors without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the alternative tool and the exact condition that selects it ('shared set that can later be applied to multiple campaigns' vs 'adds negatives directly to one campaign'). It also states the workflow prerequisite: nothing is applied until confirm_and_apply runs.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_entityDraft removing an entityA
Destructive
Inspect

Draft REMOVING an entity — returns a PREVIEW. This is IRREVERSIBLE.

Removed entities cannot be re-enabled; pause_entity is the reversible way to temporarily disable something. Returns a preview with a plan_id and requires_double_confirm=true; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesThe resource ID. campaign / ad_group / asset_group / asset: simple numeric ID. ad: "adGroupId~adId" (a bare ad ID is resolved to its ad group). keyword and ad_group_criterion: "adGroupId~criterionId". negative_keyword and campaign_criterion: "campaignId~criterionId" (the resource_id field from get_negative_keywords). shared_criterion: "sharedSetId~criterionId" (the resource_id field from get_negative_keyword_list_keywords). campaign_asset: "campaignId~assetId~fieldType". customer_asset: "assetId~fieldType".
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
entity_typeYes"campaign", "ad_group", "ad", "keyword", "asset_group", "negative_keyword", "shared_criterion", "campaign_asset", "asset", "customer_asset", "ad_group_criterion", or "campaign_criterion".

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the destructiveHint annotation, the description discloses irreversibility, that removed entities cannot be re-enabled, that the call returns a preview with plan_id and requires_double_confirm=true, and that no change occurs until confirm_and_apply. This is materially more useful than the annotations alone.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is short, front-loads the irreversible preview warning, and uses clear sentences without waste. The Google Ads API link is a minor addition that does not disrupt readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive draft-operation tool with an output schema present, the description covers the key behavioral contract: preview-only, irreversible, double-confirm required, and confirmation via a sibling tool. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all three parameters in detail, including entity_id formats and entity_type values. The description adds no additional parameter meaning beyond the schema, so baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb ('Draft REMOVING') and resource ('an entity'), clarifies it returns a preview, and explicitly distinguishes itself from pause_entity and confirm_and_apply. An agent can identify the tool's unique role without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It names the alternative reversible tool (pause_entity) and explains the apply step (confirm_and_apply), making clear when this irreversible removal path is appropriate versus the reversible pause path. Nothing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_from_brand_listDraft removing brands from a listA
Destructive
Inspect

Remove brands from a brand list — returns a PREVIEW.

SharedCriteria have no status field, so removal is the only way to take a brand out of a list — there is nothing to pause. Removing a brand does not detach the list from any campaign.

Returns a preview with a plan_id; nothing changes until the returned plan_id is applied with confirm_and_apply.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.
criterion_idsYesNumeric criterion_id values from get_brand_list_brands. This is irreversible — the brand leaves the list immediately.
shared_set_idYesNumeric list ID from get_brand_lists.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the destructiveHint=true annotation: it discloses that the call is only a preview with a plan_id, that nothing changes until confirm_and_apply runs, and that removal does not detach the list from any campaign. It also explains the underlying reason (no status field), which is real behavioral context the agent cannot get from annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the most important fact (returns a PREVIEW) and organized into short, digestible paragraphs. There is minor repetition between 'returns a PREVIEW' and 'Returns a preview with a plan_id', and the trailing API doc link adds little value, but overall it is efficient.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a destructive draft-preview mutation tool, it covers what the call does, the two-step apply workflow, the irreversibility, and the non-side-effect on campaigns. With an output schema present, return values need not be detailed, so nothing essential is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so shared_set_id and criterion_ids are already fully documented (including source tools and irreversibility warnings). The description adds no parameter-specific meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource (remove brands from a brand list) and immediately flags the key output characteristic (returns a PREVIEW). This clearly distinguishes it from add_to_brand_list and propose_brand_list without the agent needing to open a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the essential context for using it: SharedCriteria have no status field, so removal is the only way to take a brand out of a list (nothing to pause). It also names confirm_and_apply as the follow-up step. It stops short of explicitly contrasting with sibling tools like detach_brand_list_from_campaigns, so it is clear context rather than full when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

remove_reddit_entityDraft archiving a Reddit entityA
Destructive
Inspect

Draft ARCHIVING a Reddit campaign, ad group or ad — irreversible, PREVIEW.

Reddit has no hard delete for entities that ran; ARCHIVED is permanent. pause_reddit_entity is the reversible alternative when the entity does not need to be gone. Returns a preview with a plan_id that requires double confirmation; confirm_and_apply executes it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
entity_idYesReddit id of the entity, from the read tools (get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads).
entity_typeYes"campaign", "ad_group" or "ad".
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations mark destructiveHint=true but provide no detail. The description adds substantial context beyond them: Reddit has no hard delete for entities that ran, ARCHIVED is permanent and irreversible, the call returns a preview with a plan_id, and execution requires a separate double-confirmation step. That is exactly the behavioral disclosure a mutation tool needs.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the action and its irreversibility, then the alternative, then the preview/confirmation mechanics, closing with a doc link. Every sentence carries distinct information with no redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers irreversibility, the archive-instead-of-delete caveat, the alternative tool, and the two-step confirmation flow. With an output schema present, the preview/plan_id return contract need not be restated, so nothing an agent needs to invoke it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so entity_id, entity_type and ad_account_id are already fully documented in the schema. The description adds only the enumeration of entity types, which the schema also provides, so it does not meaningfully extend parameter meaning beyond the baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Draft archiving/removal) applied to a named resource family (Reddit campaign, ad group or ad). It also makes clear this is a preview rather than an immediate mutation, which distinguishes it sharply from pause_reddit_entity and the update_reddit_* siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the reversible alternative (pause_reddit_entity) and the condition that should route the agent there: 'when the entity does not need to be gone.' It also states the confirmation workflow (plan_id, double confirmation, confirm_and_apply), so an agent knows the full call path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_ga4_reportAnalytics reportA
Read-only
Inspect

Run a custom GA4 report with optional filters, ordering, paging and a comparison period.

Returns the property, the date range, the dimension and metric headers, one row per dimension combination (values as strings), row_count and total_row_count (plus next_offset while more rows remain). At least one dimension or metric is required. With compare_start/compare_end the comparison period is a second date range: every row then carries a dateRange value of "current" or "comparison", and date_ranges maps both labels to their dates. Invalid filters or ordering return "Validation failed" with details, before anything is sent.

Queries the GA4 Data API. Dimensions and metrics: https://developers.google.com/analytics/devguides/reporting/data/v1/api-schema

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of rows returned (positive).
offsetNoZero-based row offset for paging; pass next_offset from the previous result to get the following page.
metricsNoGA4 metric API names, e.g. sessions, totalUsers, newUsers, screenPageViews, keyEvents, eventCount, bounceRate.
order_byNoSort order as [{"field": <name>, "desc": true|false}]; each field must be one of the requested dimensions or metrics.
dimensionsNoGA4 dimension API names, e.g. date, pagePath, sessionSource, sessionMedium, country, deviceCategory, eventName. Custom ones (customEvent:...) and every valid name are listed by list_ga4_dimensions_and_metrics.
compare_endNoEnd of the comparison period.
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
compare_startNoStart of the comparison period (same formats as date_range_start). Set together with compare_end.
metric_filterNoConditions on metrics, applied after aggregation, all of which must hold (AND). Each is {"field": <metric>, "op": <op>, "value": <number>}; op is EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL, GREATER_THAN, GREATER_THAN_OR_EQUAL (or =, <, <=, >, >=), or BETWEEN with "value": [from, to]. Optional "not": true. Example: [{"field": "sessions", "op": ">", "value": 100}].
date_range_endNoEnd date, same formats as date_range_start.today
date_range_startNoStart date: "today", "yesterday", "NdaysAgo" (e.g. "7daysAgo", "28daysAgo", "90daysAgo"), or "YYYY-MM-DD".7daysAgo
dimension_filterNoConditions on dimensions, all of which must hold (AND). Each is {"field": <dimension>, "op": <match>, "value": <string>}; op is EXACT (default), BEGINS_WITH, ENDS_WITH, CONTAINS, FULL_REGEXP, PARTIAL_REGEXP, or IN_LIST with "values": [<strings>]. Optional keys: "case_sensitive" (default false) and "not": true to exclude matches. Example: [{"field": "sessionDefaultChannelGroup", "op": "EXACT", "value": "Paid Search"}].

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, destructiveHint=false, and openWorldHint, so the safety profile is covered. The description goes beyond that by disclosing error behavior ('Validation failed' with details, before anything is sent), the comparison-period semantics (dateRange values 'current'/'comparison', date_ranges mapping), and paging via next_offset — genuinely useful behavioral context for a read tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, followed by constraints and comparison semantics. Some sentences restate the return shape (property, headers, row_count, next_offset) that the output schema already provides, which is mildly redundant, but the description remains organized and free of filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter tool with an output schema present, the description covers the key non-schema constraint (at least one dimension or metric), error behavior, and comparison-period mechanics. Given the output schema carries return values, the remaining omission (no explicit sibling routing) keeps it just short of fully complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description adds a real constraint that the schema does not encode (0 required parameters): 'At least one dimension or metric is required', plus the semantic framing of compare_start/compare_end as a second date range. That is meaningful semantics beyond the schema, though most per-parameter detail lives in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a custom GA4 report') with the scope qualifier 'custom', which implicitly separates it from standard/realtime reporting. The GA4 API reference and property/date-range framing make the tool's identity clear. It does not explicitly name which sibling to prefer instead (e.g., run_realtime_report, run_gsc_report, run_gaql), so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied through constraints ('At least one dimension or metric is required') and a routing pointer for valid names ('list_ga4_dimensions_and_metrics'). There is no explicit when-to-use/when-not guidance relative to run_realtime_report, run_gsc_report, or run_gaql, so the agent must infer the boundary from the GA4 scope alone.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_gaqlCustom Google Ads queryA
Read-only
Inspect

Execute an arbitrary GAQL (Google Ads Query Language) query.

For queries beyond the dedicated report tools. Returns the result rows in the requested format with the query echoed back; cost fields stay in raw micros (cost_micros / 1,000,000 = account currency). A failing query returns an error with a hint.

Queries the Google Ads API. GAQL syntax and fields: https://developers.google.com/google-ads/api/docs/query/overview

ParametersJSON Schema
NameRequiredDescriptionDefault
queryYesThe GAQL query, e.g. "SELECT campaign.name, metrics.clicks FROM campaign WHERE segments.date DURING LAST_7_DAYS".
formatNoOutput format: "table" (default, readable), "json" (structured), or "csv" (exportable).table
customer_idNoGoogle Ads customer ID, digits with or without dashes (123-456-7890). Empty uses the configured default account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already carry the safety profile (readOnlyHint=true, destructiveHint=false, openWorldHint=true), so the bar is lower, yet the description adds real behavioral context: the query is echoed back, cost fields remain in raw micros with the conversion formula, and failures return an error with a hint. It does not mention rate limits, row caps, or pagination, which is the remaining gap for an arbitrary-query tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first line, followed by the disambiguation, then return semantics and error behavior, with the docs link last as a reference. Every sentence carries information; nothing is redundant with the schema or annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, return values need not be re-explained, and the description correctly focuses on scope, format echoing, micros handling, and error behavior. An arbitrary-query tool could still benefit from noting limits or that GAQL validity is the caller's responsibility, but the essentials are covered.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and each parameter (query, format, customer_id) is fully documented in the schema, including enum-like format values and the dashed/undashed customer ID. The description adds no parameter-level detail beyond what the schema already provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource ('Execute an arbitrary GAQL query') and explicitly positions itself against the siblings: 'For queries beyond the dedicated report tools.' An agent can tell this is the escape hatch versus get_campaign_performance or get_ad_performance without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the selecting condition clearly ('beyond the dedicated report tools'), which routes the agent here only when no dedicated tool covers the query. It stops short of naming which dedicated report tool to prefer for common cases, so it is clear context rather than a full when/when-not matrix.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_gsc_reportSearch Console reportA
Read-only
Inspect

Run a Google Search Console search analytics report.

Returns clicks, impressions, CTR, and average position broken down by the requested dimensions. Useful for diagnosing organic traffic drops, finding keyword opportunities, and cross-referencing with GA4 and Ads data. One request returns at most 25,000 rows; a full page carries next_start_row for the following request. With data_state "all" the response metadata names the first date whose data is still incomplete.

Queries the Search Console API: https://developers.google.com/webmaster-tools/v1/searchanalytics/query

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum rows to return (default 100, max 25000 per request; higher values are capped at 25000).
site_urlNoThe GSC property URL (e.g. "https://example.com/" or "sc-domain:example.com"), as listed by list_gsc_sites. Defaults to the configured Search Console site (gsc.site_url).
start_rowNoZero-based offset of the first row, for paging past the 25,000-row cap (pass the previous response's next_start_row).
data_stateNo"final" (default) returns finalized data only; "all" adds fresh data from the last days that can still change; "hourly_all" is the state the hour dimension uses.final
dimensionsNoOne or more of "query", "page", "country", "device", "date", "searchAppearance" (search result feature, e.g. rich results) or "hour" (hourly rows for roughly the last 10 days; switches data_state to "hourly_all"). Defaults to ["query"].
search_typeNo"web" (default), "image", "video", "news", "discover", or "googleNews".web
date_range_endNoEnd date, same formats as date_range_start.today
aggregation_typeNo"auto" (default), "byPage" (aggregate by canonical URL) or "byProperty" (aggregate by property; not combinable with grouping or filtering by page).auto
date_range_startNoStart date as ISO "YYYY-MM-DD" or a relative value like "7daysAgo", "30daysAgo", "today".7daysAgo
dimension_filter_groupsNoOptional list of GSC DimensionFilterGroup objects to filter by query, page, country, or device, e.g. [{"filters": [{"dimension": "query", "operator": "contains", "expression": "analytics"}]}]. searchAppearance is filterable too.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/openWorld/destructive annotations, it discloses operational traits an agent needs: a hard 25,000-row cap, the next_start_row paging handoff, and the data_state 'all' freshness metadata quirk. This is meaningful behavioral context for paginated, freshness-sensitive reporting.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then returns, usage, and behavioral caveats, ending with the API reference. Well ordered and mostly waste-free, though the metrics list slightly overlaps the schema's return shape and the doc URL is tangential.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out. The description covers the key operational gaps (row cap, pagination, data freshness), leaving only auth/rate-limit context unstated for a 10-parameter read-only tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents every parameter including limit, start_row, dimensions, and data_state. The description reiterates the row cap and data_state behavior but adds little syntax or format detail not already in the schema, matching the baseline-3 rule.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Run a Google Search Console search analytics report') and lists the exact metrics returned. It implicitly separates itself from run_ga4_report by framing GSC data as the input to cross-referencing, but never names an alternative tool directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear use contexts (diagnosing organic traffic drops, finding keyword opportunities, cross-referencing with GA4/Ads data). It does not state when to prefer run_ga4_report or get_search_terms instead, so there are no explicit exclusions or alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_realtime_reportAnalytics realtime reportA
Read-only
Inspect

Run a GA4 realtime report showing current active users and events.

Useful for checking if tracking is firing correctly after code changes. Returns the dimension and metric headers and one row per dimension combination over the realtime window (the last 30 minutes).

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Admin API: https://developers.google.com/analytics/devguides/config/admin/v1

ParametersJSON Schema
NameRequiredDescriptionDefault
metricsNoGA4 realtime metric API names, e.g. activeUsers, eventCount. Defaults to ["activeUsers"].
dimensionsNoGA4 realtime dimension API names, e.g. unifiedScreenName, eventName, country, deviceCategory.
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so the safety profile is covered. The description adds genuinely useful behavioral context beyond that: the 30-minute realtime window and the return shape (dimension/metric headers plus one row per dimension combination).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, followed by the use case and then the return shape, all in four short sentences with no filler. The trailing API documentation links are slightly extraneous but minimally costly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be explained, yet the description still characterizes them helpfully. Combined with annotations covering safety and the schema covering all parameters, an agent has what it needs, with only the missing sibling differentiation as a gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents metrics, dimensions, and property_id including the properties/123456789 format and defaults. The description adds no additional parameter meaning, which is the expected baseline when the schema does the work.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (run a GA4 realtime report) and scopes it to the realtime window (last 30 minutes), which separates it conceptually from the historical run_ga4_report sibling. It never names that sibling explicitly, so an agent must infer the realtime-vs-historical split from the title alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Useful for checking if tracking is firing correctly after code changes" gives one concrete usage scenario, which is more than nothing. However, it offers no exclusions or alternatives (e.g. run_ga4_report for historical data, validate_tracking for deeper validation), so an agent picking among the many report siblings still has to guess.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

run_reddit_reportRaw Reddit reportA
Read-only
Inspect

Run a custom Reddit Ads report for metrics get_reddit_performance omits.

Returns the requested fields per breakdown row, the date range and the account currency. Microcurrency and cent fields are converted to currency amounts.

Queries the Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
fieldsYesReddit report field names (required), e.g. ["SPEND", "CLICKS", "REACH", "VIDEO_STARTED", "CONVERSION_PURCHASE_TOTAL_VALUE", "KEY_CONVERSION_TOTAL_COUNT"].
filterNoReddit filter expression (e.g. "campaign_id==abc123"). Empty means no filter.
breakdownsNoUp to 3 of DATE, HOUR, CAMPAIGN_ID, AD_GROUP_ID, AD_ID, COUNTRY, REGION, COMMUNITY, KEYWORD, INTEREST, PLACEMENT, GENDER, OS_TYPE (4 when COUNTRY and REGION are both included; HOUR and DATE cannot be combined).
time_zone_idNoIANA time zone for the day boundaries and DATE/HOUR rows, e.g. "Europe/Berlin". Empty uses the ad account's time zone.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
date_range_endNoLast day (inclusive), YYYY-MM-DD (account-local day). Empty means today.
date_range_startNoFirst day, YYYY-MM-DD (account-local day). Empty means 29 days before date_range_end (a 30-day window).

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=true, so safety is covered. The description adds genuine behavioral context beyond that: it returns requested fields per breakdown row plus date range and account currency, and it normalizes microcurrency/cent values to currency amounts, which materially affects interpretation of results.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, front-loaded with the differentiator, then output behavior, then an API reference link. The doc URL is mildly expendable but genuinely useful for field-name discovery, so structure is tight overall.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description need not explain return values, and it still summarizes the return shape and currency conversion. Combined with 100% schema coverage and annotations, an agent has enough to call this correctly; only auth/permission prerequisites are unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all seven parameters are already documented in the schema with examples, defaults and constraints. The description only echoes 'requested fields' and 'breakdown row' without adding syntax or semantics beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Run) and resource (custom Reddit Ads report) and immediately distinguishes itself from the sibling get_reddit_performance by scoping to 'metrics get_reddit_performance omits'. An agent can tell which Reddit reporting tool to pick without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'for metrics get_reddit_performance omits' establishes the selection condition relative to a named alternative, which is clear routing guidance. It stops short of an explicit when-not rule or a direct pointer back to get_reddit_performance for standard metrics, so it is not fully prescriptive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_audience_segmentsSearch audience segmentsA
Read-only
Inspect

Find Google's in-market and affinity segments by name, with the segment_id to attach.

In-market segments are people actively researching a purchase; affinity segments are long-term interests. Matching is on the segment name, in English, e.g. "running", "insurance", "travel".

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
kindNo"in_market", "affinity" or "all" (default).all
limitNoMaximum number of segments to return (1-100, default 25).
queryYesPart of the segment name to look for (at least 2 characters).
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true and destructiveHint=false, so the safety profile is covered. The description adds real context beyond annotations: matching is on the English segment name (not localized or ID-based) and it queries Google's external catalog. It says nothing about rate limits or result ordering, so it is solid but not rich.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and return value, then supported by the useful in-market/affinity definitions and examples before the API link. Every sentence earns its place; it is efficiently sized for a four-parameter search tool.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value structure need not be described. Given the low complexity, annotations, and full schema coverage, the description supplies the conceptual context (what the two segment types mean, how matching works) an agent needs. It is nearly complete, though a note on how results relate to attachment siblings would close the workflow loop.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters (query, kind, limit, customer_id) are already documented in the schema; baseline is 3. The description adds minor value by giving example query terms ('running', 'insurance', 'travel') and noting English matching, but adds no syntax or format detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (find) and resource (Google's in-market and affinity segments) and clarifies the payload value: returning the segment_id to attach. It further defines the two segment kinds, so the agent knows exactly what is being looked up. It does not explicitly differentiate itself from similar siblings such as get_audience_lists or draft_audience_attachment, so it stops short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'with the segment_id to attach' implies this is a discovery step feeding an attachment workflow, which is light usage guidance. However, there is no explicit when-to-use, when-not, or named alternative versus get_audience_lists or search_reddit_targeting. Usage is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_reddit_targetingSearch Reddit targetingA
Read-only
Inspect

Look up targeting options for draft_reddit_ad_group.

Returns ids/names to pass into the targeting lists, with the kind, the query and the total number of matches. Communities target by name, interests by id, geolocations by id (e.g. "DE" or "DE:2874225"), languages by code (e.g. "DE"), carriers by id (e.g. "O2_DEUTSCHLAND"). Devices come back as make/model pairs for the label_map of a device target. Keyword suggestions carry Reddit-wide monthly views, not search volume.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
kindYesWhat to look up: "communities" (subreddits; query required), "interests" (query filters by name), "geolocations" (country ISO code and/or city query), "languages" (upper-case ISO 639-1 codes), "keywords" (comma-separated seed terms → suggestions with Reddit-wide monthly views), "community_suggestions" (Reddit's related-community picks for seed communities in query and/or a website_url), "devices" (device makes and models; query filters by make or model) or "carriers" (mobile carrier ids; query filters by name, country by country code).
limitNoMaximum number of results, clamped to 1-100.
queryNoSearch text for the chosen kind: a community search term, an interest or language name filter, a city name, comma-separated seed keywords, comma-separated seed communities for community_suggestions (e.g. "PPC,googleads"), a device make or model filter, or a carrier name filter.
countryNoCountry ISO code (e.g. "DE") for kinds "geolocations" and "carriers"; ignored for other kinds.
website_urlNoWebsite for kind "community_suggestions"; ignored for other kinds.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only/non-destructive/open-world, so safety is covered. The description adds genuine value beyond that: it discloses the return shape (ids/names plus kind, query, total matches), how each kind is keyed (communities by name, interests by id, languages by code, carriers by id, devices as make/model pairs), and the "monthly views not search volume" caveat for keywords.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads purpose, then methodically walks through the return format and per-kind key conventions in a compact block. The kind-by-kind list is somewhat dense but each clause carries distinct information and the API doc link is a useful pointer.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 5-parameter, fully-covered schema with an output schema, this is essentially complete: the agent knows what it searches, what comes back, and how to feed results into targeting lists. Minor absence of pagination/rate-limit notes, but nothing blocking.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the kind enum values are exhaustively documented in the schema, so the description largely restates that mapping (name/id/code conventions). Baseline 3 is appropriate; it adds little parameter detail the schema does not already contain.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb ("Look up") and resource ("targeting options") and scopes it to "draft_reddit_ad_group", making clear this populates ad-group targeting rather than reporting on existing audiences. It is cleanly distinguished from data-retrieval siblings like get_reddit_audiences or get_demographic_targeting.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explains the workflow context ("Returns ids/names to pass into the targeting lists") so an agent knows this is a pre-draft lookup step feeding draft_reddit_ad_group. It does not name alternatives or state exclusions, but the intended usage is clear.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

suggest_brandsSuggest brandsA
Read-only
Inspect

Resolve a brand name to the brands Google recognizes for it.

Mirrors the brand picker in the Google Ads UI (BrandSuggestionService.SuggestBrands): takes a free-text name such as "EscapeGame München" or "NoWayOut" and returns the matching brands with their ID, display name, state, and associated URLs.

The returned brand ID is the Commercial Knowledge Graph ID. Brand criteria — brand lists, brand exclusions — target that ID, not a display name, so a name is resolved here before it can go into a brand list.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
customer_idNoAds account ID. Defaults to the configured account.
brand_prefixYesThe brand name to look up, free text (e.g. "NoWayOut").
selected_brand_idsNoCommercial Knowledge Graph MIDs already picked, handed back so Google keeps them in the suggestion set while the prefix narrows. Optional.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=true, destructiveHint=false, so the safety profile is covered. The description adds real context beyond that: it discloses the return payload (ID, display name, state, URLs), explains that the ID is a Commercial Knowledge Graph ID, and clarifies the purpose of selected_brand_ids as keeping picked brands in the set.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then supporting detail in descending importance. Slightly padded by the API docs URL and a repeated restatement of the brand-criteria/ID relationship, but nothing is misleading or wasted at length.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value explanation is not strictly required, and annotations carry the safety profile. The description nonetheless covers the resolve-then-use-in-brand-list workflow adequately; only pagination/result-count behavior and any ambiguity-handling for fuzzy matches are left unstated.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description goes beyond it: it explains that selected_brand_ids are Commercial Knowledge Graph MIDs that must be handed back so Google retains them while the prefix narrows, and it gives concrete free-text examples for brand_prefix. This is genuine added meaning over the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource: 'Resolve a brand name to the brands Google recognizes for it,' with the concrete operation (BrandSuggestionService.SuggestBrands) and returned fields named. It implicitly separates itself from brand-list readers (get_brand_list_brands) by stating the resolved ID is what brand lists target, but it never names a sibling directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clear context is given: a free-text name must be resolved here before it can go into a brand list, which situates the tool in the brand-list workflow. However, no explicit when-not-to-use or named alternative (e.g. check_brand_names vs this tool) is offered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_ad_groupDraft ad group changesAInspect

Draft an ad group update for name and/or manual CPC bid — returns a PREVIEW.

A bid change applies only when the campaign uses MANUAL_CPC: automated bidding strategies ignore ad-group CPC bids, so such a change is refused (for Maximize Clicks the campaign cpc_bid_ceiling, set through update_campaign, is the active constraint). Bid increases above the configured safety.max_bid_increase_pct are refused. Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
max_cpcNoNew maximum CPC bid in the account's currency (an amount, not micros). 0 leaves the bid unchanged; negative values are rejected. At least one of ad_group_name or max_cpc is required.
ad_group_idYesNumeric ID of the ad group to update.
customer_idNoGoogle Ads customer ID (digits, dashes optional). Defaults to the configured account.
ad_group_nameNoNew ad group name. Empty leaves the name unchanged.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only cover the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true); the description goes well beyond them by disclosing the preview/plan_id/confirm workflow, the MANUAL_CPC precondition, refusal of increases above safety.max_bid_increase_pct, and the Google Ads API reference. Nothing contradicts the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core action and the PREVIEW outcome in one sentence, then layers conditional rules compactly. The Maximize Clicks parenthetical is dense but earns its place by routing to update_campaign; the API URL is mildly superfluous.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a preview-then-confirm mutation with an output schema (plan_id) and full annotation coverage, the description supplies everything needed: preconditions, refusal cases, safety cap, and the follow-up confirm step. No material gaps remain.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% so the schema already defines max_cpc, ad_group_id, customer_id and ad_group_name, making 3 the baseline. The description adds genuine meaning on top: the MANUAL_CPC-only applicability of max_cpc, the safety.max_bid_increase_pct refusal threshold, and the name/bid pairing — all absent from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (draft an update), a specific resource (ad group), and the exact mutable fields (name and/or manual CPC bid), plus the key behavioral fact that it returns a preview rather than applying changes. It is clearly separable from draft_ad_group (creation) and update_campaign (which it explicitly names for the cpc_bid_ceiling case).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit when-not conditions: a bid change only applies under MANUAL_CPC, is refused under automated bidding, and the relevant alternative for Maximize Clicks is update_campaign's cpc_bid_ceiling. It also states the sequencing rule — nothing changes until confirm_and_apply applies the plan_id.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_campaignDraft campaign changesAInspect

Draft an update to an existing campaign — returns a PREVIEW, does NOT apply.

Only the parameters passed are changed; omitted ones stay as they are, and at least one change is required. Replacing geo targets keeps the campaign's negative geo exclusions (the preview lists them).

Returns a preview with a plan_id plus any warnings; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
max_cpcNoMaximize Clicks CPC cap in the account's currency when bidding_strategy is TARGET_SPEND, or when the existing campaign already uses TARGET_SPEND. Increases are limited by the config's max_bid_increase_pct. 0 leaves it unchanged.
target_cpaNoTarget CPA in the account's currency; required if bidding_strategy is TARGET_CPA. 0 leaves it unchanged.
campaign_idYesThe numeric ID of the campaign to update (required).
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
target_roasNoTarget ROAS as a ratio (e.g. 4.0 = 400%); required if bidding_strategy is TARGET_ROAS. 0 leaves it unchanged.
daily_budgetNoNew daily budget in the account's currency (not micros), at most the config's max_daily_budget. 0 leaves it unchanged.
language_idsNoREPLACES all language targets; must not be empty when given. Common IDs: "1001" German, "1000" English, "1002" French, "1003" Spanish, "1004" Italian.
geo_target_idsNoREPLACES all positive geo targets; must not be empty when given. Common IDs: "2276" Germany, "2040" Austria, "2756" Switzerland, "2840" USA, "2826" UK.
bidding_strategyNoMAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS | MAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC. Empty leaves the strategy unchanged.
display_network_enabledNoEnable Search campaign display expansion. Omitted leaves the setting unchanged.
search_partners_enabledNoInclude ads on Search partners. Omitted leaves the setting unchanged.
display_expansion_enabledNoAlias for display_network_enabled; both must match when both are given.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.7/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: partial-update semantics ('only parameters passed are changed; omitted ones stay'), the at-least-one-change rule, non-destructive preview behavior, and the non-obvious side effect that replacing geo targets preserves negative geo exclusions (surfaced in the preview). The readOnlyHint=false / destructiveHint=false pair is consistent with a draft that stores a plan_id without applying changes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, each earning its place, with the most decision-critical fact (preview, does not apply) front-loaded. The trailing API doc link is the only mild filler but does not dilute the structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, but the description still usefully summarizes the return (plan_id plus warnings) and clarifies the confirm step. Combined with 100% schema coverage and annotations, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the schema carries the per-parameter detail (defaults, 0-leaves-unchanged, ID examples), setting the baseline at 3. The description adds a genuine cross-parameter rule ('only the parameters passed are changed') and the geo-replacement/negative-exclusion interaction that the schema does not state, lifting it above baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft an update to an existing campaign') and immediately front-loads the critical scope fact that it returns a PREVIEW and does NOT apply. This clearly distinguishes it from confirm_and_apply and from the draft_campaign creation siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly names the alternative that completes the workflow ('nothing changes until confirm_and_apply applies it'), which routes the agent correctly. It also states the at-least-one-change requirement. It stops short of naming the opposite case (creating a new campaign via draft_campaign) as a when-not-to-use, so it's not a full 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_reddit_adDraft Reddit ad changesAInspect

Draft changes to a Reddit ad — name, landing URL (click_url), comments on/off.

The headline and body of a live Reddit post cannot be edited; new copy means a new ad via draft_reddit_ad, with the old ad paused. Returns a preview with a plan_id showing old → new; nothing changes until confirm_and_apply executes it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew ad name; empty keeps the current one.
ad_idYesReddit ad id (from get_reddit_ads).
click_urlNoNew landing URL (http:// or https://), verified to be reachable. TEXT (free-form) ads open the post itself and take no click_url.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
allow_commentsNotrue or false turns comments on the ad's post on or off; omitted leaves them unchanged.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations cover the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true), and the description adds value beyond that: it discloses the two-phase draft/confirm model, that a preview with a plan_id is returned showing old → new, and that no mutation occurs until confirm_and_apply. This is exactly the behavioral context an agent needs for a staging tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then the key constraint, then the confirm workflow — every paragraph earns its place. The trailing Reddit Ads API documentation URL is mildly extraneous but harmless as a reference.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, yet the description still usefully characterizes the return (preview with plan_id). Combined with the workflow and editability constraints, an agent has everything needed to call this correctly in a multi-step Reddit ad update.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all five parameters are fully documented in the schema itself (including the TEXT-ad click_url caveat). The description restates name/click_url/comments but adds no syntax or format detail beyond the schema, so the baseline 3 for high coverage applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Draft changes to a Reddit ad') plus the editable field set (name, click_url, comments). It explicitly distinguishes itself from the sibling draft_reddit_ad by explaining that new copy requires a new ad, so an agent can route correctly without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit when-to-use-this-vs-alternative rule: editable fields go here, but headline/body edits require draft_reddit_ad plus pausing the old ad. It also states the follow-up requirement (nothing applies until confirm_and_apply), so the agent knows the full workflow.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_reddit_ad_groupDraft Reddit ad group changesAInspect

Draft changes to a Reddit ad group — budget, bid, run dates, weekly schedule, targeting.

Budget (daily_budget or lifetime_budget + end_time) is checked against max_daily_budget; bid_value against max_bid_increase_pct. Targeting lists REPLACE the current value of each key passed (each takes the full list); omitted keys are preserved. Ids/names come from search_reddit_targeting. Budget and schedule of an ad group in a campaign-budget-optimization campaign are set on the campaign (update_reddit_campaign). Returns a preview with a plan_id showing old → new per field; nothing changes until confirm_and_apply applies it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew ad group name; empty keeps the current one.
genderNoFEMALE or MALE; empty leaves gender targeting unchanged.
devicesNoFull list of device targets, objects like {"type": "MOBILE", "os": "IOS", "min_version": "16"} (type DESKTOP or MOBILE; optional os ANDROID or IOS, major OS versions with iOS at least 14, and label_map {make: [models]} with makes/models from search_reddit_targeting kind "devices"). [] clears it (every device).
bid_typeNoCPC, CPM, CPV, CPV6 or CPV15.
carriersNoFull list of mobile carrier ids (from search_reddit_targeting kind "carriers", e.g. "O2_DEUTSCHLAND"), checked against Reddit's carrier list. [] clears it.
end_timeNoNew end, same formats as start_time.
keywordsNoFull list of keywords to target.
scheduleNoWeekly delivery windows ("time of day" in Ads Manager), a list of blocks like {"days": "MON-FRI", "start_hour": 13, "end_hour": 23} (day names, hours 0-23, end_hour inclusive) or the native {"start_day": "FRI", "start_hour": 22, "end_day": "SAT", "end_hour": 3}. [] clears it (deliver at any time). Hours apply in each viewer's local time, not the account time zone.
bid_valueNoNew bid in account currency.
interestsNoFull list of interest ids to target.
languagesNoFull list of language codes (ISO 639-1, upper-cased automatically, e.g. "DE").
locationsNoPlacements, FEED and/or COMMENTS_PAGE (conversation pages); cannot be an empty list.
platformsNoFull list of platforms: ALL, DESKTOP, DESKTOP_LEGACY, MOBILE_NATIVE, MOBILE_WEB, MOBILE_WEB_3X or SHREDTOP.
start_timeNoNew start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare YYYY-MM-DD means 00:00 UTC that day.
view_modesNoFull list of feed layouts: ALL, CARD, CLASSIC, COMPACT or IMMERSIVE. [] clears it.
ad_group_idYesReddit ad group id (from get_reddit_ad_groups).
communitiesNoFull list of community (subreddit) names to target.
bid_strategyNoBIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX.
daily_budgetNoNew daily budget in account currency (positive). Mutually exclusive with lifetime_budget; the budget type (daily vs lifetime) cannot change after publishing.
geolocationsNoFull list of geolocation ids to target (e.g. "DE" or "DE:2874225").
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
lifetime_budgetNoNew lifetime budget in account currency (positive). Needs an end_time (passed or already set); compared to max_daily_budget by its per-day share.
expand_targetingNoWhether Reddit may expand delivery beyond the targeting; omitted leaves it unchanged.
excluded_keywordsNoFull list of keywords to exclude.
excluded_interestsNoFull list of interest ids to exclude (Reddit marks this field deprecated). [] clears it.
custom_audience_idsNoFull list of custom audiences to target (from get_reddit_audiences). It narrows the ad group to those people. [] clears it.
excluded_communitiesNoFull list of community names to exclude.
excluded_geolocationsNoFull list of geolocation ids to exclude.
excluded_custom_audience_idsNoFull list of custom audiences to exclude, e.g. existing customers. [] clears it.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only carry the safety profile (readOnlyHint=false, destructiveHint=false, openWorldHint=true); the description adds the substance: validation against max_daily_budget and max_bid_increase_pct, list-replacement semantics, and the preview/plan_id staging model. That staging behavior is the single most important thing to know and it is stated plainly, consistent with destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with a one-line summary, then constraint and workflow detail in compact clauses; little is wasted given 29 parameters. It is dense but every sentence (validation caps, replace semantics, campaign routing, staging) carries operational weight. Slightly heavy for a single prose block.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers the full lifecycle an agent needs: where targeting ids come from, the replace/preserve rule, the validation constraints, the campaign-level exception, and the preview→confirm_and_apply handoff. With an output schema present, return-format details are correctly left out, and the docs link closes the loop.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning on top: budget mutual exclusivity and per-day comparison for lifetime budgets, the REPLACE-vs-preserved rule for all list parameters, and validation caps. It doesn't restate per-param enum values, which the schema handles.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb and resource ('Draft changes to a Reddit ad group') and enumerates the mutability surface: budget, bid, run dates, weekly schedule, targeting. It clearly differentiates from update_reddit_campaign for the campaign-budget-optimization case. The only gap is that it doesn't disambiguate from the sibling 'draft_reddit_ad_group' (create vs. update), which a reader must infer from the 'changes to an ad group' phrasing.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicit routing conditions are given: budget/schedule for a campaign-budget-optimization campaign must go through update_reddit_campaign, targeting ids/names come from search_reddit_targeting, and the change is inert until confirm_and_apply applies the plan_id. It also states the replace-vs-preserve rule for omission, so the agent knows how to invoke it in the right sequence.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_reddit_campaignDraft Reddit campaign changesAInspect

Draft changes to a Reddit campaign — name, run dates, spend cap, and (CBO only) budget/bid/schedule.

daily_budget / lifetime_budget / bid_* / schedule apply only when the campaign uses campaign budget optimization; otherwise the budget lives on its ad groups (changed via update_reddit_ad_group). Budgets are in account currency and checked against max_daily_budget; bid_value against max_bid_increase_pct. Returns a preview with a plan_id showing old → new per field; nothing changes until confirm_and_apply applies it.

Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault
nameNoNew campaign name; empty keeps the current one.
bid_typeNoCPC, CPM, CPV, CPV6 or CPV15 (CBO only).
end_timeNoNew end, same formats as start_time.
scheduleNoWeekly delivery windows ("time of day" in Ads Manager; CBO only), a list of blocks like {"days": "MON-FRI", "start_hour": 13, "end_hour": 23} (day names, hours 0-23, end_hour inclusive) or the native {"start_day": "FRI", "start_hour": 22, "end_day": "SAT", "end_hour": 3}. [] clears it (deliver at any time). Hours apply in each viewer's local time, not the account time zone. A campaign schedule replaces every ad group's.
bid_valueNoNew bid in account currency (CBO only).
spend_capNoCampaign spend cap in account currency; 0 removes it.
start_timeNoNew start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare YYYY-MM-DD means 00:00 UTC that day.
campaign_idYesReddit campaign id (from get_reddit_campaigns).
bid_strategyNoBIDLESS, MAXIMIZE_VOLUME or TARGET_CPX (CBO only).
daily_budgetNoNew daily budget in account currency (positive; CBO only). Mutually exclusive with lifetime_budget; the budget type (daily vs lifetime) cannot change after publishing.
ad_account_idNoReddit ad account id (from list_reddit_accounts). Empty uses reddit.ad_account_id from the config.
lifetime_budgetNoNew lifetime budget in account currency (positive; CBO only). Needs an end_time (passed or already set); compared to max_daily_budget by its per-day share.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: it discloses that this is a staged/draft operation returning a plan_id preview with old → new per field, that nothing commits until confirm_and_apply, that budgets are in account currency and validated against max_daily_budget, and that bid_value is checked against max_bid_increase_pct. It also warns that a campaign schedule replaces every ad group's schedule. This reconciles nicely with readOnlyHint=false / destructiveHint=false by clarifying the two-step draft-then-apply flow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded one-line summary followed by two tight paragraphs covering conditionality, validation, and the confirm flow. Every sentence carries signal, with only the API docs link being mild filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 12-parameter mutation tool with an output schema, the description supplies the CBO conditionality, currency/unit semantics, validation limits, and the draft-to-apply lifecycle. Combined with the existing output schema and annotations, an agent has everything needed to invoke it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already 100%, so the baseline is 3, but the description adds real meaning on top: it flags which parameters are CBO-only, the account-currency unit, and the validation limits each value is checked against. It does not restate every field, which is appropriate given the detailed schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource ('Draft changes to a Reddit campaign') and enumerates the mutable field families (name, run dates, spend cap, CBO budget/bid/schedule). It also positions itself against the sibling update_reddit_ad_group by noting where budget lives when CBO is not used, so an agent can distinguish it without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly states the condition that gates the CBO-only fields and redirects non-CBO budget edits to update_reddit_ad_group, plus that confirm_and_apply is the step that actually commits. It lacks an explicit contrast against the similarly named draft_reddit_campaign sibling, so routing isn't fully unambiguous, but the usage context is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_responsive_search_adUpdate a responsive search adAInspect

Update mutable fields on an existing RSA in place — returns a PREVIEW.

Edits an existing RSA without creating a new ad; the ad keeps its ID. Google Ads API v23 (AdService.MutateAds) permits in-place mutation of final_urls, path1, path2, headlines, and descriptions. At least one mutation must be requested.

IMPORTANT: replacing headlines or descriptions is NOT a free in-place edit. Even though the ad ID is preserved, swapping the creative text RESETS the ad's asset-combination learning and performance history and sends the ad BACK THROUGH Google policy review — Google treats the creative as new for optimization. URL-only and path-only edits do not incur this. When headlines/descriptions change, the returned preview includes a warnings entry stating this trade-off before anything is applied.

Returns a preview with a plan_id; nothing changes until confirm_and_apply applies it.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
ad_idYesNumeric ID of the existing responsive search ad.
path1NoEmpty means no change; non-empty sets the first display path (max 15 chars).
path2NoEmpty means no change; non-empty sets the second display path (max 15 chars).
final_urlNoEmpty means no change; non-empty replaces the final URL and is checked for reachability.
headlinesNoLIST-REPLACE: None or [] means no change; a non-empty list fully swaps in for the existing headlines. Google's RSA constraints apply: 3-15 headlines, max 30 chars each, every pin position fillable. Each entry is a plain string (unpinned) or {"text": "...", "pinned_field": "HEADLINE_1"} (HEADLINE_1-3). Insertion tags such as {KeyWord:Clogged Drain Service} count as their default text, which is required.
clear_path1NoTrue sets path1 to an empty string (overrides path1).
clear_path2NoTrue sets path2 to an empty string (overrides path2).
customer_idNoGoogle Ads customer ID (digits, e.g. "1234567890"). Empty uses the configured default account.
descriptionsNoLIST-REPLACE: None or [] means no change; a non-empty list fully swaps in. 2-4 descriptions, max 90 chars each, pins to DESCRIPTION_1 or DESCRIPTION_2 with every position fillable. Same entry format and insertion-tag counting as headlines.

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: despite destructiveHint=false, it discloses that swapping headlines/descriptions resets asset-combination learning and sends the ad back through policy review, while URL/path edits do not — a critical side effect the annotations do not convey. It also explains the preview-with-plan_id staging semantics and the returned warnings entry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the in-place edit plus return type, then trade-offs under an IMPORTANT marker, then the confirm flow. Slightly repetitive (the preview is stated at the top and again at the end) and the trailing API doc URL adds little, but the structure is easy to scan.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present, the description needn't document return values, and it correctly focuses on the mutation constraints, side effects, and staging flow instead. Annotations cover safety, schema covers parameters; nothing material is missing for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema carries the field semantics (baseline 3). The description adds a genuine cross-parameter constraint the schema cannot express — at least one mutation must be requested — and corroborates which fields are in-place mutable (final_urls, path1, path2, headlines, descriptions).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb+resource (update mutable fields on an existing RSA) and distinguishes itself from the create path by stating 'without creating a new ad; the ad keeps its ID.' The scope is further pinned by naming the exact mutable fields, so an agent can separate this from draft_responsive_search_ad without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear conditions of use: 'At least one mutation must be requested,' which fields are permitted, and the required preview-then-confirm_and_apply workflow. It doesn't explicitly name a sibling alternative for the create case, but the when/why is unambiguous for this tool.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

upload_conversion_csvUpload a conversion CSV
Read-only
Inspect

Let the user upload a conversion CSV for an offline conversion upload.

For the CSV behind draft_upload_call_conversions or draft_upload_enhanced_conversions_for_leads when the file is not on the machine running AdLoop, as on AdLoop Cloud. Apps that show AdLoop's cards display an upload card where the user drops the .csv file; the card then posts the upload id into the chat. Other apps on AdLoop Cloud get an upload link for the user (or a coding agent, with curl). The file holds personal data (phone numbers, emails), so it is kept for two hours at most and deleted as soon as a draft has read it. Returns the CSV uploads waiting to be used and how to add one.

Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

upload_imagesUpload imagesA
Read-only
Inspect

Let the user upload images (PNG, JPEG, GIF up to 5 MB) for ad assets.

For images without a public URL, such as a file on the user's computer or an image attached in the chat. An attached image cannot reach a tool, so the user drops the same file on the card. Apps that show AdLoop's cards display an upload card where the user drops the files; the card then posts the upload ids into the chat. On AdLoop Cloud in other apps the result carries an upload link for the user (or a coding agent, with curl). Uploads expire after a day. The ids go into upload_ids of draft_image_assets, or as "upload:" into the image fields of draft_reddit_ad. Returns the current uploads and how to add more.

Google Ads API: https://developers.google.com/google-ads/api/docs/start, Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Reddit Ads API: https://ads-api.reddit.com/docs/v3/

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses valuable behavior: supported formats, a 5 MB cap, that uploads expire after a day, where the ids must be placed, and that the result carries an upload link for non-card contexts. It adds real context on top of readOnlyHint/openWorldHint. The only friction is a mild tension between 'upload' and readOnlyHint=true, though the card-mediated, ephemeral nature makes it defensible rather than a clear contradiction.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and constraints are front-loaded effectively in the first paragraph, but the block is long and meandering. The trailing sentence listing Google Ads, Google Analytics Data, and Reddit Ads API documentation links is unrelated to uploading images and reads as boilerplate, diluting focus.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, and the description still risks little. It covers formats, size, expiration, the card mechanism, and id placement, which is enough for an agent to call a parameterless tool correctly. A brief note on what happens on failure would close the remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4. The description still usefully characterizes the input surface (PNG/JPEG/GIF, 5 MB limit, public-URL vs. local-file distinction), which is meaningful given there is no schema to convey any of it.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence gives a specific verb and resource with concrete constraints: 'upload images (PNG, JPEG, GIF up to 5 MB) for ad assets.' It also clarifies the tool's place in the pipeline by naming where the resulting ids are consumed (upload_ids of draft_image_assets, image fields of draft_reddit_ad). It stops short of an explicit 'use this instead of draft_image_assets' contrast, so it is clear but not fully sibling-differentiating.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear when-to-use condition: 'For images without a public URL, such as a file on the user's computer or an image attached in the chat.' It also explains the surrounding workflow (card drops files, card posts ids into chat). There is no explicit when-not-to-use or named alternative, so it is clear context without exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

validate_trackingValidate trackingA
Read-only
Inspect

Compare tracking events found in the codebase against actual GA4 data.

Takes the event names found in the codebase's gtag('event', ...) or dataLayer.push calls and checks which ones actually fire in GA4.

Returns matched events with their GA4 counts, events missing from GA4, unexpected GA4 events, auto-collected events (page_view, session_start, etc.), insights on likely causes, and the date range.

Google Analytics Data API: https://developers.google.com/analytics/devguides/reporting/data/v1 and Google Ads API: https://developers.google.com/google-ads/api/docs/start

ParametersJSON Schema
NameRequiredDescriptionDefault
property_idNoGA4 property as "properties/123456789" (see get_account_summaries). If empty, uses the default from config.
date_range_endNoEnd date, same formats as date_range_start.today
expected_eventsYesEvent names found in the codebase, e.g. ["sign_up", "purchase"].
date_range_startNoStart date: "today", "yesterday", "NdaysAgo" (e.g. "28daysAgo"), or "YYYY-MM-DD".28daysAgo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A3.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and openWorldHint, establishing the safe read profile. The description adds real behavioral context beyond that: it reads gtag('event', ...)/dataLayer.push calls, diffs them against GA4-fired events, and produces "insights on likely causes" — explaining what the comparison actually yields.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded, but the long enumeration of return fields duplicates what the existing output schema already covers, and the trailing API links include an irrelevant Google Ads API reference for a GA4-only tool. Structure is fine; several sentences do not earn their place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With 100% schema coverage and an output schema, the description need not restate parameters or return values, and it is complete enough to call correctly: it covers the input source, the diff behavior, and the date-range output. Missing only explicit sibling routing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema fully documents property_id, date_range_start/end, and expected_events. The description adds no format or syntax detail beyond what the schema already provides, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb and resource ("Compare tracking events found in the codebase against actual GA4 data") and details the mechanism via gtag/dataLayer calls. It is clear, but it never distinguishes itself from the closely-related sibling audit_event_coverage, leaving the agent to infer which one to pick.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is only implied: the agent can infer it runs after extracting event names from a codebase. There is no explicit when-to-use, no exclusions, and no routing to alternatives such as get_tracking_events or audit_event_coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 3 tool updatesv0.33.1
    • Changeddraft_upload_call_conversions4 fields changed
      • addedInput schema / properties / csv_path / default
        Added value: +""
      • changedInput schema / properties / csv_path / description
        Previous value: -"Path of the CSV file holding the upload rows, read on the\nmachine that runs AdLoop. The hosted server refuses this tool\nrather than reading a path of its own."New value: +"Path of the CSV file holding the upload rows, read on the\nmachine that runs AdLoop. Refused on the hosted server; use\nupload_id there."
      • addedInput schema / properties / upload_id
        Added value: +{
        +  "default": "",
        +  "description": "Id of a CSV uploaded with upload_conversion_csv (up_...),\ninstead of csv_path.",
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "csv_path"
        -]
    • Changeddraft_upload_enhanced_conversions_for_leads4 fields changed
      • addedInput schema / properties / csv_path / default
        Added value: +""
      • changedInput schema / properties / csv_path / description
        Previous value: -"Path of the CSV file holding the upload rows, read on the\nmachine that runs AdLoop. The hosted server refuses this tool\nrather than reading a path of its own."New value: +"Path of the CSV file holding the upload rows, read on the\nmachine that runs AdLoop. Refused on the hosted server; use\nupload_id there."
      • addedInput schema / properties / upload_id
        Added value: +{
        +  "default": "",
        +  "description": "Id of a CSV uploaded with upload_conversion_csv (up_...),\ninstead of csv_path.",
        +  "type": "string"
        +}
      • removedInput schema / required
        Removed value: -[
        -  "csv_path"
        -]
    • Addedupload_conversion_csv
  2. 3 tool updatesv0.32.0
    • Changeddraft_delete_gtm_entity2 fields changed
      • changedInput schema / properties / entity_id / description
        Previous value: -"Numeric ID of the entity (see list_gtm_tags and\nlist_gtm_triggers)."New value: +"Numeric ID of the entity (see list_gtm_tags,\nlist_gtm_triggers and list_gtm_variables)."
      • changedInput schema / properties / entity_type / description
        Previous value: -"\"tag\" or \"trigger\"."New value: +"\"tag\", \"trigger\" or \"variable\"."
    • Addeddraft_gtm_variable
    • Changedupdate_responsive_search_ad2 fields changed
      • changedInput schema / properties / descriptions / description
        Previous value: -"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in. 2-4 descriptions, max 90 chars each, at most 1 per\npin slot (DESCRIPTION_1, DESCRIPTION_2). Same entry format and\ninsertion-tag counting as headlines."New value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in. 2-4 descriptions, max 90 chars each, pins to\nDESCRIPTION_1 or DESCRIPTION_2 with every position fillable. Same\nentry format and insertion-tag counting as headlines."
      • changedInput schema / properties / headlines / description
        Previous value: -"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in for the existing headlines. Google's RSA constraints\napply: 3-15 headlines, max 30 chars each, at most 2 per pin slot.\nEach entry is a plain string (unpinned) or {\"text\": \"...\",\n\"pinned_field\": \"HEADLINE_1\"} (HEADLINE_1-3). Insertion tags such as\n{KeyWord:Clogged Drain Service} count as their default text, which\nis required."New value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in for the existing headlines. Google's RSA constraints\napply: 3-15 headlines, max 30 chars each, every pin position fillable.\nEach entry is a plain string (unpinned) or {\"text\": \"...\",\n\"pinned_field\": \"HEADLINE_1\"} (HEADLINE_1-3). Insertion tags such as\n{KeyWord:Clogged Drain Service} count as their default text, which\nis required."
  3. 8 tool updatesv0.29.2
    • Addeddraft_audience_attachment
    • Changeddraft_responsive_search_ad2 fields changed
      • changedInput schema / properties / descriptions / description
        Previous value: -"2-4 descriptions, max 90 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"DESCRIPTION_1\"};\nvalid pins are DESCRIPTION_1, DESCRIPTION_2."New value: +"2-4 descriptions, max 90 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"DESCRIPTION_1\"};\nvalid pins are DESCRIPTION_1, DESCRIPTION_2. Insertion tags count\nas their default text, as for headlines."
      • changedInput schema / properties / headlines / description
        Previous value: -"3-15 headlines, max 30 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"HEADLINE_1\"};\nvalid pins are HEADLINE_1, HEADLINE_2, HEADLINE_3."New value: +"3-15 headlines, max 30 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"HEADLINE_1\"};\nvalid pins are HEADLINE_1, HEADLINE_2, HEADLINE_3. Keyword or\nlocation insertion such as {KeyWord:Drain Cleaning} counts as its\ndefault text, which is required."
    • Addedget_audience_lists
    • Addedget_audience_targeting
    • Addedget_merchant_product_issues
    • Addedget_shopping_product_performance
    • Addedsearch_audience_segments
    • Changedupdate_responsive_search_ad2 fields changed
      • changedInput schema / properties / descriptions / description
        Previous value: -"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in. 2-4 descriptions, max 90 chars each, at most 1 per\npin slot (DESCRIPTION_1, DESCRIPTION_2). Same entry format as\nheadlines."New value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in. 2-4 descriptions, max 90 chars each, at most 1 per\npin slot (DESCRIPTION_1, DESCRIPTION_2). Same entry format and\ninsertion-tag counting as headlines."
      • changedInput schema / properties / headlines / description
        Previous value: -"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in for the existing headlines. Google's RSA constraints\napply: 3-15 headlines, max 30 chars each, at most 2 per pin slot.\nEach entry is a plain string (unpinned) or {\"text\": \"...\",\n\"pinned_field\": \"HEADLINE_1\"} (HEADLINE_1-3)."New value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in for the existing headlines. Google's RSA constraints\napply: 3-15 headlines, max 30 chars each, at most 2 per pin slot.\nEach entry is a plain string (unpinned) or {\"text\": \"...\",\n\"pinned_field\": \"HEADLINE_1\"} (HEADLINE_1-3). Insertion tags such as\n{KeyWord:Clogged Drain Service} count as their default text, which\nis required."
  4. 125 tool updatesv0.27.1
    • Changedadd_negative_keywords4 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign that gets the negatives."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / keywords / description
        Added value: +"Negative keyword texts; at least one is required. All share\nthe same match_type."
      • addedInput schema / properties / match_type / description
        Added value: +"\"EXACT\" (default), \"PHRASE\", or \"BROAD\"."
    • Changedadd_negative_locations3 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign to add the location exclusions to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / geo_target_ids / description
        Added value: +"Numeric Google geo target constant IDs to exclude (e.g.\n\"1001773\"). Duplicates are collapsed; non-numeric IDs are rejected."
    • Addedadd_to_brand_list
    • Changedadd_to_negative_keyword_list4 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / keywords / description
        Added value: +"Keyword strings to append. Blank entries are dropped and\nduplicates in the input list are collapsed (case-insensitive)."
      • addedInput schema / properties / match_type / description
        Added value: +"Match type applied to every keyword: \"EXACT\" (default),\n\"PHRASE\", or \"BROAD\" (case-insensitive)."
      • addedInput schema / properties / shared_set_id / description
        Added value: +"Numeric ID of the list (shared_set.id from\nget_negative_keyword_lists)."
    • Changedanalyze_campaign_conversions5 fields changed
      • addedInput schema / properties / campaign_name / description
        Added value: +"Optional case-insensitive substring; only campaigns\nwhose name contains it are included. Empty = all campaigns."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedanalyze_page_speed2 fields changed
      • addedInput schema / properties / strategy / description
        Added value: +"\"mobile\" (default — most paid traffic) or \"desktop\"."
      • addedInput schema / properties / url / description
        Added value: +"Full URL of the page to analyze, e.g. an ad's final_url\n(\"https://example.com/landing\")."
    • Addedattach_brand_list_to_campaigns
    • Changedattach_shared_set_to_campaigns3 fields changed
      • addedInput schema / properties / campaign_ids / description
        Added value: +"Numeric campaign IDs to attach the set to (at least one).\nBlank entries are dropped and duplicates collapsed."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / shared_set_id / description
        Added value: +"Numeric ID of the shared set (from\nget_negative_keyword_lists)."
    • Changedattribution_check5 fields changed
      • addedInput schema / properties / conversion_events / description
        Added value: +"Optional list of GA4 event names to specifically\ncheck (e.g. [\"sign_up\", \"purchase\"]). If omitted, compares\naggregate totals only."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedaudit_event_coverage6 fields changed
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date \"YYYY-MM-DD\". Empty (or an empty\ndate_range_start) means the last 30 days."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date \"YYYY-MM-DD\". Empty (or an empty\ndate_range_end) means the last 30 days."
      • addedInput schema / properties / expected_events / description
        Added value: +"Distinct event names found in the codebase's\ngtag('event', ...) and dataLayer.push({event: ...}) calls."
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (Tag Manager UI → Admin →\nContainer Settings, or list_gtm_accounts). Empty uses\ngtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (not the GTM-XXXXXXX public\nID; see list_gtm_containers). Empty uses gtm.container_id from the\nconfig."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\". Empty uses the\ndefault from config."
    • Addedcheck_brand_names
    • Changedconfirm_and_apply2 fields changed
      • addedInput schema / properties / dry_run / description
        Added value: +"True (default) validates without changing anything; false\napplies the change for real."
      • addedInput schema / properties / plan_id / description
        Added value: +"The plan_id returned by a prior draft_*, update_*, add_*,\npause/enable/remove or other preview tool call. An unknown or\nexpired plan_id returns an error."
    • Addeddetach_brand_list_from_campaigns
    • Changeddetach_shared_set_from_campaigns3 fields changed
      • addedInput schema / properties / campaign_ids / description
        Added value: +"Numeric campaign IDs to detach the set from (at least one).\nBlank entries are dropped and duplicates collapsed."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / shared_set_id / description
        Added value: +"Numeric ID of the shared set (from\nget_negative_keyword_lists)."
    • Changeddiscover_keywords7 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes allowed). Defaults\nto the configured account."
      • addedInput schema / properties / geo_target_id / description
        Added value: +"Geo target constant ID (2276=Germany, 2840=USA, 2826=UK).\nDefaults to 2276."
      • addedInput schema / properties / include_monthly_volumes / description
        Added value: +"true adds per-month search history (last 24\nmonths, top-20 ideas) plus a seasonality insight — relevant to\nquestions about demand trends, seasonality, or \"when should I ramp\nbudget\"."
      • addedInput schema / properties / language_id / description
        Added value: +"Language constant ID (1000=English, 1001=German,\n1002=French). Defaults to 1000."
      • addedInput schema / properties / page_size / description
        Added value: +"Max keyword ideas to return (default 50, clamped to 1-1000)."
      • addedInput schema / properties / seed_keywords / description
        Added value: +"Seed terms, e.g. [\"running shoes\", \"trail running\"]."
      • addedInput schema / properties / url / description
        Added value: +"A landing page or site URL to extract ideas from, e.g.\n\"https://example.com/products\"."
    • Changeddraft_ad_group5 fields changed
      • addedInput schema / properties / ad_group_name / description
        Added value: +"Name for the new ad group."
      • addedInput schema / properties / campaign_id / description
        Added value: +"The campaign to add the ad group to (numeric ID as returned\nby get_campaign_performance)."
      • addedInput schema / properties / cpc_bid_micros / description
        Added value: +"Optional ad group CPC bid in micros (1,000,000 = one\nunit of the account's currency); only used by MANUAL_CPC campaigns.\n0 means no ad-group bid; must not be negative."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / keywords / description
        Added value: +"Optional list of {\"text\": \"keyword\", \"match_type\":\n\"EXACT|PHRASE|BROAD\"}."
    • Addeddraft_ai_max_settings
    • Addeddraft_asset_group_assets
    • Addeddraft_asset_group_signals
    • Addeddraft_assign_custom_conversion_goal
    • Changeddraft_callouts3 fields changed
      • addedInput schema / properties / callouts / description
        Added value: +"Callout texts (at least one), each non-empty and at most 25\ncharacters after trimming."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign to attach the callouts to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
    • Changeddraft_campaign15 fields changed
      • addedInput schema / properties / ad_group_name / description
        Added value: +"Name of the initial ad group. Empty uses campaign_name."
      • addedInput schema / properties / bidding_strategy / description
        Added value: +"MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS |\nMAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC. BROAD\nkeywords require a Smart Bidding strategy (MAXIMIZE_CONVERSIONS,\nMAXIMIZE_CONVERSION_VALUE, TARGET_CPA, TARGET_ROAS)."
      • addedInput schema / properties / campaign_name / description
        Added value: +"Name of the new campaign."
      • addedInput schema / properties / channel_type / description
        Added value: +"SEARCH (default). DISPLAY, SHOPPING, VIDEO and\nPERFORMANCE_MAX are refused with the reason (see above)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / daily_budget / description
        Added value: +"Daily budget in the account's currency (not micros);\nmust be greater than 0 and at most the config's max_daily_budget."
      • addedInput schema / properties / display_expansion_enabled / description
        Added value: +"Alias for display_network_enabled; both must\nmatch when both are given."
      • addedInput schema / properties / display_network_enabled / description
        Added value: +"Enable Search campaign display expansion\n(SEARCH campaigns only). Defaults to off."
      • addedInput schema / properties / geo_target_ids / description
        Added value: +"REQUIRED list of geo target constant IDs.\nCommon: \"2276\" Germany, \"2040\" Austria, \"2756\" Switzerland, \"2840\" USA,\n\"2826\" UK, \"2250\" France. Full list: Google Ads API geo target constants."
      • addedInput schema / properties / keywords / description
        Added value: +"Optional list of {\"text\": \"keyword\", \"match_type\":\n\"EXACT|PHRASE|BROAD\"} added to the initial ad group."
      • addedInput schema / properties / language_ids / description
        Added value: +"REQUIRED list of language constant IDs.\nCommon: \"1001\" German, \"1000\" English, \"1002\" French, \"1003\" Spanish,\n\"1004\" Italian, \"1014\" Portuguese. Full list: Google Ads API\nlanguage constants."
      • addedInput schema / properties / max_cpc / description
        Added value: +"In the account's currency: the manual CPC bid for the initial\nad group when bidding_strategy is MANUAL_CPC, or the Maximize Clicks\nCPC cap when bidding_strategy is TARGET_SPEND. Not allowed with\nother strategies; 0 means none."
      • addedInput schema / properties / search_partners_enabled / description
        Added value: +"Include ads on Search partners (SEARCH\ncampaigns only)."
      • addedInput schema / properties / target_cpa / description
        Added value: +"Target cost per acquisition in the account's currency;\nrequired if bidding_strategy is TARGET_CPA, optional target for\nMAXIMIZE_CONVERSIONS. 0 means none."
      • addedInput schema / properties / target_roas / description
        Added value: +"Target return on ad spend as a ratio (e.g. 4.0 = 400%);\nrequired if bidding_strategy is TARGET_ROAS, optional target for\nMAXIMIZE_CONVERSION_VALUE. 0 means none."
    • Addeddraft_clear_custom_conversion_goal
    • Changeddraft_create_conversion_action14 fields changed
      • addedInput schema / properties / always_use_default_value / description
        Added value: +"True ignores transaction values from the\ntag/import and always uses default_value; False uses default_value\nonly as a fallback when no value is supplied."
      • addedInput schema / properties / attribution_model / description
        Added value: +"AttributionModel enum value, e.g.\nGOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN. Empty leaves Google's default."
      • addedInput schema / properties / category / description
        Added value: +"ConversionActionCategory enum value, e.g. PHONE_CALL_LEAD,\nSUBMIT_LEAD_FORM, PURCHASE, ... (default DEFAULT)."
      • addedInput schema / properties / click_through_window_days / description
        Added value: +"Click-through attribution window in days,\n1-90. 0 leaves Google's default."
      • addedInput schema / properties / counting_type / description
        Added value: +"ONE_PER_CLICK (default; one conversion per click, typical\nfor lead gen) or MANY_PER_CLICK (every conversion counts, typical\nfor ecommerce)."
      • addedInput schema / properties / currency_code / description
        Added value: +"3-letter ISO 4217 currency code for default_value\n(default USD)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes allowed). Defaults\nto the configured account."
      • addedInput schema / properties / default_value / description
        Added value: +"Value attributed to each conversion, in currency_code\nunits (not micros). Must be >= 0. A positive default_value with\nalways_use_default_value=False is a legal \"fallback\" config: the\npreview warns but does NOT flip the flag."
      • addedInput schema / properties / include_in_conversions_metric / description
        Added value: +"IMMUTABLE on create — Google derives it\nfrom the category, so this value is not sent; change it later via\ndraft_update_conversion_action."
      • addedInput schema / properties / name / description
        Added value: +"Conversion action name as it appears in Google Ads. Required."
      • addedInput schema / properties / phone_call_duration_seconds / description
        Added value: +"Minimum call length in seconds for a call\nto count; only meaningful for call conversions (PHONE_CALL_LEAD\ncategory). 0 leaves Google's default."
      • addedInput schema / properties / primary_for_goal / description
        Added value: +"True (default) makes it a Primary action that Smart\nBidding optimizes toward; False makes it Secondary (recorded only)."
      • addedInput schema / properties / type_ / description
        Added value: +"ConversionActionType enum value, e.g. AD_CALL, WEBSITE_CALL,\nWEBPAGE, WEBPAGE_CODELESS, GOOGLE_ANALYTICS_4_CUSTOM,\nGOOGLE_ANALYTICS_4_PURCHASE, UPLOAD_CALLS, UPLOAD_CLICKS."
      • addedInput schema / properties / view_through_window_days / description
        Added value: +"View-through attribution window in days,\n1-30. 0 leaves Google's default."
    • Addeddraft_custom_conversion_goal
    • Addeddraft_delete_gtm_entity
    • Addeddraft_delete_key_event
    • Changeddraft_demographic_targeting8 fields changed
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Numeric ad group ID to add the criteria to. Mutually\nexclusive with campaign_id."
      • addedInput schema / properties / age_ranges / description
        Added value: +"Age buckets '18-24', '25-34', '35-44', '45-54', '55-64',\n'65+', 'undetermined' (or canonical names such as AGE_RANGE_18_24).\nGoogle's buckets are FIXED — 'Exclude 23-35' has no exact mapping\nand needs a choice of buckets."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric campaign ID to add the criteria to. Mutually\nexclusive with ad_group_id; campaign-level criteria can only be\nexclusions (negative=True)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / genders / description
        Added value: +"'female', 'male', 'undetermined'."
      • addedInput schema / properties / income_ranges / description
        Added value: +"PERCENTILES (not currency): 'top-10', '11-20', '21-30',\n'31-40', '41-50', 'lower-50', 'undetermined'. Available in select\ncountries only (US, AU, JP, etc.)."
      • addedInput schema / properties / negative / description
        Added value: +"True (default) excludes the listed segments; False adds\npositive criteria that narrow an ad group's targeting to them."
      • addedInput schema / properties / parental_statuses / description
        Added value: +"'parent', 'not_a_parent', 'undetermined'."
    • Addeddraft_gtm_tag
    • Addeddraft_gtm_trigger
    • Changeddraft_image_assets7 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign to attach the images to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / image_paths / default
        Added value: +[]
      • addedInput schema / properties / image_paths / description
        Added value: +"Local PNG/JPEG/GIF file paths on the machine running\nAdLoop. Not available on a hosted server, where image_urls\napplies instead."
      • addedInput schema / properties / image_urls
        Added value: +{
        +  "default": [],
        +  "description": "Public http(s) URLs of PNG/JPEG/GIF images. Links to\nprivate, local or internal addresses are refused.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • addedInput schema / properties / upload_ids
        Added value: +{
        +  "default": [],
        +  "description": "Ids of images the user uploaded (up_..., from\nupload_images or list_uploads). The way to use an image that has\nno public URL.",
        +  "items": {
        +    "type": "string"
        +  },
        +  "type": "array"
        +}
      • changedInput schema / required
        Previous value: -[
        -  "campaign_id",
        -  "image_paths"
        -]New value: +[
        +  "campaign_id"
        +]
    • Changeddraft_key_event3 fields changed
      • addedInput schema / properties / counting_method / description
        Added value: +"ONCE_PER_EVENT (counts every occurrence, e.g.\npurchases) or ONCE_PER_SESSION (counts once per session, e.g.\nsign-ups). Defaults to ONCE_PER_EVENT."
      • addedInput schema / properties / event_name / description
        Added value: +"Name of the GA4 event to mark as a key event, exactly as it\nfires (e.g. \"sign_up\", \"purchase\"). Required."
      • addedInput schema / properties / property_id / description
        Added value: +"Numeric GA4 property ID, with or without the \"properties/\"\nprefix. If empty, uses the default from config."
    • Changeddraft_keywords3 fields changed
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Numeric ID of the ad group that gets the keywords."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / keywords / description
        Added value: +"List of {\"text\": \"keyword phrase\", \"match_type\":\n\"EXACT|PHRASE|BROAD\"}; at least one is required."
    • Addeddraft_pmax_product_exclusions
    • Addeddraft_prepare_brand_exclusions
    • Addeddraft_publish_gtm_workspace
    • Changeddraft_reddit_ad16 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Reddit ad group id (from get_reddit_ad_groups)."
      • addedInput schema / properties / ad_name / description
        Added value: +"Ad name; empty uses the headline. Truncated to 200\ncharacters."
      • addedInput schema / properties / allow_comments / description
        Added value: +"Whether Redditors can comment publicly on the ad\n(default true); false disables them."
      • addedInput schema / properties / body / description
        Added value: +"Post body text, up to 40,000 characters. Optional for media\nposts."
      • addedInput schema / properties / call_to_action / description
        Added value: +"One of Reddit's fixed labels for media posts: Apply\nNow, Book Now, Buy Tickets, Contact Us, Donate Now, Download, Get\na Quote, Get Directions, Get Showtimes, Install, Learn More,\nListen Now, Order Now, Play Now, Pre-order Now, Read More, Remind\nMe, See Menu, Shop Now, Sign Up, Subscribe, View More, Visit\nStore, Watch Now. On a carousel it is the default for every card."
      • addedInput schema / properties / carousel_cards
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "For CAROUSEL posts, 2 to 6 cards, each\n{\"image_url\": \"...\", \"caption\": \"...\", \"click_url\": \"...\",\n\"call_to_action\": \"...\"}. Only image_url is required; caption is\nat most 180 characters, click_url and call_to_action default to\nthe ad's."
        +}
      • addedInput schema / properties / click_url / description
        Added value: +"Landing page (http:// or https://). Required for a new\npost. TEXT posts open themselves, so the full click_url must also\nappear in body. With post_id, TEXT posts take no click_url and\nmedia posts default it to the post's destination."
      • addedInput schema / properties / display_url / description
        Added value: +"Optional display URL shown with media posts; must be on\nthe click_url's domain."
      • addedInput schema / properties / headline / description
        Added value: +"Post headline, required for a new post, at most 300\ncharacters."
      • addedInput schema / properties / image_url / description
        Added value: +"Publicly reachable image URL, required for IMAGE posts."
      • addedInput schema / properties / post_id / description
        Added value: +"Existing post to promote (t3_...); headline, body, the\nmedia arguments, call_to_action and display_url are then ignored.\nEmpty creates a new post."
      • addedInput schema / properties / post_type / description
        Added value: +"TEXT (headline + optional body; default), IMAGE\n(public image_url), VIDEO (public video_url + thumbnail_url) or\nCAROUSEL (2 to 6 carousel_cards)."
      • addedInput schema / properties / profile_id / description
        Added value: +"Reddit profile that authors the post, from\nlist_reddit_funding_instruments (profiles). Required for a new\npost; with post_id it defaults to the post's."
      • addedInput schema / properties / thumbnail_url
        Added value: +{
        +  "default": "",
        +  "description": "Publicly reachable image Reddit shows before the video\nplays, required for VIDEO posts.",
        +  "type": "string"
        +}
      • addedInput schema / properties / video_url
        Added value: +{
        +  "default": "",
        +  "description": "Direct link to the video file (MP4 or MOV, up to 1 GB),\nrequired for VIDEO posts. Reddit downloads it when the post is\ncreated; a page that embeds the video does not work.",
        +  "type": "string"
        +}
    • Changeddraft_reddit_ad_group31 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / ad_group_name / description
        Added value: +"Name of the new ad group."
      • addedInput schema / properties / bid_strategy / description
        Added value: +"BIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX.\nRequired for non-CBO campaigns; in CBO campaigns it must match the\ncampaign's."
      • addedInput schema / properties / bid_type / description
        Added value: +"CPC, CPM, CPV, CPV6 or CPV15. Required for non-CBO\ncampaigns."
      • addedInput schema / properties / bid_value / description
        Added value: +"Bid in account currency; MANUAL_BIDDING and TARGET_CPX\n(target cost per result) need it."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Reddit campaign id (from get_reddit_campaigns)."
      • addedInput schema / properties / carriers
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Mobile carrier ids (from search_reddit_targeting kind\n\"carriers\", e.g. \"O2_DEUTSCHLAND\"), checked against Reddit's\ncarrier list. Omitted means every carrier."
        +}
      • addedInput schema / properties / communities / description
        Added value: +"Community (subreddit) names to target."
      • addedInput schema / properties / conversion_pixel_id / description
        Added value: +"Pixel id (Reddit rule; from get_reddit_pixels)."
      • addedInput schema / properties / custom_audience_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Custom audiences to target (from\nget_reddit_audiences), e.g. website visitors for retargeting."
        +}
      • addedInput schema / properties / daily_budget / description
        Added value: +"Daily budget in account currency (positive). Required\nfor non-CBO campaigns unless lifetime_budget is given; not allowed\nin CBO campaigns. Mutually exclusive with lifetime_budget."
      • addedInput schema / properties / devices
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Device targets, objects like {\"type\": \"MOBILE\", \"os\":\n\"IOS\", \"min_version\": \"16\"} (type DESKTOP or MOBILE; optional os\nANDROID or IOS, major OS versions with iOS at least 14, and\nlabel_map {make: [models]} with makes/models from\nsearch_reddit_targeting kind \"devices\"). Omitted means every\ndevice; APP_INSTALLS campaigns take exactly one."
        +}
      • addedInput schema / properties / end_time / description
        Added value: +"End, same formats as start_time."
      • addedInput schema / properties / excluded_communities / description
        Added value: +"Community names to exclude."
      • addedInput schema / properties / excluded_custom_audience_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Custom audiences to exclude, e.g.\npeople who already bought."
        +}
      • addedInput schema / properties / excluded_geolocations / description
        Added value: +"Geolocation ids to exclude."
      • addedInput schema / properties / excluded_interests
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Interest ids to exclude (Reddit marks this field\ndeprecated)."
        +}
      • addedInput schema / properties / excluded_keywords / description
        Added value: +"Keywords to exclude."
      • addedInput schema / properties / expand_targeting / description
        Added value: +"Whether Reddit may expand delivery beyond the\ntargeting; omitted uses Reddit's default."
      • addedInput schema / properties / gender / description
        Added value: +"FEMALE or MALE; empty means all genders."
      • addedInput schema / properties / geolocations / description
        Added value: +"Geolocation ids to target (e.g. \"DE\" or \"DE:2874225\")."
      • addedInput schema / properties / interests / description
        Added value: +"Interest ids to target."
      • addedInput schema / properties / keywords / description
        Added value: +"Keywords to target; Reddit refuses keywords that are not\nbrand-safe."
      • addedInput schema / properties / languages / description
        Added value: +"Language codes (ISO 639-1, upper-cased automatically,\ne.g. \"DE\"). Empty means every language."
      • addedInput schema / properties / lifetime_budget / description
        Added value: +"Lifetime budget in account currency (positive);\nrequires end_time and is compared to max_daily_budget by its\nper-day share."
      • addedInput schema / properties / locations / description
        Added value: +"Placements, FEED and/or COMMENTS_PAGE (conversation\npages); cannot be an empty list."
      • addedInput schema / properties / optimization_goal / description
        Added value: +"The pixel event to optimize for (PURCHASE,\nSIGN_UP, LEAD, PAGE_VISIT, ...). Empty in a CBO campaign inherits\nthe campaign's."
      • addedInput schema / properties / platforms / description
        Added value: +"ALL, DESKTOP, DESKTOP_LEGACY, MOBILE_NATIVE, MOBILE_WEB,\nMOBILE_WEB_3X or SHREDTOP."
      • addedInput schema / properties / schedule / description
        Added value: +"Weekly delivery windows (\"time of day\" in Ads Manager), a\nlist of blocks like {\"days\": \"MON-FRI\", \"start_hour\": 13,\n\"end_hour\": 23} (day names, hours 0-23, end_hour inclusive) or the\nnative {\"start_day\": \"FRI\", \"start_hour\": 22, \"end_day\": \"SAT\",\n\"end_hour\": 3}. Omitted means delivery at any time. Hours apply in\neach viewer's local time, not the account time zone. Not allowed\nin CBO campaigns, whose schedule overrides every ad group."
      • addedInput schema / properties / start_time / description
        Added value: +"Start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare\nYYYY-MM-DD means 00:00 UTC that day. Empty means now."
      • addedInput schema / properties / view_modes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Feed layouts: ALL, CARD, CLASSIC, COMPACT or IMMERSIVE.\nOmitted uses Reddit's default."
        +}
    • Changeddraft_reddit_campaign16 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / bid_strategy / description
        Added value: +"BIDLESS, MAXIMIZE_VOLUME or TARGET_CPX (CBO only)."
      • addedInput schema / properties / bid_type / description
        Added value: +"CPC, CPM, CPV, CPV6 or CPV15 (CBO only)."
      • addedInput schema / properties / bid_value / description
        Added value: +"Bid in account currency (CBO only)."
      • addedInput schema / properties / campaign_budget_optimization / description
        Added value: +"true holds the budget on the campaign\n(then daily_budget or lifetime_budget, bid_strategy, bid_type and\nconversion_pixel_id are required). false (default) leaves budget\nand bids to the ad groups, and none of the budget or bid\nparameters may be passed."
      • addedInput schema / properties / campaign_name / description
        Added value: +"Name of the new campaign."
      • addedInput schema / properties / conversion_pixel_id / description
        Added value: +"Pixel id from get_reddit_pixels; required with\nCBO, optional otherwise."
      • addedInput schema / properties / daily_budget / description
        Added value: +"Daily budget in account currency (positive; CBO only).\nMutually exclusive with lifetime_budget."
      • addedInput schema / properties / end_time / description
        Added value: +"End, same formats as start_time."
      • addedInput schema / properties / funding_instrument_id / description
        Added value: +"Servable funding instrument id from\nlist_reddit_funding_instruments."
      • addedInput schema / properties / lifetime_budget / description
        Added value: +"Lifetime budget in account currency (positive; CBO\nonly); requires end_time and is compared to max_daily_budget by\nits per-day share."
      • addedInput schema / properties / objective / description
        Added value: +"CLICKS, CONVERSIONS, IMPRESSIONS, LEAD_GENERATION,\nAPP_INSTALLS, CATALOG_SALES or VIDEO_VIEWABLE_IMPRESSIONS. Other\nvalues only produce a warning, since Reddit is rolling out new\nobjective enums."
      • addedInput schema / properties / optimization_goal / description
        Added value: +"Pixel event to optimize for (PURCHASE, SIGN_UP,\nLEAD, PAGE_VISIT, ...); used with CBO only."
      • addedInput schema / properties / schedule / description
        Added value: +"Weekly delivery windows (\"time of day\" in Ads Manager; CBO\nonly), a list of blocks like {\"days\": \"MON-FRI\", \"start_hour\": 13,\n\"end_hour\": 23} (day names, hours 0-23, end_hour inclusive) or the\nnative {\"start_day\": \"FRI\", \"start_hour\": 22, \"end_day\": \"SAT\",\n\"end_hour\": 3}. [] clears it (deliver at any time). Hours apply in\neach viewer's local time, not the account time zone. A campaign\nschedule replaces every ad group's."
      • addedInput schema / properties / spend_cap / description
        Added value: +"Campaign spend cap in account currency; 0 or empty means\nnone."
      • addedInput schema / properties / start_time / description
        Added value: +"Start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare\nYYYY-MM-DD means 00:00 UTC that day."
    • Addeddraft_reddit_custom_audience
    • Changeddraft_remove_conversion_action2 fields changed
      • addedInput schema / properties / conversion_action_id / description
        Added value: +"Numeric ConversionAction ID, e.g. from SELECT\nconversion_action.id, conversion_action.name FROM conversion_action."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes allowed). Defaults\nto the configured account."
    • Changeddraft_responsive_search_ad7 fields changed
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Numeric ID of the ad group that gets the ad."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / descriptions / description
        Added value: +"2-4 descriptions, max 90 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"DESCRIPTION_1\"};\nvalid pins are DESCRIPTION_1, DESCRIPTION_2."
      • addedInput schema / properties / final_url / description
        Added value: +"Landing page URL the ad links to; must be reachable."
      • addedInput schema / properties / headlines / description
        Added value: +"3-15 headlines, max 30 chars each. Each entry is a plain\nstring (unpinned) or {\"text\": \"...\", \"pinned_field\": \"HEADLINE_1\"};\nvalid pins are HEADLINE_1, HEADLINE_2, HEADLINE_3."
      • addedInput schema / properties / path1 / description
        Added value: +"Optional first display-URL path segment (Google allows up to 15\nchars)."
      • addedInput schema / properties / path2 / description
        Added value: +"Optional second display-URL path segment (Google allows up to 15\nchars)."
    • Addeddraft_rollback_gtm_version
    • Addeddraft_shopping_campaign
    • Changeddraft_sitelinks3 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign to attach sitelinks to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / sitelinks / description
        Added value: +"List of dicts (at least one), each with link_text (str,\nrequired, max 25 chars) — the clickable text shown; final_url (str,\nrequired) — destination URL for this sitelink; description1 (str,\noptional, max 35 chars) — first description line; description2\n(str, optional, max 35 chars) — second description line."
    • Changeddraft_structured_snippets3 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign to attach the snippets to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / snippets / description
        Added value: +"At least one dict with \"header\" and \"values\". header is one of\nAmenities, Brands, Courses, Degree programs, Destinations, Featured\nHotels, Insurance coverage, Models, Neighborhoods, Services, Shows,\nStyles, Types (exact spelling). values is a list of 3-10 non-empty\nstrings, each at most 25 characters."
    • Changeddraft_update_conversion_action13 fields changed
      • addedInput schema / properties / always_use_default_value / description
        Added value: +"True always uses default_value; False uses\nit only as a fallback when the tag/import supplies no value (the\npreview warns when combined with a positive default_value). Omit to\nleave unchanged."
      • addedInput schema / properties / attribution_model / description
        Added value: +"AttributionModel enum value, e.g.\nGOOGLE_SEARCH_ATTRIBUTION_DATA_DRIVEN. Empty leaves it unchanged."
      • addedInput schema / properties / click_through_window_days / description
        Added value: +"Click-through attribution window in days,\n1-90. 0 leaves it unchanged."
      • addedInput schema / properties / conversion_action_id / description
        Added value: +"Numeric ConversionAction ID. It comes from:\nSELECT conversion_action.id, conversion_action.name FROM\nconversion_action."
      • addedInput schema / properties / counting_type / description
        Added value: +"ONE_PER_CLICK or MANY_PER_CLICK. Empty leaves it\nunchanged."
      • addedInput schema / properties / currency_code / description
        Added value: +"New 3-letter ISO 4217 currency code. Empty leaves it\nunchanged."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes allowed). Defaults\nto the configured account."
      • addedInput schema / properties / default_value / description
        Added value: +"New default value in the action's currency (not micros),\n>= 0. 0 leaves it unchanged."
      • addedInput schema / properties / include_in_conversions_metric / description
        Added value: +"True shows the action in the\n\"Conversions\" column; False in \"All conversions\" only. Mutable here\n(unlike on create). Omit to leave unchanged."
      • addedInput schema / properties / name / description
        Added value: +"New name. Empty keeps the current name."
      • addedInput schema / properties / phone_call_duration_seconds / description
        Added value: +"Minimum call length in seconds for a call\nto count. 0 leaves it unchanged."
      • addedInput schema / properties / primary_for_goal / description
        Added value: +"True makes it Primary (Smart Bidding optimizes toward\nit); False demotes it to Secondary. Omit to leave unchanged."
      • addedInput schema / properties / view_through_window_days / description
        Added value: +"View-through attribution window in days,\n1-30. 0 leaves it unchanged."
    • Addeddraft_update_custom_conversion_goal
    • Addeddraft_upload_call_conversions
    • Addeddraft_upload_enhanced_conversions_for_leads
    • Changedenable_entity3 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / entity_id / description
        Added value: +"ID in the format for its type. campaign: campaign ID (e.g.\n\"12345678\"); ad_group: ad group ID (e.g. \"12345678\"); ad:\n\"adGroupId~adId\" (e.g. \"12345678~987654\"; a bare ad ID is resolved\nto its ad group at apply time); keyword: \"adGroupId~criterionId\"\n(e.g. \"12345678~987654\")."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\", \"ad\", \"keyword\" or\n\"asset_group\" (Performance Max)."
    • Changedenable_reddit_entity3 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / entity_id / description
        Added value: +"Reddit id of the entity, from the read tools\n(get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads)."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\" or \"ad\"."
    • Changedestimate_budget6 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes allowed). Defaults\nto the configured account."
      • addedInput schema / properties / daily_budget / description
        Added value: +"Daily budget in account currency. If provided, insights\nwill show what % of traffic the budget captures. 0 = no budget\ncomparison."
      • addedInput schema / properties / forecast_days / description
        Added value: +"Forecast horizon in days, starting tomorrow (default 30)."
      • addedInput schema / properties / geo_target_id / description
        Added value: +"Geo target constant ID (2276=Germany, 2840=USA, 2826=UK,\n2250=France). Defaults to 2276."
      • addedInput schema / properties / keywords / description
        Added value: +"List of {\"text\": \"keyword\", \"match_type\": \"EXACT|PHRASE|BROAD\",\n\"max_cpc\": 1.50}. match_type defaults to BROAD; max_cpc is optional\n(defaults to 1.00 in account currency, not micros). At least one\nkeyword is required."
      • addedInput schema / properties / language_id / description
        Added value: +"Language constant ID (1000=English, 1001=German,\n1002=French, 1003=Spanish). Defaults to 1000."
    • Changedestimate_reddit_ad_group21 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / bid_strategy / description
        Added value: +"BIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX.\nEmpty means BIDLESS."
      • addedInput schema / properties / bid_type / description
        Added value: +"CPC (default), CPM, CPV, CPV6 or CPV15; the bid suggestion\nis for this bid type."
      • addedInput schema / properties / bid_value / description
        Added value: +"Planned bid in account currency; compared with Reddit's\nsuggested minimum."
      • addedInput schema / properties / carriers
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Mobile carrier ids (from search_reddit_targeting kind\n\"carriers\", e.g. \"O2_DEUTSCHLAND\"). Empty means every carrier."
        +}
      • addedInput schema / properties / communities / description
        Added value: +"Community (subreddit) names to target."
      • addedInput schema / properties / daily_budget / description
        Added value: +"Daily budget in account currency (positive). One of\ndaily_budget or lifetime_budget is required; daily_budget wins\nwhen both are given."
      • addedInput schema / properties / devices
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Device targets, objects like {\"type\": \"MOBILE\", \"os\":\n\"IOS\", \"min_version\": \"16\"} (type DESKTOP or MOBILE; optional os\nANDROID or IOS, major OS versions, and label_map {make: [models]}\nwith makes/models from search_reddit_targeting kind \"devices\").\nEmpty means every device."
        +}
      • addedInput schema / properties / end_time / description
        Added value: +"Schedule end, ISO 8601. Empty means 30 days after the\ndefault start."
      • addedInput schema / properties / excluded_communities / description
        Added value: +"Community names to exclude."
      • addedInput schema / properties / excluded_geolocations / description
        Added value: +"Geolocation ids to exclude."
      • addedInput schema / properties / gender / description
        Added value: +"FEMALE or MALE; empty means all genders."
      • addedInput schema / properties / geolocations / description
        Added value: +"Geolocation ids to target (e.g. \"DE\" or \"DE:2874225\",\nfrom search_reddit_targeting kind \"geolocations\")."
      • addedInput schema / properties / interests / description
        Added value: +"Interest ids to target (from search_reddit_targeting kind\n\"interests\")."
      • addedInput schema / properties / keywords / description
        Added value: +"Keywords to target."
      • addedInput schema / properties / languages / description
        Added value: +"Language codes (ISO 639-1, upper-cased automatically,\ne.g. \"DE\"). Empty means all languages."
      • addedInput schema / properties / lifetime_budget / description
        Added value: +"Lifetime budget in account currency (positive),\nused when daily_budget is not given."
      • addedInput schema / properties / objective / description
        Added value: +"Campaign objective the estimate assumes, e.g. CLICKS\n(default), CONVERSIONS, IMPRESSIONS, LEAD_GENERATION,\nAPP_INSTALLS, CATALOG_SALES or VIDEO_VIEWABLE_IMPRESSIONS."
      • addedInput schema / properties / optimization_goal / description
        Added value: +"Pixel event to optimize for (PURCHASE, SIGN_UP,\nLEAD, PAGE_VISIT, ...). Empty means none."
      • addedInput schema / properties / platforms / description
        Added value: +"Platforms to target, e.g. ALL, DESKTOP, MOBILE_NATIVE,\nMOBILE_WEB. Empty means no platform restriction."
      • addedInput schema / properties / start_time / description
        Added value: +"Schedule start, ISO 8601 (e.g. 2026-10-01T00:00:00Z).\nEmpty means tomorrow 00:00 UTC."
    • Changedgenerate_tracking_code5 fields changed
      • addedInput schema / properties / check_existing / description
        Added value: +"When true (default), looks up the last 28 days of GA4\nevents to report whether this event already fires."
      • addedInput schema / properties / event_name / description
        Added value: +"GA4 event name for the snippet, e.g. \"sign_up\" or\n\"generate_lead\"."
      • addedInput schema / properties / event_params / description
        Added value: +"Event parameters as a name-to-value object, e.g.\n{\"method\": \"email\"}. Missing recommended parameters for well-known\nevents are added as typed placeholders."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" used for the\nexisting-event check. If empty, uses the default from config."
      • addedInput schema / properties / trigger / description
        Added value: +"\"form_submit\", \"button_click\", or \"page_load\" — wraps the gtag\ncall in an appropriate event listener (with a YOUR_SELECTOR\nplaceholder for forms and buttons). Empty = bare gtag call."
    • Changedget_ad_performance4 fields changed
      • addedInput schema / properties / compact / description
        Added value: +"When true (for audits/overviews), returns totals, the top-10\nads with headline/description COUNTS instead of full asset lists,\nplus incomplete-RSA, single-ad ad-group and policy findings with\napproval-status counts (~90% smaller)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Addedget_ai_max_settings
    • Addedget_asset_group_signals
    • Removedget_asset_performance
    • Changedget_audience_performance4 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Optional numeric ID to filter to a single campaign."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Addedget_brand_list_brands
    • Addedget_brand_list_campaigns
    • Addedget_brand_lists
    • Changedget_campaign_performance4 fields changed
      • addedInput schema / properties / compact / description
        Added value: +"When true (for audits/overviews on large accounts), returns\naccount totals, status/type breakdowns, the top-10 spenders,\nzero-conversion offenders and budget-limited converters instead\nof every row (~90% smaller)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Addedget_change_history
    • Addedget_custom_conversion_goals
    • Changedget_demographic_targeting3 fields changed
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Numeric ad group ID. Mutually exclusive with campaign_id."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric campaign ID. Mutually exclusive with ad_group_id."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
    • Changedget_detailed_asset_performance2 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Optional numeric ID to filter to a single PMax campaign."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
    • Changedget_gtm_tag4 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / tag_id / description
        Added value: +"Numeric GTM tag ID, as listed by list_gtm_tags."
      • addedInput schema / properties / workspace_id
        Added value: +{
        +  "default": "",
        +  "description": "Workspace to read (see list_gtm_workspaces), which\nincludes drafted changes that are not published yet. Empty reads\nthe live (published) container version.",
        +  "type": "string"
        +}
    • Changedget_gtm_trigger4 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / trigger_id / description
        Added value: +"Numeric GTM trigger ID, as listed by list_gtm_triggers or\na tag's firing/blocking triggers."
      • addedInput schema / properties / workspace_id
        Added value: +{
        +  "default": "",
        +  "description": "Workspace to read (see list_gtm_workspaces), which\nincludes drafted changes that are not published yet. Empty reads\nthe live (published) container version.",
        +  "type": "string"
        +}
    • Changedget_gtm_version3 fields changed
      • addedInput schema / properties / container_version_id / description
        Added value: +"Numeric container version ID from\nlist_gtm_versions."
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
    • Addedget_gtm_version_diff
    • Changedget_gtm_workspace_diff3 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / workspace_id / description
        Added value: +"Numeric GTM workspace ID from list_gtm_workspaces."
    • Changedget_keyword_performance4 fields changed
      • addedInput schema / properties / compact / description
        Added value: +"When true (for audits/overviews), returns totals, match-type\ndistribution, the top-10 spenders, low-quality-score keywords, and\nzero-conversion spenders instead of every row (~90% smaller)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Changedget_merchant_feed_health3 fields changed
      • addedInput schema / properties / account_id / default
        Added value: +""
      • addedInput schema / properties / account_id / description
        Added value: +"Numeric Merchant Center ID from list_merchant_accounts.\nDefaults to merchant.account_id in the config."
      • removedInput schema / required
        Removed value: -[
        -  "account_id"
        -]
    • Changedget_negative_keyword_list_campaigns2 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / shared_set_id / description
        Added value: +"Numeric ID from get_negative_keyword_lists. When\nomitted, returns all list-to-campaign attachments across the account."
    • Changedget_negative_keyword_list_keywords2 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / shared_set_id / description
        Added value: +"Numeric ID from get_negative_keyword_lists (shared_set.id)."
    • Changedget_negative_keyword_lists1 field changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
    • Changedget_negative_keywords2 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric campaign ID to filter by. If empty, returns\nnegatives across all campaigns."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
    • Addedget_pmax_assets
    • Changedget_pmax_performance3 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Changedget_recommendations3 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Optional numeric campaign ID to scope to a single campaign."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / recommendation_types / description
        Added value: +"Optional filter of Google Ads RecommendationType\nnames, e.g. [\"KEYWORD\", \"TARGET_CPA_OPT_IN\",\n\"MAXIMIZE_CONVERSIONS_OPT_IN\", \"RESPONSIVE_SEARCH_AD\"].\nEmpty = all types."
    • Changedget_reddit_account_history6 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / date_range_end / description
        Added value: +"Last day (inclusive), YYYY-MM-DD (account-local day).\nEmpty means today."
      • addedInput schema / properties / date_range_start / description
        Added value: +"First day, YYYY-MM-DD (account-local day). Empty\nmeans 29 days before date_range_end (default window is the last\n30 days)."
      • addedInput schema / properties / entity_ids / description
        Added value: +"Ids of the entities of entity_type to filter to; required\nwhen entity_type is set."
      • addedInput schema / properties / entity_type / description
        Added value: +"Optional filter to one entity type: \"campaign\",\n\"ad_group\" or \"ad\". Requires entity_ids."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of changes returned, clamped to 1-500."
    • Changedget_reddit_ad_groups2 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Reddit campaign id (from get_reddit_campaigns) to limit\nthe list to; empty lists every ad group of the account."
    • Changedget_reddit_ads4 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Reddit ad group id (from get_reddit_ad_groups) to limit\nthe list to; empty means no ad group filter."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Reddit campaign id (from get_reddit_campaigns) to limit\nthe list to; empty means no campaign filter."
      • addedInput schema / properties / include_copy / description
        Added value: +"When true, adds each ad's post: type (TEXT, IMAGE,\nVIDEO, CAROUSEL), headline, body, destination and media, one\nrequest per distinct post (at most 50 posts per call), so creative\ncan be reviewed without opening Reddit."
    • Addedget_reddit_audiences
    • Changedget_reddit_campaigns2 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / include_archived / description
        Added value: +"Include ARCHIVED and DELETED campaigns, which are\nleft out by default."
    • Changedget_reddit_performance6 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / breakdown / description
        Added value: +"Optional extra dimension: \"date\", \"hour\", \"country\",\n\"region\", \"community\", \"keyword\", \"interest\", \"placement\",\n\"gender\" or \"os_type\". Empty means none."
      • addedInput schema / properties / compact / description
        Added value: +"When true, returns totals + top-10 rows by spend + offender\nlists instead of every row."
      • addedInput schema / properties / date_range_end / description
        Added value: +"Last day (inclusive), YYYY-MM-DD, in the account's\ntime zone. Empty means today."
      • addedInput schema / properties / date_range_start / description
        Added value: +"First day, YYYY-MM-DD, in the account's time zone.\nEmpty means 29 days before date_range_end (a 30-day window)."
      • addedInput schema / properties / level / description
        Added value: +"Row granularity: \"account\", \"campaign\" (default), \"ad_group\"\nor \"ad\"."
    • Changedget_reddit_pixels1 field changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
    • Changedget_search_terms4 fields changed
      • addedInput schema / properties / compact / description
        Added value: +"When true (for audits/overviews), returns totals, the top-10\nterms by clicks, ready-made negative-keyword waste candidates\n(5+ clicks, zero conversions), and top converters (~90% smaller)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
    • Changedget_tracking_events3 fields changed
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date, same formats as date_range_start."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date: \"today\", \"yesterday\", \"NdaysAgo\" (e.g.\n\"28daysAgo\"), or \"YYYY-MM-DD\"."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedlanding_page_analysis4 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(e.g. \"123-456-7890\"). Defaults to the configured ads.customer_id."
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date as \"YYYY-MM-DD\" (inclusive)."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as \"YYYY-MM-DD\". Both dates must be set\nto apply a range; if either is empty, the last 30 days are used."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedlist_accounts1 field changed
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of accounts listed under the manager (MCC)\naccount. The default cap of 200 covers the vast majority of agency\nMCCs in one call."
    • Addedlist_ga4_dimensions_and_metrics
    • Changedlist_gtm_containers1 field changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID from list_gtm_accounts. Empty\nuses gtm.account_id from the config; the tool errors when neither\nis set."
    • Changedlist_gtm_tags3 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers),\nnot the GTM-XXXXXXX public ID. Empty uses gtm.container_id from\nthe config."
      • addedInput schema / properties / workspace_id
        Added value: +{
        +  "default": "",
        +  "description": "Workspace to read (see list_gtm_workspaces), which\nincludes drafted changes that are not published yet. Empty reads\nthe live (published) container version.",
        +  "type": "string"
        +}
    • Changedlist_gtm_triggers3 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / workspace_id
        Added value: +{
        +  "default": "",
        +  "description": "Workspace to read (see list_gtm_workspaces), which\nincludes drafted changes that are not published yet. Empty reads\nthe live (published) container version.",
        +  "type": "string"
        +}
    • Changedlist_gtm_variables3 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / workspace_id
        Added value: +{
        +  "default": "",
        +  "description": "Workspace to read (see list_gtm_workspaces), which\nincludes drafted changes that are not published yet. Empty reads\nthe live (published) container version.",
        +  "type": "string"
        +}
    • Changedlist_gtm_versions3 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
      • addedInput schema / properties / page_size / description
        Added value: +"Maximum number of version headers returned (newest first)."
    • Changedlist_gtm_workspaces2 fields changed
      • addedInput schema / properties / gtm_account_id / description
        Added value: +"Numeric GTM account ID (see list_gtm_accounts). Empty\nuses gtm.account_id from the config."
      • addedInput schema / properties / gtm_container_id / description
        Added value: +"Numeric GTM container ID (see list_gtm_containers).\nEmpty uses gtm.container_id from the config."
    • Addedlist_key_events
    • Changedlist_reddit_funding_instruments1 field changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
    • Addedlist_uploads
    • Changedpause_entity3 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / entity_id / description
        Added value: +"ID in the format for its type. campaign: campaign ID (e.g.\n\"12345678\"); ad_group: ad group ID (e.g. \"12345678\"); ad:\n\"adGroupId~adId\" (e.g. \"12345678~987654\"; a bare ad ID is resolved\nto its ad group at apply time); keyword: \"adGroupId~criterionId\"\n(e.g. \"12345678~987654\")."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\", \"ad\", \"keyword\" or\n\"asset_group\" (Performance Max)."
    • Changedpause_reddit_entity3 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / entity_id / description
        Added value: +"Reddit id of the entity, from the read tools\n(get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads)."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\" or \"ad\"."
    • Addedpropose_brand_list
    • Changedpropose_negative_keyword_list5 fields changed
      • addedInput schema / properties / campaign_id / description
        Added value: +"Numeric ID of the campaign the new list is attached to."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / keywords / description
        Added value: +"Negative keyword texts to put in the list (at least one)."
      • addedInput schema / properties / list_name / description
        Added value: +"Name of the new shared negative keyword list."
      • addedInput schema / properties / match_type / description
        Added value: +"Match type applied to every keyword: \"EXACT\" (default),\n\"PHRASE\", or \"BROAD\" (case-insensitive)."
    • Changedremove_entity3 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / entity_id / description
        Added value: +"The resource ID. campaign / ad_group / asset_group / asset: simple numeric\nID. ad: \"adGroupId~adId\" (a bare ad ID is resolved to its ad group).\nkeyword and ad_group_criterion: \"adGroupId~criterionId\".\nnegative_keyword and campaign_criterion: \"campaignId~criterionId\"\n(the resource_id field from get_negative_keywords).\nshared_criterion: \"sharedSetId~criterionId\" (the resource_id field\nfrom get_negative_keyword_list_keywords). campaign_asset:\n\"campaignId~assetId~fieldType\". customer_asset: \"assetId~fieldType\"."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\", \"ad\", \"keyword\", \"asset_group\",\n\"negative_keyword\", \"shared_criterion\", \"campaign_asset\", \"asset\",\n\"customer_asset\", \"ad_group_criterion\", or \"campaign_criterion\"."
    • Addedremove_from_brand_list
    • Changedremove_reddit_entity3 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / entity_id / description
        Added value: +"Reddit id of the entity, from the read tools\n(get_reddit_campaigns, get_reddit_ad_groups, get_reddit_ads)."
      • addedInput schema / properties / entity_type / description
        Added value: +"\"campaign\", \"ad_group\" or \"ad\"."
    • Changedrun_ga4_report12 fields changed
      • addedInput schema / properties / compare_end
        Added value: +{
        +  "default": "",
        +  "description": "End of the comparison period.",
        +  "type": "string"
        +}
      • addedInput schema / properties / compare_start
        Added value: +{
        +  "default": "",
        +  "description": "Start of the comparison period (same formats as\ndate_range_start). Set together with compare_end.",
        +  "type": "string"
        +}
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date, same formats as date_range_start."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date: \"today\", \"yesterday\", \"NdaysAgo\" (e.g.\n\"7daysAgo\", \"28daysAgo\", \"90daysAgo\"), or \"YYYY-MM-DD\"."
      • addedInput schema / properties / dimension_filter
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Conditions on dimensions, all of which must hold\n(AND). Each is {\"field\": <dimension>, \"op\": <match>, \"value\":\n<string>}; op is EXACT (default), BEGINS_WITH, ENDS_WITH,\nCONTAINS, FULL_REGEXP, PARTIAL_REGEXP, or IN_LIST with \"values\":\n[<strings>]. Optional keys: \"case_sensitive\" (default false) and\n\"not\": true to exclude matches. Example: [{\"field\":\n\"sessionDefaultChannelGroup\", \"op\": \"EXACT\", \"value\": \"Paid\nSearch\"}]."
        +}
      • addedInput schema / properties / dimensions / description
        Added value: +"GA4 dimension API names, e.g. date, pagePath,\nsessionSource, sessionMedium, country, deviceCategory, eventName.\nCustom ones (customEvent:...) and every valid name are listed by\nlist_ga4_dimensions_and_metrics."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of rows returned (positive)."
      • addedInput schema / properties / metric_filter
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Conditions on metrics, applied after aggregation, all\nof which must hold (AND). Each is {\"field\": <metric>, \"op\": <op>,\n\"value\": <number>}; op is EQUAL, LESS_THAN, LESS_THAN_OR_EQUAL,\nGREATER_THAN, GREATER_THAN_OR_EQUAL (or =, <, <=, >, >=), or\nBETWEEN with \"value\": [from, to]. Optional \"not\": true.\nExample: [{\"field\": \"sessions\", \"op\": \">\", \"value\": 100}]."
        +}
      • addedInput schema / properties / metrics / description
        Added value: +"GA4 metric API names, e.g. sessions, totalUsers, newUsers,\nscreenPageViews, keyEvents, eventCount, bounceRate."
      • addedInput schema / properties / offset
        Added value: +{
        +  "default": 0,
        +  "description": "Zero-based row offset for paging; pass next_offset from the\nprevious result to get the following page.",
        +  "type": "integer"
        +}
      • addedInput schema / properties / order_by
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Sort order as [{\"field\": <name>, \"desc\": true|false}]; each\nfield must be one of the requested dimensions or metrics."
        +}
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedrun_gaql3 fields changed
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID, digits with or without dashes\n(123-456-7890). Empty uses the configured default account."
      • addedInput schema / properties / format / description
        Added value: +"Output format: \"table\" (default, readable), \"json\"\n(structured), or \"csv\" (exportable)."
      • addedInput schema / properties / query / description
        Added value: +"The GAQL query, e.g. \"SELECT campaign.name, metrics.clicks\nFROM campaign WHERE segments.date DURING LAST_7_DAYS\"."
    • Changedrun_gsc_report10 fields changed
      • addedInput schema / properties / aggregation_type
        Added value: +{
        +  "default": "auto",
        +  "description": "\"auto\" (default), \"byPage\" (aggregate by canonical\nURL) or \"byProperty\" (aggregate by property; not combinable with\ngrouping or filtering by page).",
        +  "type": "string"
        +}
      • addedInput schema / properties / data_state
        Added value: +{
        +  "default": "final",
        +  "description": "\"final\" (default) returns finalized data only; \"all\"\nadds fresh data from the last days that can still change;\n\"hourly_all\" is the state the hour dimension uses.",
        +  "type": "string"
        +}
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date, same formats as date_range_start."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date as ISO \"YYYY-MM-DD\" or a relative value\nlike \"7daysAgo\", \"30daysAgo\", \"today\"."
      • addedInput schema / properties / dimension_filter_groups / description
        Added value: +"Optional list of GSC DimensionFilterGroup\nobjects to filter by query, page, country, or device, e.g.\n[{\"filters\": [{\"dimension\": \"query\", \"operator\": \"contains\",\n\"expression\": \"analytics\"}]}]. searchAppearance is filterable too."
      • addedInput schema / properties / dimensions / description
        Added value: +"One or more of \"query\", \"page\", \"country\", \"device\",\n\"date\", \"searchAppearance\" (search result feature, e.g. rich\nresults) or \"hour\" (hourly rows for roughly the last 10 days;\nswitches data_state to \"hourly_all\"). Defaults to [\"query\"]."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum rows to return (default 100, max 25000 per request;\nhigher values are capped at 25000)."
      • addedInput schema / properties / search_type / description
        Added value: +"\"web\" (default), \"image\", \"video\", \"news\", \"discover\",\nor \"googleNews\"."
      • addedInput schema / properties / site_url / description
        Added value: +"The GSC property URL (e.g. \"https://example.com/\" or\n\"sc-domain:example.com\"), as listed by list_gsc_sites. Defaults to\nthe configured Search Console site (gsc.site_url)."
      • addedInput schema / properties / start_row
        Added value: +{
        +  "default": 0,
        +  "description": "Zero-based offset of the first row, for paging past the\n25,000-row cap (pass the previous response's next_start_row).",
        +  "type": "integer"
        +}
    • Changedrun_realtime_report3 fields changed
      • addedInput schema / properties / dimensions / description
        Added value: +"GA4 realtime dimension API names, e.g. unifiedScreenName,\neventName, country, deviceCategory."
      • addedInput schema / properties / metrics / description
        Added value: +"GA4 realtime metric API names, e.g. activeUsers, eventCount.\nDefaults to [\"activeUsers\"]."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
    • Changedrun_reddit_report7 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / breakdowns / description
        Added value: +"Up to 3 of DATE, HOUR, CAMPAIGN_ID, AD_GROUP_ID, AD_ID,\nCOUNTRY, REGION, COMMUNITY, KEYWORD, INTEREST, PLACEMENT, GENDER,\nOS_TYPE (4 when COUNTRY and REGION are both included; HOUR and\nDATE cannot be combined)."
      • addedInput schema / properties / date_range_end / description
        Added value: +"Last day (inclusive), YYYY-MM-DD (account-local day).\nEmpty means today."
      • addedInput schema / properties / date_range_start / description
        Added value: +"First day, YYYY-MM-DD (account-local day). Empty\nmeans 29 days before date_range_end (a 30-day window)."
      • addedInput schema / properties / fields / description
        Added value: +"Reddit report field names (required), e.g. [\"SPEND\",\n\"CLICKS\", \"REACH\", \"VIDEO_STARTED\",\n\"CONVERSION_PURCHASE_TOTAL_VALUE\", \"KEY_CONVERSION_TOTAL_COUNT\"]."
      • addedInput schema / properties / filter / description
        Added value: +"Reddit filter expression (e.g. \"campaign_id==abc123\"). Empty\nmeans no filter."
      • addedInput schema / properties / time_zone_id / description
        Added value: +"IANA time zone for the day boundaries and DATE/HOUR\nrows, e.g. \"Europe/Berlin\". Empty uses the ad account's time zone."
    • Changedsearch_reddit_targeting5 fields changed
      • addedInput schema / properties / country / description
        Added value: +"Country ISO code (e.g. \"DE\") for kinds \"geolocations\" and\n\"carriers\"; ignored for other kinds."
      • addedInput schema / properties / kind / description
        Added value: +"What to look up: \"communities\" (subreddits; query required),\n\"interests\" (query filters by name), \"geolocations\" (country ISO\ncode and/or city query), \"languages\" (upper-case ISO 639-1\ncodes), \"keywords\" (comma-separated seed terms → suggestions with\nReddit-wide monthly views), \"community_suggestions\" (Reddit's\nrelated-community picks for seed communities in query and/or a\nwebsite_url), \"devices\" (device makes and models; query filters\nby make or model) or \"carriers\" (mobile carrier ids; query\nfilters by name, country by country code)."
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of results, clamped to 1-100."
      • addedInput schema / properties / query / description
        Added value: +"Search text for the chosen kind: a community search term, an\ninterest or language name filter, a city name, comma-separated\nseed keywords, comma-separated seed communities for\ncommunity_suggestions (e.g. \"PPC,googleads\"), a device make or\nmodel filter, or a carrier name filter."
      • addedInput schema / properties / website_url / description
        Added value: +"Website for kind \"community_suggestions\"; ignored for\nother kinds."
    • Addedsuggest_brands
    • Changedupdate_ad_group4 fields changed
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Numeric ID of the ad group to update."
      • addedInput schema / properties / ad_group_name / description
        Added value: +"New ad group name. Empty leaves the name unchanged."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, dashes optional). Defaults to\nthe configured account."
      • addedInput schema / properties / max_cpc / description
        Added value: +"New maximum CPC bid in the account's currency (an amount, not\nmicros). 0 leaves the bid unchanged; negative values are rejected.\nAt least one of ad_group_name or max_cpc is required."
    • Changedupdate_campaign12 fields changed
      • addedInput schema / properties / bidding_strategy / description
        Added value: +"MAXIMIZE_CONVERSIONS | TARGET_CPA | TARGET_ROAS |\nMAXIMIZE_CONVERSION_VALUE | TARGET_SPEND | MANUAL_CPC. Empty leaves\nthe strategy unchanged."
      • addedInput schema / properties / campaign_id / description
        Added value: +"The numeric ID of the campaign to update (required)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / daily_budget / description
        Added value: +"New daily budget in the account's currency (not micros),\nat most the config's max_daily_budget. 0 leaves it unchanged."
      • addedInput schema / properties / display_expansion_enabled / description
        Added value: +"Alias for display_network_enabled; both must\nmatch when both are given."
      • addedInput schema / properties / display_network_enabled / description
        Added value: +"Enable Search campaign display expansion.\nOmitted leaves the setting unchanged."
      • addedInput schema / properties / geo_target_ids / description
        Added value: +"REPLACES all positive geo targets; must not be empty\nwhen given. Common IDs: \"2276\" Germany, \"2040\" Austria, \"2756\"\nSwitzerland, \"2840\" USA, \"2826\" UK."
      • addedInput schema / properties / language_ids / description
        Added value: +"REPLACES all language targets; must not be empty when\ngiven. Common IDs: \"1001\" German, \"1000\" English, \"1002\" French,\n\"1003\" Spanish, \"1004\" Italian."
      • addedInput schema / properties / max_cpc / description
        Added value: +"Maximize Clicks CPC cap in the account's currency when\nbidding_strategy is TARGET_SPEND, or when the existing campaign\nalready uses TARGET_SPEND. Increases are limited by the config's\nmax_bid_increase_pct. 0 leaves it unchanged."
      • addedInput schema / properties / search_partners_enabled / description
        Added value: +"Include ads on Search partners. Omitted leaves\nthe setting unchanged."
      • addedInput schema / properties / target_cpa / description
        Added value: +"Target CPA in the account's currency; required if\nbidding_strategy is TARGET_CPA. 0 leaves it unchanged."
      • addedInput schema / properties / target_roas / description
        Added value: +"Target ROAS as a ratio (e.g. 4.0 = 400%); required if\nbidding_strategy is TARGET_ROAS. 0 leaves it unchanged."
    • Changedupdate_reddit_ad5 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / ad_id / description
        Added value: +"Reddit ad id (from get_reddit_ads)."
      • addedInput schema / properties / allow_comments / description
        Added value: +"true or false turns comments on the ad's post on or\noff; omitted leaves them unchanged."
      • addedInput schema / properties / click_url / description
        Added value: +"New landing URL (http:// or https://), verified to be\nreachable. TEXT (free-form) ads open the post itself and take no\nclick_url."
      • addedInput schema / properties / name / description
        Added value: +"New ad name; empty keeps the current one."
    • Changedupdate_reddit_ad_group29 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / ad_group_id / description
        Added value: +"Reddit ad group id (from get_reddit_ad_groups)."
      • addedInput schema / properties / bid_strategy / description
        Added value: +"BIDLESS, MANUAL_BIDDING, MAXIMIZE_VOLUME or TARGET_CPX."
      • addedInput schema / properties / bid_type / description
        Added value: +"CPC, CPM, CPV, CPV6 or CPV15."
      • addedInput schema / properties / bid_value / description
        Added value: +"New bid in account currency."
      • addedInput schema / properties / carriers
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of mobile carrier ids (from\nsearch_reddit_targeting kind \"carriers\", e.g. \"O2_DEUTSCHLAND\"),\nchecked against Reddit's carrier list. [] clears it."
        +}
      • addedInput schema / properties / communities / description
        Added value: +"Full list of community (subreddit) names to target."
      • addedInput schema / properties / custom_audience_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of custom audiences to target (from\nget_reddit_audiences). It narrows the ad group to those people.\n[] clears it."
        +}
      • addedInput schema / properties / daily_budget / description
        Added value: +"New daily budget in account currency (positive).\nMutually exclusive with lifetime_budget; the budget type (daily vs\nlifetime) cannot change after publishing."
      • addedInput schema / properties / devices
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "additionalProperties": true,
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of device targets, objects like {\"type\":\n\"MOBILE\", \"os\": \"IOS\", \"min_version\": \"16\"} (type DESKTOP or\nMOBILE; optional os ANDROID or IOS, major OS versions with iOS at\nleast 14, and label_map {make: [models]} with makes/models from\nsearch_reddit_targeting kind \"devices\"). [] clears it (every\ndevice)."
        +}
      • addedInput schema / properties / end_time / description
        Added value: +"New end, same formats as start_time."
      • addedInput schema / properties / excluded_communities / description
        Added value: +"Full list of community names to exclude."
      • addedInput schema / properties / excluded_custom_audience_ids
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of custom audiences to\nexclude, e.g. existing customers. [] clears it."
        +}
      • addedInput schema / properties / excluded_geolocations / description
        Added value: +"Full list of geolocation ids to exclude."
      • addedInput schema / properties / excluded_interests
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of interest ids to exclude (Reddit\nmarks this field deprecated). [] clears it."
        +}
      • addedInput schema / properties / excluded_keywords / description
        Added value: +"Full list of keywords to exclude."
      • addedInput schema / properties / expand_targeting / description
        Added value: +"Whether Reddit may expand delivery beyond the\ntargeting; omitted leaves it unchanged."
      • addedInput schema / properties / gender / description
        Added value: +"FEMALE or MALE; empty leaves gender targeting unchanged."
      • addedInput schema / properties / geolocations / description
        Added value: +"Full list of geolocation ids to target (e.g. \"DE\" or\n\"DE:2874225\")."
      • addedInput schema / properties / interests / description
        Added value: +"Full list of interest ids to target."
      • addedInput schema / properties / keywords / description
        Added value: +"Full list of keywords to target."
      • addedInput schema / properties / languages / description
        Added value: +"Full list of language codes (ISO 639-1, upper-cased\nautomatically, e.g. \"DE\")."
      • addedInput schema / properties / lifetime_budget / description
        Added value: +"New lifetime budget in account currency (positive).\nNeeds an end_time (passed or already set); compared to\nmax_daily_budget by its per-day share."
      • addedInput schema / properties / locations / description
        Added value: +"Placements, FEED and/or COMMENTS_PAGE (conversation\npages); cannot be an empty list."
      • addedInput schema / properties / name / description
        Added value: +"New ad group name; empty keeps the current one."
      • addedInput schema / properties / platforms / description
        Added value: +"Full list of platforms: ALL, DESKTOP, DESKTOP_LEGACY,\nMOBILE_NATIVE, MOBILE_WEB, MOBILE_WEB_3X or SHREDTOP."
      • addedInput schema / properties / schedule / description
        Added value: +"Weekly delivery windows (\"time of day\" in Ads Manager), a\nlist of blocks like {\"days\": \"MON-FRI\", \"start_hour\": 13,\n\"end_hour\": 23} (day names, hours 0-23, end_hour inclusive) or the\nnative {\"start_day\": \"FRI\", \"start_hour\": 22, \"end_day\": \"SAT\",\n\"end_hour\": 3}. [] clears it (deliver at any time). Hours apply in\neach viewer's local time, not the account time zone."
      • addedInput schema / properties / start_time / description
        Added value: +"New start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare\nYYYY-MM-DD means 00:00 UTC that day."
      • addedInput schema / properties / view_modes
        Added value: +{
        +  "anyOf": [
        +    {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "description": "Full list of feed layouts: ALL, CARD, CLASSIC, COMPACT\nor IMMERSIVE. [] clears it."
        +}
    • Changedupdate_reddit_campaign12 fields changed
      • addedInput schema / properties / ad_account_id / description
        Added value: +"Reddit ad account id (from list_reddit_accounts).\nEmpty uses reddit.ad_account_id from the config."
      • addedInput schema / properties / bid_strategy / description
        Added value: +"BIDLESS, MAXIMIZE_VOLUME or TARGET_CPX (CBO only)."
      • addedInput schema / properties / bid_type / description
        Added value: +"CPC, CPM, CPV, CPV6 or CPV15 (CBO only)."
      • addedInput schema / properties / bid_value / description
        Added value: +"New bid in account currency (CBO only)."
      • addedInput schema / properties / campaign_id / description
        Added value: +"Reddit campaign id (from get_reddit_campaigns)."
      • addedInput schema / properties / daily_budget / description
        Added value: +"New daily budget in account currency (positive; CBO\nonly). Mutually exclusive with lifetime_budget; the budget type\n(daily vs lifetime) cannot change after publishing."
      • addedInput schema / properties / end_time / description
        Added value: +"New end, same formats as start_time."
      • addedInput schema / properties / lifetime_budget / description
        Added value: +"New lifetime budget in account currency (positive;\nCBO only). Needs an end_time (passed or already set); compared to\nmax_daily_budget by its per-day share."
      • addedInput schema / properties / name / description
        Added value: +"New campaign name; empty keeps the current one."
      • addedInput schema / properties / schedule / description
        Added value: +"Weekly delivery windows (\"time of day\" in Ads Manager; CBO\nonly), a list of blocks like {\"days\": \"MON-FRI\", \"start_hour\": 13,\n\"end_hour\": 23} (day names, hours 0-23, end_hour inclusive) or the\nnative {\"start_day\": \"FRI\", \"start_hour\": 22, \"end_day\": \"SAT\",\n\"end_hour\": 3}. [] clears it (deliver at any time). Hours apply in\neach viewer's local time, not the account time zone. A campaign\nschedule replaces every ad group's."
      • addedInput schema / properties / spend_cap / description
        Added value: +"Campaign spend cap in account currency; 0 removes it."
      • addedInput schema / properties / start_time / description
        Added value: +"New start, ISO 8601 (e.g. 2026-10-01T00:00:00Z); a bare\nYYYY-MM-DD means 00:00 UTC that day."
    • Changedupdate_responsive_search_ad9 fields changed
      • addedInput schema / properties / ad_id / description
        Added value: +"Numeric ID of the existing responsive search ad."
      • addedInput schema / properties / clear_path1 / description
        Added value: +"True sets path1 to an empty string (overrides path1)."
      • addedInput schema / properties / clear_path2 / description
        Added value: +"True sets path2 to an empty string (overrides path2)."
      • addedInput schema / properties / customer_id / description
        Added value: +"Google Ads customer ID (digits, e.g. \"1234567890\"). Empty\nuses the configured default account."
      • addedInput schema / properties / descriptions / description
        Added value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in. 2-4 descriptions, max 90 chars each, at most 1 per\npin slot (DESCRIPTION_1, DESCRIPTION_2). Same entry format as\nheadlines."
      • addedInput schema / properties / final_url / description
        Added value: +"Empty means no change; non-empty replaces the final URL and\nis checked for reachability."
      • addedInput schema / properties / headlines / description
        Added value: +"LIST-REPLACE: None or [] means no change; a non-empty list\nfully swaps in for the existing headlines. Google's RSA constraints\napply: 3-15 headlines, max 30 chars each, at most 2 per pin slot.\nEach entry is a plain string (unpinned) or {\"text\": \"...\",\n\"pinned_field\": \"HEADLINE_1\"} (HEADLINE_1-3)."
      • addedInput schema / properties / path1 / description
        Added value: +"Empty means no change; non-empty sets the first display path\n(max 15 chars)."
      • addedInput schema / properties / path2 / description
        Added value: +"Empty means no change; non-empty sets the second display path\n(max 15 chars)."
    • Addedupload_images
    • Changedvalidate_tracking4 fields changed
      • addedInput schema / properties / date_range_end / description
        Added value: +"End date, same formats as date_range_start."
      • addedInput schema / properties / date_range_start / description
        Added value: +"Start date: \"today\", \"yesterday\", \"NdaysAgo\" (e.g.\n\"28daysAgo\"), or \"YYYY-MM-DD\"."
      • addedInput schema / properties / expected_events / description
        Added value: +"Event names found in the codebase, e.g. [\"sign_up\",\n\"purchase\"]."
      • addedInput schema / properties / property_id / description
        Added value: +"GA4 property as \"properties/123456789\" (see\nget_account_summaries). If empty, uses the default from config."
  5. 20 tool updatesv0.14.0
    • Addeddraft_reddit_ad
    • Addeddraft_reddit_ad_group
    • Addeddraft_reddit_campaign
    • Addedenable_reddit_entity
    • Addedestimate_reddit_ad_group
    • Addedget_reddit_account_history
    • Addedget_reddit_ad_groups
    • Addedget_reddit_ads
    • Addedget_reddit_campaigns
    • Addedget_reddit_performance
    • Addedget_reddit_pixels
    • Addedlist_reddit_accounts
    • Addedlist_reddit_funding_instruments
    • Addedpause_reddit_entity
    • Addedremove_reddit_entity
    • Addedrun_reddit_report
    • Addedsearch_reddit_targeting
    • Addedupdate_reddit_ad
    • Addedupdate_reddit_ad_group
    • Addedupdate_reddit_campaign
  6. 4 tool updatesv0.13.3
    • Addeddraft_create_conversion_action
    • Addeddraft_remove_conversion_action
    • Addeddraft_update_conversion_action
    • Addedupdate_responsive_search_ad
  7. 30 tool updatesv0.13.2
    • Addedadd_negative_locations
    • Addedadd_to_negative_keyword_list
    • Addedanalyze_page_speed
    • Addedattach_shared_set_to_campaigns
    • Addedaudit_event_coverage
    • Addedconfirm_and_apply
    • Addeddiscover_keywords
    • Addeddraft_callouts
    • Addeddraft_campaign
    • Addeddraft_image_assets
    • Addeddraft_key_event
    • Addedestimate_budget
    • Addedgenerate_tracking_code
    • Addedget_account_summaries
    • Addedget_audience_performance
    • Addedget_campaign_performance
    • Addedget_gtm_version
    • Addedget_gtm_workspace_diff
    • Addedget_keyword_performance
    • Addedget_negative_keyword_list_campaigns
    • Addedget_pmax_performance
    • Addedget_recommendations
    • Addedget_search_terms
    • Addedget_tracking_events
    • Addedlist_gtm_accounts
    • Addedlist_gtm_workspaces
    • Addedpropose_negative_keyword_list
    • Addedrun_gaql
    • Addedrun_realtime_report
    • Addedvalidate_tracking
  8. 30 tool updatesv0.13.0
    • Removedadd_negative_locations
    • Removedadd_to_negative_keyword_list
    • Removedanalyze_page_speed
    • Removedattach_shared_set_to_campaigns
    • Removedaudit_event_coverage
    • Removedconfirm_and_apply
    • Removeddiscover_keywords
    • Removeddraft_callouts
    • Removeddraft_campaign
    • Removeddraft_image_assets
    • Removeddraft_key_event
    • Removedestimate_budget
    • Removedgenerate_tracking_code
    • Removedget_account_summaries
    • Removedget_audience_performance
    • Removedget_campaign_performance
    • Removedget_gtm_version
    • Removedget_gtm_workspace_diff
    • Removedget_keyword_performance
    • Removedget_negative_keyword_list_campaigns
    • Removedget_pmax_performance
    • Removedget_recommendations
    • Removedget_search_terms
    • Removedget_tracking_events
    • Removedlist_gtm_accounts
    • Removedlist_gtm_workspaces
    • Removedpropose_negative_keyword_list
    • Removedrun_gaql
    • Removedrun_realtime_report
    • Removedvalidate_tracking
  9. 26 tool updatesv0.12.0
    • Addedadd_negative_locations
    • Addedanalyze_page_speed
    • Addedaudit_event_coverage
    • Changeddiscover_keywords1 field changed
      • addedInput schema / properties / include_monthly_volumes
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Addeddraft_demographic_targeting
    • Addeddraft_key_event
    • Changedget_ad_performance1 field changed
      • addedInput schema / properties / compact
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Changedget_campaign_performance1 field changed
      • addedInput schema / properties / compact
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Addedget_demographic_targeting
    • Addedget_gtm_tag
    • Addedget_gtm_trigger
    • Addedget_gtm_version
    • Addedget_gtm_workspace_diff
    • Changedget_keyword_performance1 field changed
      • addedInput schema / properties / compact
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Addedget_merchant_feed_health
    • Changedget_search_terms1 field changed
      • addedInput schema / properties / compact
        Added value: +{
        +  "default": false,
        +  "type": "boolean"
        +}
    • Addedlist_gsc_sites
    • Addedlist_gtm_accounts
    • Addedlist_gtm_containers
    • Addedlist_gtm_tags
    • Addedlist_gtm_triggers
    • Addedlist_gtm_variables
    • Addedlist_gtm_versions
    • Addedlist_gtm_workspaces
    • Addedlist_merchant_accounts
    • Addedrun_gsc_report
  10. 46 tool updatesv0.9.0
    • First observedadd_negative_keywords
    • First observedadd_to_negative_keyword_list
    • First observedanalyze_campaign_conversions
    • First observedattach_shared_set_to_campaigns
    • First observedattribution_check
    • First observedconfirm_and_apply
    • First observeddetach_shared_set_from_campaigns
    • First observeddiscover_keywords
    • First observeddraft_ad_group
    • First observeddraft_callouts
    • First observeddraft_campaign
    • First observeddraft_image_assets
    • First observeddraft_keywords
    • First observeddraft_responsive_search_ad
    • First observeddraft_sitelinks
    • First observeddraft_structured_snippets
    • First observedenable_entity
    • First observedestimate_budget
    • First observedgenerate_tracking_code
    • First observedget_account_summaries
    • First observedget_ad_performance
    • First observedget_asset_performance
    • First observedget_audience_performance
    • First observedget_campaign_performance
    • First observedget_detailed_asset_performance
    • First observedget_keyword_performance
    • First observedget_negative_keyword_list_campaigns
    • First observedget_negative_keyword_list_keywords
    • First observedget_negative_keyword_lists
    • First observedget_negative_keywords
    • First observedget_pmax_performance
    • First observedget_recommendations
    • First observedget_search_terms
    • First observedget_tracking_events
    • First observedhealth_check
    • First observedlanding_page_analysis
    • First observedlist_accounts
    • First observedpause_entity
    • First observedpropose_negative_keyword_list
    • First observedremove_entity
    • First observedrun_ga4_report
    • First observedrun_gaql
    • First observedrun_realtime_report
    • First observedupdate_ad_group
    • First observedupdate_campaign
    • First observedvalidate_tracking

TDQS

A3.7/5.0

Scored across 137 tools

Disambiguation4/5

Most tools have a clearly distinct purpose and the descriptions actively cross-reference siblings (e.g. propose_negative_keyword_list vs add_negative_keywords vs add_to_negative_keyword_list), which sharply limits misselection. However, several name-level clusters remain confusable at a glance (get_negative_keywords vs get_negative_keyword_lists vs get_negative_keyword_list_keywords; get_brand_lists vs get_brand_list_brands vs get_brand_list_campaigns; analyze_campaign_conversions vs attribution_check vs audit_event_coverage), and draft_ad_group/draft_campaign optionally absorb keywords that draft_keywords also adds.

Naming Consistency4/5

Names are uniformly snake_case and follow a verb_noun shape, so the surface is readable and predictable. The verb choice is heterogeneous, though: the same 'preview then confirm_and_apply' pattern is exposed as draft_*, add_*, propose_*, attach_*, detach_* and update_*, and there are outliers like health_check and confirm_and_apply, which is a minor deviation rather than a break in convention.

Tool Count2/5

137 tools is far more than one server should expose, well past the 50+ threshold in the rubric. The scope genuinely spans Google Ads, Reddit Ads, GA4, GTM, GSC, Merchant Center and PageSpeed, which justifies breadth, but the read/write/discovery surface is fragmented into so many near-adjacent tools that the set is heavy and hard to navigate.

Completeness4/5

Coverage is extensive across every advertised platform: discovery, full read/report coverage, and a consistent draft → confirm_and_apply write pipeline spanning CRUD for campaigns, ad groups, ads, keywords, audiences, brand lists, negatives, conversions and GTM entities, plus diagnostics and uploads. The few gaps (e.g. no campaign creation for Display/Video/PMax, no GA4 property administration) are deliberate refusals rather than missing operations.

Maintenance

ActivityActive
ResponsivenessSlow

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    F
    maintenance
    MCP server for managing Google Ads, Meta Ads, LinkedIn Ads, and TikTok Ads via AI. 210+ tools including account audits, wasted spend detection, and PMax insights.
    2
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    A unified MCP server that gives AI assistants direct access to Google Analytics 4, Google Search Console, Google Ads and Google Merchant Center data using OAuth2 user credentials.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A universal marketing MCP server that lets AI clients manage 20+ ad and marketing platforms (Google Ads, Meta, TikTok, etc.) with 500+ operations, including write actions with user approval.
    53
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    A hosted MCP server that enables managing Google Ads, Microsoft Advertising, TikTok Ads, LinkedIn Ads, and other Google services from ChatGPT, Claude, or any MCP client using natural language, with no code or API keys required.
    MIT