MCP & AI agents
Waveband ships a Model Context Protocol (MCP) server at /mcp so AI assistants and agents can operate your seat with the same scoped permissions as the REST API. Connect Claude, Cursor, or any MCP-capable client and ask it to launch campaigns, adjust budgets, or explain performance. The server advertises itself at /.well-known/mcp.json for clients that support MCP discovery.
Connecting (developer tools)
{
"mcpServers": {
"waveband": {
"url": "https://<your-host>/mcp",
"headers": { "Authorization": "Bearer wbk_..." }
}
}
}Tool availability follows your key's scopes: a key with reports:read only can answer questions but never touch budgets.
Hosted assistants (OAuth)
Hosted clients (claude.ai connectors, ChatGPT connectors) authenticate via OAuth instead of static keys: connect from the client's integration settings using your Waveband host; you will be asked to sign in and approve the requested scopes.
GET /.well-known/oauth-authorization-server GET /.well-known/oauth-protected-resource POST /oauth/register # RFC 7591 dynamic client registration GET /oauth/authorize # consent screen (console sign-in) POST /oauth/token # authorization_code + PKCE
Tokens are scoped to the intersection of the requested scopes and the approving user's own permissions: an analyst can never mint an agent token that writes campaigns.
Guardrails
Write actions from agents obey the same permission policy as Autopilot automations: action grants, bounded budget changes, propose-vs-auto-apply modes, full decision logging, and one-click undo. Configure per key/automation in the console. A key with a permission policy makes changes only through the dedicated tools (which apply the policy): its REST writes, including through waveband_api, are refused, and it can't create, edit or resume automations (it can still pause one). It can't approve or undo a decision either: a person, or a key without a policy, does that. Budget, status, targeting, bid, and creative changes each go through the policy, so send each one in its own call.
MCP server vs the in-app Copilot
- MCP lists the tools below that your key or token's scopes allow, plus
waveband_api, which calls any operation in the API reference. Everything the API can do, an MCP client can do. - Copilot (Console → Copilot) uses the same tools with your console role's permissions, but not
waveband_api. For an operation without a tool (rate cards, teams, branding), use the console or an MCP client.
Where can I do this? maps each capability to its console page, REST operations, and tool.
Tools
Money values are integer USD cents. Most tools take a workspaceId; start with list_workspaces. Input schemas come from tools/list.
| Tool | Scope | What it does |
|---|---|---|
list_workspaces | workspaces:read | List the workspaces (advertiser accounts) this token can access. |
update_workspace | workspaces:write | Update workspace settings: advertiser domain (e.g. example.com) and IAB category (e.g. IAB1), set together and required before campaigns can deliver; and/or disclosureLevel, what client roles see of spend (billed_rates, percent_delivery, or full_transparency). |
list_campaigns | campaigns:read | List campaigns in a workspace, newest first. |
get_campaign | campaigns:read | Get one campaign with budget, dates, goal, and status. |
create_campaign | campaigns:write | Create a campaign. Budgets are integer USD cents. Channels: display, mobile_app, olv, ctv, native, dooh. |
update_campaign | campaigns:write | Update a campaign: budget, dates, goal, or status (active/paused for pause/resume). |
list_line_items | line_items:read | List line items (ad groups) in a campaign with budgets, bids, and targeting. |
get_line_item | line_items:read | Get one line item with budget, bid, pacing, flight, status, and full targeting. |
list_line_item_creatives | line_items:read | List the creatives currently attached to a line item (removed ones excluded). |
create_line_item | line_items:write | Create a line item under a campaign with budget (USD cents), CPM bid, pacing, and targeting (geo, device, inventory, dayparting). Targeting needs the targeting:write scope. |
update_line_item | line_items:write | Update a line item: budget, bid, pacing, targeting, or status (activate/pause/resume). Targeting replaces the whole object, except that omitted adsTxtOnly and defaultExchanges keep their current values. Changing targeting needs the targeting:write scope. |
set_targeting | targeting:write | Replace a line item's targeting (geo countries/regions/DMAs/zips, cities as GeoNames ids, device types, environments, exchanges, deal IDs, domain and app bundle lists, video content genres, adsTxtOnly and defaultExchanges (omitted, they keep the line item's current values; defaultExchanges false = all exchanges when none are picked), dayparting). Look up DMA, region, city, exchange, and genre values with lookup_targeting_options. |
list_creatives | creatives:read | List creatives in a workspace with type and processing status. |
get_creative | creatives:read | Get one creative with its type, assets, and processing status. |
upload_creative | creatives:write | Create a creative from URL-hosted assets (image/video; audio comes with audio campaigns), an inline html5 `html` body (Studio/Waveforms path), Soundframe render.kind=audio_led_video (audio URL and/or script, companion URL and/or image prompt), or native content fields. |
attach_creative | line_items:write | Attach a creative to a line item (validates channel compatibility). |
detach_creative | line_items:write | Remove a creative from a line item. A running line item must keep at least one creative. |
list_conversion_events | events:read | List conversion event definitions in a workspace. |
create_conversion_event | events:write | Define a conversion event (name, click/view attribution windows, default value). |
lookup_targeting_options | targeting:read | Find values for targeting fields that take ids: metros (DMA codes), regions, cities (numeric city ids), inventorySources (exchanges), contentGenres. Pass q to search by name, or values to get labels for ids you already have. At most 50 results. |
forecast_line_item | targeting:read | Estimate available impressions for a line item's channel, targeting, and flight (startDate, endDate; UTC, from tomorrow, at most 31 days). Available supply, not a delivery promise. Capacity is limited per account per minute: a result of unavailable/busy means retry in a minute. |
list_deals | catalog:read | List the private marketplace deals in your library (target them via targeting.inventory.dealIds). Set includeCurated to also see platform curated deals you can activate. |
activate_curated_deal | catalog:write | Copy a platform curated deal into your deal library so line items can target it. Returns the existing deal when it is already there. |
quote_ad_generation | ai:invoke | Price an AI ad generation (format: display, video, ctv; a brief; an https landing URL). Returns the typical and maximum cost in USD cents and the wallet balance. Nothing is charged. |
generate_ads | ai:invoke | Generate finished ads with AI. This charges the wallet: up to the quoted maximum is set aside now and settled to the actual cost when the ads are ready (usually a few minutes). Call quote_ad_generation first and confirm the price with the user. The ads appear as processing creatives in the workspace. Do not retry a call that may have gone through; for safe retries call waveband_api with POST /api/v1/creative-generations and an idempotencyKey. |
list_ad_generations | creatives:read | List the 20 most recent AI ad generations in a workspace with status and cost. |
list_audiences | audiences:read | List audience segments in a workspace with matched counts, kind, and provisioning status. |
create_audience | audiences:write | Create an audience segment: site_visitors/converters/event_rule (pixel rules), crm_list/ip_list (uploads), or marketplace (activate a catalog row). |
search_audience_marketplace | audiences:read | Browse/search the third-party data marketplace. Filter by provider, max/min data CPM (USD dollars), min reach, and sort; returns { items, total } with data CPM and reach. Omit query to browse. |
attach_audience | audiences:write | Attach a segment to a line item's audience targeting (retargeting). Set exclude=true to suppress the segment instead. |
detach_audience | audiences:write | Remove a segment from a line item's audience targeting. |
run_report | reports:read | Query delivery/performance metrics (impressions, clicks, conversions, spend in USD cents, video/audio starts, quartiles, completes, and completion rate) grouped by day, campaign, line_item, creative, or channel over a date range. Conversions are null when grouped by creative (they are attributed per line item). Set format to csv for a CSV export of the same rows. |
narrate_report | reports:read | Write a plain-English summary of a report: what happened, why, and what to do next. Runs an AI model (needs ai:invoke as well as reports:read); usage on platform models is billed to the account. |
create_share_link | reports:write | Create a read-only report link that anyone with the URL can open without signing in, optionally limited to one campaign. Expires after ttlDays (default 30). Returns the id (to revoke it) and the full url. |
get_billing | billing:read | Read the account's billing position: billing mode, whether the wallet has ever been funded, wallet balance, the amount set aside for running campaigns, and availableUsdMinor (what is left to fund more delivery), plus plan limits and usage. Use it to tell whether campaigns will be funded before activating them. |
create_top_up_link | billing:write | Create a hosted checkout link to add funds to the prepaid wallet. A person must open the link and pay; nothing is charged by this tool. Give the link to the user. Amount is in USD cents; new accounts have a top-up limit in their first 30 days. |
list_automations | automations:read | List Autopilot automations in a workspace with goals, cadence, and status. |
create_automation | automations:write | Create an Autopilot automation: a goal, a cron cadence, a template (pacing_keeper | cpa_guard | reach_maximizer), and a permission policy (action grants, guardrails, execution modes). Refused for tokens bound to an agent policy. |
update_automation | automations:write | Change an automation's name, goal, cadence, template, params, or permission policy. Only the fields you send change. Refused for tokens bound to an agent policy. |
set_automation_status | automations:write | Pause (kill switch) or resume an automation. Tokens bound to an agent policy can pause but not resume. |
list_decisions | automations:read | List agent/automation decisions (the explainable audit log), optionally filtered to proposed items awaiting approval. |
approve_decision | automations:write | Approve and apply a proposed decision from the approvals inbox. Refused for tokens bound to an agent policy: point the user at the approvals inbox instead. |
reject_decision | automations:write | Reject a proposed decision from the approvals inbox; nothing is applied. |
undo_decision | automations:write | One-click undo of an applied decision (restores the previous values). |
list_members | members:read | List people with access to this account (staff and client logins) with role and workspace. |
invite_member | members:write | Invite a person by email with a role. Client roles (client_viewer, client_approver, client_collaborator) need a workspaceId. They sign in with an emailed code. |
plan_media | campaigns:read | Price a media plan: give tiers (name, totalBudgetUsdMinor in cents, strategy, channel splits with percent and rationale). Budgets, CPMs from the rate card, and impression forecasts are computed for you. Add `save` with workspaceId and name to store it. |
get_book_overview | reports:read | The whole book: each client workspace's health score and band, 14-day spend vs the prior 14 days, active campaigns, pending change requests, and channel CPM/CTR benchmarks. |
generate_display_set | creatives:write | Studio: write ad copy from a brief with AI and render html5 display creatives for the brand across IAB sizes, or one Waveform engagement unit. Returns the new creative ids. |
waveband_api | per operation | MCP only. Calls any REST operation: { method, path, query?, body?, idempotencyKey? } with path starting /api/v1/. The operation's scopes apply, and idempotencyKey is sent as the Idempotency-Key header so a retried POST never runs twice. |