Skip to main content
Glama
juan-sibbo

GAM Seller MCP Node

by juan-sibbo

Governed MCP seller control-plane prototype for future GAM integration.

npm version npm downloads CI License: MIT TypeScript MCP

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 buyer

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.

Quick start

Run a full pilot in one command. scripts/pilot.sh brings 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) — see docs/PILOT-QUICKSTART.md. The reference buyer agent lives at examples/buyer-client-ts/agent.ts; hosting behind TLS is a filled-in-the-blanks recipe in deploy/.

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-node

Demo mode. With no config of your own, the node boots on a bundled pilot-publisher example (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 the token argument to discover_products / get_forecast to see the example families, prices and forecasts.

For a real deployment, point MCP_CONFIG_DIR at a directory holding your own deployment.json, catalog.json, entitlements.json and pricing.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:3900

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:

npm run demo          # or: npx tsx demo/run-demo.ts

With Docker

docker compose up

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.

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 stays synthetic: 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 (buyer_id / request_id) is stored per entry but sits outside the chain's tamper-evidence hash

audit/event.ts

Design decision, not a defect — traceability vs. erasability (ADR-4)

Head-hash anchor rewrote its whole file each write (writeFileSync) — not append-only, no external WORM

audit/anchor.ts

Closed 2026-08-23 — append-only JSONL + injectable AnchorSink; selectable tsa (RFC 3161) and s3 (S3 Object Lock) backends via MCP_ANCHOR_SINK

#92 #94 #95

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

audit/anchor-tsa.ts, audit/anchor-s3.ts

Open — deployment boundary (infra act)

client_request_id (replay guard) is optional by default; omitting it bypasses SEC-GATE-3

src/server.ts

Mitigated 2026-08-24 — MCP_REQUIRE_IDEMPOTENCY_KEY makes it mandatory on every authenticated surface (fail-closed); optional by default for back-compat

#82

No TLS in transit (a reverse proxy is expected to terminate)

Open — deployment boundary

revoke_intent is not covered by the rate-limit stage

src/server.ts

Closed 2026-08-18 — now behind the rate-limit gate like every authenticated surface

#80

GDPR DSR CLI (scripts/dsr.ts, …) not shipped in the npm package

package.json files

Closed 2026-08 — ships as the gam-seller-dsr bin

#78

Ledger loaded fail-open — a corrupt file reset to an empty chain

audit/ledger.ts

Closed 2026-08-07

#65

Chain integrity not verified before serving on startup

src/server.ts

Closed 2026-08-07

#65

Architecture

See docs/ARCHITECTURE.md for the module map and data-flow diagrams.

Key modules:

Module

Role

src/server.ts

MCP tool definitions + request pipeline

src/policy/

Default-Deny engine, entitlement store, surface allowlist/denylist

src/identity/

RS256 key management, token issuance/validation, revocation denylist

src/audit/

Hash-chained ledger, HMAC pseudonymization, append-only head-hash anchoring with selectable WORM backends (anchor-tsa.ts, anchor-s3.ts)

src/pricing/

Firm list price store, expiry-aware (fail-closed on stale prices)

src/forecast/

Bucket engine + GAM adapter seam (synthetic today)

src/dsr/

GDPR Art. 15/17/18/20 data-subject-rights toolkit (also shipped as the gam-seller-dsr bin)

src/catalog/

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

end_user_personal_data

"none"

No end-user personal data in any response path

audience_segmentation

"not_offered_v1"

No audience targeting surfaces

tc_string_consumption

"none"

Node does not consume TC strings (server-to-server, PATH A)

device_storage_access

"none"

No device storage access (ePrivacy N/A)

jurisdiction

["ES", "EU"]

Declared operating jurisdiction

regulatory_alignment_declared

["GDPR", "AEPD-orientaciones-IA-agentica-2026"]

Declared alignment

dsr_contact

from deployment.json

Contact for data-subject requests

controller_model

from deployment.json

Publisher's declared controller role

audit_retention

from deployment.json

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 getAvailabilityForecast via the ForecastService SOAP API

  • Buyer agent SDKs — Python and TypeScript client libraries for the MCP buyer flow

  • OpenRTB 3.0 taxonomy — align family_id scheme with IAB standards

  • Well-known observability properties — expose data_source / anchor_store / deployment_mode so 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 tools
create_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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tokenNoBuyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub.
periodYesTarget period (e.g. Q4-2026, 2026-10)
family_idYesProduct family ID from discover_products
price_refYesThe firm list price the buyer commits to; must match the family's current firm price
client_request_idNoClient-supplied idempotency key for replay detection

TDQS

A3.9/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines4/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tokenNoBuyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub.
client_request_idNoClient-supplied idempotency key for replay detection

TDQS

C2.9/5.0
Behavior2/5

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.

Conciseness4/5

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.

Completeness2/5

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.

Parameters3/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tokenNoBuyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub.
periodYesTarget period (e.g. Q4-2026, 2026-10)
family_idYesProduct family ID from discover_products
client_request_idNoClient-supplied idempotency key for replay detection

TDQS

A3.5/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault
tokenNoBuyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub.
intent_idYesThe intent_id returned by create_intent
client_request_idNoClient-supplied idempotency key for replay detection

TDQS

A3.6/5.0
Behavior3/5

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.

Conciseness5/5

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.

Completeness4/5

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.

Parameters3/5

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.

Purpose5/5

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.

Usage Guidelines2/5

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.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

B3.2/5.0
Behavior2/5

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.

Conciseness5/5

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.

Completeness3/5

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.

Parameters4/5

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.

Purpose4/5

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.

Usage Guidelines2/5

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.

  1. 4 tool updatesv0.8.0
    • Addedcreate_intent
    • Changeddiscover_products3 fields changed
      • removedInput schema / properties / buyer_id
        Removed value: -{
        -  "description": "Buyer identifier (opaque, B2B)",
        -  "type": "string"
        -}
      • changedInput schema / properties / token / description
        Previous value: -"Domain-2 inter-service JWT (RS256)"New value: +"Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub."
      • removedInput schema / required
        Removed value: -[
        -  "buyer_id"
        -]
    • Changedget_forecast3 fields changed
      • removedInput schema / properties / buyer_id
        Removed value: -{
        -  "description": "Buyer identifier (opaque, B2B)",
        -  "type": "string"
        -}
      • changedInput schema / properties / token / description
        Previous value: -"Domain-2 inter-service JWT (RS256)"New value: +"Buyer bearer JWT (RS256, aud=seller-mcp-node). Identity is derived from token.sub."
      • changedInput schema / required
        Previous value: -[
        -  "buyer_id",
        -  "family_id",
        -  "period"
        -]New value: +[
        +  "family_id",
        +  "period"
        +]
    • Addedrevoke_intent
  2. 2 tool updatesv0.2.0
    • Changeddiscover_products1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
    • Changedget_forecast1 field changed
      • removedInput schema / additionalProperties
        Removed value: -false
  3. 2 tool updatesv0.1.1
    • Addedget_forecast
    • Addedwell_known_capabilities
  4. 2 tool updates
    • Removedget_forecast
    • Removedwell_known_capabilities
  5. 3 tool updatesv0.1.0
    • First observeddiscover_products
    • First observedget_forecast
    • First observedwell_known_capabilities

TDQS

A3.7/5.0
Disambiguation5/5

Each tool serves a distinct purpose: capabilities document, product discovery, forecasting, intent creation, and intent revocation. No overlap in functionality.

Naming Consistency5/5

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.

Tool Count5/5

Five tools is well-scoped for a seller MCP node, covering essential operations (capabilities, discovery, forecast, intent lifecycle) without unnecessary bloat.

Completeness4/5

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

ActivityActive
ResponsivenessResponsive

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

Related MCP Servers

  • A
    license
    Not graded
    quality
    B
    maintenance
    MCP server that provides tools and resources for interacting with Google Ads API, enabling search, metadata retrieval, and account management through natural language.
    907
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    A 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.
    16
    2
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A 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.
    65
    MIT

Latest Blog Posts

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