Skip to main content
Use Plainrouter MCP to propose a copy of a human-selected Meta ad with a different creative asset. The request creates a governed proposal. Ask waits for human approval; Full can automatically queue a policy-allowed copy; Landed requires verification of the resulting Meta ad. This walkthrough uses an image already in the connected account’s library. It covers Plainrouter’s governed workflow. For provider selection, see the Meta Ads MCP comparison.

Before you begin

You need a connected agent, a Write workspace key for the intended workspace, and the required creative and proposal permissions. Read get_account_state to confirm scope. A person must select the source ad; obtain the selected asset ID from the account’s creative library. Check the workspace’s action policy. Use Ask for this walkthrough so you can review the proposal before execution. In Full, an allowed proposal can queue automatically; asking the agent to stop after submission does not prevent that execution. These creative tools cannot activate the copy. Canonical pause, resume, and daily-budget changes use separate governed proposals.

Creative tool flow

The anonymous MCP sandbox has no creative tools. Use the authenticated production connection for this workflow. Reading the library contacts Meta; submitting the proposal writes to Plainrouter and performs account-bound provider reads. It does not itself create the copied Meta ad.

Example: propose a paused creative variant

The request examples below contain arguments for the named MCP tools, not Signals REST API requests. Your MCP client wraps them in tools/call. Example IDs and response excerpts are illustrative; substitute your selected account’s actual values.

1. Confirm the account and read its images

Call get_account_state to inspect the workspace’s Signals-bound Meta account. Confirm it is also eligible for Actions in this workspace. For the creative calls below, supply account_id when multiple eligible active accounts exist; use that same intended account throughout. Confirm the returned workspace and Meta ad account, then check authorization.permissions for creative.read, creative.write, and actions.propose. Stop if the account or permissions do not match the intended task; issue the appropriate workspace token before proceeding. For this example, 91 is the internal Plainrouter account ID verified in the first read, not the Meta external account ID. Keep the same account_id across the workflow. Call get-creative-library with:
An illustrative response excerpt is:
Select an asset_id from the returned assets. The human-selected source ad is a separate numeric Meta ad ID; an image hash, ad-set ID, or preview URL is not a source ad ID. If pagination.images.has_more is true, repeat the image request with the returned pagination.images.after value as cursor. Preserve the cursor unchanged. An empty page does not prove the account has no assets of another type. If you need to add an image, complete image upload and its verification before returning here.

2. Submit one proposal for the selected pair

Call duplicate-ad-with-creative with the source ad selected by the person and the chosen asset. This example uses the illustrative image above:
Persist the idempotency key with this intent and reuse it for an identical retry. Use a distinct key for a new proposal, such as a different selected image. Do not recycle a key while changing its arguments. There is no status argument: Plainrouter fixes params.status to paused. It re-reads the selected source and asset under the approved account before producing the proposal. Do not ask the agent to choose a different account, guess a target, or activate the copy when validation fails.

3. Read the proposal before requesting approval in Ask

A passing proposal in Ask can return this excerpt. Other fields, including scope, evidence, and the queue URL, are omitted here:
This result means the example proposal awaits a person. It does not identify a newly created Meta ad: actions[].target_entity.id still identifies the source ad. Check these fields in the complete response: If the client reports a protocol error or a tool result with isError: true, do not interpret transport success as proposal creation. Read the error and inspect the queue before retrying an uncertain result. The MCP error model distinguishes protocol failures from tool execution failures.

4. Follow the human decision and final outcome

For the Ask example, open the returned inbox_url for Inbox. The older approval_queue_url field remains an alias to the same link. Review the proposal and its execution_mode_snapshot before using the generic Approve button. The decision applies to the containing batch, not just the selected action. For the Ask example above, Approve queues execution after fresh policy checks; it does not complete the walkthrough. Follow the receipt until the copy is verified. A historical suggest-only approval appears separately under Approval recorded, nothing sent and never creates a copy. Changing current policy does not rewrite that historical snapshot. For executed copies, verify both status=PAUSED and effective_status=PAUSED on the exact receipt-addressed ad. A verified paused copy is not an active campaign, a delivery result, or evidence of improved advertising performance. See Paused-copy invariant for pending verification and compensation.

Give your agent a bounded request

After selecting the actual source ad and asset, use a request like this:

Creative library output

get-creative-library returns account-owned images and videos, asset metadata, pagination, associated ads, and aggregated last-30-day impressions, clicks, spend, and conversions.
Do not treat creative-library history as causal performance or proof that an asset is a winner. Durable proposal provenance records only identity, account ownership, readiness, and status.
When requesting asset_type: "all", pagination is returned separately for images and videos. To continue from a cursor, request either image or video.

Image upload rules

Before staging an image, check its JPEG/PNG dimensions and crop for the intended placements. Meta image specifications explains placement review. Meeting a documented specification does not prove Meta acceptance; verify the upload through its execution receipt. If the image is not already in Meta, upload-asset privately stages its bytes and creates a separate upload_asset proposal. It does not immediately produce an uploaded Meta image. Ask requires approval; Full can queue a policy-allowed upload automatically. Wait for verified provider completion, then call get-creative-library again to select the returned image:<hash>. Do not use the staged manifest ID as the asset ID for duplication. The upload-asset convenience tool accepts:
  • account_id when needed to select the same authorized account
  • asset_type: "image"
  • A bare .jpg, .jpeg, or .png filename, up to 100 characters, that matches the detected content type; no directory path
  • Raw base64 bytes without a data URI prefix
  • A rationale of up to 1,000 characters
  • A stable idempotency key of up to 64 characters
The configured upload limit is 5 MiB unless the deployment overrides it. Reusing the same idempotency key with different bytes is rejected. Video assets can be read from the Meta creative library and used for ad duplication. New video upload execution is not supported in this release.

Paused-copy invariant

A duplicate must be created and verified with both configured and effective status equal to PAUSED. Creating a copy never activates it. A later governed resume action is a separate proposal that uses Ask or Full and its own policy checks. If Meta reports IN_PROCESS, the batch moves to Executed pending verification and remains Not Landed. Plainrouter performs scheduled reads for up to 48 hours. Contradictory state, rejection, or expiry triggers verified compensation, which archives the receipt-addressed copy.

Safe retries

Both proposal-producing creative tools are idempotent. Reuse the same idempotency key when retrying the same intent. Do not generate a new key merely because an MCP request timed out. After a timeout, check the returned or existing proposal in Inbox before attempting another action. Provider reconciliation uses the durable execution key and receipt to avoid silently creating duplicate objects.

Common failures