Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, get in touch and we’ll put it right.

Trillboards DOOH Advertising

REMOTE · API.TRILLBOARDS.COM · SCANNED SEP 24

DOOH advertising via AI agents. 5,000+ screens with edge AI audience intelligence.

0 this week 79 Trust /100
Trust breakdown (7 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score → Why this is hard to score →

Endpoint Security63
Transport & Reachability100
Schema Quality & AI Usability76
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 22172 tokens (~260/item across 85 items; 83 tools + 2 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management100
  • No destabilizing schema changes in the last 30 days.Pass
Tool Coverage93
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 78% of tool parameters carry a description.Partial
Tool Safety75
  • No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.Pass
  • 0 of 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation; "delete_device" implies "delete" and declares no destructiveHint at all, which the MCP spec reads as destructive by default. See how to fix → Fail
  • An AI judge read all 85 captured unit(s) of tool text and found none that tries to manipulate the model reading it.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

How do I install the Trillboards DOOH Advertising MCP server?

Trillboards DOOH Advertising is a hosted endpoint at https://api.trillboards.com/mcp, so there is nothing to install locally. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

remote · api.trillboards.com

# add to Claude Code
claude mcp add --transport http snehdhruv-trillboards-dooh 'https://api.trillboards.com/mcp'
// .cursor/mcp.json
{
  "mcpServers": {
    "snehdhruv-trillboards-dooh": {
      "url": "https://api.trillboards.com/mcp"
    }
  }
}
// .vscode/mcp.json
{
  "servers": {
    "snehdhruv-trillboards-dooh": {
      "type": "http",
      "url": "https://api.trillboards.com/mcp"
    }
  }
}
# ~/.codex/config.toml
[mcp_servers.snehdhruv-trillboards-dooh]
url = "https://api.trillboards.com/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "snehdhruv-trillboards-dooh": {
      "type": "remote",
      "url": "https://api.trillboards.com/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add snehdhruv-trillboards-dooh --url 'https://api.trillboards.com/mcp' --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  snehdhruv-trillboards-dooh:
    url: "https://api.trillboards.com/mcp"
// ~/.netclaw/config/netclaw.json
{
  "McpServers": {
    "snehdhruv-trillboards-dooh": {
      "Transport": "http",
      "Url": "https://api.trillboards.com/mcp"
    }
  }
}
# add to Vellum
assistant mcp add snehdhruv-trillboards-dooh -t streamable-http -u 'https://api.trillboards.com/mcp'
// mcp.json
{
  "mcpServers": {
    "snehdhruv-trillboards-dooh": {
      "type": "http",
      "url": "https://api.trillboards.com/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 18 Sept 26 0
    • A breaking change shipped without a version bump: still 1.0.0 security
    • Tool “comply_test_controller” was removed security
  • 15 Sept 26 0
    • The server rewrote its instructions, which are the text every model session reads security
  • 12 Sept 26 0
    • Injection markers: unverified → pass security
    • Stability: unverified → pass security
    • Transport: fail → pass security
    • HSTS header: fail → pass security
    • Authorization: Authorisation not fully verified: no authorisation is required to call this server, and 84 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe. security
    • Endpoint reachability: unreachable → reachable functional
    • Tool coverage: unverified → 100 functional
    • Schema quality: unverified → 100 functional
    • MCP protocol: unverified → pass functional
  • 11 Sept 26 0
    • Endpoint reachability: reachable → unreachable security
    • Stability: pass → unverified security
    • Tool safety: pass → unverified security
    • Transport: pass → fail security
    • HSTS header: pass → fail security
    • Authorization: Authorisation not fully verified: no authorisation is required to connect, but we couldn't read the tool list to see what that exposes. security
    • Schema quality: 100 → unverified functional
    • Capabilities: pass → unverified functional
    • Tool coverage: 100 → unverified functional
  • 2 Sept 26 0
    • Tool “get_signals” rewrote its description, which is the text the model reads security
    • New tool “comply_test_controller” functional
    • “activate_signal” added an optional parameter “signal_agent_segment_id” cosmetic
    • “get_signals” added an optional parameter “pagination” cosmetic
    • “get_signals” reworded the description of “signal_spec” cosmetic
  • 29 Aug 26 0
    • Stability: 0.97 → pass security
  • 28 Aug 26 0
    • Stability: pass → 0.97 functional
  • 26 Aug 26 79
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 24 Sept 2026 · Probed https://api.trillboards.com/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=trillboards.com CN=YR1,O=Let's Encrypt,C=US 13 Sept 2026 12 Dec 2026 RSA 2048 SHA256-RSA 603beb61649777f99150d87a26019def768
SANs: *.trillboards.com, trillboards.com
CN=YR1,O=Let's Encrypt,C=US (CA) CN=Root YR,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 RSA 2048 SHA256-RSA a20253f15f2691c05dc1ce13b9bcca4e
CN=Root YR,O=ISRG,C=US (CA) CN=ISRG Root X1,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 RSA 4096 SHA256-RSA f24b6d17f9d9ad7cb1c9fea78782699f

Background: What to check on a remote MCP endpoint →

DNSSEC insecure

Validation of api.trillboards.com. Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
com. present 19718 13 Verified
trillboards.com. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Header Value
strict-transport-security max-age=31536000; includeSubDomains
content-security-policy default-src 'self';script-src 'self' 'unsafe-inline' https://screen.trillboards.com https://cdn.jsdelivr.net;style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://fonts.googleapis.com;img-src 'self' https://cdn.trillboards.com https://maps.googleapis.com data: blob:;connect-src 'self' https://api.trillboards.com wss://api.trillboards.com;font-src 'self' https://fonts.gstatic.com https://cdn.jsdelivr.net;frame-src 'self' https://js.stripe.com;object-src 'none';upgrade-insecure-requests;base-uri 'self';form-action 'self';frame-ancestors 'self';script-src-attr 'none'
x-content-type-options nosniff
x-frame-options SAMEORIGIN
referrer-policy no-referrer

Background: How OAuth 2.1 works in the 2026 MCP spec →

Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://api.trillboards.com/mcp Verified 200
http (plaintext) http://api.trillboards.com/mcp HTTPS enforced 301 https://api.trillboards.com/mcp
MCP tools · 83 exposed · ~21,774 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability. A tool's description is untrusted text the model reads on every call, which is what makes this list a security surface and not just an inventory: how tool poisoning works →

Tool Tokens
get_webhook_deliveries ~243

Get delivery history for a webhook. WHEN TO USE: - Debugging failed webhook deliveries - Auditing webhook activity - Checking delivery success rates RETURNS: - deliveries: Array of delivery records with: - delivery_id: Unique delivery ID - event: Event type - status: success/failed - response_code: HTTP response code - response_time_ms: Response time - attempted_at: Attempt timestamp - error: Error message (if failed) - total: Total delivery count - success_rate: Percentage of successful deliveries EXAMPLE: User: "Show me failed deliveries for this webhook" get_webhook_deliveries({ webhook_id: "wh_mmmpdbvj_8b7c5a59296d", status: "failed", limit: 20 })

NameTypeReqDescription
limitintegerMaximum number of deliveries to return (default: 50, max: 100)
statusstringFilter by delivery status
webhook_idstringyesWebhook ID to get deliveries for (wh_xxx format or legacy ObjectId)

No output schema declared.

No examples provided.

list_accounts ~373

[AdCP Accounts] List the accounts this credential can transact on. This seller's account model is 'explicit': one API key IS one account, so this returns exactly one account — the partner behind the key. Use it to discover your account_id before any account-scoped call, and to confirm the account's status before you buy. WHEN TO USE: - Discovering the account_id to pass to account-scoped tasks - Checking your account is 'active' before creating a media buy - Introspecting what your key is permitted to do (accounts[].authorization.allowed_tasks) RETURNS: - accounts: AdCP Account objects (account_id, name, status, operator, brand, billing, account_scope) plus an authorization object naming the tasks this key may invoke - pagination: has_more is always false — one credential, one account EXAMPLE: list_accounts({}) list_accounts({ status: "active" })

NameTypeReqDescription
accountobjectExact account filter. Either account_id, or the natural key (brand.domain + operator). Returns empty when it does not match this credential's account — which is how you confirm the key you hold is th…
contextobject
paginationobject
sandboxbooleanFilter by sandbox status — matched against the account's real state, not a stub. A sandbox account validates a buy exactly as a live one does (same errors, same codes) but books no placements and mar…
statusstringFilter by account status. Omit to return the account in any status.

No output schema declared.

No examples provided.

list_creative_formats ~580

[AdCP Media Buy] List the creative formats this network actually accepts. Every format is DERIVED from live per-screen capability (panel size, min/max spot length, audio) — not a hand-written list. The set published here is exactly the set sync_creatives accepts: if a creative matches a format returned by this tool, it will not be rejected for dimensions, duration or file size. WHEN TO USE: - Before building creative, to size it to the panels you are buying - To check whether an existing asset can run on this network - To find the panel sizes with the most reach (results are ordered by live screen count) RETURNS: - formats: AdCP Format objects (format_id, name, renders[].dimensions, assets[].requirements) - pagination: cursor-based; total_count is the full catalogue size - Each format carries ext.trillboards with the live screen count, the share of the network, how many of those screens have audio, and — for video — duration_coverage: how many screens accept a spot of at most 10/15/20/30/60/120/300 seconds. A long ceiling does not mean every screen at that size can play it, and this says so. EXAMPLE: User: "What sizes and lengths does this network take?" list_creative_formats({ pagination: { max_results: 20 } }) User: "Can I run a 1080x1920 portrait video?" list_creative_formats({ format_ids: [{ agent_url: "https://api.trillboards.com/mcp", id: "dooh_video_1080x1920" }] })

NameTypeReqDescription
asset_typesarrayFilter to formats containing these asset types, e.g. ['video'] or ['image'].
contextobject
format_idsarrayReturn only these formats. Each entry is an AdCP structured format reference ({agent_url, id}), never a bare string.
is_responsivebooleanFilter for responsive formats. Every DOOH panel is a fixed pixel grid, so true matches nothing here.
max_heightnumberMaximum render height in pixels (inclusive)
max_widthnumberMaximum render width in pixels (inclusive)
min_heightnumberMinimum render height in pixels (inclusive)
min_widthnumberMinimum render width in pixels (inclusive)
name_searchstringCase-insensitive partial match on the format name
paginationobjectCursor-based pagination
publisher_domainstringResolve formats for this publisher. This agent derives formats from its own inventory only, so anything other than 'trillboards.com' returns an empty list with UNSUPPORTED_PUBLISHER_DOMAIN.

No output schema declared.

No examples provided.

list_creatives ~418

[AdCP Creative] List the creatives this buyer has on file with us. OUR LIBRARY IS PER-BUY, AND THIS SAYS SO. AdCP's creative library models concepts, variables, assignments and snapshots; ours does not have those. A creative here is the one asset attached to a media buy by sync_creatives, so this is a projection of YOUR OWN buys — never someone else's assets, and never an invented concept_id to look richer than we are. WHEN TO USE: - To confirm a creative you sent actually landed, and where it is in review - To see which media buy a creative is attached to (include_assignments: true) - Before cancelling a buy, to check what happens to its creative RETURNS: - creatives[]: creative_id, name, format_id ({agent_url, id}), status, created_date, updated_date. Status is 'pending_review' until the buy is servable, then 'approved' — every creative goes through the same moderation every other creative on this network goes through. - query_summary: total_matching + returned - pagination: cursor-based, with total_count EXAMPLE: User: "Did my creative go through?" list_creatives({ filters: { media_buy_ids: ["mbuy_123"] }, include_assignments: true })

NameTypeReqDescription
accountobject
contextobject
extobject
fieldsarray
filtersobjectNarrow the result set. All fields optional.
include_assignmentsbooleanInclude which media buys each creative is attached to.
include_itemsboolean
include_pricingboolean
include_purgedboolean
include_snapshotboolean
include_variablesboolean
include_webhook_activityboolean
paginationobject
sortobject
webhook_activity_limitinteger

No output schema declared.

No examples provided.

list_devices ~167

List all devices registered to the partner account. WHEN TO USE: - Getting an overview of all connected devices - Finding devices by status (online/offline) - Auditing the device fleet RETURNS: - devices: Array of device objects - total: Total device count - online_count: Number of online devices - offline_count: Number of offline devices EXAMPLE: User: "Show me all my online devices" list_devices({ status: "online", limit: 50 })

NameTypeReqDescription
device_typestringFilter by device type
limitintegerMaximum number of devices to return (default: 50, max: 100)
offsetintegerPagination offset
statusstringFilter by device status

No output schema declared.

No examples provided.

list_endpoints ~212

List every registered Trillboards API operation. WHEN TO USE: - First call in an agent session to learn what the API offers. - Filter to agent_safe=true to list only side-effect-free endpoints. - Narrow to a single surface (data-api, sdk-api, device-api, sensing-api, partner-api-generated, dsp-api-generated). RETURNS: - operations: Array of { surface, method, path, operation_id, summary, description, agent_safe, idempotent, cost_tier, tags, doc_url, example_request } - total_operations: Total count. - surfaces: Known surface identifiers. EXAMPLE: Agent: "What read-only endpoints can I call?" list_endpoints({ agent_safe: true })

NameTypeReqDescription
agent_safebooleanWhen true, return only endpoints flagged agent-safe.
idempotentbooleanWhen true, return only endpoints flagged idempotent.
surfacestringFilter to one surface (e.g. "data-api").

No output schema declared.

No examples provided.

list_error_codes ~132

List every error code in the Trillboards API error catalog. WHEN TO USE: - Understanding what error codes the API can return. - Building a client-side error handler that covers all cases. - Looking up error types, HTTP statuses, and documentation URLs. RETURNS: - object: "list" - data: Array of { code, type, http_status, description, doc_url } - total: Total number of error codes. Equivalent to GET /v1/errors but executed in-process (no HTTP round-trip). EXAMPLE: Agent: "What error codes can the API return?" list_error_codes()

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

list_tasks ~108

[AdCP Protocol] List AdCP tasks belonging to your account, newest first. Returns `query_summary` (totals and a status breakdown), `tasks`, and `pagination`. Filter by status or task type. Scoped to the calling account — an unauthenticated call returns an empty page rather than another account's tasks.

NameTypeReqDescription
accountobject
contextobject
filtersobjectNarrow the returned tasks.
paginationobject

No output schema declared.

No examples provided.

list_webhooks ~124

List all webhook subscriptions for the partner account. WHEN TO USE: - Viewing all configured webhooks - Auditing webhook subscriptions - Finding a webhook to update or delete RETURNS: - webhooks: Array of webhook objects with: - webhook_id: Unique identifier - url: Endpoint URL - events: Subscribed events - enabled: Whether webhook is active - created_at: Creation timestamp - last_delivery: Last successful delivery time EXAMPLE: User: "Show me all my webhooks" list_webhooks({})

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

log_event ~180

[AdCP Media Buy] Record a conversion or attribution event. Records conversion events for post-campaign attribution analysis. Events are deduplicated by event_id + event_type combination. WHEN TO USE: - Recording offline conversions (store visits, purchases) - Tracking post-view attribution events - Logging custom KPI events EXAMPLE: log_event({ media_buy_id: "mbuy_abc123", event: { event_id: "conv_12345", event_type: "store_visit", value_cents: 5000, screen_id: "507f1f77bcf86cd799439011", metadata: { store: "NYC-001", dwell_minutes: 12 } } })

NameTypeReqDescription
eventobjectyesEvent data
media_buy_idstringyesMedia buy ID

No output schema declared.

No examples provided.

predict_moment_quality ~344

Predict the VAS (Viewability Attention Score) a specific creative would achieve at a given moment, based on historical data and causal modeling. Uses the CausalPredictionService which: 1. Embeds the moment description to find historically similar moments 2. If >= 5 similar moments exist with the same creative, uses weighted-average prediction 3. If insufficient data, falls back to Gemini generative prediction 4. Always decomposes the prediction into causal factors WHEN TO USE: - Evaluating whether a creative will perform well in a specific context - A/B testing creative placement hypotheses before committing budget - Understanding which causal factors drive VAS for a creative - Comparing expected performance across different moment types RETURNS: - prediction: { predictedVAS (0-1), confidence (0-1), method ('historical'|'model'), sampleSize } - causal_factors: { audienceMatch, contextMatch, attentionState, socialPotential } (each 0-1) - metadata: { creative_id, moment_description } - suggested_next_queries: Follow-up queries EXAMPLE: User: "How would a coffee ad perform at a transit station during morning rush?" predict_moment_quality({ moment_description: "transit venue, morning commute, 12 viewers, high attention, mostly 25-34 age range", creative_id: "coffee-brand-morning-30s" })

NameTypeReqDescription
creative_idstringyesThe creative/ad ID to predict performance for.
moment_descriptionstringyesNatural-language description of the target moment context. Include venue type, time of day, audience size, demographics, attention level, etc.

No output schema declared.

No examples provided.

predictive_query ~469

Generate predictive insights from observation patterns. Predict whether a venue is likely to see increased foot traffic based on current patterns. Uses historical observation_stream data to compute trend analysis via linear regression on time-bucketed metrics. Generates predictions with confidence intervals based on the observed trend, variance, and sample size. WHEN TO USE: - Predicting future audience patterns at a venue or screen - Forecasting foot traffic trends for campaign planning - Understanding whether metrics are trending up, down, or stable - Making data-driven decisions about inventory and pricing RETURNS: - prediction: The predicted trend and expected values - trend: 'increasing' | 'decreasing' | 'stable' - current_avg: Current average metric value - predicted_avg: Predicted average over the time horizon - change_pct: Expected percentage change - confidence_interval: { lower, upper } bounds - confidence: Overall prediction confidence (0-1) - supporting_data: Recent data points that inform the prediction - data_points: Array of { bucket, avg_value, sample_count } - total_observations: Total observations analyzed - methodology: Description of the prediction approach - suggested_next_queries: Follow-up queries to refine the prediction EXAMPLE: User: "Will this QSR venue see more foot traffic next week?" predictive_query({ question: "Will foot traffic increase at QSR venues?", venue_type: "restaurant_qsr", time_horizon: "7d" }) User: "Predict audience attention trends for this screen" predictive_query({ question: "What will audience attention look like?", screen_id: "507f1f77bcf86cd799439011", time_horizon: "3d" })

NameTypeReqDescription
questionstringyesNatural language question about the predicted trend or outcome
screen_idstringFilter predictions to a specific screen (mongo ID). Optional.
time_horizonstringHow far ahead to predict (e.g., "1d", "3d", "7d", "14d"). Default: "7d", max: "30d"
venue_typestringFilter predictions to a specific venue type. Optional.

No output schema declared.

No examples provided.

provide_performance_feedback ~186

[AdCP Media Buy] Provide optimization signals from buyer agent. Accepts feedback from buyer agents for floor price adjustment and inventory optimization. Enables closed-loop optimization between buyer and seller agents. WHEN TO USE: - Sending bid response feedback to optimize future pricing - Providing conversion data for bid price calibration - Adjusting floor prices based on demand signals EXAMPLE: provide_performance_feedback({ media_buy_id: "mbuy_abc123", feedback: { type: "bid_response", avg_bid_price_cpm: 6.5, fill_rate_percent: 72, preferred_hours: [8, 9, 10, 17, 18], quality_score: 0.85 } })

NameTypeReqDescription
feedbackobjectyesPerformance feedback data
media_buy_idstringyesMedia buy ID

No output schema declared.

No examples provided.

purchase_credits ~91

Purchase committed-use credits at a discount. Three tiers: tier_500 ($500 → $625 credit, 25% bonus), tier_2000 ($2,000 → $3,100 credit, 55% bonus), tier_5000 ($5,000 → $10,000 credit, 100% bonus). Requires an active payment method.

NameTypeReqDescription
tierstringyesCredit purchase tier

No output schema declared.

No examples provided.

query_changelog ~286

Query the Trillboards API changelog for recent changes, breaking changes, deprecations, and fixes. WHEN TO USE: - Check what has changed in the API before upgrading an integration. - Find breaking changes since a specific date. - Discover new features added to a specific API surface. PARAMETERS: - since (YYYY-MM-DD, optional): Only entries dated on or after this date. Unreleased entries are always included. - type (string, optional): Filter by change category. Accepts: "breaking" → changed + removed entries "additive" → added entries "deprecation" → deprecated entries "fix" → fixed entries Can be comma-separated: "breaking,deprecation" RETURNS: - object: "list" - data: Array of { version, date, type, surface, description } - total: Number of matching entries. EXAMPLE: Agent: "What broke since April 1st?" query_changelog({ since: "2026-04-01", type: "breaking" })

NameTypeReqDescription
sincestringOnly entries dated on or after this date (YYYY-MM-DD). Unreleased entries are always included.
typestringFilter by change category: "breaking", "additive", "deprecation", "fix". Comma-separated for multiple.

No output schema declared.

No examples provided.

query_observations ~429

Query the universal observation stream using natural language or structured filters. Returns multi-modal sensing data (audience, vehicle, environment, commerce) from physical-world observations across the screen network. WHEN TO USE: - Exploring raw observation data from edge AI sensors on screens - Filtering observations by venue type, device, time range, or geography - Getting audience, vehicle, environment, or commerce observation data - Answering natural language questions about what screens are sensing RETURNS: - data: Array of observation objects with device, venue, payload, confidence, model versions - metadata: { observation_count, time_range, coverage_pct, model_versions } - suggested_next_queries: Contextual follow-up queries Each observation includes: - observation_id, device_id, screen_mongo_id, venue_type - observed_at: Timestamp of the observation - observation_family: audience | vehicle | environment | commerce - payload: JSONB with model outputs (face_count, emotion, vehicle_count, etc.) - confidence: Model confidence score (0-1) - evidence_grade: Quality grade of the observation - model_versions: Which ML models produced this data EXAMPLE: User: "Show me audience observations at QSR venues in the last hour" query_observations({ query: "audience observations at QSR venues", filters: { observation_family: ["audience"], venue_type: ["restaurant_qsr"], time_range: { start: "2026-03-16T14:00:00Z", end: "2026-03-16T15:00:00Z" } }, limit: 50 }) User: "What are screens sensing right now?" query_observations({ query: "latest observations from all screens", limit: 20 })

NameTypeReqDescription
filtersobjectStructured filters to narrow results
limitintegerMaximum observations to return (default: 100, max: 1000)
querystringyesNatural language query describing what observations to find

No output schema declared.

No examples provided.

recommend_creative ~283

Given a moment description, rank candidate creatives by predicted VAS performance. Evaluates each creative candidate against the described moment context using historical similarity and causal prediction. Returns a ranked list sorted by predicted VAS score, with confidence levels for each prediction. WHEN TO USE: - Choosing which creative to show at a specific moment/venue - Comparing multiple creatives for a campaign across different contexts - Optimizing creative rotation for maximum VAS - Pre-campaign creative selection based on audience and venue RETURNS: - rankings: Array sorted by predicted VAS (descending) - creativeId, predictedVAS (0-1), confidence (0-1), rank (1-N) - metadata: { candidate_count, moment_description } - suggested_next_queries: Follow-up queries EXAMPLE: User: "Which of these 3 creatives will perform best at a gym in the evening?" recommend_creative({ moment_description: "gym venue, evening, 6 viewers, high attention, mostly male 18-34", creative_ids: ["fitness-brand-30s", "energy-drink-15s", "tech-gadget-20s"] })

NameTypeReqDescription
creative_idsarrayyesArray of creative/ad IDs to rank. Maximum 20 candidates.
moment_descriptionstringyesNatural-language description of the target moment context.

No output schema declared.

No examples provided.

record_impression ~224

Record a single ad impression from a device. WHEN TO USE: - Reporting that an ad was displayed on a device - Recording impression with detailed metadata - Single impression events (for batch, use batch_impressions) RETURNS: - success: Boolean indicating success - impression_id: Unique impression identifier - earnings: Earnings credited for this impression EXAMPLE: User: "Record an impression for ad 507f1f77bcf86cd799439011" record_impression({ fingerprint: "P_abc123", ad_id: "507f1f77bcf86cd799439011", duration_seconds: 15 })

NameTypeReqDescription
ad_idstringyesAdvertisement ID (MongoDB ObjectId)
duration_secondsnumberHow long the ad was displayed (seconds)
fingerprintstringyesDevice fingerprint (e.g., "P_abc123")
metadataobjectAdditional impression metadata
timestampstringISO 8601 timestamp when impression occurred (optional, defaults to now)

No output schema declared.

No examples provided.

register_device ~275

Register or update a device in the partner's network. WHEN TO USE: - Adding a new screen/kiosk/vending machine to the network - Updating device location or configuration - Re-registering a device after maintenance RETURNS: - device_id: Your internal device ID (echoed back) - trillboards_device_id: Internal Trillboards device ID - fingerprint: Device fingerprint (e.g., "P_abc123") - embed_url: URL to load in the device's WebView - status: Device status EXAMPLE: User: "Register a vending machine in NYC" register_device({ device_id: "vending-001-nyc", name: "NYC Office Lobby Vending", device_type: "vending_machine", location: { lat: 40.7128, lng: -74.0060, city: "New York", state: "NY", venue_type: "office" } })

NameTypeReqDescription
device_idstringyesYour internal unique device identifier
device_typestringType of device
locationobjectDevice location information
metadataobjectAdditional custom metadata
namestringHuman-readable device name
specsobjectDevice specifications

No output schema declared.

No examples provided.

register_partner ~227

Register a new partner organization with Trillboards. WHEN TO USE: - First-time setup for a new partner integration - Creating a new partner account to manage devices RETURNS: - partner_id: Unique partner identifier - api_key: API key for authenticated requests (store securely!) - status: Account status EXAMPLE: User: "Register my vending machine company" register_partner({ company_name: "Acme Vending Co", email: "tech@acmevending.com", industry: "vending", expected_devices: 50 })

NameTypeReqDescription
company_namestringyesCompany or organization name
contact_namestringPrimary contact person name (optional)
contact_phonestringContact phone number (optional)
emailstringyesContact email for the partner account
expected_devicesintegerEstimated number of devices to connect
industrystringIndustry type (e.g., "vending", "retail", "hospitality")
websitestringCompany website URL (optional)

No output schema declared.

No examples provided.

search_content ~287

Semantic search over content library using natural language queries and 768-D pgvector embeddings. WHEN TO USE: - Finding content by description or theme ("upbeat music videos", "cooking shows") - Discovering content similar to a concept or mood - Searching the content library without knowing exact titles or IDs - Content discovery for programmatic content scheduling RETURNS: - data: Array of matching content with similarity scores - videoId, title, contentCategory, description, durationSeconds - reviewStatus (approved/pending/rejected) - similarity (0-1, cosine similarity against query embedding) - meta: { count, query, limit, minSimilarity } EXAMPLE: User: "Find fitness and workout content" search_content({ query: "fitness workout exercise gym", limit: 10, min_similarity: 0.6 }) User: "Search for calming nature content suitable for medical offices" search_content({ query: "calming nature scenes peaceful landscapes meditation", min_similarity: 0.5 })

NameTypeReqDescription
limitintegerMaximum results to return (default: 20, max: 100)
min_similaritynumberMinimum cosine similarity threshold (default: 0.5, range: 0-1)
querystringyesNatural language search query (min 3 characters)

No output schema declared.

No examples provided.

semantic_audience_search ~246

Search screens by natural language scene description using pgvector. Uses 768-dimensional Gemini embeddings on scene descriptions from FEIN edge AI to find screens matching a natural language query. WHEN TO USE: - Finding screens by audience context ("families eating lunch in a food court") - Contextual ad placement based on real-time scene understanding - Discovering inventory matching a specific audience scenario RETURNS: Array of matching screens ranked by semantic similarity, each with: - screen_id, mongo_screen_id, scene_description, contextual_relevance, similarity, created_at EXAMPLE: semantic_audience_search({ query: "young professionals in a coffee shop looking at phones", limit: 10 })

NameTypeReqDescription
limitintegerMaximum number of results (default: 20, max: 100)
min_similaritynumberMinimum semantic similarity threshold 0-1 (default: 0.5)
querystringyesNatural language description of the audience/scene to search for
sincestringTime window for scene data (e.g., "1h", "24h", "7d"). Default: "24h"

No output schema declared.

No examples provided.

semantic_search_observations ~564

Search observations by semantic similarity. Find moments that match a description like "lunch rush at fast casual restaurants" using vector embeddings. Uses 768-dimensional Gemini embeddings on observation payloads to find promoted observations matching a natural language query via approximate nearest-neighbour (ANN) cosine similarity search over a Lance IVF_PQ index. CONSISTENCY: results are APPROXIMATE and EVENTUALLY CONSISTENT. - Approximate: retrieval is ANN, not an exhaustive scan (measured recall ~0.96 against exact KNN), so an identical query may omit a borderline match. - Eventually consistent: the index is served from a replicated pool whose replicas refresh independently, so for up to 5 minutes after new observations are published, two identical calls may return slightly different result sets. The difference is confined to the VISIBILITY of newly-published observations; the relative ranking of already-visible ones does not change. Do not use this tool where a repeatable, exhaustive result set is required. TIME BOUND: searches the last 30 days by default. Pass filters.time_range to widen or narrow it; the window actually applied is echoed in metadata.time_range. Observations are retained for 90 days. WHEN TO USE: - Finding observations that match a conceptual description - Discovering contextual moments across the screen network - Searching for audience situations ("families waiting in line", "professionals on coffee break") - Finding commerce patterns ("high purchase intent near checkout") RETURNS: - data: Array of matching observations ranked by semantic similarity, each with: - observation_id, device_id, venue_type, observation_family - observed_at, payload, confidence, evidence_grade - similarity: Cosine similarity score (0-1, higher = more relevant) - metadata: { result_count, query_embedding_model, search_scope, time_range } - suggested_next_queries: Related semantic queries to explore EXAMPLE: User: "Find lunch rush moments at…

NameTypeReqDescription
filtersobjectAdditional structured filters to narrow semantic search
limitintegerMaximum results to return (default: 20, max: 100)
querystringyesNatural language description of the observation moments to search for

No output schema declared.

No examples provided.

setup_billing ~70

Set up pay-per-use billing with a Stripe payment method. Required after exceeding free tier limits. Pass a Stripe payment method token (pm_xxx) obtained from Stripe.js or Stripe Elements.

NameTypeReqDescription
payment_method_idstringyesStripe payment method token (pm_xxx) from Stripe.js or Elements

No output schema declared.

No examples provided.

sync_accounts ~583

[AdCP Accounts] Establish or confirm the account behind this credential. IMPORTANT — what this does NOT do: it does not provision a new account. This seller's namespace is one account per API key, so a provisioning-mode entry (brand + operator + billing) is LINKED to the account your key already owns and the response says so in warnings[]. Two different brands on one key resolve to the SAME account_id. Register one agent per brand at https://api.trillboards.com/v1/partner/agent/register if you need per-brand separation. BILLING IS THE ONE SETTING THAT IS APPLIED. Send billing: 'operator' (we invoice you, buying direct) or 'agent' (you are a buying agent consolidating across the brands you front, and we invoice you for all of them — the marketplace-clearing model). The value is stored on the account, reported back by list_accounts, and reflected in action 'updated'. The set we accept is exactly account.supported_billing from get_adcp_capabilities; 'advertiser' is refused, with the reason, because we hold no billing relationship with a third-party advertiser. One key is one account with one invoiced party, so a request declaring two different billing values applies neither and says so. Everything else is read-only and reports 'unchanged': payment terms, billing entity and notification subscriptions are not per-account state on this platform, and anything sent that was not applied is named in warnings[] rather than silently swallowed. WHEN TO USE: - The account-setup step at the start of a buying flow - Declaring how you want to be invoiced, before create_media_buy - Confirming your account_id and status before create_media_buy RETURNS: - accounts: per-entry result with account_id, action ('updated' | 'unchanged' | 'failed'), status, billing, account_scope, and warnings naming anything not applied EXAMPLE: sync_accounts({ idempotency_key: "8f1c...", accounts: [{ brand: { domain: "acme.example" }, operator: "agency.example", billing: "agent" }] })

NameTypeReqDescription
accountsarrayyesPer-account entries. Each uses ONE key shape: `account` (settings-update) or the flat brand + operator + billing trio (provisioning).
contextobject
delete_missingbooleanNot supported — this seller never deletes an account from a sync.
dry_runbooleanEcho what would happen without applying it. Reported back as dry_run.
idempotency_keystringyesClient-generated key for safe retries. This operation has no side effects, so a replay returns the same result.
push_notification_configobject

No output schema declared.

No examples provided.

sync_creatives ~255

[AdCP Media Buy] Validate and sync creative assets for a media buy. Validates creative assets (resolution, duration, format) against screen specifications. Returns compatibility status for each screen in the campaign. WHEN TO USE: - Submitting creative assets before campaign launch - Checking if a creative meets screen requirements - Validating VAST tags EXAMPLE: sync_creatives({ media_buy_id: "mbuy_abc123", creatives: [{ url: "https://cdn.example.com/ad.mp4", type: "video", width: 1920, height: 1080, duration_seconds: 15, file_size_mb: 12 }] })

NameTypeReqDescription
accountobject
assignmentsarray
contextobject
creative_idsarray
creativesarrayyesCreative assets to validate
delete_missingboolean
dry_runboolean
extobject
idempotency_keystring
media_buy_idstringMedia buy ID
push_notification_configobject
validation_modestring

No output schema declared.

No examples provided.

tasks_get ~407

[AdCP Protocol] Get the status of a previously issued AdCP task. Every AdCP task Trillboards serves for an AUTHENTICATED caller is recorded and returned a `task_id`. Poll that id here to read the task's terminal state and, with `include_result: true`, its completion payload. Trillboards answers every AdCP task in-process, so a task is already `completed` by the time you hold its id — this tool exists so a buyer that polls does not hang, and so an async arm has somewhere to report from when one lands. TASK SCOPE: tasks are visible only to the account that created them. An id belonging to another account, an id we never issued, or a poll with no credential all answer identically — "Task <id> not found" — so the surface cannot be used to probe which ids exist. NOT RECORDED: read-only protocol and catalogue calls that AdCP does not model as tasks (get_adcp_capabilities, list_creative_formats, get_media_buys, list_accounts), and any anonymous call, which has no account to scope to. LEGACY NAME. Identical to `get_task_status`; this is the name the AdCP MCP binding emits (`agent.protocol === "mcp" ? "tasks_get" : "tasks/get"`). Prefer `get_task_status` in new code.

NameTypeReqDescription
accountobject
contextobject
include_historybooleanInclude conversation history. Trillboards tasks complete in-process and hold no multi-turn history, so this is accepted and has no effect.
include_resultbooleanInclude the task's result payload when status is completed. Defaults to false for lightweight status-only polls.
task_idstringyesUnique identifier of the task to retrieve, as issued in the `task_id` field of the originating task response.

No output schema declared.

No examples provided.

tasks_list ~128

[AdCP Protocol] List AdCP tasks belonging to your account, newest first. Returns `query_summary` (totals and a status breakdown), `tasks`, and `pagination`. Filter by status or task type. Scoped to the calling account — an unauthenticated call returns an empty page rather than another account's tasks. LEGACY NAME. Identical to `list_tasks`. Prefer `list_tasks` in new code.

NameTypeReqDescription
accountobject
contextobject
filtersobjectNarrow the returned tasks.
paginationobject

No output schema declared.

No examples provided.

test_webhook ~171

Send a test event to a webhook endpoint. WHEN TO USE: - Verifying webhook endpoint is working - Testing integration during development - Debugging webhook delivery issues RETURNS: - success: Boolean indicating delivery success - response_code: HTTP response code from endpoint - response_time_ms: Response time in milliseconds - error: Error message if delivery failed EXAMPLE: User: "Test my webhook with a device.online event" test_webhook({ webhook_id: "wh_mmmpdbvj_8b7c5a59296d", event: "device.online" })

NameTypeReqDescription
eventstringEvent type to simulate (optional, defaults to device.online)
webhook_idstringyesWebhook ID to test (wh_xxx format or legacy ObjectId)

No output schema declared.

No examples provided.

update_media_buy ~250

[AdCP Media Buy] Update an existing media buy (campaign). Modify budget, targeting, schedule, or status of an existing media buy. WHEN TO USE: - Adjusting campaign budget mid-flight - Pausing or resuming a campaign - Changing targeting parameters - Extending campaign dates EXAMPLE: update_media_buy({ media_buy_id: "mbuy_abc123", updates: { status: "paused", budget: { daily_usd: 300 } } })

NameTypeReqDescription
accountobject
canceledboolean
cancellation_reasonstring
contextobject
end_timestring
extobject
idempotency_keystring
invoice_recipientobject
media_buy_idstringyesMedia buy ID to update
new_packagesarray
packagesarray
pausedboolean
push_notification_configobject
reporting_webhookobject
revisioninteger
start_time
updatesobjectFields to update

No output schema declared.

No examples provided.

update_webhook ~184

Update an existing webhook subscription. WHEN TO USE: - Changing the webhook endpoint URL - Adding or removing subscribed events - Enabling or disabling a webhook - Updating the webhook description RETURNS: - webhook_id: The updated webhook ID - url: Updated endpoint URL - events: Updated event subscriptions - enabled: Updated enabled status - updated_at: Update timestamp EXAMPLE: User: "Disable the webhook for maintenance" update_webhook({ webhook_id: "wh_mmmpdbvj_8b7c5a59296d", enabled: false }) User: "Add impression events to my webhook" update_webhook({ webhook_id: "wh_mmmpdbvj_8b7c5a59296d", events: ["device.online", "device.offline", "impression.recorded"] })

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

validate_request ~202

Validate a proposed request payload against the registered Zod schema for an operation, returning the exact canonical error envelope the HTTP surface would emit. WHEN TO USE: - Before calling a write endpoint, to catch payload bugs locally. - Debugging 400 validation_error responses. RETURNS: - valid: true when the payload would pass Zod validation. - When invalid, the canonical { error: { type, code, message, param, doc_url, details[] } } envelope is included under `error`. EXAMPLE: validate_request({ path: "/v1/data/query", method: "POST", payload: { dataset: "inference_outcomes", limit: 9999 } })

NameTypeReqDescription
methodstringyes
pathstringyesOperation path (OpenAPI template form).
payloadShape is operation-dependent. GET → { query?, params? }. POST → body + optional { query?, params? }.

No output schema declared.

No examples provided.

verify_proof_of_play ~487

Verify cryptographic proof of ad delivery or get campaign proofs. Requires either campaign_id or proof_payload (at least one must be provided). Two modes: 1. Verify a proof: pass proof_payload with signature fields to verify 2. Get proofs: pass campaign_id to get Ed25519-signed proofs for a campaign Uses Ed25519 signatures (v2) that can be independently verified by third parties using the Trillboards public key. WHEN TO USE: - Verifying that ads were actually delivered to screens - Exporting cryptographically signed proof records for auditors - Getting proof-of-play data for campaign transparency reports RETURNS (verify mode): - valid: boolean, reason: string if invalid, version: 'v1' or 'v2' RETURNS (get proofs mode): - campaignId, totalImpressions, proofsReturned - proofs: Array of signed impression proofs - pagination: { limit, hasMore, nextCursor } - signatureVersion, publicKeyUrl EXAMPLE (verify): verify_proof_of_play({ proof_payload: { signature: "ed25519=abc123...", timestamp: "2026-03-10T15:30:00Z", adId: "ad_123", impressionId: "imp_456", screenId: "scr_789", deviceId: "dev_012" } }) EXAMPLE (get proofs): verify_proof_of_play({ campaign_id: "camp_abc123", start_date: "2026-03-01", end_date: "2026-03-10" })

NameTypeReqDescription
campaign_idstringCampaign ID to get proofs for (mutually exclusive with proof_payload)
cursorstringPagination cursor from previous response (used with campaign_id)
end_datestringEnd date for proof query (YYYY-MM-DD, used with campaign_id)
limitintegerMax proofs to return (default: 1000, used with campaign_id)
proof_payloadobjectProof data to verify (mutually exclusive with campaign_id). Must include: signature, timestamp, adId, impressionId, screenId, deviceId
start_datestringStart date for proof query (YYYY-MM-DD, used with campaign_id)

No output schema declared.

No examples provided.

Common questions

What is the Trillboards DOOH Advertising MCP server?

Trillboards DOOH Advertising is an MCP server listed in the public MCP registry as io.github.snehdhruv/trillboards-dooh. DOOH advertising via AI agents. 5,000+ screens with edge AI audience intelligence. This page covers its hosted endpoint (https://api.trillboards.com/mcp).

Is the Trillboards DOOH Advertising MCP server safe to use?

Trillboards DOOH Advertising scores 79 out of 100 on VerifyMCP. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

What tools does the Trillboards DOOH Advertising MCP server expose?

Trillboards DOOH Advertising exposes 83 tools: register_partner, get_partner_info, register_device, list_devices, get_device, and 78 more. Their descriptions and schemas cost roughly 21,774 tokens of context every time the server is loaded.

Does the Trillboards DOOH Advertising MCP server require authentication?

No. We connected to Trillboards DOOH Advertising without credentials and it answered, so anything it exposes is reachable by anyone who knows the address.

Is the Trillboards DOOH Advertising MCP server still maintained?

Trillboards DOOH Advertising is still listed as active in the MCP registry. We last reached this channel on 24 September 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.