This tutorial walks through using the mock adapter to test the full campaign lifecycle without connecting to a real ad server. The mock adapter simulates all ad server operations including delivery, creative processing, and approval workflows.
A running Sales Agent instance with Docker. See the Quick Start guide if you have not deployed yet.
docker-compose exec adcp-server python -m scripts.setup.setup_tenant "Test Publisher" --adapter mock
This creates a tenant configured to use the mock adapter instead of a real ad server.
Retrieve the principal token for API access:
docker-compose exec postgres psql -U adcp_user -d adcp \
-c "SELECT access_token FROM principals LIMIT 1;"
Save this token for use in subsequent commands.
uvx adcp http://localhost:8000/mcp/ --auth YOUR_TOKEN get_products '{"brief":"all products"}'
The mock adapter returns a set of pre-configured products spanning display, video, audio, and native channels. Note the product_id values for the next step.
uvx adcp http://localhost:8000/mcp/ --auth YOUR_TOKEN create_media_buy '{
"campaign_name": "Test Campaign",
"media_buy_start_date": "2026-03-01",
"media_buy_end_date": "2026-03-31",
"packages": [{
"product_id": "PRODUCT_ID_FROM_STEP_3",
"budget": 5000,
"currency": "USD"
}]
}'
The mock adapter processes this immediately (or routes through approval, depending on HITL configuration). Note the media_buy_id from the response.
uvx adcp http://localhost:8000/mcp/ --auth YOUR_TOKEN sync_creatives '{
"creatives": [{
"name": "Test Banner",
"format_id": "FORMAT_ID",
"asset_url": "https://example.com/banner.jpg",
"click_through_url": "https://example.com/landing"
}],
"assignments": {
"PACKAGE_ID": ["CREATIVE_ID"]
}
}'
uvx adcp http://localhost:8000/mcp/ --auth YOUR_TOKEN get_media_buy_delivery '{
"media_buy_id": "YOUR_MEDIA_BUY_ID"
}'
The mock adapter returns simulated delivery metrics based on the product’s simulation parameters (daily impressions, fill rate, CTR, viewability).
The mock adapter supports four simulation scenarios that control delivery behavior. Configure these through the product’s simulation parameters in the Admin UI.
| Scenario | Behavior |
|---|---|
normal |
Standard delivery at configured rates |
high_demand |
Competitive inventory, higher CPMs, slower fill |
degraded |
Partial delivery failures, reduced fill rate |
outage |
Complete ad server failure, all operations return errors |
| Parameter | Default | Description |
|---|---|---|
daily_impressions |
10,000 | Simulated daily impression volume |
fill_rate |
85% | Percentage of available inventory filled |
ctr |
2% | Simulated click-through rate |
viewability |
65% | Simulated viewability rate |
scenario |
normal |
Active simulation scenario |
The mock adapter can simulate human-in-the-loop (HITL) approval flows where media buys or creatives require manual approval before activation.
In sync mode, the mock adapter delays responses to simulate human review time:
create_media_buypending_approvallist_tasks to see the pending approval taskcomplete_task to approve or reject# List pending tasks
tasks = await client.call_tool("list_tasks", {"status": "requires_approval"})
# Approve the task
await client.call_tool("complete_task", {
"task_id": tasks["tasks"][0]["task_id"],
"status": "completed"
})
In async mode, tasks enter a pending state and can be completed via webhook or manual intervention:
get_task or wait for a webhook notificationMixed mode applies per-operation overrides. For example, media buys may require approval while creative uploads process automatically.
Configure HITL mode through the adapter’s platform_mappings.mock.hitl_config setting in the Admin UI.
from fastmcp import Client
from fastmcp.client.transports import StreamableHttpTransport
transport = StreamableHttpTransport(
"http://localhost:8000/mcp/",
headers={"x-adcp-auth": "YOUR_TOKEN"}
)
async with Client(transport) as client:
# Discover products
products = await client.call_tool("get_products", {"brief": "display banner"})
product_id = products["products"][0]["product_id"]
# Create media buy
result = await client.call_tool("create_media_buy", {
"campaign_name": "Mock Test",
"media_buy_start_date": "2026-03-01",
"media_buy_end_date": "2026-03-31",
"packages": [{
"product_id": product_id,
"budget": 5000,
"currency": "USD"
}]
})
media_buy_id = result["media_buy_id"]
# Check delivery
delivery = await client.call_tool("get_media_buy_delivery", {
"media_buy_id": media_buy_id
})
print(f"Impressions: {delivery['impressions']}")
print(f"Spend: ${delivery['spend']:.2f}")
The mock adapter supports time-accelerated delivery simulation with webhook notifications. This allows testing of pacing, budget depletion, and campaign completion without waiting for real calendar time.
For a detailed walkthrough of delivery simulation with working code, see examples/delivery_simulation_demo.py in the salesagent repository.