Trillboards DOOH Advertising
REMOTE · API.TRILLBOARDS.COM · SCANNED SEP 24
DOOH advertising via AI agents. 5,000+ screens with edge AI audience intelligence.
Available components
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
- The endpoint's TLS certificate is valid, in date, and uses a strong key. View diagnostics → Pass
- Authorisation not fully verified: no authorisation is required to call this server, and 83 tool(s) never declared a destructiveHint. The MCP spec treats an absent hint as destructive by default, so we cannot call this surface safe. See how to fix → View diagnostics → Unverified
- HTTPS is enforced; there's no plaintext access path. View diagnostics → Pass
- The HSTS (Strict-Transport-Security) header is present. View diagnostics → Pass
- DNSSEC check failed: this domain isn't protected by DNSSEC. See how to fix → View diagnostics → Fail
Transport & Reachability100
- Verified streamable-http transport via a live MCP handshake. View diagnostics → Pass
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
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
claude mcp add --transport http snehdhruv-trillboards-dooh 'https://api.trillboards.com/mcp'
{
"mcpServers": {
"snehdhruv-trillboards-dooh": {
"url": "https://api.trillboards.com/mcp"
}
}
} {
"servers": {
"snehdhruv-trillboards-dooh": {
"type": "http",
"url": "https://api.trillboards.com/mcp"
}
}
} [mcp_servers.snehdhruv-trillboards-dooh] url = "https://api.trillboards.com/mcp"
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"snehdhruv-trillboards-dooh": {
"type": "remote",
"url": "https://api.trillboards.com/mcp",
"enabled": true
}
}
} openclaw mcp add snehdhruv-trillboards-dooh --url 'https://api.trillboards.com/mcp' --transport streamable-http
mcp_servers:
snehdhruv-trillboards-dooh:
url: "https://api.trillboards.com/mcp" {
"McpServers": {
"snehdhruv-trillboards-dooh": {
"Transport": "http",
"Url": "https://api.trillboards.com/mcp"
}
}
} assistant mcp add snehdhruv-trillboards-dooh -t streamable-http -u 'https://api.trillboards.com/mcp'
{
"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.
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
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 |
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 →
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 })
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Maximum number of deliveries to return (default: 50, max: 100) |
| status | string | – | Filter by delivery status |
| webhook_id | string | yes | Webhook 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" })
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | Exact 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… |
| context | object | – | – |
| pagination | object | – | – |
| sandbox | boolean | – | Filter 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… |
| status | string | – | Filter 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" }] })
| Name | Type | Req | Description |
|---|---|---|---|
| asset_types | array | – | Filter to formats containing these asset types, e.g. ['video'] or ['image']. |
| context | object | – | – |
| format_ids | array | – | Return only these formats. Each entry is an AdCP structured format reference ({agent_url, id}), never a bare string. |
| is_responsive | boolean | – | Filter for responsive formats. Every DOOH panel is a fixed pixel grid, so true matches nothing here. |
| max_height | number | – | Maximum render height in pixels (inclusive) |
| max_width | number | – | Maximum render width in pixels (inclusive) |
| min_height | number | – | Minimum render height in pixels (inclusive) |
| min_width | number | – | Minimum render width in pixels (inclusive) |
| name_search | string | – | Case-insensitive partial match on the format name |
| pagination | object | – | Cursor-based pagination |
| publisher_domain | string | – | Resolve 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| context | object | – | – |
| ext | object | – | – |
| fields | array | – | – |
| filters | object | – | Narrow the result set. All fields optional. |
| include_assignments | boolean | – | Include which media buys each creative is attached to. |
| include_items | boolean | – | – |
| include_pricing | boolean | – | – |
| include_purged | boolean | – | – |
| include_snapshot | boolean | – | – |
| include_variables | boolean | – | – |
| include_webhook_activity | boolean | – | – |
| pagination | object | – | – |
| sort | object | – | – |
| webhook_activity_limit | integer | – | – |
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 })
| Name | Type | Req | Description |
|---|---|---|---|
| device_type | string | – | Filter by device type |
| limit | integer | – | Maximum number of devices to return (default: 50, max: 100) |
| offset | integer | – | Pagination offset |
| status | string | – | Filter 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| agent_safe | boolean | – | When true, return only endpoints flagged agent-safe. |
| idempotent | boolean | – | When true, return only endpoints flagged idempotent. |
| surface | string | – | Filter 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.
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| context | object | – | – |
| filters | object | – | Narrow the returned tasks. |
| pagination | object | – | – |
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 } } })
| Name | Type | Req | Description |
|---|---|---|---|
| event | object | yes | Event data |
| media_buy_id | string | yes | Media 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" })
| Name | Type | Req | Description |
|---|---|---|---|
| creative_id | string | yes | The creative/ad ID to predict performance for. |
| moment_description | string | yes | Natural-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" })
| Name | Type | Req | Description |
|---|---|---|---|
| question | string | yes | Natural language question about the predicted trend or outcome |
| screen_id | string | – | Filter predictions to a specific screen (mongo ID). Optional. |
| time_horizon | string | – | How far ahead to predict (e.g., "1d", "3d", "7d", "14d"). Default: "7d", max: "30d" |
| venue_type | string | – | Filter 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 } })
| Name | Type | Req | Description |
|---|---|---|---|
| feedback | object | yes | Performance feedback data |
| media_buy_id | string | yes | Media 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.
| Name | Type | Req | Description |
|---|---|---|---|
| tier | string | yes | Credit 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" })
| Name | Type | Req | Description |
|---|---|---|---|
| since | string | – | Only entries dated on or after this date (YYYY-MM-DD). Unreleased entries are always included. |
| type | string | – | Filter 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| filters | object | – | Structured filters to narrow results |
| limit | integer | – | Maximum observations to return (default: 100, max: 1000) |
| query | string | yes | Natural 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"] })
| Name | Type | Req | Description |
|---|---|---|---|
| creative_ids | array | yes | Array of creative/ad IDs to rank. Maximum 20 candidates. |
| moment_description | string | yes | Natural-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 })
| Name | Type | Req | Description |
|---|---|---|---|
| ad_id | string | yes | Advertisement ID (MongoDB ObjectId) |
| duration_seconds | number | – | How long the ad was displayed (seconds) |
| fingerprint | string | yes | Device fingerprint (e.g., "P_abc123") |
| metadata | object | – | Additional impression metadata |
| timestamp | string | – | ISO 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" } })
| Name | Type | Req | Description |
|---|---|---|---|
| device_id | string | yes | Your internal unique device identifier |
| device_type | string | – | Type of device |
| location | object | – | Device location information |
| metadata | object | – | Additional custom metadata |
| name | string | – | Human-readable device name |
| specs | object | – | Device 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| company_name | string | yes | Company or organization name |
| contact_name | string | – | Primary contact person name (optional) |
| contact_phone | string | – | Contact phone number (optional) |
| string | yes | Contact email for the partner account | |
| expected_devices | integer | – | Estimated number of devices to connect |
| industry | string | – | Industry type (e.g., "vending", "retail", "hospitality") |
| website | string | – | Company 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Maximum results to return (default: 20, max: 100) |
| min_similarity | number | – | Minimum cosine similarity threshold (default: 0.5, range: 0-1) |
| query | string | yes | Natural 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 })
| Name | Type | Req | Description |
|---|---|---|---|
| limit | integer | – | Maximum number of results (default: 20, max: 100) |
| min_similarity | number | – | Minimum semantic similarity threshold 0-1 (default: 0.5) |
| query | string | yes | Natural language description of the audience/scene to search for |
| since | string | – | Time 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…
| Name | Type | Req | Description |
|---|---|---|---|
| filters | object | – | Additional structured filters to narrow semantic search |
| limit | integer | – | Maximum results to return (default: 20, max: 100) |
| query | string | yes | Natural 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.
| Name | Type | Req | Description |
|---|---|---|---|
| payment_method_id | string | yes | Stripe 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" }] })
| Name | Type | Req | Description |
|---|---|---|---|
| accounts | array | yes | Per-account entries. Each uses ONE key shape: `account` (settings-update) or the flat brand + operator + billing trio (provisioning). |
| context | object | – | – |
| delete_missing | boolean | – | Not supported — this seller never deletes an account from a sync. |
| dry_run | boolean | – | Echo what would happen without applying it. Reported back as dry_run. |
| idempotency_key | string | yes | Client-generated key for safe retries. This operation has no side effects, so a replay returns the same result. |
| push_notification_config | object | – | – |
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 }] })
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| assignments | array | – | – |
| context | object | – | – |
| creative_ids | array | – | – |
| creatives | array | yes | Creative assets to validate |
| delete_missing | boolean | – | – |
| dry_run | boolean | – | – |
| ext | object | – | – |
| idempotency_key | string | – | – |
| media_buy_id | string | – | Media buy ID |
| push_notification_config | object | – | – |
| validation_mode | string | – | – |
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.
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| context | object | – | – |
| include_history | boolean | – | Include conversation history. Trillboards tasks complete in-process and hold no multi-turn history, so this is accepted and has no effect. |
| include_result | boolean | – | Include the task's result payload when status is completed. Defaults to false for lightweight status-only polls. |
| task_id | string | yes | Unique 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.
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| context | object | – | – |
| filters | object | – | Narrow the returned tasks. |
| pagination | object | – | – |
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" })
| Name | Type | Req | Description |
|---|---|---|---|
| event | string | – | Event type to simulate (optional, defaults to device.online) |
| webhook_id | string | yes | Webhook 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 } } })
| Name | Type | Req | Description |
|---|---|---|---|
| account | object | – | – |
| canceled | boolean | – | – |
| cancellation_reason | string | – | – |
| context | object | – | – |
| end_time | string | – | – |
| ext | object | – | – |
| idempotency_key | string | – | – |
| invoice_recipient | object | – | – |
| media_buy_id | string | yes | Media buy ID to update |
| new_packages | array | – | – |
| packages | array | – | – |
| paused | boolean | – | – |
| push_notification_config | object | – | – |
| reporting_webhook | object | – | – |
| revision | integer | – | – |
| start_time | – | – | – |
| updates | object | – | Fields 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 } })
| Name | Type | Req | Description |
|---|---|---|---|
| method | string | yes | – |
| path | string | yes | Operation path (OpenAPI template form). |
| payload | – | – | Shape 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" })
| Name | Type | Req | Description |
|---|---|---|---|
| campaign_id | string | – | Campaign ID to get proofs for (mutually exclusive with proof_payload) |
| cursor | string | – | Pagination cursor from previous response (used with campaign_id) |
| end_date | string | – | End date for proof query (YYYY-MM-DD, used with campaign_id) |
| limit | integer | – | Max proofs to return (default: 1000, used with campaign_id) |
| proof_payload | object | – | Proof data to verify (mutually exclusive with campaign_id). Must include: signature, timestamp, adId, impressionId, screenId, deviceId |
| start_date | string | – | Start date for proof query (YYYY-MM-DD, used with campaign_id) |
No output schema declared.
No examples provided.
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.