vastlint

VAST validation in agentic ad delivery

AI agents are now buying, trafficking, and delivering ads without human review. Over $30 billion in annual CTV and video ad spend flows through VAST XML. When agents skip creative validation, they ship broken tags at machine speed. vastlint ships a native MCP server so any agent can call VAST validation before a deal is confirmed or an impression fires.

vastlint/mcp-server
SSEconnected

AGENT

reject
escalate
approve
repaired
thinking: Validating creative before confirming deal…

TOOL CALL

validate_vast_url("https://ads.partner.io/vast?adid=summer-30s")
RESPONSE
awaiting call…
vastlint.org/mcp · MCP 2025-03-26118 rules · IAB VAST 2.0–4.3

Why validation belongs in the agent loop

Agentic pipelines automate everything from brief to impression delivery. But there is still a VAST tag at the end, and that tag has to be spec-compliant. The usual failures in generated or trafficked tags:

  • Missing <Impression> URL. Required by spec, silently omitted by templates that expect it to be injected later.
  • <Duration> as bare seconds (30) instead of HH:MM:SS (00:00:30). Breaks all VAST 4.x players.
  • HTTP media or tracking URLs. Blocked by most players and ad servers outright.
  • Wrapper chains that exceed the player's depth limit or never resolve inline.
  • Wrong MIME type on <MediaFile>. The player skips the file silently.

None of this changes because the buy was agentic. A broken VAST tag drops the impression regardless of how cleanly the upstream pipeline executed.

Quick start

Claude Desktop

Open Settings → Developer → Edit Config and add:

{
  "mcpServers": {
    "vastlint": {
      "type": "sse",
      "url": "https://vastlint.org/mcp"
    }
  }
}

Restart Claude Desktop. You can now ask: "Validate this VAST tag" or "Fix the HTTPS issues in my XML" and Claude calls vastlint directly.

Cursor

Open Settings → MCP or edit ~/.cursor/mcp.json:

{
  "mcpServers": {
    "vastlint": {
      "type": "sse",
      "url": "https://vastlint.org/mcp"
    }
  }
}

VS Code (GitHub Copilot Agent Mode)

Add to .vscode/mcp.json:

{
  "servers": {
    "vastlint": {
      "type": "sse",
      "url": "https://vastlint.org/mcp"
    }
  }
}

Local binary (stdio, for ARTF containers)

cargo install vastlint-mcp
{
  "mcpServers": {
    "vastlint": {
      "command": "vastlint-mcp"
    }
  }
}

Full setup guide with Windsurf and all transport options: vastlint MCP server setup →

Tools available to your agent

ToolWhat it does
validate_vastValidate a VAST XML string. Returns all issues with severity, rule ID, XPath location, and spec reference.
validate_vast_urlFetch a VAST tag from a URL and validate it. Follows wrapper chains up to the configured depth (default 5, per IAB VAST 4.x recommendation).
list_rulesReturn all 118 rule IDs with severities and descriptions. Cache this; it is static.
explain_ruleFull spec reference, what triggers the rule, and how to fix it. Call after validate_vast returns a rule ID you want to act on.
fix_vastAuto-apply all deterministic safe fixes: HTTP→HTTPS upgrades, deprecated attribute removal. Returns patched XML and a diff.

Agentic loop patterns

Pre-trafficking validation gate (Python)

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import json

async def validate_before_deal(vast_url: str) -> dict:
    server = StdioServerParameters(command="vastlint-mcp")
    async with stdio_client(server) as (read, write):
        async with ClientSession(read, write) as session:
            await session.initialize()
            result = await session.call_tool(
                "validate_vast_url",
                {"url": vast_url, "max_depth": 5}
            )
            data = json.loads(result.content[0].text)
            if data["errors"] > 0:
                raise ValueError(f"VAST rejected: {data['errors']} errors")
            return data

Pre-trafficking validation gate (Node.js)

import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";

const transport = new SSEClientTransport(new URL("https://vastlint.org/mcp"));
const client = new Client({ name: "buyer-agent", version: "1.0.0" });
await client.connect(transport);

async function validateBeforeDeal(vastUrl) {
  const result = await client.callTool({
    name: "validate_vast_url",
    arguments: { url: vastUrl, max_depth: 5 },
  });
  const data = JSON.parse(result.content[0].text);
  if (data.errors > 0) throw new Error(`VAST rejected: ${data.errors} errors`);
  return data;
}

Fix-and-retry loop

When an agent can mutate the creative before delivery:

agent → validate_vast(xml)
      ← { valid: false, errors: 1,
           issues: [{ rule: "VAST-2.0-duration-format",
                      path: "/VAST/Ad/InLine/Creatives/Creative/Linear/Duration",
                      message: "Duration must be HH:MM:SS.mmm" }] }

agent → explain_rule("VAST-2.0-duration-format")
      ← { hint: "Duration must be HH:MM:SS or HH:MM:SS.mmm",
           example: "00:00:30.000",
           spec_ref: "VAST 2.0 §3.2" }

agent → fix_vast(xml)
      ← { xml: "<VAST …>…</VAST>",
           fixes_applied: [{ rule: "VAST-2.0-duration-format", … }],
           remaining_issues: [] }

agent → validate_vast(fixed_xml)   # confirm clean
      ← { valid: true }

The agentic advertising standards landscape

Several industry bodies are publishing standards for autonomous ad delivery. Here is how they relate and where vastlint MCP fits into each.

IAB Tech Lab: AAMP (Agentic Advertising Management Protocols)

AAMP (updated April 2026) is the IAB Tech Lab's umbrella for all agentic work. Three pillars:

PillarStandardWhat it covers
Agent FoundationsARTFHigh-performance agent execution inside RTB systems. MCP interface is built into the spec. Cuts latency by 80% via containerised agent services.
Agentic ProtocolsBuyer Agent SDK, Seller Agent SDK, Agentic Direct, Agentic Deals, Agentic RTBDiscovery, negotiation, deal execution, order management. Built on OpenDirect, AdCOM, and the Deals API.
Trust and TransparencyAgent RegistryNeutral agent identity, verification, and disclosure across the ecosystem.

IAB Tech Lab put it this way: "The key agentic protocols, MCP from Anthropic and Google's Agent to Agent, perform best when they have utility schemas along with reference implementations." vastlint MCP is a utility tool with a fixed schema that an agent can call and get a consistent result from.

Where vastlint fits in AAMP

ARTF containers: Deploy vastlint-mcp as a containerised service in your ARTF host platform. Buyer and seller agents call validate_vast_url via the ARTF MCP interface before confirming a deal or before impression delivery. Same pattern as identity resolution or fraud detection agents in ARTF.

Buyer Agent SDK: The AAMP Buyer Agent SDK accepts additional MCP tool servers. Point it at vastlint.org/mcp and the agent calls VAST validation at the creative-acceptance step before confirming a deal. No custom integration code.

AgenticAdvertising.Org: AdCP 3.0

AdCP (Ad Context Protocol) 3.0 is published by AAO (AgenticAdvertising.Org), a separate consortium from IAB Tech Lab. It covers campaign planning, deal execution, creative production (brand.json, Creative Protocol), governance, and reporting across 20 media channels. Already in production at Snap, Pinterest, Reddit, Netflix, and Vox Media.

AdCP operates at the campaign and deal layer. For video, it still hands off to VAST XML at the delivery layer. An AdCP creative agent that generates a VAST tag still needs that tag validated. vastlint MCP is consumable from any A2A-compatible or MCP-compatible agent runtime an AdCP buyer agent runs on.

See AdCP and VAST: the full breakdown →

Google: Agent-to-Agent (A2A)

Google's Agent-to-Agent protocol defines how autonomous agents discover and call each other over HTTP. vastlint's hosted SSE endpoint (vastlint.org/mcp) is consumable from any A2A-compatible orchestrator over standard HTTP. No MCP-specific client library required.

Amazon programmatic and CTV

Amazon's programmatic channels (Fire TV, Prime Video, Amazon DSP) deliver video via VAST. Buyers trafficking into Amazon inventory submit VAST tags that are validated server-side at ingestion. Malformed tags result in missed impressions with no fill and no useful error returned at auction time. Common failures on Amazon inventory:

  • MediaFile URLs over HTTP (blocked; Amazon enforces HTTPS across all inventory)
  • Missing or blank AdSystem. Required for Amazon reporting.
  • Incorrect Duration format for pre-roll slots.
  • Wrapper chains that time out before resolving. Fire TV has a strict fetch timeout.

Run vastlint before submitting to Amazon DSP to catch these before they reach the ad server. The same validation applies to any SSAI system stitching into Amazon's streaming inventory.

OpenRTB and SSAI

OpenRTB bid responses that include VAST XML and SSAI stitchers that resolve wrapper chains both need validation at the creative level. validate_vast_url follows wrapper chains and validates each hop, returning per-hop issues. That is the signal an OpenRTB DSP or SSAI platform needs to decide whether to use a creative.

At 363 µs for a 17 KB tag on a single thread, vastlint adds less than 0.4% to a typical 100 ms SSAI stitching budget. At 10 cores, throughput reaches 15,760 tags/sec.

What your agent receives

Every validate_vast and validate_vast_url response returns structured JSON an agent can act on without any string parsing:

{
  "version": "4.2",
  "valid": false,
  "errors": 1,
  "warnings": 2,
  "info": 0,
  "issues": [
    {
      "rule": "VAST-4.2-secure-media-url",
      "severity": "error",
      "path": "/VAST/Ad/InLine/Creatives/Creative/Linear/MediaFiles/MediaFile[1]",
      "line": 42,
      "col": 5,
      "message": "MediaFile URL must use HTTPS in VAST 4.x",
      "spec_ref": "VAST 4.2 §4.11.4"
    }
  ]
}

Every issue carries a rule ID (maps to explain_rule), an XPath path, a line/col position, and a spec_ref. An agent can reject, escalate, or attempt auto-repair using any of these fields.

Latency

ScenarioLatency
Local stdio, 17 KB tag (single thread)363 µs
Local stdio, 44 KB tag2.1 ms
Hosted SSE (vastlint.org/mcp), typical round-trip15–40 ms
Typical OpenRTB bid cycle budget100–300 ms
Validation as % of bid budget (local)< 2.1%

Use the local binary for ARTF containers and latency-sensitive SSAI pipelines. Use the hosted endpoint for cloud-native agents where you want zero operational overhead.

FAQ

What is the vastlint MCP server?
A Model Context Protocol server that exposes VAST validation as structured tools. A hosted SSE endpoint is live at https://vastlint.org/mcp. Five tools: validate_vast, validate_vast_url, list_rules, explain_rule, fix_vast.
Is it compatible with IAB Tech Lab AAMP and ARTF?
Yes. ARTF has an MCP interface built into the spec. vastlint-mcp can run as an ARTF-compliant container and be called by agents using the AAMP Buyer or Seller Agent SDKs.
Does it work with AdCP (AAO)?
Yes. AdCP agents run on MCP- or A2A-compatible runtimes. vastlint's hosted SSE endpoint is callable from either. See AdCP and VAST for the full layer breakdown.
Does it work with Google A2A?
Yes. The hosted SSE endpoint is callable over standard HTTP from any A2A-compatible orchestrator.
Is there a rate limit on the hosted endpoint?
The hosted endpoint is free with no API key. It is rate-limited to prevent abuse. For high-throughput production use, install the local binary (cargo install vastlint-mcp) or use the REST API.
What VAST versions are supported?
VAST 2.0, 3.0, 4.0, 4.1, 4.2, and 4.3. 118 rules across all versions.
Is it open-source?
Yes. Apache 2.0. github.com/aleksUIX/vastlint.

See also