Cross-Channel Paid Media Performance Report (Supermetrics MCP → branded HTML/PDF)
A single AI agent operated the Supermetrics MCP server end to end: discovering authenticated sources, resolving the client's account IDs per platform, and running async data queries for FebJul 2026 spend plus July-MTD campaign breakdowns across Google Ads, LinkedIn Ads and X Ads. Month-over-month deltas, blended CTR/CPC/CPA and a full-month pace projection handled the partial 20-day July window honestly. Google conversions were re-scoped via a ConversionTypeName filter to Download, Copy curl and Contact Sales Form, cutting an inflated 1,282 down to 148 and correcting CPA to $119.59. The client's real SVG logo assets and brand tokens were extracted from their site and embedded into a self-contained HTML report with an inline SVG stacked bar chart and no external chart library. Headless Chromium printed it to A4 using CSS @page control, and output was verified programmatically by rasterizing pages and measuring per-page content bounding boxes to confirm consistent ~13mm margins.
One AI agent ran the full pipeline, MCP data pulls, brand extraction, HTML generation, PDF rendering and pixel-level margin QA, to ship a client report under an EOD deadline.
Role: Sole architect and implementer
The Problem
The client (Tereza at the client) urgently requested, by end-of-day, a paid media performance report covering total spend per month, spend per platform per month (with MoM change), and current-month performance per platform including best/worst campaigns and key conversion/engagement metrics. She needed it fast while finishing her own overall performance reporting.
Data lived across three separate ad platforms (Google Ads, LinkedIn Ads, X/Twitter Ads) accessed via the Supermetrics MCP server, each with different field IDs, report-type quirks, and no default currency dimension. Google Ads conversions included micro-conversions (CTA clicks, login/signup clicks) that inflated totals and cross-platform comparisons. The current month (July) was only partial (1 to 20), so naive MoM comparison against full June was misleading.
Required correct account discovery per platform (partial-string search), correct per-source field IDs, handling of X Ads null conversions (awareness objective, no conversion tracking), conversion-action-level filtering to strip micro-conversions, honest handling of a partial-month window (MTD + projection), faithful replication of the client's monochrome brand identity including extracting their real logo assets, and a print-accurate PDF where margins did not collapse or cut tables across A4 page breaks.
Approach & Architecture
Connected to the Supermetrics MCP server and discovered authenticated data sources and the client account IDs on each platform. Pulled monthly spend/impressions/clicks/conversions for FebJul 2026 per platform, plus July-MTD campaign-level breakdowns. Computed month-over-month deltas, blended KPIs, and a full-month pace projection for the partial July window. Extracted the client's real logo assets and brand tokens from the client and [internal-host], then generated a self-contained branded HTML report via a Python generator script, and rendered it to an A4 PDF with Playwright/Chromium. Iterated to fix PDF margins, filter Google conversions to only meaningful actions, and remove interpretive commentary at the client's request.
Supermetrics MCP (data_source_discovery → accounts_discovery → field_discovery → data_query → get_async_query_results, async schedule_id pattern) feeds hardcoded, verified figures into a Python build script (build_report.py). The script embeds the client's real SVG wordmark and droid mark (currentColor inline SVG) and Summit Chase's logo (base64 PNG), builds an inline SVG stacked bar chart with no external chart library, and emits a single self-contained HTML file to /mnt/user-data/outputs. Playwright Chromium prints the HTML to A4 PDF using CSS @page control (size:A4; margin:14mm 13mm 13mm) with print break rules.
Key Decisions & Trade-offs
Hardest Part
Getting consistent A4 margins in the exported PDF. Initial export used a fixed 1040x1500px page with zero margins, jamming content to page edges and cutting tables. A later attempt with @page{margin:0} plus Playwright pdf() margins caused Chromium to ignore the engine margins and collapse left/right margins to 0. Resolved by controlling margins entirely via CSS @page{size:A4;margin:14mm 13mm 13mm} with prefer_css_page_size=True, then verifying per-page content bounding boxes programmatically (PIL/ImageChops) to confirm ~13mm on all four sides across all pages.
Technical Detail
Monthly time series per platform (FebJul 2026) with spend/impressions/clicks/conversions; July-MTD campaign-level tables per platform; Google conversions segmented by ConversionTypeName. Campaign naming convention observed: Int_[PS|DS|PSM][Theme][MM_YY]_[Geo] (e.g. Int_PS_Non_Brand_Evergreen_2_26_WW, Int_DS_RAISE_Summit_Paris_Geo_7_26_EMEA, Int_PSM_Slack_Integration_7_26_AMER_X).
Python generator script in a Linux container; output to /mnt/user-data/outputs; Playwright Chromium headless for PDF; curl for asset retrieval; fonts via cdn.jsdelivr.net fontsource (Geist, Geist Mono).
Programmatic QA: rendered PDF pages to PNG via pdftoppm; measured per-page content bounding boxes with PIL/ImageChops to confirm margins (~13mm all sides); grepped generated HTML to confirm callouts removed (0), conversion figures updated (148, $119.59, blended $151.21), old total 1,282 absent, and best/worst pills present and mapped to correct campaigns (BEST CPA→Brand, HIGH CPA→RAISE Summit Paris); pdfinfo to confirm A4 size and 4-page count.
Code
// Supermetrics data_query, AW account [ads account], 2026-07-01..2026-07-20 // fields: ConversionTypeName, Conversions // result: // Click Header CTA 977.71 (micro, excluded) // Click Login/Sign Up 153.06 (micro, excluded) // Click Download for Mac 97.89 (kept) // Copy curl 41.98 (kept) // Contact Sales Form 7.99 (kept) => kept total 147.86
{ "ds_id": "AW", "ds_accounts": "[ads account]", "date_range_type": "custom", "start_date": "2026-07-01", "end_date": "2026-07-20", "fields": "Campaignname,ConversionTypeName,Conversions", "filters": "ConversionTypeName [] Click Download for Mac,Copy curl,Contact Sales Form"
}days_elapsed=20; days_month=31 proj_factor=days_month/days_elapsed jul_total=totals[5]; jun_total=totals[4] jul_proj=jul_totalproj_factor # ~= 50194 proj_vs_jun=(jul_proj-jun_total)/jun_total100 # ~= +43.8%
import re
html=open('client_home.html',encoding='utf-8',errors='ignore').read()
svgs=re.findall(r'<svg.*?</svg>', html, re.S)
open('client_wordmark.svg','w').write(svgs[0]) # <title>the client Logo</title>
open('client_mark.svg','w').write(svgs[72]) # id="client-logo" droid markawait pg.goto('file://.../Client_Paid_Media_Report_Jul2026.html', wait_until='networkidle')
await pg.wait_for_timeout(2500)
await pg.pdf(path='.../Client_Paid_Media_Report_Jul2026.pdf', print_background=True, prefer_css_page_size=True)
// CSS: @page{ size:A4; margin:14mm 13mm 13mm; }@page{ size:A4; margin:14mm 13mm 13mm; }
@media print{ .kpis,.pkpi,.callout,.panel,.pbar,.mast,.foot{ break-inside:avoid; } tr,thead,.legend{ break-inside:avoid; } .s-head,.pbar{ break-after:avoid; } table.camp thead{ display:table-header-group; }
}The entire report was produced through an AI agent (Claude) operating an MCP toolchain end to end: discovering Supermetrics data sources and accounts, resolving per-platform field IDs, running async data queries and polling results, extracting the client's live brand assets via shell/curl, generating a deterministic Python build script that assembles a self-contained branded HTML report, rendering it to PDF with headless Chromium, and self-QA'ing the output programmatically (PDF rasterization + pixel bounding-box margin verification + HTML content assertions).
A repeatable, data-driven report generator that pulls live multi-platform Supermetrics data and outputs a brand-matched HTML + A4 PDF; a Slack delivery message was drafted for client handoff. Follow-up (not built in this chat): a dynamic on-demand Supermetrics Studio dashboard.
Measured Results
A brand-faithful, data-only paid media report was produced and delivered to the client by EOD as HTML and a 4-page A4 PDF, sourced entirely from live Supermetrics data across Google, LinkedIn and X. Two client-requested revisions were applied: Google conversions were re-scoped to three meaningful actions (dropping the count from 1,282 to 148 and correcting CPA to $119.59), and interpretive commentary was removed in favor of a separate Slack follow-up. A pre-existing generator bug that suppressed Google best/worst campaign labels was also found and fixed.
| Metric | Value | Before | Source |
|---|---|---|---|
| Total spend June 2026 (all platforms) +83.4% MoM vs May, last full month | $34,897 | $19,032 (May) | Supermetrics (Google+LinkedIn+X) |
| Total spend July 2026 MTD (Jul 1 to 20) Partial 20-day window | $32,383 | $34,897 (June full) | Supermetrics |
| July 2026 projected full-month spend Projection, not a measured result; +43.8% vs June on pace | ≈$50,194 | $34,897 (June) | Projection (MTD x 31/20) |
| Cumulative spend FebJul 2026 | $110,381 | n/a | Supermetrics sum |
| Google Ads conversions Jul MTD (filtered) After excluding micro-conversions; exact filtered sum 147.86 | 148 | 1,282 (unfiltered total) | Supermetrics ConversionTypeName filter |
| Google Ads cost per conversion Jul MTD (filtered) | $119.59 | $13.80 (unfiltered) | Spend $17,681.93 / 147.86 conv |
| Blended CPA Jul MTD (Google+LinkedIn tracked) | $151.21 | $22.27 (pre-filter) | $29,616.61 tracked spend / 195.86 conv |
| July MTD total impressions (3 platforms) Displayed as 3.50M | 3,496,718 | n/a | Supermetrics |
| July MTD total clicks (3 platforms) Blended CTR 0.81%, blended CPC $1.14 | 28,360 | n/a | Supermetrics |
| X Ads engagements Jul MTD Engagement rate ~10.4%; no conversion tracking on X | 280,810 | n/a | Supermetrics (X) |
| LinkedIn best campaign CPL ([campaign], Document) 5.27% CTR, lowest CPL | $238.81 | n/a | Supermetrics (LIA) |
| PDF page margins (all four sides, all pages) A4, 4 pages | ~13mm L/R, ~14 to 24mm T | 0mm (broken initial export) | PIL/ImageChops bounding-box on rasterized pages |
Every figure above was recorded during the work itself. Where no number was measured, none is claimed.