Validate OpenRTB bid requests and responses against IAB specs. ARTF, Rust core.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
π‘ Paste the JSON block into your client's configuration file under mcpServers, then restart the application.
OpenRTB linter. Validates OpenRTB 2.x bid requests and bid responses against versioned IAB Tech Lab spec snapshots, from 2.0 through the monthly 2.6 releases (currently up to 2.6-202606).
Website and playground: rtblint.org
ext subtrees stay open)bid.adm content vs the declared bid.mtype (native JSON encoding, VAST/DAAST roots, double-encoded payloads)impid, mtype, adm markup, dealid, seat, and currency are checked against what the request actually offeredimp.secure and regs.coppa as integers, while the IAB OpenRTB protobuf schema declares 28 of them bool. Either encoding is correct on its own transport and wrong on the other, so the caller declares which one it meant--profile google-ab accepts at: 3 (FIXED_PRICE) and requires Imp.ext.billing_id. --profile prebid-server requires each Imp to name a bidder or stored request and refuses wseat/bseat. --profile xandr requires ext.appnexus.seller_member_id and video ext.appnexus.context. --profile magnite requires xAPI identity fields (imp.ext.rp.zone_id, site/app ext.rp.site_id, publisher.ext.rp.account_id). Business policy stays outext: Native Ads 1.2 markup (imp.native.request and native bid.adm, including required-asset pairing), GPP header vs gpp_sid and TCF 2 shape, ${AUCTION_*} macros on billing and loss URLs, EID/SUA structure, SKAdNetwork ext.skadnregs.coppa / device.lmt / device.dnt / regs.gdpr versus identifiers on the same payload, TCF Purpose 1 versus device-storage IDs, US Privacy Opt-Out Sale versus hashed EIDs, email-shaped user.id / site.page, DSA Transparency field presence. Findings describe the document. They do not state a legal conclusion.Every finding carries a stable rule id, a severity, a message, and a JSON path.
ARTF, the IAB Tech Lab Agentic Real Time Framework, hands an agent an OpenRTB payload inside an RTBRequest envelope and takes back mutations: proposed changes the orchestrator may accept or reject one at a time. Nothing in the framework checks that the auction still validates once they are applied, and a mutation is only meaningful relative to the request it targets.
Three passes:
lifecycle against the payloads actually carried, tmax plausibility for an in-auction call, originator and applicable_intents enum values, and the carried bid request and bid response validated as protobuf JSON.applicable_intents, the operation and payload oneof member match the intent, and every semantic path (/imp/{id}, /imp/{id}/pmp/deals/{id}, /user/data/segment, /seatbid/{seat}/bid/{id}) resolves to something the auction carries. ADJUST_DEAL_MARGIN is reported as having no OpenRTB field to write to, because it does not.The ARTF v1.0 document and its .proto use different vocabularies for the same mutation (activateSegments and a value: {IDsPayload: ...} wrapper against ACTIVATE_SEGMENTS and top-level oneof members). Payloads written from the document are mapped and reported as artf.mutation.legacy_spec_encoding rather than dismissed as unknown.
| Surface | Package | Status |
|---|---|---|
| Rust CLI | rtblint | Working |
| Rust library | rtblint-core | Working |
| MCP server | rtblint-mcp | Working |
| Node (WASM) | rtblint-core on npm | Working |
| GitHub Action | aleksUIX/rtblint | Working |
| Python | rtblint on PyPI | Not implemented yet |
| Go | github.com/aleksUIX/rtblint/go | Not implemented yet |
OpenRTB 3.0 validates through its layered envelope: the transport objects (Openrtb, Request, Item, Deal, Source, Response, Seatbid, Bid) and the AdCOM 1.0 domain objects under item.spec (Placement), bid.media (Ad), and request.context. A 2.x payload sent to a 3.0 validator gets a migration diagnostic rather than a bare parse error. The 2.6-202204 snapshot has no extracted catalog and reports itself as unsupported instead of passing payloads silently. See ROADMAP.md for what's next and CHANGELOG.md for release history.
--request supplies the originating bid request so the response is also cross-validated against it (works with --batch too: one request, many response lines). --dialect proto-json validates a payload that came off a gRPC bidstream integration. --profile google-ab applies Google Authorized Buyers' documented protocol extras (at: 3 FIXED_PRICE, required Imp.ext.billing_id) on top of the spec. --profile prebid-server applies Prebid Server /openrtb2/auction extras (bidder or stored request on each Imp, no wseat/bseat). --profile xandr applies Microsoft Monetize extras (ext.appnexus.seller_member_id, video ext.appnexus.context). --profile magnite applies Magnite xAPI identity fields. --resolve --cache <dir> checks SupplyChain hops against sellers.json and the publisher's ads.txt / app-ads.txt from a local directory:
Nothing is fetched; populate the cache yourself. --batch lints one JSON object per line from a file or stdin. --summary adds rule-frequency totals for a captured stream (--summary bids.ndjson for the histogram alone). See ARTF for --type artf-request and --type artf-response.
Exit codes: 0 valid, 1 validation errors, 2 usage or I/O error.
The Action lives in this repo. Pin a release tag so CI downloads that CLI tarball:
version selects the CLI release (auto follows the action's own v* tag). spec-version is the OpenRTB snapshot. Linux and macOS runners, x86_64 and aarch64.
For gRPC bidstream payloads and ARTF:
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/rtblint)<a href="https://allmcps.com/mcp/rtblint"><img src="https://allmcps.com/api/badge/rtblint?style=directory" alt="RTBlint on AllMCPs" /></a>