Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "synter",
"displayName": "Synter",
"description": "The AI Agent Operator for Ads. Connect every ad platform, build audiences from signals and first-party data, generate on-brand creative, launch cross-platform campaigns, and reallocate spend by ROAS — all in one conversation. You direct, the agents execute. Nothing ships without your approval.",
"version": "0.3.0",
"version": "0.4.0",
"license": "MIT",
"author": {
"name": "Synter",
Expand Down
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@

All notable changes to the Synter plugin are documented here. This project follows [semantic versioning](https://semver.org).

## [0.4.0] — 2026-08-04

RSA asset floor: the Google Ads API accepts as few as 3 headlines and 2 descriptions, but ads built at that minimum score "Poor" on Google Ad Strength and get throttled in the auction. The plugin now enforces a real floor everywhere ad copy is created or reviewed.

### Changed
- **`ad-copy-generation`** — RSAs require **11 headlines / 4 descriptions minimum (15/4 recommended)**, every slot filled, the ad group's actual keywords echoed in at least 5 headlines, no filler padding, no truncation (rewrite to the character limit instead).
- **`campaign-preflight`** — new blocking "Creative asset completeness" check: per-ad asset counts read from the platform and compared against the floor; Google Ad Strength POOR/AVERAGE must be fixed before launch; the same fill-every-slot rule applies on every platform at its own ceiling.
- **`creative-director`** and **`media-buyer`** agents — carry the floor rule wherever they direct ad creation or launch.

## [0.3.0] — 2026-07-25

Fourteen new skills deepening diagnostics, measurement, and creative coverage — every one grounded exclusively in public Synter MCP tools.
Expand Down
1 change: 1 addition & 0 deletions agents/creative-director.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@ Method:
Non-negotiables:
- Brand voice: terse, certain, doing the work — show, don't sell. Approved CTAs and verbs only. No banned language ("AI-Powered", "seamless", "revolutionary", "Try the beta", "Start Your Free Trial Today!", and the rest of the forbidden list).
- Accuracy over polish: never fabricate a price, competitor, statistic, or claim. No real number → say so; don't invent it.
- Fill the format: RSAs ship with 11+ headlines and 4 descriptions (15/4 recommended, never the API minimum of 3/2), with the ad group's actual keywords echoed in at least 5 headlines — under-filled asset sets score "Poor" on Ad Strength and get throttled. No filler lines; rewrite to the character limit rather than truncate.
- Policy: pre-check against the target platform's ad rules and flag anything restricted.
- Generating is safe; attaching creative to a live, spending campaign is an action the user approves.
1 change: 1 addition & 0 deletions agents/media-buyer.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ Discipline:
- Confirm the target before touching anything: `list_connected_accounts`. Use the exact account IDs the tools return — never invent or guess an ID. Never run one org's campaign through another org's key.
- Confirm conversion tracking exists and is attached before launch (`ga4_list_conversions`, `get_gtm_tag`, `verify_pixel_ownership`). No tracking → stop and fix it.
- Run preflight every time: geo correct, exclusions applied, tracking firing, budget and bid caps sane (guard hard against fat-finger budgets — a daily budget 10–100x intended is the classic incident), creative policy- and brand-clean, final URL resolves and matches the ad.
- Creative floor before launch: every RSA carries 11+ headlines and 4 descriptions (15/4 recommended — never the API minimum of 3/2), keywords echoed in the headlines. Google Ad Strength POOR or AVERAGE means fix the assets first, not launch and hope.
- Build with `create_campaign_plan` / `create_campaign_for_audience` / `execute_campaign_plan`; go live with `enable_campaign`. For multi-platform, ship each platform and confirm each with its real campaign ID.
- Porting an existing campaign to another platform (e.g. "build my Google campaign on Microsoft"): read the source structure first (`list_campaigns`, `run_gaql_query` for Google), map it to the target platform, then build. Carry over geo, match types, and negatives, not just keywords. This is the **replicate** workflow; the per-platform mapping lives in the **platform-google** / **platform-microsoft** / **platform-meta** / **platform-linkedin** and sibling playbook skills.

Expand Down
3 changes: 2 additions & 1 deletion skills/ad-copy-generation/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Apply brand voice from `${CLAUDE_PLUGIN_ROOT}/context/brand-and-safety.md` to ev

## Fit the format

- **Search (Google, Microsoft) RSAs:** up to 15 headlines and 4 descriptions. Vary them so the platform can assemble strong combinations; pin only when a legal or brand line must always show. Lead with the keyword intent and the offer.
- **Search (Google, Microsoft) RSAs:** the API accepts as few as 3 headlines and 2 descriptions — never ship that. Write **11 headlines and 4 descriptions minimum; 15 headlines and 4 descriptions recommended**. Fill every slot: under-filled RSAs score "Poor" or "Average" on Google Ad Strength and get throttled in the auction. Echo the ad group's actual keywords in at least 5 headlines — the platform grades relevance against the real keyword list, not a paraphrase. Vary the rest so the platform can assemble strong combinations; pin only when a legal or brand line must always show. Lead with the keyword intent and the offer. Never pad with filler lines to hit the count, and never truncate a strong line to fit — rewrite it to the character limit instead.
- **Social (Meta, TikTok, Reddit, X):** primary text plus a hook that earns the first second. Match the platform's native tone; a LinkedIn line is not a TikTok line.
- **LinkedIn:** professional, outcome-led, decision-maker framing.

Expand All @@ -32,5 +32,6 @@ Run every variant through the **ad-policy-compliance** thinking and the brand fo
## Rules

- On brand and on policy, every line. No forbidden words, no invented claims.
- RSAs ship with 11+ headlines and 4 descriptions (15/4 recommended) — the platform minimum of 3/2 is a floor for the API, not for a real ad. At least 5 headlines echo the ad group's actual keywords. No filler, no truncation.
- RSAs get varied, unpinned assets unless a line must always appear.
- Report the variants and the one variable each set is built to test.
12 changes: 10 additions & 2 deletions skills/campaign-preflight/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,20 @@ A campaign with no location criteria serves everywhere, including low-quality an
- Prefer presence-based matching (people in the location) over interest-based unless the goal truly needs it.
- Verify click geography matches intent after launch, not just the configured setting.

## 5. Negatives, budget, and schedule (warn)
## 5. Creative asset completeness (blocking for Search RSAs)

A structurally complete campaign can still launch handicapped: an RSA created with the platform-minimum 3 headlines and 2 descriptions is accepted by the API but scores "Poor" on Google Ad Strength and gets throttled in the auction.

- Read each ad's actual asset counts (Google: `run_gaql_query` on `ad_group_ad` with the RSA headline/description fields). Compare against the floor: **11 headlines / 4 descriptions minimum, 15 / 4 recommended** per RSA.
- Check Google's Ad Strength rating where available. **POOR or AVERAGE = fix the assets before launch**, not after. Add real, keyword-echoing headlines — never filler lines written just to raise the count.
- Apply the same completeness check on every platform at that platform's own ceiling: fill the ad format's available text and creative slots (e.g., Microsoft RSAs mirror Google's 15/4; social formats get all placements' aspect ratios and full primary-text/headline slots), don't ship the minimum the API will accept.

## 6. Negatives, budget, and schedule (warn)

- **Negatives** on Search: confirm a negative list exists so new match surface does not leak spend. See the **negative-keywords** skill.
- **Budget:** sane daily amount, guarded against a fat-finger 10 to 100x. Set a max CPC on manual bidding.
- **Schedule:** if the offer is business-hours only, confirm an ad schedule rather than 24/7.

## Report

Output a short table: each check as PASS, WARN, or FAIL with a one-line note, then a clear recommendation (enable, or fix these first). Blocking fails (structure, tracking, UTMs, geo) must clear before you enable. Then, on the user's go, `enable_campaign` and confirm live with `list_campaigns`.
Output a short table: each check as PASS, WARN, or FAIL with a one-line note, then a clear recommendation (enable, or fix these first). Blocking fails (structure, tracking, UTMs, geo, under-floor creative assets) must clear before you enable. Then, on the user's go, `enable_campaign` and confirm live with `list_campaigns`.