Skip to content
Draft
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/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
},
"metadata": {
"description": "Taboola Realize plugins for Claude Code",
"version": "0.4.0"
"version": "0.5.0"
},
"plugins": [
{
Expand Down
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "realize-plugin",
"displayName": "Realize Plugin",
"version": "0.4.0",
"version": "0.5.0",
"description": "Query Realize campaigns, pull performance reports, and create/update campaigns, ad items, and conversion rules through natural language β€” powered by the Realize remote MCP.",
"author": {
"name": "Taboola"
Expand Down
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,17 @@ All notable changes to this plugin will be documented here. Format loosely follo

## [Unreleased]

> **Release gate:** the dynamic-report changes below track an upstream MCP release that is **not yet live on production `mcp.realize.com`**. Do not ship this version until the live tool list shows `get_dynamic_report_settings` / `get_dynamic_report_data` and drops the three retired report tools β€” then re-verify the staging-observed behaviors marked below against the shipped release.

### Changed
- **Reporting is now the metamodel-driven dynamic report; three fixed report tools retired (breaking).** Upstream replaced `get_top_campaign_content_report`, `get_campaign_breakdown_report`, and `get_campaign_site_day_breakdown_report` with `get_dynamic_report_settings` + `get_dynamic_report_data` β€” any combination of the metamodel's dimensions (per the Realize UI's list: campaign, ad, day/week/month/quarter, country, region, DMA, site, platform, browser, OS β€” the account's live metamodel is authoritative) and metrics, with structured filters, server-side sort, and top-N paging. `get_campaign_history_report` survives, reframed per upstream as the campaign **change/audit log** (not performance data β€” previously documented here as a performance time-series). The dimensions previously unreachable from the plugin are now covered (country, platform, and OS validated on staging; browser and region per the UI's dimension list).
- **The two-step workflow is mandatory and documented everywhere the data tool is:** `get_dynamic_report_settings` first β€” it is the only source of valid fully-qualified column/filter names (account-specific; per-rule conversion metrics vary) β€” then `get_dynamic_report_data` with names copied verbatim. Dates are `date_preset` XOR `date_from`+`date_to`; `ACCOUNT_ID` and date filters are auto-injected.
- **The response banner drops the grand `Total`** (now `Records | Grain | pagination`), so the pagination stop-rule changed from "read `Total`" to "page until a short page", and skills state fetched scope instead of implying completeness. `knowledge/reporting-aggregation.md` was rebuilt around this, gaining the sum-vs-ratio / weighted-re-derivation rules the old version lacked, and a preference for server-side aggregation (request the grain you want; don't sum day rows client-side).
- **Staging-validated 2026-08-20 (10-question comparison, 20/20 runs, raw counters exact):** the behavior quirks found there are recorded as *staging-observed, re-verify at release*: CTR = clicks / **visible** impressions (differs from other surfaces β€” raw counters reconcile, rates may not), Week buckets start Sunday with labels that can precede the range, `SITE.NAME` 400s (use `SITE.DESCRIPTION`), and entity-attribute dimensions (bidding strategy, Ad CTA) returning unaggregated rows.
- **Reporting account types documented:** PARTNER and NETWORK accounts report; GROUP accounts and admin networks return 403 by design β€” pick another account, don't retry or re-auth.
- **Every stale claim site updated in the same change** (per the stale-capability-claims policy): the agent's Tool Reference, examples, claim-validation list, CSV/sort/filter technical specs, and tool-existence boundary (now naming the three retired tools as off-surface); the `reports` skill and both its references; `optimize-campaign`'s dimension table; `campaigns`' top-campaign flow; `knowledge/reporting-aggregation.md`; `CLAUDE.md`'s diagram, CSV section, and a new design-decision note; `README.md`'s skills table; read Scenarios 5–9 and 11; `docs/realize-best-practices-gap.md`'s tool baseline; `tests/README.md`'s truncation note; and `knowledge/manifest.json`'s retrieval keywords. `tests/test-scenarios-dynamic-report.md` (the 10 prepared comparison questions) and `docs/reports-gaps.md` (with a migration status update) are committed alongside.
- **Independent review rounds also fixed pre-existing guidance the migration exposed** (bugs that predate this change but broke loudest under the new tool surface): `optimize-campaign`'s P1 pre-check and RCA Signal 1 had the history report's meaning inverted; Signal 4 demanded fired/matched ratios no tool exposes (now: attributed-conversions trend + `diagnose-tracking` handoff); auction insights, frequency, and SpendGuard state are now marked UI-sourced (ask the user, never fabricate); the action-prescription bullets routed MCP-writable fixes to UI paths (now: `manage-campaigns` writes); the sum-reconciliation gate's reference is now window-scoped (`get_campaign.spent` is lifetime β€” using it for a bounded window failed the gate by construction); and the **daily-spend β‰₯ 8Γ— CPA goal floor** β€” promised by the agent, README, the capability baseline, and two test scenarios, but missing from the skill itself after an earlier rewrite β€” is reinstated in the data-sufficiency gates with its toolkit provenance.

### Added
- **`diagnose-tracking` skill β€” pixel-health diagnosis, previously an explicit refusal.** Adapted from an internal Taboola support team's pixel-diagnostics skill with everything internal stripped β€” no internal databases, no Salesforce intake, no internal config flags; adoption notes and the MCP capability asks are in `docs/2026-08-22-pixel-expert-adoption-plan.md`. The skill verifies the Taboola Pixel end to end from evidence a client can produce: it fetches the user's page (static install check), reads a user-captured HAR / `window._tfa` dump (runtime firing check, with copy-paste capture instructions written for a non-technical reader), and cross-checks conversion rules and spend via the MCP. Fixes route by owner: site-side as copy-paste instructions, rule-side through `manage-campaigns`' preview-then-confirm gate, Taboola-side through the `/realize-plugin:support` escalation.
- **This flips a documented refusal, so every stale claim site was updated in the same change**: the agent's description, UI-only triage row (pixel-health removed; a dedicated routing row added), over-engagement anchor (Q18 rewritten β€” rule-list archaeology is still the anti-pattern, but the request now has a real workflow), tracking ladder (new rung 3), and tool-existence boundary; the guardrails' out-of-MCP list ("reading pixel health" removed; the belongs-on-the-list-but-doesn't paragraph grew to three); `manage-campaigns`' UI-fallback section; `optimize-campaign`'s P1 pre-check and prescription hand-offs; `README.md` scope + skills table; `knowledge/tracking.md`'s covers/doesn't section and its manifest entry. Pixel *installation*, codeless-conversion setup, and *test-firing* remain genuinely UI-only.
Expand Down
11 changes: 8 additions & 3 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@ This is a thin Claude Code plugin that wraps the [Realize remote MCP](https://gi
β”‚ search_lookalike_audiences, search_contextual_segments,
β”‚ search_publishers, get_conversion_rules,
β”‚ list_time_zones, list_cta_types
β”œβ”€β”€β–Ί reports skill β†’ 4 report tools (CSV output)
β”œβ”€β”€β–Ί reports skill β†’ get_dynamic_report_settings + get_dynamic_report_data
β”‚ (metamodel-driven performance reports, CSV)
β”‚ + get_campaign_history_report (change log)
β”œβ”€β”€β–Ί optimize-campaign skill β†’ diagnoses underperformance; hands write
β”‚ prescriptions to manage-campaigns
β”œβ”€β”€β–Ί diagnose-tracking skill β†’ pixel-health diagnosis. ONE non-MCP fetch:
Expand Down Expand Up @@ -56,7 +58,7 @@ This is a thin Claude Code plugin that wraps the [Realize remote MCP](https://gi
β–Ό
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ Realize MCP (https://mcp.realize.com) β”‚
β”‚ OAuth 2.1, 19 read + 8 write tools β”‚
β”‚ OAuth 2.1, 18 read + 8 write tools β”‚
β”‚ wired here. Writes routed exclusively β”‚
β”‚ through the manage-campaigns skill. β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
Expand Down Expand Up @@ -196,7 +198,10 @@ Also check for a **deprecation** alongside the addition β€” this release renamed
The plugin's agent and skills must never fabricate tool calls. When a user requests an action that the current upstream MCP does not expose (e.g., deleting or duplicating a campaign β€” there are no MCP tools for those today), the `manage-campaigns` skill takes over with a UI fallback reference. When upstream adds new tools, update the agent's Tool Reference, wire the new tool into the most appropriate skill, and trim the `manage-campaigns` UI fallback for the steps that become automatable β€” in an explicit PR, not silently. **Write tools require special handling**: route them exclusively through `manage-campaigns` so the preview-then-confirm gate (and the mandatory `β–Ά WRITE TARGET` account header) cannot be bypassed.

### CSV, not JSON
Report tools return CSV. The leading metadata line (`Records: N | Total: M | Page: X | Size: Y`) is the primary pagination signal. Skills must cite `Total` in their summaries.
Report tools return CSV. The dynamic report's metadata line carries `Records`, the row `Grain`, and pagination β€” **no grand `Total`**, so the pagination signal is a short page (fewer rows than `page_size`), and skills must state fetched scope instead of implying completeness. `get_campaign_history_report` keeps the legacy `Records | Total | Page | Size` line β€” there, skills cite `Total`.

### The dynamic report replaced three fixed report tools β€” and the plugin ships that swap only when production does
Upstream retired `get_top_campaign_content_report`, `get_campaign_breakdown_report`, and `get_campaign_site_day_breakdown_report` from the live surface (handlers kept server-side for re-enable) in favor of the metamodel pair `get_dynamic_report_settings` / `get_dynamic_report_data`. `get_campaign_history_report` survives because it's a change/audit log, not PERFORMANCE data β€” the docs must keep that distinction, or trend questions get routed to an audit log. The two-step is load-bearing: settings-first is the only source of valid fully-qualified field names, and every doc that mentions the data tool repeats it because guessing names is the observed failure mode. The staging-validated behavior quirks (visible-impressions CTR, Sunday weeks, `SITE.DESCRIPTION` over `SITE.NAME`, unaggregated entity-attribute dimensions) are recorded in the skill and `knowledge/reporting-aggregation.md` as *staging-observed* β€” re-verify them against the shipped release before treating one as permanent, and remove any that upstream fixed (stale-capability-claims class, in the flattering direction). The missing grand `Total` is **not** on that list β€” it's the upstream banner contract, and the short-page pagination rule that replaces the `Total` read stays.

### All IDs are opaque strings from the API
Users often type numeric IDs in natural language. The MCP expects opaque string identifiers (e.g., `advertiser_12345_prod` for `account_id`) returned by its own tools. Every skill and the agent must route account lookups through `search_accounts` first and pass returned IDs through verbatim β€” no coercion to numbers, no re-casing, no stripping. This applies to `account_id`, `campaign_id`, and `item_id` alike.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ This plugin wraps the remote [realize-mcp](https://github.com/taboola/realize-mc
| [`accounts`](skills/accounts/SKILL.md) | Find Realize accounts and capture the `account_id` every other tool needs |
| [`campaigns`](skills/campaigns/SKILL.md) | List and inspect campaigns and their creatives |
| [`discovery`](skills/discovery/SKILL.md) | Look up targeting metadata, audiences, publishers, conversion rules, time zones, and CTA types β€” resolves opaque IDs before campaign work |
| [`reports`](skills/reports/SKILL.md) | Pull the four Realize performance reports and interpret the CSV output |
| [`reports`](skills/reports/SKILL.md) | Build any-dimension performance reports via the dynamic report (metamodel-driven), pull the campaign change log, and interpret the CSV output |
| [`optimize-campaign`](skills/optimize-campaign/SKILL.md) | Diagnose underperforming campaigns against the toolkit's signal-quality thresholds (100+ clicks per item, daily spend β‰₯ 8Γ— CPA goal, 7–14 day learning phase) and prescribe concrete actions (most now applied via `manage-campaigns`) |
| [`diagnose-tracking`](skills/diagnose-tracking/SKILL.md) | Verify the Taboola Pixel on your site: install check from your page, firing check from a browser recording (HAR) you capture in one minute, cross-check against your conversion rules and spend. Site-side fixes come back as copy-paste instructions; rule fixes apply through `manage-campaigns`' write gate; Taboola-side gaps route to the support escalation |
| [`manage-campaigns`](skills/manage-campaigns/SKILL.md) | Create and update campaigns, Native + Display items, and account-level conversion rules (including attribution windows and retiring a rule). Tiered preview-and-confirm pattern surfaces the target account on every write. Falls back to a UI reference for actions not supported here (delete, duplicate, bulk ops, Custom Rules, CRM uploads, pixel installation, codeless-conversion setup, pixel test-fire) |
Expand Down
Loading
Loading