Plainrouter Sandbox
Test Meta advertising account, signal-health, and performance tools with synthetic data through a public MCP endpoint; no credentials required.
Hosted MCP Server
npx add-mcp 'https://plainrouter.com/mcp/sandbox'Installs into Claude Code, Codex, Cursor and more
Documentation
Meta Ads MCP: connect your agent with Plainrouter
Connect Claude Code to Plainrouter's Meta Ads MCP server, read signal health, and submit creative proposals for approval in one Meta ad account.
Connect Claude Code to Plainrouter MCP, verify a synthetic response, then configure a workspace execution token for your own Meta ad account. A successful production setup returns the workspace and account you selected when issuing the token.
For supported tasks, client requirements, and approval boundaries, start with the MCP introduction.
Check the client connection without a Plainrouter account or token. Configure your workspace token and confirm the first account read.Choose your MCP endpoint
| Endpoint | Use | Credential |
|---|---|---|
https://plainrouter.com/mcp/sandbox | Prove a client against four synthetic tools. | None |
https://plainrouter.com/mcp | Read one approved account and submit governed proposals. | Workspace execution token for tool calls and account data |
Plainrouter MCP uses workspace execution tokens issued by a current owner or member. New workspace keys authorize one workspace and a Read or Write tier. Account-scoped tools select an eligible account inside that workspace; older account-bound keys keep their original restriction.
If you are choosing between a Signals workspace secret, workspace execution token, or OAuth management credential, see Authentication and clients.
Warning
OAuth management credentials cannot authenticate to the MCP server. They may read only
GET /api/v1/agent/contextfor account discovery. Use a workspace token for every MCP tool call.
Before you begin
For the sandbox, you only need a client with remote HTTP MCP support. For production, you also need:
- A Plainrouter account with access to the intended workspace.
- An active Meta ad account connection.
- An MCP-compatible client that can send a fixed bearer token to a remote HTTP server.
- Current team membership with permission for the key tier you need. Check key permissions.
- A clear choice of the one advertising account the client should use.
For creative-library reads, the Meta connection needs ads_read or ads_management. Governed creative execution needs ads_management.
Start in test mode
In a terminal with Claude Code installed, add the test server:
claude mcp add --transport http plainrouter-test https://plainrouter.com/mcp/sandbox
Open Claude Code in the same directory and run /mcp to check the connection. No Plainrouter account or credential is required. Other MCP clients can use the same URL with HTTP transport.
The endpoint exposes:
get_account_stateget_signal_healthget_performancevalidate_sandbox_event
Every response is synthetic and carries "sandbox": true. Test mode reads no
tenant data, persists nothing, and contacts no advertising provider. It exposes
no proposal, write, approval, Launcher, or spend-affecting tool.
Ask the agent:
Use plainrouter-test to call get_account_state, then get_signal_health.
Summarize the synthetic account and signal health. Do not call other tools.
A successful account response includes the following fields. This is an excerpt from the synthetic response, not a real advertising account:
{
"sandbox": true,
"workspace": { "id": 0, "name": "Sandbox Workspace" },
"ad_account": {
"id": 0,
"external_id": "act_SANDBOX",
"name": "Sandbox Ad Account"
}
}
Both calls should return without a tool error. This proves the test connection works; it does not verify your production account or event collection.
When the client can discover or initialize the server, list tools, and call a sandbox tool, change its
server URL to https://plainrouter.com/mcp and configure a workspace execution
token. The three read-tool names and their argument shapes match production.
Note
The production endpoint exposes its protocol handshake, tool and resource catalogs, and static
ui://app shells without a credential. Tool calls and account-data reads remain account-bound and return HTTP401without a valid workspace execution token.
Which MCP protocol should my client use?
Plainrouter supports 2026-07-28 through server/discover. Existing clients using initialize can negotiate 2025-11-25 or 2025-06-18. Let your MCP client handle the protocol; the Claude Code configuration below does not need manual protocol fields.
For a custom HTTP client, start with this credential-free sandbox discovery request:
curl https://plainrouter.com/mcp/sandbox \
--header 'Content-Type: application/json' \
--header 'Accept: application/json, text/event-stream' \
--header 'MCP-Protocol-Version: 2026-07-28' \
--header 'Mcp-Method: server/discover' \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "server/discover",
"params": {
"_meta": {
"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {}
}
}
}'
Check that result.supportedVersions includes 2026-07-28 and result._meta["io.modelcontextprotocol/serverInfo"].name is Plainrouter Sandbox. Discovery confirms protocol compatibility; it does not read your account or verify a tool call.
For subsequent 2026-07-28 requests:
| Field or header | Requirement |
|---|---|
params._meta | Include both protocol version and client capabilities on each request. |
MCP-Protocol-Version | Match the protocol version in _meta. |
Mcp-Method | Match the JSON-RPC method, such as tools/list or tools/call. |
Mcp-Name | For tools/call, match params.name. For resources/read, match params.uri. |
Authorization | Include the workspace bearer token on every production tool call or account-data read. |
Requests are stateless: do not wait for or require an Mcp-Session-Id response header. Legacy clients without protocol metadata in _meta remain on the compatibility path; do not mix the two request formats. Sending either protocol metadata key selects the modern validation path.
The published server card lists the current protocol, tools, and resources. The transport upgrade reference explains modern headers and legacy compatibility.
Connect with a workspace token
In Plainrouter, switch to the intended workspace and open **Settings → Workspace keys**. Enter a name, choose Read or Write and an expiry, then select **Create key**. Copy the complete token immediately after issuance. Plainrouter cannot display it again. In your MCP client, add `https://plainrouter.com/mcp` as a remote HTTP server and configure the token as its bearer credential. Call `get_account_state` first. Supply `account_id` when multiple eligible accounts exist. Confirm the returned workspace and account before continuing.See Workspace tokens for tier selection, account selection, replacement, and revocation.
Configure Claude Code for your Meta ad account
Add this server entry to your project's .mcp.json, preserving any existing servers. Claude Code expands environment variables in MCP headers.
{
"mcpServers": {
"plainrouter": {
"type": "http",
"url": "https://plainrouter.com/mcp",
"headers": {
"Authorization": "Bearer ${PLAINROUTER_WORKSPACE_TOKEN}"
}
}
}
}
Supply PLAINROUTER_WORKSPACE_TOKEN in the terminal environment through your local secret manager before starting Claude Code. Keep the variable reference in the file; do not replace it with the token or paste the token into an agent prompt. Open /mcp and allow the project connection when prompted.
Start with a Read token for account and library inspection. Use Write only when you need proposal-producing tools.
Confirm a read-only production connection
Ask the agent:
Use plainrouter to call get_account_state. Show the workspace name and
Meta ad account name and external ID, then stop. If account_id is required,
ask me to select the intended Plainrouter account ID. Do not propose changes.
Check that the returned workspace and Meta ad account match the intended task. For a workspace with multiple active accounts, pass the same selected account_id to each account-scoped call; use Plainrouter's internal account ID, not the Meta external ID. If they do, ask for get_signal_health to inspect conversion delivery and matching diagnostics. Missing Signals setup or measurement history is a separate setup issue; a successful account read does not establish healthy tracking.
For the returned fields and their meaning, see the MCP tool reference.
Permissions
| Permission | Allows |
|---|---|
ad-account.read | Read the approved account and its Plainrouter Signals context. |
signals.verify | Write an identity-free, consent-safe Signal ingestion diagnostic. It does not complete onboarding. |
actions.propose | Submit actions through workspace policy and the approval pipeline. |
creative.read | Read the approved Meta account's creative library. |
creative.write | Stage creative assets and propose creative changes. It does not bypass actions.propose. |
The agent can select only accounts authorized by the workspace key; an account ID cannot widen that scope. Creative tools recheck that provider objects belong to the approved account.
Warning
Creative write permission is not direct mutation authority.
upload-assetandduplicate-ad-with-creativereturn a governed proposal. A later policy decision or human approval determines whether execution is queued.
Recommended workflows
Once the account read succeeds, choose a task:
- Diagnose Signals with a stored read. Use ingestion verification only when you explicitly want a diagnostic write; it does not verify a real arrival.
- Inspect stored reconciliation and its evidence limits.
- Create a paused creative variant: read the account library, select the source ad and asset, submit a proposal, and review the approval link.
Ask the agent to distinguish suggest-only, pending approval, blocked, awaiting verification, and Landed. The Actions overview lists supported changes.
Example: request a creative proposal
After you select a source ad and an asset from the approved account's creative library, ask:
Use the source ad and asset I selected to propose a paused ad copy.
Summarize the proposed change and show its approval link. Stop for my review.
The creative tool submits a proposal to Plainrouter; it does not change Meta during that MCP call. In Suggest only, approval records agreement without execution. In an executable mode, supported creative work still requires policy checks and human approval. A new ad copy remains PAUSED.
Follow the creative workflow and proposal review guide for the next steps. Use the Actions overview to check supported changes before requesting a different operation.
Authorization lifetime and revocation
Workspace tokens expire after 30, 90, or 365 days. From Settings → Workspace keys, the issuing member can create a replacement within their current role and Delete the old key to revoke it. The current UI has no token Rotate button.
Plainrouter also caps a token by the issuing person's current workspace role on every request. If that person's role no longer covers the token tier, the token stops authenticating at that tier. Issue a new token instead of trying to reuse a credential whose authority changed.
Troubleshoot
A custom client gets HTTP 400 or a protocol error
For JSON-RPC error -32020, compare MCP-Protocol-Version, Mcp-Method, and, where required, Mcp-Name with the request body. A missing required header or mismatched value fails before the tool runs. Ensure your reverse proxy preserves these headers.
For -32022, check the protocol version against discovery and use a supported version. Follow the complete modern request format; changing only the version header is not enough. An authentication 401 is a separate credential failure.
The client waits for a session ID
Plainrouter processes requests independently and does not return Mcp-Session-Id. Update a client or custom transport that requires that header. Keep sending the workspace bearer credential on each production tool request; a successful discovery response does not authorize later calls.
Claude Code cannot load the token variable
Confirm PLAINROUTER_WORKSPACE_TOKEN is set in the environment that starts Claude Code. Restart the client after supplying it. Keep the variable name consistent with .mcp.json; do not print the token to debug the connection.
The client receives 401 Unauthorized
Confirm the client sends the complete workspace token as a bearer credential and that it has not expired or been revoked. Also confirm its issuing person still holds a workspace role that covers the token tier.
If the client is sending an OAuth access token, the rejection is expected. Replace it with a workspace execution token.
A creative tool reports a missing permission
Issue a token with the required tier. Use Read for library access and Write for proposal-producing creative tools and Launcher draft batches where enabled.
Plainrouter asks you to reconnect Meta
The selected account may lack an active Meta connection or the required ads_read or ads_management access. Reconnect Meta, confirm the same ad account, and retry the same idempotent request.
The wrong account appears
Check account_id and the key's workspace. New workspace keys can select an active account owned by that workspace; an older account-bound key rejects a different account. Follow account selection.
Signals tools show setup required
The account may be authorized correctly while its workspace has no active Signal or destination. Complete Signals setup and call the tools again.