v0.5.0
What's New
Shared Negative Keyword Lists (SharedSet API)
Create reusable negative keyword lists that can be applied across multiple campaigns — a major improvement over add_negative_keywords which only targets a single campaign.
New tools:
propose_negative_keyword_list— draft a shared list and attach it to a campaign (write, preview-based)get_negative_keyword_lists— list all SharedSets in the account with name, ID, status, and keyword countget_negative_keyword_list_keywords— inspect keywords inside a specific listget_negative_keyword_list_campaigns— see which campaigns use a list
The orchestration rules now guide the AI to check for existing lists before creating new ones, avoiding duplicates.
Keyword Discovery via Keyword Planner
Discover new keyword ideas from seed keywords and/or a URL — mirrors the "Discover new keywords" workflow in the Google Ads Keyword Planner UI.
New tool:
discover_keywords— returns keyword ideas sorted by avg monthly search volume, with competition level (LOW/MEDIUM/HIGH), competition index, and top-of-page bid range. Supports both seed modes: start with keywords, start with a website, or both together.
Chains naturally with estimate_budget (forecast cost) and draft_keywords / draft_campaign (act on ideas).
Retry/Backoff for API Rate Limits
call_with_retry— exponential backoff with jitter for 429 / RESOURCE_EXHAUSTED errors (up to 3 retries)- Rate-limit detection checks gRPC
StatusCode.RESOURCE_EXHAUSTEDonGoogleAdsExceptionfirst (reliable), with string matching as a fallback for non-gRPC exceptions
Safety & Reliability Improvements
- Partial failure handling: The 3-step SharedSet mutation (create list → add keywords → attach to campaign) now reports partial failures with the SharedSet resource name, so you can clean up or retry instead of being left with orphaned resources
- Input validation:
shared_set_idis validated as numeric before GAQL interpolation in all SharedSet read tools - Correct safety scoping:
propose_negative_keyword_listuses its own operation name (create_negative_keyword_list) in the safety guard, so blocking it doesn't accidentally blockadd_negative_keywordsor vice versa
Documentation
- README updated with all 43 tools (was 38), new roadmap items, and keyword discovery usage example
- Orchestration rules updated in both
.cursor/rules/adloop.mdc(canonical) and.claude/rules/adloop.md(synced) with new tool tables, negative keyword list workflow, and keyword discovery pattern
Total tools: 43 (was 38) | Tests: 118 passing
Based on PR #9 by @chrmoller, with review fixes applied. Full details in the PR comment.