Skip to main content
Glama
marketing-page-quality-gate

marketing-page-quality-gate

Marketing Page Quality Gate — MCP Server

Stop paying to send traffic to leaky pages. AI velocity never ships a leaky funnel.

A media-buying team ships AI-generated landing pages at velocity. The expensive failure mode isn't ugly copy — it's a leaky funnel silently burning ad spend: a missing Meta Pixel so you can't retarget or even measure, a CTA buried below the fold, a fixed-width shell that horizontal-scrolls on every phone, a 1.5MB page that bounces before it paints, a dead link in the hero. None of it shows up in a glance. Every one of them wastes budget.

This is an MCP server that scores any landing page deterministically — the same page always gets the same grade — and translates each defect into dollars of ad spend at risk, so a page gets gated before a dollar of budget hits it. CodeSieve-for-marketing-pages.

It does two things:

  1. Quality Gate (real, working core). Score a page A–F on the signals that move conversion, get the % of ad spend at risk, and block spend on sub-C pages — all deterministic, no API keys, offline.

  2. Ad-platform connector (Half-A). Campaign metrics for Meta / Google / Taboola / TikTok — mocked demo data ("mock": true), plus a real CSV-export reader so the spend gate runs on your actual numbers today. Live API keys are a documented TODO.


See it on real pages

We graded 7 recognizable DTC landing pages as-is (Dr. Squatch, HelloFresh, Bombas, AG1, Magic Spoon, Ruggable, Manscaped). Not one scored an A — even big brands ship leaky funnels.

Live scorecard

Regenerate it yourself: PYTHONPATH=. uv run python examples/build_scorecard.py → report/scorecard.html.

▶ 90-second demo video: demo/demo_video.mp4 — the gate scoring a leaky page F, a clean page A, blocking $10,711 of spend, and the live scorecard. (Script: demo/VIDEO_SCRIPT.md.)


Related MCP server: speed-to-lead-agent

The tools (8)

Tool

What it returns

score_page(url | html)

A–F grade + per-signal scores + % spend at risk

gate_spend(url | html, platform_csv)

PASS/BLOCK verdict + $ at risk — refuses to greenlight a sub-C page

detect_pixels(url | html)

Meta Pixel / GA4 / GTM / TikTok presence

audit_mobile(url | html)

Viewport, responsiveness, horizontal-scroll risk

audit_speed(url | html)

HTML weight, render-blocking scripts, layout-shift images

cta_clarity(url | html)

Primary CTA presence, count, above-the-fold

check_links(url | html)

Broken / internal / outbound links with HTTP status codes

get_campaign_metrics(platform)

MOCKED spend / ROAS / creative perf ("mock": true)

Page tools take either a live url (fetched server-side) or raw html — so you score AI output before it's ever deployed.

Sample score_page output

{
  "grade": "B",
  "score": 85,
  "signals": { "pixels": 0, "mobile": 100, "cta": 100, "speed": 100, "links": 100 },
  "spend_at_risk": {
    "risk_pct": 30,
    "factors": ["Missing tracking pixels blind optimization"]
  }
}

The grade

Five conversion signals, weights sum to 1.0 (links .25, mobile .20, cta .20, speed .20, pixels .15), mapped to a letter: A≥90 · B≥80 · C≥70 · D≥60 · else F.

Spend at risk (think like a buyer, not a QA engineer)

The dollar lens differs from the quality lens. A missing pixel is the single biggest dollar leak — with no pixel you can't measure conversions, can't optimize, can't build retargeting audiences: the entire budget runs blind. So in spend_at_risk, pixels rank top (pixels 30, links 25, cta 20, mobile 15, speed 10). gate_spend multiplies that risk by your real CSV spend and blocks any page below a C.


Run it

Requires Python 3.14 and uv.

uv sync                                 # install deps (mcp, beautifulsoup4, httpx)
uv run pytest -q                        # 54/54 — the deterministic oracle
uv run python -m quality_gate.server    # start the MCP server (stdio)

A no-MCP taste of the scoring: PYTHONPATH=. uv run python demo/show.py score fixtures/leaky_funnel.html.

Register with an MCP client

Claude Code (one-liner):

claude mcp add quality-gate -- uv --directory /path/to/itstoday-entry run python -m quality_gate.server

Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json on macOS):

{
  "mcpServers": {
    "marketing-page-quality-gate": {
      "command": "uv",
      "args": ["--directory", "/path/to/itstoday-entry", "run", "python", "-m", "quality_gate.server"]
    }
  }
}

Then, in natural language: "Gate spend on this landing page before we launch it" → the agent calls gate_spend and gets a PASS/BLOCK verdict with the dollars at risk.


Scope & limits (read this — it's a strength)

This is deterministic static analysis of the pre-launch HTML you control, before you spend. It's built for the buyer's real page type — server-rendered campaign / DTC / affiliate landing pages (Shopify, ClickFunnels, Leadpages, Carrd, WordPress) where the pixel, CTA, and content are in the HTML payload, exactly what static analysis reads accurately and what a CI/agent step can gate in milliseconds with no browser.

It is not a JS-SPA homepage auditor. A React/Next homepage (e.g. a big SaaS marketing site) injects its pixels and renders its CTAs client-side after JS runs, so static analysis of the served HTML will under-report them. That's a deliberate boundary, not a miss: a pixel that only fires after a heavy JS bundle genuinely misses fast-bounce conversions — and the page you're about to gate in your pipeline is your own pre-launch HTML, which is static by definition.

What's real vs. mocked (honest)

  • Quality Gate — real, working, deterministic. No external keys. This is the demo.

  • Ad connectors — get_campaign_metrics is mocked ("mock": true, with a note pointing at where real API keys plug into connectors.py). read_spend_csv is real — it parses an actual Meta/Google/Taboola Ads Manager CSV export so gate_spend works on live spend today. Nothing pretends to be a live API it isn't.


How it was built — the Grok contract-loop

Built with a deterministic contract loop: Claude authored a pytest oracle (contract/pytest_oracle.py, 54 criteria) testing every scorer against fixture HTML pages with known defects; Grok built the implementation under quality_gate/ until the oracle went green, one passing criterion at a time (build_loop.sh). Grok never grades itself — the oracle does, and the contract (tests/, fixtures/, CONTRACT.md) is protected from the builder. A 3-agent review then found real bugs (CTA substring false-matches, pixel-id false positives, a protocol-relative-URL crash, a max-width scroll-risk false positive) — each was fixed the same way: write a failing guard test first, then let the loop fix it against the oracle.

contract/pytest_oracle.py   # the deterministic oracle (Claude-authored)
tests/                      # 54 acceptance tests = the contract
fixtures/                   # HTML pages with known defects
examples/                   # illustrative pages + the live scorecard generator
CONTRACT.md                 # exact spec Grok built against
build_loop.sh               # the Grok contract-loop
quality_gate/               # the implementation (Grok-built)
  pixels · mobile · cta · speed · links · scoring · connectors · gate · server

Built for the It's Today Media build challenge · Marcin Dudek · marcin.dudek.dev@gmail.com

Available Tools

8 tools
audit_mobileA

Audit viewport meta and horizontal-scroll risk on mobile.

Pass a live url (fetched server-side) OR a raw html string. Returns viewport flags, issues list, and mobile score.

Inputs: url, html.

audit_speedB

Audit static load-speed signals from HTML.

Pass a live url (fetched server-side) OR a raw html string. Returns html_bytes, render-blocking scripts, missing img dimensions, and score.

Inputs: url, html.

cta_clarityA

Analyze CTA presence, count, and above-the-fold placement.

Pass a live url (fetched server-side) OR a raw html string. Returns cta_count, primary_cta, above_the_fold flag, and score.

Inputs: url, html.

detect_pixelsA

Detect Meta Pixel, GA4, GTM, and TikTok tracking pixels.

Pass a live url (fetched server-side) OR a raw html string. Returns per-pixel booleans, found list, and count.

Inputs: url, html.

gate_spendA

Block ad spend on leaky landing pages.

Pass a live url (fetched server-side) OR a raw html string. Returns verdict, grade, monthly_spend, spend_at_risk, and risk factors.

Inputs: url, html, platform, platform_csv.

get_campaign_metricsA

Return mock ad-platform campaign metrics (plug real API keys to go live).

Inputs: platform (required).

score_pageA

Score a landing page and return an A-F grade with per-signal breakdown.

Pass a live url (fetched server-side) OR a raw html string. Returns grade, overall score, signals, spend_at_risk, and optional details.

Inputs: url, html, verbose.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A3.9/5.0

    Scored across 8 tools

    Disambiguation5/5

    Each tool targets a distinct audit or analysis aspect (mobile, speed, links, CTA, pixels, spend, campaign metrics, overall score). There is no overlap or ambiguity in their purposes.

    Naming Consistency4/5

    Most tools follow a verb_noun pattern (e.g., audit_mobile, check_links, detect_pixels), but 'cta_clarity' and 'gate_spend' deviate slightly, and 'get_campaign_metrics' uses 'get_' instead of an action verb. Overall consistent with minor exceptions.

    Tool Count5/5

    8 tools is an ideal count for a specialized marketing page audit server. Each tool covers a necessary inspection area without overloading the agent.

    Completeness4/5

    The tool set covers major landing page quality signals: mobile, speed, links, CTA, tracking, spend, and overall scoring. Minor gaps like SEO or content analysis exist but are outside the stated purpose. 'get_campaign_metrics' is noted as mock, but still provides expected functionality.

    Maintenance

    ActivitySlowing
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers