Skip to main content
Plainrouter MCP server version 0.3.2 exposes ten tools with the default configuration. Four additional legacy launcher.* tools are available only when Launcher is explicitly enabled. Use MCP discovery to check the tools available on your connection. Account-scoped tools use the advertising account selected during workspace-token issuance. Start with the MCP introduction for supported tasks and access boundaries. For client configuration and your first account read, follow Setup. The server version is separate from the MCP protocol revision. For custom clients, see the stateless discovery and request-header requirements. MCP App support is advertised under capabilities.extensions["io.modelcontextprotocol/ui"] in the server card. Conditional legacy tools
The four launcher.* entries above describe the conditional legacy contract. Launcher is disabled by default, so those tools are absent from discovery and the file-import route returns 404.
Proposal-producing tools do not write to Meta during the MCP request. In Suggest only, approval ends without execution. In an executable mode, supported creative work can run only after the policy and approval pipeline authorizes it.

Test mode and production boundaries

Use https://plainrouter.com/mcp/sandbox to prove an integration without an account or credential. It exposes four tools: Every result is marked with "sandbox": true. The endpoint reads no tenant data, writes nothing, and contacts no advertising provider. It does not expose production proposal, creative, approval, Launcher, or spend-affecting tools. The production endpoint is https://plainrouter.com/mcp. Its handshake, tool and resource catalogs, and static ui:// MCP App shells are publicly discoverable. Every tool call and account-data read requires an account-bound workspace execution token.

Busy-workspace errors

A concurrent operation can return workspace_lock_timeout through MCP. Affected JSON HTTP routes return HTTP 503 with Retry-After: 1; the browser shows The workspace is busy. Retry the operation shortly. Wait before retrying and retain the original idempotency key for the same operation.

Shared authorization and scope

Signals read tools require an active principal with ad-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. Every production call also checks an active, unexpired grant for the same workspace and the requested operation. Revoked grants cannot authorize a call. The revoke_grant tool applies its separate revocation-authority check described below. 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.
Current capability flags are intentionally explicit:
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

Use this diagnostic for collection, delivery, and stored account health. Both production and sandbox accept the same optional reporting window:
The result includes the shared scope, status, label, summary, Signal and destination state, and:
  • activity.completed_window: arrivals for the retained completed-day reporting window.
  • activity.today_so_far: the separate incomplete local-day arrival count.
  • activity.receiving and activity.last_event_at: collection activity and freshness.
  • delivery: non-test delivery counts and acceptance rate for the last 24 hours, independently of the requested arrival window.
  • match_quality: the latest stored Meta score, measurement time, and history when available.
  • performance: stored reconciliation for the requested window.
  • diagnostics, data_sources, and generated_at: explanations, provenance, and response freshness.
Arrival windows use completed days in the account timezone and are clipped to retention. Do not assume the fixed 24-hour delivery diagnostics cover that same period. Arrival totals remain complete when a strict-EU component is withheld: partial marks that component, not a reduced total. Missing platform history is not zero activity. See Signals measurements and troubleshooting. This call reads stored measurements. It does not trigger a live Meta Marketing API read.
Treat this tool as diagnostic. Plainrouter rejects it as evidence for any proposal that can affect spend or delivery, including a mixed batch containing one such action. Use get_performance for stored reconciliation-derived performance evidence.

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, and until.
  • 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.
The response also includes stored account-level platform_claimed_clicks, platform_impressions, platform_spend, per-day platform_daily read states, and claimed_clicks_last_read_at when available. These platform fields are descriptive context, not admissible spend or target-performance evidence for Actions proposals.

Measurability

Possible non-measurable reasons are 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 to run an identity-free write-path diagnostic against an active Signal. It accepts no input and resolves the Signal from the authorized workspace. The tool writes one idempotent signal_verification event and returns:
The event is identity-free, modeled, excluded from enforcement, and never dispatched to Meta. It does not count as real arrival evidence or complete onboarding. A repeated call returns the same event with 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.

revoke_grant

Revoke a workspace grant using its 26-character ULID in grant_id. Obtain the grant ID from the authorized token-management response; it is different from the token ID and plaintext credential.
The caller needs an active execution credential in the same workspace and either an active revoke_grant permission or authority as the human who delegated the target agent. Admin-tier grants include revocation permission. Knowing a grant ID does not grant access to another workspace. The tool returns grant_id, workspace_id, and revoked_at. It records the revocation in the audit chain and prevents credentials backed by that grant from authorizing subsequent operations. An authorized repeat returns the existing revocation without creating another one. It does not undo previously executed advertising actions. Invalid grant-ID input fails validation. Missing or inactive caller authorization, another workspace’s grant, or insufficient revocation authority is refused.

show_spend_cap_approval

This read-only, idempotent tool renders the static ui://resources/spend-cap-approval-app MCP App preview. It accepts no input and returns only a confirmation that the preview card loaded. The card contains fixed demonstration values and is labeled Preview — not a live control. Its Approve and Reject buttons are disabled. The tool does not read an account, submit an approval, call another tool, persist data, contact Meta, or change spend. Use it only to verify that an MCP host can render Plainrouter’s app presentation.

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:
Aggregate 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. The set_status example below describes a recommendation only: delivery-status and budget execution are disabled, even after approval. For the executable creative path, use Create governed Meta creatives.
Supported target types are ad_account, campaign, ad_set, and ad.

Action parameters

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.
Requires status equal to active or paused.
Requires asset_id and status: "paused". An optional name_suffix can identify the duplicate.
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 as video:<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".
The performance block is descriptive account history, not causal lift. When this tool supplies proposal provenance, Plainrouter persists only the selected asset’s identity, account ownership, readiness, and status.

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.

launcher.draft_batch

Available only when legacy Launcher is enabled. 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_unresolved
  • overrides_invalid
  • overrides_limit_exceeded
  • batch_limit_exceeded
  • media_limit_exceeded
The current MCP entry point returns an advisory gate with not_evaluated. Treat the result as a draft, not authorization to execute.

Launcher batch status and preview

These tools are available only when legacy Launcher is enabled. They accept one batch_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.
The tool requires only a Read-tier token and the shared 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

When legacy Launcher is enabled, the execution entry is discoverable but 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 return invalid_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.