# MGID Campaign Cloner

Copies a proven campaign into a new geo or segment **with its learnings**: the
config, the creatives, and — the step nobody does by hand — the sources already
proven bad on the original.

Tools: [../_shared/ads-mcp-tools.md](../_shared/ads-mcp-tools.md)
Assumptions: [../_shared/assumptions.md](../_shared/assumptions.md)

Neither API has a duplicate endpoint: this skill composes the clone from read +
create calls. Every step is therefore individually visible and individually
approvable.

---

## Required inputs

| Input | Required | Default |
|---|---|---|
| Source campaign ID | Yes | ask |
| What changes | Yes | ask: geo, language, OS/browser, budget, or a plain rename |
| New daily budget | No | source campaign's `limits.dailyLimit` |
| Carry blocklist | No | yes |

---

## MCP tools

| Tool | Purpose |
|---|---|
| `get_campaign` | Full source config — the clone template |
| `get_source_filters` | Blocklist to carry over |
| `get_quality_factors` | QF multipliers worth carrying |
| `get_selective_bidding_statistics` | Sources proven bad but not yet blocked |
| `list_teasers` / `get_teaser` | Creatives to copy |
| `lookup_dictionary` | Resolve the new geo/language/OS ids |
| `create_campaign` | ⚠️ The clone |
| `create_teaser` | ⚠️ Copy each creative |
| `update_source_filters` | ⚠️ Pre-block the carried sources |
| `update_quality_factors` | ⚠️ Carry QF multipliers |

---

## Workflow

### Phase 1 — Read the source

```
get_campaign(sourceId)                    → type, bidding, limits, schedule, targeting, tracking
list_teasers(campaignId: sourceId)        → active creatives
get_source_filters(sourceId, entity)      → existing blocks
get_quality_factors(sourceId, entity)     → existing multipliers
get_selective_bidding_statistics(sourceId, entity, last 30d)
```

`type` and `sourcesOptimization` are **immutable after creation** — the clone
must be created with the source's values, not patched afterwards.

`search_feed` and `newsletter` sources are out of scope.

### Phase 2 — Build the blocklist to carry

Two sets, and be explicit about which is which:

1. **Already blocked** on the source — carry verbatim.
2. **Proven bad but not blocked** — from selective bidding stats, entities with
   spend ≥ $50 and zero conversions, or CPA > 2× target (**ASSUMPTION**, same
   thresholds as `mgid-source-auditor`). Propose, do not assume.

Carrying set 1 is the point of this skill. Set 2 needs the user's yes — those
sources are still unblocked on the original for a reason, even if the reason is
just that nobody got to it.

**Geo caveat:** widget and source performance is geo-specific. When the clone
changes geo, say plainly that carried blocks are a prior, not a fact — a source
that fails in the US may be the best source in Brazil. Recommend carrying blocks
anyway (cheap and reversible) but never present it as validated.

### Phase 3 — Resolve the new targeting

`lookup_dictionary` for every changed dimension. Never guess an id, and never
carry the source's geo ids into a clone whose whole point is a different geo.

### Phase 4 — Preview

Show a diff table: field, source value, clone value, changed?

Include: name (collision-checked against `list_campaigns`), type, bidding
strategy and price, daily limit, every targeting dimension, conversion tracking,
teaser count, blocked entity count.

**Nothing is created before the user approves this table.**

### Phase 5 — Create, in this order

1. `create_campaign` — paused, never live on creation
2. `update_source_filters` — pre-block before a single impression is bought
3. `update_quality_factors` — if carrying
4. `create_teaser` per creative, at the source's `priceOfClick`
5. Report: what exists, what is in moderation, what the user must do to go live

Order matters: blocking after the campaign is live means paying for the traffic
the original already proved worthless.

If any step fails, **stop** and report exactly what exists so far. A half-built
clone that the user knows about is recoverable; one they do not is not.

---

## Output

**Chat:** diff table, then the created-objects list with ids, then the go-live
checklist (moderation pending, budget, activation).

**Return:** the new `campaignId` and the created `teaserId`s.

---

## Guardrails

- The clone is created **paused**. Activation is always a separate, explicit step.
- Never carry `conversionTracking` blindly across accounts — confirm the target
  and postback apply to the new campaign.
- Teaser copy is a **copy**: same title, text and image as the source. Do not
  "improve" or translate the creative — localisation goes through MGID's own
  creative generation, not the agent.
- Budget starts at the source's daily limit or lower, never higher, unless the
  user says so: a clone has no learning history.
- Write scope required from Phase 5; without it, deliver the preview and stop.
