0.3.0 exposes exactly 12 tools. All use the advertising account selected during workspace-token issuance.
Shared authorization and scope
Signals read tools require an active principal withad-account.read. verify_signal_ingestion requires signals.verify. propose-actions requires actions.propose. Creative-library reads require creative.read. Creative proposal tools require both creative.write and actions.propose. Every Launcher tool requires the ad-account.read baseline.
Clients authenticate with an owner-issued workspace execution token. A Read token derives the read scopes. Write and Admin tokens also derive the proposal scopes. OAuth management credentials cannot authenticate to the MCP server.
launcher.batch_status accepts a Read, Write, or Admin token. launcher.draft_batch, launcher.preview_batch, launcher.execute_batch, and the file-import adapter require the Write or Admin tier. Drafting also requires creative.write and actions.propose; preview and the closed execution entry require actions.propose.
Scoped responses identify:
destination_id and dataset_id are null until the authorized account has a matching destination. The caller cannot provide a different account ID.
get_account_state
Call this first in every account-specific workflow. It returns:
- Agent ID, name, and granted permissions.
- Shared scope.
- Advertising account ID, platform-native ID, name, platform, currency, timezone, and status.
- Workspace ID and name.
- Platform connection status and expiry.
- Signal ID, status, collection domain, and connected destination.
- Available capability flags.
- Response generation time.
verified_performance becomes true only when the matching destination is active. It describes stored reconciliation availability, not live target performance. The marketing_api_reads and writes flags describe this Signals-oriented account-state call; use the separately permissioned creative tools for live creative-library reads and governed creative proposals.
get_signal_health
This tool accepts no input. It returns the shared scope plus:
- Overall status, label, and summary.
- Signal, hostname, Meta connection, and dataset state.
- Event counts for 24 hours, seven days, and all time.
- Last event time.
- Accepted, failed, pending, and total non-test deliveries from the last 24 hours.
- Delivery acceptance rate.
- Latest Event Match Quality score, week-over-week change, alert state, measurement time, and recent history.
- A seven-day stored performance comparison by default.
- Structured diagnostics.
- Data-source names and response generation time.
event_ledger, delivery_ledger, emq_snapshots, and reconciliation_reports. It reports marketing_api_called: false.
get_performance
Use this tool for a stored reconciliation window.
PlainRouter excludes modeled and portfolio-only events from this proposal-evidence path. Only eligible observed reconciliation data contributes to its performance fields.
Input
Output
The response includes:- Shared scope.
- Requested period with
days,since, anduntil. - Measurability state.
- Gateway-verified accepted count.
- Meta-reported count.
- Observed gap.
- Alignment percentage.
- Number of alert days.
- Latest report date.
- Totals grouped by event.
- Daily report rows.
data_source: "stored_reconciliation_reports".marketing_api_called: false.- Response generation time.
Measurability
no_history and stale_history. When quantitative_citations_allowed is false, an agent must not cite count, gap, alignment, alert-day, daily, or by-event values as proposal evidence.
verify_signal_ingestion
Use this tool when an active Signal is waiting for its authoritative server-side onboarding check. It accepts no input and resolves the Signal from the authorized workspace.
The tool writes one idempotent signal_verification event and returns:
duplicate: true. The tool has no spend capability.
The call fails if the connection lacks signals.verify or the authorized workspace has no active Signal.
launcher.draft_batch
This tool creates a Launcher draft batch from Drive assets already synced into the token’s workspace. It writes only the PlainRouter draft model; it does not write to Meta, evaluate the final execution gate, or activate spend.
It requires an owner-issued workspace token with the Write or Admin tier.
Input
Overrides use contract version
v: 1 and can contain up to five primary_texts, headlines, and descriptions, plus website_url and display_link.
Workspace and account IDs are never accepted as input. PlainRouter derives them from the execution token. A Drive link that is unknown, stale, failed, removed, or belongs to another workspace is rejected without widening the token scope.
Output
The response includes the draft batch ID and status, frozen tier and capacity limits, item and media counts, accepted items, bounded rejected-item reason codes, import provenance when present, and an advisory gate result. Possible rejection codes are:drive_asset_unresolvedoverrides_invalidoverrides_limit_exceededbatch_limit_exceededmedia_limit_exceeded
not_evaluated. Treat the result as a draft, not authorization to execute.
Launcher batch status and preview
These tools accept onebatch_id: the 26-character ULID returned by launcher.draft_batch or the file-import adapter. PlainRouter resolves it only inside the workspace and ad account bound to the token. A caller cannot inspect another account by guessing an ID.
launcher.batch_status
Use this read-only tool to inspect a batch without evaluating its gate or contacting a provider. It returns:
- Batch status, mode, and item counts.
- Sub-batch status.
- The latest stored gate result.
- Ordered item status, bounded failure stage and code, and linked Actions proposal IDs.
- Partition status and latest proposal attempts for duplicate-ad-set modes.
ad-account.read scope.
launcher.preview_batch
Use this non-destructive checkpoint before presenting a batch as ready. PlainRouter re-evaluates the authoritative gate and returns status: "previewed" or status: "gated", the resulting batch status, and checks for source relationships, tracking verification, tracked-domain coverage, ledger health, and Actions readiness.
The previews array is intentionally empty in this release. No provider preview, Meta write, Actions proposal, or spend activation happens during the call. A successful preview is not execution authorization; any future execution path must evaluate the gate again.
This tool requires a Write or Admin token with actions.propose.
launcher.execute_batch
The execution entry is registered so clients can discover the complete Phase B-1 contract, but it is deliberately closed. After validating the token and token-bound batch, every call returns not_executable_in_phase_b1.
It does not evaluate the gate, advance the batch, create an Actions proposal or receipt, contact Meta, or mutate provider state.
Refusals
All three tools can returninvalid_token, insufficient_scope, invalid_arguments, batch_not_found, or internal_error. Preview can also return batch_not_operable or gate_receipt_raced. Execute returns not_executable_in_phase_b1 after successful authorization and batch resolution.
propose-actions
This tool validates the action shapes, captures fresh evidence provenance, evaluates policy, and creates one batch.
Top-level input
Each evidence declaration contains:
source_tool values are get_account_state, get_signal_health, and get_performance. Creative actions can also use the action-bound sources get-creative-library and staged-asset-manifest.
Every field path must exist in a fresh server-side capture. Aggregate sources cannot include action_index. An action-bound source requires action_index and can cite only its matching creative action.
Action object
Every action has this common shape:ad_account, campaign, ad_set, and ad.
Action parameters
adjust_budget
adjust_budget
Requires
new_daily_budget_minor, a positive integer in the account currency’s minor unit. For example, 4900 means 49.00 for a two-decimal currency.set_status
set_status
Requires
status equal to active or paused.duplicate_ad_with_creative
duplicate_ad_with_creative
Requires
asset_id and status: "paused". An optional name_suffix can identify the duplicate.upload_asset
upload_asset
Requires
staged_asset_id, asset_type (image or video), filename, and a lowercase 64-character content_sha256. Optional fields include detected mime_type and positive size_bytes.Evidence restrictions
PlainRouter rejects evidence paths that claim campaign, ad set, ad, target, CPA, spend, budget, or learning-phase state from aggregate Signals reads.get_signal_health is diagnostic and cannot support a batch containing adjust_budget, set_status, or duplicate_ad_with_creative. This rule applies to the entire batch: adding an upload_asset action does not make a mixed spend-affecting proposal eligible. An upload-only upload_asset batch is the current non-spend exception and may retain signal-health context.
Use get_performance when a spend-affecting proposal needs stored reconciliation-derived performance evidence.
It also rejects:
- Unknown source tools.
- Field paths absent from the cited response.
- Quantitative performance fields from non-measurable history.
- A target source other than
human_supplied. - Proposals from a connection without
actions.propose.
Response
The response includes the batch ID, scope, evidence provenance, status, policy decision and reasons, approval requirement, queue URL, proposer, rationale, and normalized action records. Evidence provenance records the source service, scope level, exact fields, observation time, reporting window, measurability, and the target-selection boundary.get-creative-library
This tool makes live Meta Marketing API reads for the approved account. It requires creative.read and an active Meta connection with ads_read or ads_management.
Input
Output
The response includes:- Images as
image:<hash>and videos asvideo:<id>. - Names, status, dimensions or duration, previews, and creation time when available.
- Ads historically associated with each asset.
- Aggregated last-30-day impressions, clicks, spend, and conversions.
- Separate image and video pagination cursors.
performance_window: "last_30d".
upload-asset
This tool validates and privately stages an image, then creates one canonical upload_asset proposal. It requires creative.write and actions.propose.
The response wraps the canonical proposal with its ID, scope, evidence provenance, immutable execution-mode snapshot, status, policy result, approval requirement, approval-queue URL, and action record.
PlainRouter freezes the staged bytes and records only the approved manifest fields: staged ID, SHA-256 digest, detected MIME type, byte size, account binding, and frozen/immutable state. Raw bytes do not enter the action or audit record.
Only JPEG and PNG upload execution is supported. Video upload execution remains blocked.
duplicate-ad-with-creative
This tool creates one canonical duplicate_ad_with_creative proposal. It requires creative.write and actions.propose.
PlainRouter re-reads the source ad and selected asset under the approved account before creating the proposal. The normalized action always contains
status: "paused".
If approved in an executable mode, the worker rechecks policy, creates the copy as PAUSED, persists the provider ad ID in a durable receipt, and verifies the exact receipt-addressed object. IN_PROCESS can enter scheduled verification for up to 48 hours. The batch is not Landed until every receipt is exactly verified.