Governed, read-only MCP server exposing Google Ad Manager inventory discovery to buyer agents
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.
A Model Context Protocol server that exposes sell-side ad inventory to buyer-side AI agents: discovery, firm pricing, and a buyer-scoped soft commitment primitive. No writes to an ad server exist. The Google Ad Manager adapter is not yet connected; catalog and forecast data are synthetic.
Sell-side ad inventory (availability, pricing, product structure) lives inside ad servers that hold commercially sensitive and sometimes personal data. Giving an AI buyer agent direct API access to GAM or a similar system creates three risks:
| Risk | Without this project | With this project |
|---|---|---|
| Data over-exposure | Agent can read raw avails, deal IDs, exact floor prices | Only coarse buckets and pre-declared families |
| Accidental writes | Agent SDK can create orders, modify line items | No ad-server writes exist; the only write is a buyer's own soft commitment, which can never become a GAM order or an inventory hold |
| No accountability | API calls are logged but not auditable | Hash-chained audit ledger; every allow/deny recorded |
A buyer agent connects via MCP and gets five tools β three read-only, plus a buyer-scoped commitment primitive (create/revoke) that is the sole write surface:
Every call flows through the same pipeline before any domain logic runs:
Each request-path gate rejects on failure. One honest caveat to the diagram above:
client_request_id (the replay-guard deduplication key) is optional by default; a request
that omits it bypasses SEC-GATE-3. A deployment can set MCP_REQUIRE_IDEMPOTENCY_KEY to make it
mandatory on every authenticated surface (fail-closed) β off by default for back-compat.The rate-limit stage covers every authenticated tool β the read surfaces, create_intent,
and revoke_intent β so no authenticated surface bypasses it.
A corrupted or tampered on-disk ledger is detected on startup and the node refuses to serve (fail-closed on load, plus a chain-integrity verify before the first request) rather than resetting to an empty chain.
create_intent runs the same gates and adds one more before it records anything: the buyer's
price_ref must match the family's current firm price, or the request is rejected.
Run a full pilot in one command.
scripts/pilot.shbrings the node up on your config with production guards on, mints a buyer token per entitled buyer, and prints how to drive a buyer agent through the whole loop (discover β forecast β commit β revoke) β seedocs/PILOT-QUICKSTART.md. The reference buyer agent lives atexamples/buyer-client-ts/agent.ts; hosting behind TLS is a filled-in-the-blanks recipe indeploy/.
Add the server to your MCP client (Claude Desktop, Claude Code, Cursor, β¦):
Or run it directly (stdio transport β the default for MCP clients):
Demo mode. With no config of your own, the node boots on a bundled
pilot-publisherexample (illustrative catalog, prices and forecasts) and says so on stderr β it starts instead of failing, so you can try the tools immediately. Because buyer surfaces always require a token (there is no anonymous path, even in demo), the node prints a ready-to-use demo buyer token on startup: copy it and pass it as thetokenargument todiscover_products/get_forecastto see the example families, prices and forecasts.For a real deployment, point
MCP_CONFIG_DIRat a directory holding your owndeployment.json,catalog.json,entitlements.jsonandpricing.json:
Run the full buyer-agent walkthrough (scripted demo) β the five native tools driven over a real in-process MCP transport, ending in the governed refusals (fail-closed auth, Default-Deny, fail-closed pricing) and a verified audit chain:
The node starts on 127.0.0.1:3900. The well-known document is at
/.well-known/seller-mcp-capabilities. Persistent volumes for keys and audit data are
pre-configured in docker-compose.yml.
Four JSON files drive all publisher-specific behaviour β no code changes needed. Place them
in config/ (from-source) or in the directory named by MCP_CONFIG_DIR (npx/containerised):
Invalid config always fails closed: a malformed file stops the node rather than running
with a silently different access policy. Absent config (no config/ and no MCP_CONFIG_DIR)
drops to the bundled config/examples/pilot-publisher/
example β demo mode, announced on stderr β so the node is never a broken install, only ever a
real deployment or a clearly-labelled demo.
Taking a pilot onto real inventory (short of a live GAM connection) is all configuration β
see docs/PUBLISHER-DEPLOYMENT.md:
forecast.json (template: config/examples/pilot-publisher/forecast.sample.json).
Buckets become realistic while every result stays synthetic: true β pre-loaded is not a live
read, so no live-GAM claim is made.MCP_INTENT_HANDOFF=file (a local JSONL drop an operator forwarder tails). The node makes no
outbound calls (SSRF/egress deny-all) β a handoff record is a notification, never a GAM order
or inventory hold.MCP_REQUIRE_OPERATOR_CONFIG=1 (refuse to boot on demo config),
MCP_REQUIRE_IDEMPOTENCY_KEY=1 (close the replay-bypass), MCP_ANCHOR_SINK=tsa (anchor the
audit trail to a third party).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/gam-seller-mcp-node)<a href="https://allmcps.com/mcp/gam-seller-mcp-node"><img src="https://allmcps.com/api/badge/gam-seller-mcp-node?style=directory" alt="Gam Seller MCP Node on AllMCPs" /></a>