GAM Seller MCP Node
The GAM Seller MCP Node is a governed, read-only MCP server that exposes sell-side ad inventory discovery to buyer-side AI agents, with built-in security, privacy, and audit controls.
What you can do:
Verify server identity & capabilities (
well_known_capabilities): Retrieve a signed RS256 capability document confirming node identity, privacy posture, and allowed surfaces. Acts as a trust anchor; no input required.Discover ad product families (
discover_products): List coarse product categories (e.g., "Pre-Roll Video") that a specific buyer is entitled to see. Requires abuyer_id. Never exposes deal IDs, internal IDs, raw inventory, or exact pricing.Get coarse availability forecasts (
get_forecast): Obtain a Low/Mid/High availability bucket for a specific product family and time period (e.g., Q4-2026), with a firm list price if configured. Requiresbuyer_id,family_id, andperiod. Never returns exact impression counts, CPM curves, or floor prices.
What you cannot do:
No write operations – no orders, line items, or bids can be created or modified.
No sensitive data access – exact pricing, deal IDs, and raw availability numbers are blocked at the policy layer.
No unauthenticated bulk access – every request is subject to Default-Deny policy, rate limiting (1 req/30s per buyer), replay detection (via
client_request_id), and RS256 token validation.
Additional capabilities:
Hash-chained audit ledger: Every allow/deny decision is recorded with buyer identities pseudonymized via HMAC.
GDPR toolkit: Export, restrict, or erase a buyer's audit data (pseudonymized only).
Configuration-driven: Product families, entitlements, and pricing managed via JSON config files.
Exposes read-only ad inventory discovery from Google Ad Manager, providing tools for well-known capabilities, product families, and bucketized availability forecasts.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@GAM Seller MCP Nodeshow me available product families"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Governed MCP seller control-plane prototype for future GAM integration.
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.
What problem does this solve?
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 |
Related MCP server: google-ads-mcp
How it works
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:
Buyer agent
│
├── well_known_capabilities ← Signed trust anchor. Check this first.
│ Returns: RS256-signed capability document, node identity, privacy posture.
│
├── discover_products ← What can I buy here, and at what firm price?
│ Returns: product families the buyer is entitled to see (e.g. "Pre-Roll Video"),
│ each with its firm list price when the publisher has configured one.
│ Never returns: deal IDs, internal IDs, raw inventory, exact per-impression pricing.
│
├── get_forecast ← How available is this family next quarter?
│ Returns: Low / Mid / High availability bucket.
│ Never returns: exact impression counts, CPM curves, floor prices.
│
├── create_intent ← Commit to a product at its current firm price (with TTL).
│ Records a firm, time-boxed buying intent — rejected if the price is stale or
│ mismatched. NOT a GAM order and NOT an inventory hold; it is the handoff artifact
│ the classic sales rails pick up. Buyer-scoped: you can only ever commit as yourself.
│
└── revoke_intent ← Withdraw one of your own active intents by id.Every call flows through the same pipeline before any domain logic runs:
Buyer request
│
▼
[SEC-GATE-3] Replay detection — deduplicate client_request_id
│
▼
[Auth] RS256 token validation → identity confirmed or AUTH_FAILED
│
▼
[Policy] Surface denylist → entitlement check → scope check (Default-Deny)
│
▼
[Rate limit] N=1 / T=30s per buyer_id
│
▼
[Domain] Catalog / ForecastEngine — synthetic today, real GAM adapter in progress
│
▼
[Audit] Append-only hash-chained ledger, buyer pseudonymized (HMAC)
│
▼
Response to buyerEach 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 setMCP_REQUIRE_IDEMPOTENCY_KEYto 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.
Quick start
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/.
Install in an MCP client (via npx)
Add the server to your MCP client (Claude Desktop, Claude Code, Cursor, …):
{
"mcpServers": {
"gam-seller": {
"command": "npx",
"args": ["-y", "gam-seller-mcp-node"]
}
}
}Or run it directly (stdio transport — the default for MCP clients):
npx -y gam-seller-mcp-nodeDemo 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:MCP_CONFIG_DIR=/etc/gam-seller/config npx -y gam-seller-mcp-node
From source
git clone https://github.com/juan-sibbo/gam-seller-mcp-node.git
cd gam-seller-mcp-node
npm install
npm run build
npm run start:http # HTTP transport on 127.0.0.1:3900Run 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:
npm run demo # or: npx tsx demo/run-demo.tsWith Docker
docker compose upThe 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.
Configure for your publisher
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):
deployment.json # DSR contact, controller model, data retention window
catalog.json # product families + per-buyer access grants
entitlements.json # which buyers are entitled to which MCP surfaces
pricing.json # firm list prices per family (fail-closed on expiry)
forecast.json # OPTIONAL — seed availability buckets from real numbers (still synthetic-labeled)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:
Seed the forecast with the publisher's own availability, exported once from a GAM report, via an optional
forecast.json(template:config/examples/pilot-publisher/forecast.sample.json). Buckets become realistic while every result stayssynthetic: true— pre-loaded is not a live read, so no live-GAM claim is made.Close the handoff loop so a committed intent reaches the publisher's sales rails, via
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.Harden for the road:
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).
Why not just use the GAM API directly?
Approach | Data exposure | Writability | Auditability | AI-agent friendly |
Raw GAM API | Everything in the account | Full CRUD | Logging only | Poor (SOAP/REST, no MCP) |
OpenRTB bid requests | User-level data, floor prices | Bid-only | None | Poor |
This server | Coarse families + bucket forecasts | Buyer's own soft commitment only (no GAM writes) | Hash-chained ledger | Native MCP |
Current status
Working prototype. The full request pipeline (auth → policy → rate-limit → domain → audit),
the buyer-scoped commitment primitive (create_intent / revoke_intent, with TTL expiry),
the audit ledger, GDPR data-subject-rights toolkit, Docker packaging, HTTP transport,
and a live interop probe (Python buyer agent simulation) are all implemented and tested.
The persistence layer is hardened for restarts (append-only, atomic writes, durable rotation
state, fail-closed load), and the head-hash anchor is append-only with selectable external WORM
backends (RFC 3161 timestamping / S3 Object Lock) — see Known limitations
for the residual (a live write-once destination is an operator infra act).
Not yet wired: a live Google Ad Manager connection. The catalog and forecast data are
synthetic, loaded from local config. The GAM ForecastService SOAP adapter interface exists
(src/forecast/source.ts) as a stub — it throws on any call until a
service account is provisioned (DP-AB-01 §5.2). See the
open issues for the roadmap.
Known limitations — dated status. Closed rows are kept on purpose: a limitations list that changes state over time is both a proof of honesty and a proof of progress.
Limitation | Anchor | Status | Closed by |
Attribution ( |
| Design decision, not a defect — traceability vs. erasability (ADR-4) | — |
Head-hash anchor rewrote its whole file each write ( |
| ✅ Closed 2026-08-23 — append-only JSONL + injectable | |
External WORM anchoring needs the operator to point at a live write-once destination (a TSA URL, or a locked bucket) — the node ships the backends, not the destination |
| Open — deployment boundary (infra act) | — |
|
| Mitigated 2026-08-24 — | |
No TLS in transit (a reverse proxy is expected to terminate) | — | Open — deployment boundary | — |
|
| ✅ Closed 2026-08-18 — now behind the rate-limit gate like every authenticated surface | |
GDPR DSR CLI ( |
| ✅ Closed 2026-08 — ships as the | |
Ledger loaded fail-open — a corrupt file reset to an empty chain |
| ✅ Closed 2026-08-07 | |
Chain integrity not verified before serving on startup |
| ✅ Closed 2026-08-07 |
Architecture
See docs/ARCHITECTURE.md for the module map and data-flow diagrams.
Key modules:
Module | Role |
| MCP tool definitions + request pipeline |
| Default-Deny engine, entitlement store, surface allowlist/denylist |
| RS256 key management, token issuance/validation, revocation denylist |
| Hash-chained ledger, HMAC pseudonymization, append-only head-hash anchoring with selectable WORM backends ( |
| Firm list price store, expiry-aware (fail-closed on stale prices) |
| Bucket engine + GAM adapter seam (synthetic today) |
| GDPR Art. 15/17/18/20 data-subject-rights toolkit (also shipped as the |
| Product family store, per-buyer access grants |
Security model
Default-Deny. Every request is denied unless an explicit entitlement says otherwise — there is no "allow by default" path in the code.
Structural allow/denylist (SEC-GATE-*). Response surfaces are governed by a fixed list enforced
at the policy layer, independent of which tool was called. Exact pricing, deal IDs, raw availability
numbers, cross-buyer state, real inventory holds (soft-lock), and any ad-server write are permanently
denied. The one permitted write is a buyer's own commitment (create_intent / revoke_intent),
which required an explicit amendment to the surface allowlist and stays buyer-scoped. Adding a new
tool in the future cannot bypass this.
Opaque errors. A denied request, a failed authentication, and a revoked token all return the
same generic AUTH_FAILED code. Internal reasons never reach the buyer.
Audit-first. Every allow/deny is written to the ledger before the response is sent.
Buyer buyer_id values are pseudonymized (HMAC-SHA256) before entering the chain. Note that
buyer_id and request_id, while stored in each audit entry, are not included in the
hash-chain's canonical input (audit/event.ts:50); those fields are not covered by the
chain's tamper-evidence guarantee.
Privacy by construction. Responses carry only inventory-level data (product family, coarse bucket). User-level attributes don't exist in any response path.
See docs/DESIGN-PRINCIPLES.md for the full reasoning.
Regulatory posture
The AEPD (Spain's data protection authority) published guidelines on agentic AI systems in February 2026. The four recommendations most relevant to an ad-inventory node map directly to existing design decisions:
AEPD recommendation | This node |
Protection by design and by default | Default-Deny: every surface denied unless an explicit entitlement grants access |
Record and document agent actions | Append-only hash-chained audit ledger; every allow/deny recorded before the response is sent |
Control what leaves toward third parties, and with what traceability | Structural egress allowlist (SEC-GATE-*); exact pricing, deal IDs and raw availability permanently blocked |
Govern agent memory with purpose and retention rules | DSR toolkit (Arts. 15/17/18/20); configurable retention window enforced on the audit ledger |
This alignment is declared machine-readably in the signed well-known document
(/.well-known/seller-mcp-capabilities) under privacy_posture.regulatory_alignment_declared:
["GDPR", "AEPD-orientaciones-IA-agentica-2026"]. A buyer agent or auditor can verify it
cryptographically without trusting this README.
The node does not make legal determinations — whether a given processing has a legitimate basis, whether consent is valid, whether a particular treatment is permitted. Those judgements belong to the controller (the broadcaster). The node provides the mechanisms; the controller applies the criteria. This boundary is what keeps the node's design stable regardless of how the EU Data Act negotiations resolve.
Machine-readable trust anchor
The /.well-known/seller-mcp-capabilities endpoint returns an RS256-signed JWT. A buyer agent
reads and verifies this document before the first authenticated request. The privacy_posture
block inside it is machine-readable and cryptographically bound to the node's keypair:
Property | Current value | Meaning |
|
| No end-user personal data in any response path |
|
| No audience targeting surfaces |
|
| Node does not consume TC strings (server-to-server, PATH A) |
|
| No device storage access (ePrivacy N/A) |
|
| Declared operating jurisdiction |
|
| Declared alignment |
| from | Contact for data-subject requests |
| from | Publisher's declared controller role |
| from | Hot/archive retention windows in days/months |
Not yet in the well-known document (properties that remain implicit):
Whether the catalog and forecast data are synthetic or live (
data_source)Whether head-hash anchoring uses a local file or cloud Object Lock (
anchor_store)Whether the node is in demo mode or serving a real publisher config (
deployment_mode)
These properties would allow a buyer agent to programmatically distinguish a demo deployment from a production one, and a locally-anchored node from one with external tamper-evidence. They are not present in the current version.
Testing
npm test # full suite (vitest)
python3 sandbox/buyer-agent-probe.py # external Python interop probe (no shared code with server)The test suite includes:
Unit tests for each module (policy, pricing, identity, audit, catalog, forecast, DSR)
Integration tests over real in-memory MCP transports (
tests/server.test.ts)HTTP transport tests over a real ephemeral-port HTTP server (
tests/http.test.ts)End-to-end session tests simulating a full buyer-agent session (
tests/buyer-agent-session.test.ts)External Python probe that exercises the HTTP transport without any shared Node.js code
CI runs on every push via GitHub Actions.
Data protection
Raw buyer_id values never enter the audit ledger — only an HMAC pseudonym. The
src/dsr/toolkit.ts implements export, restriction, and erasure of a
buyer's audit data (GDPR Art. 15/17/18/20). The node stores nothing about end users; the DSR
scope is exactly what it records — B2B buyer organization pseudonyms and their request events.
Distribution note. The DSR toolkit ships in the npm package as the gam-seller-dsr bin, so
export / restriction / erasure can be run without a checkout. The token-management scripts
(scripts/issue-buyer-token.ts, scripts/revoke-token.ts) remain source-only — publishers who
need them must clone the repository.
Roadmap
See the open issues for the full roadmap. Highlights:
Real GAM adapter — wire
getAvailabilityForecastvia the ForecastService SOAP APIBuyer agent SDKs — Python and TypeScript client libraries for the MCP buyer flow
OpenRTB 3.0 taxonomy — align
family_idscheme with IAB standardsWell-known observability properties — expose
data_source/anchor_store/deployment_modeso a buyer agent can distinguish demo from production programmatically
(The Prometheus /metrics endpoint is already shipped — loopback-only, opt-in.)
Contributing
See CONTRIBUTING.md. Issues tagged
good first issue
are a good starting point.
License
MIT — see LICENSE.
Available Tools
5 toolscreate_intentA
Register a firm buying intent over a product family at its current firm price (soft commitment with TTL). Not a GAM order or inventory hold.
| Name | Required | Description | Default |
|---|---|---|---|
| token | No | Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub. | |
| period | Yes | Target period (e.g. Q4-2026, 2026-10) | |
| family_id | Yes | Product family ID from discover_products | |
| price_ref | Yes | The firm list price the buyer commits to; must match the family's current firm price | |
| client_request_id | No | Client-supplied idempotency key for replay detection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must disclose behavioral traits. It mentions 'soft commitment with TTL' and 'current firm price', adding some context beyond the schema. However, it lacks details on TTL duration, what happens after TTL, permission requirements, error conditions, or idempotency behavior, leaving gaps for an agent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise with two sentences that front-load the core action. Every word is meaningful, no redundancy, and it earns its place by clearly stating the purpose and what it is not.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has 5 parameters (3 required), no output schema, and no annotations, the description is somewhat incomplete. It explains the main intent but omits details about return values, error handling, idempotency via client_request_id, and authentication requirements. More information is needed for an agent to fully understand the tool's behavior.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already explains each parameter's purpose. The description does not add new semantic meaning beyond repeating 'firm price' and 'product family', which are already in the schema. Thus, it meets the baseline without adding extra value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Register' and the resource 'a firm buying intent over a product family at its current firm price', and distinguishes it from 'GAM order' and 'inventory hold'. It also notes it's a soft commitment with TTL, providing a specific and unique purpose that differentiates it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states what the tool does and what it does not do ('Not a GAM order or inventory hold'), providing clear context for when to use it. However, it does not directly mention alternatives among sibling tools (e.g., 'revoke_intent') or specify when not to use it, missing some explicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
discover_productsC
Discover coarse product families available to this buyer.
| Name | Required | Description | Default |
|---|---|---|---|
| token | No | Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub. | |
| client_request_id | No | Client-supplied idempotency key for replay detection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations, and description fails to disclose behavioral traits such as read-only nature, authentication via token, or idempotency behavior. Only parameter descriptions hint at JWT usage.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no fluff. Appropriate length for a simple discovery tool, but could include more useful details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 2 params and no output schema, description lacks context about return format, authentication requirements, or how buyer identity is resolved. Not complete for an agent to use confidently.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline 3. Tool description adds no extra meaning beyond what parameter descriptions provide.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States the tool discovers coarse product families for a buyer. Clear verb-resource but 'coarse' is vague. No differentiation from siblings.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use or when not to use. No mention of alternatives or prerequisites.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_forecastA
Get a coarse availability forecast (Low/Mid/High) for a product family and period. Demo mode: synthetic data only.
| Name | Required | Description | Default |
|---|---|---|---|
| token | No | Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub. | |
| period | Yes | Target period (e.g. Q4-2026, 2026-10) | |
| family_id | Yes | Product family ID from discover_products | |
| client_request_id | No | Client-supplied idempotency key for replay detection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses the output format (Low/Mid/High) and the demo-mode limitation (synthetic data). However, it omits behavioral details such as authentication requirements, side effects, or error scenarios. With no annotations, a higher bar is unmet.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences long, front-loading the core purpose and a key caveat. Every sentence adds value with zero waste.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The tool has 4 parameters, no output schema, and no annotations. The description covers the return type but omits important context such as when the optional token is needed, error handling, or idempotency details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
All four parameters have descriptions in the schema (100% coverage), so the baseline is 3. The description adds no new semantics beyond the schema; it does not explain parameters like token or client_request_id further.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Get', the resource 'coarse availability forecast (Low/Mid/High)', and the scope 'for a product family and period'. It is distinct from sibling tools like discover_products or create_intent, making selection unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance is provided on when to use this tool versus alternatives. The note about 'Demo mode: synthetic data only' hints at a limitation but does not advise on appropriate contexts or exclusion criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
revoke_intentA
Revoke one of your own active intents by id. Idempotent per client_request_id.
| Name | Required | Description | Default |
|---|---|---|---|
| token | No | Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub. | |
| intent_id | Yes | The intent_id returned by create_intent | |
| client_request_id | No | Client-supplied idempotency key for replay detection |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It discloses idempotency per client_request_id and scope (your own intents). However, it does not mention whether the revocation is destructive, any authentication requirements beyond the token, or what happens to related data. This is adequate but has gaps.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is only two sentences and front-loads the key action. Every word adds value, with no redundancy or filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's simplicity (3 parameters, no output schema, no annotations), the description is fairly complete. It covers purpose, idempotency, and scope. However, it omits details like whether the intent must be active or error conditions, which would enhance completeness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3. The description adds the idempotency note for client_request_id, which provides context beyond the schema. However, the schema already has detailed descriptions for each parameter, so the added value is marginal.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'revoke' and clearly states the resource ('your own active intents') and the identifier ('by id'). This distinguishes it from the sibling 'create_intent' tool, which performs the opposite operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide explicit guidance on when to use this tool versus alternatives. It mentions 'your own active intents', implying a restriction, but lacks when-to-use or when-not-to-use instructions. No alternatives are named.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
well_known_capabilitiesB
Return the signed RS256 capability document for this Seller MCP Node.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries full burden. It mentions the document is signed RS256, implying security context, but does not disclose any behavioral traits like required permissions, side effects, or what the document contains.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that front-loads the key action and resource, with no extraneous words. It is appropriately sized for a parameterless tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no parameters, no output schema, and no annotations, the description provides only the core purpose. It lacks context on the nature of the capability document, its usage, or its relationship to sibling tools, leaving room for ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so schema coverage is 100%. The description adds meaning by specifying the document type (signed RS256) and scope (for this Seller MCP Node), going beyond the empty schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns a signed RS256 capability document, which is a specific verb+resource. While it doesn't explicitly differentiate from siblings, the resource type is distinct, so purpose is clear.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives like discover_products or get_forecast. The description lacks context about appropriate usage scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
4 tool updates
v0.8.0- Added
create_intent - Changed
discover_products3 fields changed- removed
Input schema / properties / buyer_idRemoved value: -{ - "description": "Buyer identifier (opaque, B2B)", - "type": "string" -} - changed
Input schema / properties / token / descriptionPrevious value: -"Domain-2 inter-service JWT (RS256)"New value: +"Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub." - removed
Input schema / requiredRemoved value: -[ - "buyer_id" -]
- Changed
get_forecast3 fields changed- removed
Input schema / properties / buyer_idRemoved value: -{ - "description": "Buyer identifier (opaque, B2B)", - "type": "string" -} - changed
Input schema / properties / token / descriptionPrevious value: -"Domain-2 inter-service JWT (RS256)"New value: +"Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub." - changed
Input schema / requiredPrevious value: -[ - "buyer_id", - "family_id", - "period" -]New value: +[ + "family_id", + "period" +]
- Added
revoke_intent
2 tool updates
v0.2.0- Changed
discover_products1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
- Changed
get_forecast1 field changed- removed
Input schema / additionalPropertiesRemoved value: -false
2 tool updates
v0.1.1- Added
get_forecast - Added
well_known_capabilities
2 tool updates
- Removed
get_forecast - Removed
well_known_capabilities
3 tool updates
v0.1.0- First observed
discover_products - First observed
get_forecast - First observed
well_known_capabilities
TDQS
Each tool serves a distinct purpose: capabilities document, product discovery, forecasting, intent creation, and intent revocation. No overlap in functionality.
All tool names follow a consistent verb_noun pattern using snake_case (e.g., discover_products, create_intent). The one exception, well_known_capabilities, is still a descriptor_noun but fits the style.
Five tools is well-scoped for a seller MCP node, covering essential operations (capabilities, discovery, forecast, intent lifecycle) without unnecessary bloat.
The tool surface covers core workflows: discovery, forecasting, and intent registration/revocation. A minor gap is the lack of a tool to list or query existing intents, but revoke_intent implies clients track their own IDs.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Google Ads MCP server — manage campaigns, keywords, and metrics.
Read-only MCP tools for AI agent discovery, structured resources, and NIULAI information.
MCP server for querying and analyzing data from ad platforms, analytics tools, and spreadsheets
Guarded MCP server for agent-readable business truth, provenance, readiness, and discovery.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceA Multi-Agent Conversation Protocol Server that provides programmatic access to the Google Authorized Buyers Marketplace API, allowing agents to interact with the digital advertising marketplace through natural language.-

google-ads-mcpofficial
AlicenseNot gradedqualityBmaintenanceMCP server that provides tools and resources for interacting with Google Ads API, enabling search, metadata retrieval, and account management through natural language.907Apache 2.0- AlicenseAqualityBmaintenanceA read-only MCP server that enables AI agents to act as GCP platform engineers, allowing them to investigate incidents, take inventory, and find cost-optimization opportunities in Google Cloud projects without mutating any infrastructure.162MIT
- AlicenseNot gradedqualityCmaintenanceA security-first MCP server that enables AI clients to read and write Google Ad Manager data through the Ad Manager API, with least-privilege defaults, gated writes, and per-user OAuth support.65MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/juan-sibbo/gam-seller-mcp-node'
If you have feedback or need assistance with the MCP directory API, please join our Discord server