A categorized index of the runnable examples in this directory. Each example is a single-file (or single-directory) demo with a module docstring explaining what it shows and how to run it.
Two sides of the protocol are covered:
- Buyer — calling AdCP agents. Entry point:
from adcp import ADCPClient, AgentConfig.client.simple.*is the recommended starter API. - Seller — building an AdCP agent. Entry point:
from adcp.server import ADCPHandler, serve, or theDecisioningPlatformframework inadcp.decisioning.
For task-level guidance beyond these scripts, see the skills/
directory at the repo root (buyer skills like call-adcp-agent and
adcp-media-buy; seller skills like build-seller-agent).
Install the package, then run any script by path:
pip install -e .
python examples/basic_usage.pySome examples need a local mock-server or environment variables — see the "Run" section in each file's module docstring for prerequisites.
Calling AdCP agents as a buyer.
basic_usage.py— configure anADCPClient, callget_products, handle sync vs async responses.simple_api_demo.py— the.simpleaccessor: pass kwargs directly, get unwrapped data, exceptions on error.multi_agent.py— configure multiple agents and run operations across all of them in parallel.test_helpers_demo.py— use the built-in test agents fromadcp.testing(test_agent,creative_agent) for quick demos.type_aliases_demo.py— the ergonomic semantic type aliases for clearer code.fetch_agent_authorizations.py— discover which publishers have authorized your agent, via the agent's capabilities ("push") and via publisheradagents.json("pull").adagents_validation.py— verify a sales agent is authorized to sell for a publisher's properties using theadagents.jsonvalidation utilities.
Related skills: call-adcp-agent (wire-level invariants for any buyer
call), adcp-media-buy, adcp-creative, adcp-signals,
adcp-governance, adcp-brand, adcp-si.
Minimal-to-reference seller implementations. The hello_seller_*
files are each the smallest possible adopter for one AdCP specialism.
minimal_sales_agent.py— single-file MCP sales agent ("Riverdale Gazette") covering theget_adcp_capabilities→get_products→create_media_buyflow.hello_seller.py— the canonicalDecisioningPlatformstarting point: the full requiredsales-non-guaranteedmethod surface, plus minimum valid buyer payloads.hello_seller_async_handoff.py— the threecreate_media_buyreturn shapes: sync success, correctableAdcpError, andTaskHandofffor HITL/background work.hello_seller_audience.py— minimalaudience-syncseller (sync_audienceswith delta upsert).hello_seller_brand_rights.py— minimalbrand-rightsseller (get_brand_identity,get_rights,acquire_rightswith a 4-arm success union).hello_seller_catalog.py— minimalsales-catalog-drivenseller (addssync_catalogs).hello_seller_collection_lists.py— minimalcollection-listsseller (5-method CRUD + fetch-token issuance).hello_seller_content_standards.py— minimalcontent-standardsseller (CRUD + calibration + validation).hello_seller_creative.py— minimalcreative-generative/creative-templateseller; template for AI-creative integrators returning aCreativeManifest.hello_seller_governance.py— minimalgovernance-spend-authority/governance-delivery-monitorseller (note: requiresgovernance_aware=True).hello_seller_property_lists.py— minimalproperty-listsseller (5-method CRUD + fetch-token issuance).hello_seller_signals.py— minimalsignal-marketplaceseller (get_signals,activate_signal); canonicalTaskHandoffexample.seller_agent.py— referenceADCPHandlerseller for themedia_buy_sellerstoryboard (9 steps, all core tools).typed_handler_demo.py— declare handlerparamsas a Pydantic model so the dispatcher validates at the boundary.scheduler_lifespan.py— lifecycle-bound background work viaserve(on_startup=, on_shutdown=).hello_mock_seller.py— mock-mode upstream URL routing: swap the upstream per request for spec-conformance storyboards without a real backend.hello_proposal_manager.py— per-tenantProposalManagerbinding viaPlatformRouter(two-platform composition).hello_proposal_manager_v15.py— the full v1.5 proposal lifecycle (get_products/refine_products/finalize_proposal) behind a minimal-LOC adopter.multi_platform_seller/— directory example: N tenants, NDecisioningPlatformsubclasses, oneserve()process, dispatched byPlatformRouter.sales_proposal_mode_seller/— directory example: the v1.5ProposalManagersurface end-to-end, passing theproposal_finalize.yamlstoryboard.v3_reference_seller/— directory example: canonical multi-tenant translator-pattern seller (AdCP wire in, real upstream ad server out); includesMIGRATION.md.
Related skills: build-seller-agent, build-generative-seller-agent,
build-retail-media-agent, build-creative-agent,
build-signals-agent. The seller storyboard tests live at
../tests/test_seller_agent_storyboard.py.
mcp_with_auth_middleware.py— multi-tenant MCP server with bearer-token auth viaBearerTokenAuthMiddleware+auth_context_factory.buyer_agent_registry_sqlalchemy.py— SQLAlchemy-backedBuyerAgentRegistryfor v3 sellers: the commercial-identity allowlist gate (signing-only and bearer-only factory shapes).
hello_seller_with_webhooks.py— wire anInMemoryWebhookDeliverySupervisorso completion webhooks reach buyers who registerpush_notification_config.url; usesWebhookSender.from_bearer_token.
See docs/handler-authoring.md#webhooks for the full WebhookSender
constructor comparison (bearer vs RFC 9421 JWK signing).
buyer_agent_registry_sqlalchemy.py— the commercial side of v3 identity (the cryptographic side lives inadcp.signing). The framework verifies signed traffic before this registry runs the commercial allowlist lookup.
Durable, scope-isolated A2A TaskStore + PushNotificationConfigStore
implementations. Both carry an important security model in their
docstrings (tenant-scoped lookups; webhook-URL SSRF and plaintext
secret risks the adopter must address before production).
a2a_db_tasks.py— raw-SQLite reference durable stores; SQLite chosen because the SQL pattern ports directly to Postgres / MySQL.a2a_sqlalchemy_tasks.py— SQLAlchemy-ORM companion: wrap an existing schema behind the a2a-sdk Protocols; runs on any SQLAlchemy backend.
Fetch creative-format preview URLs from a creative agent and render
them with the <rendered-creative> web component.
fetch_preview_urls.py— connect to the reference creative agent, list formats, generate preview URLs, and save them topreview_urls.json.generate_mock_previews.py— generate mock preview data (for when the reference creative agent returns text rather than structured format data).web_component_demo.html— HTML page that renders the saved previews with the<rendered-creative>web component.preview_urls.json— generated preview-URL data consumed by the HTML demo.
# 1. Fetch preview URLs from the creative agent (writes preview_urls.json)
python examples/fetch_preview_urls.py
# 2. Serve the repo over HTTP (the web component needs http://, not file://)
python -m http.server 8000
# 3. Open the demo
# http://localhost:8000/examples/web_component_demo.htmlThe Python side uses the fetch_previews=True parameter on
list_creative_formats (and get_products) to attach preview data to
the response metadata:
from adcp import ADCPClient
from adcp.types import AgentConfig, ListCreativeFormatsRequest, Protocol
creative_agent = ADCPClient(
AgentConfig(
id="creative_agent",
agent_uri="https://creative.adcontextprotocol.org",
protocol=Protocol.MCP,
)
)
result = await creative_agent.list_creative_formats(
ListCreativeFormatsRequest(),
fetch_previews=True,
)
formats_with_previews = result.metadata["formats_with_previews"]If the previews file is missing, run python examples/fetch_preview_urls.py
first. If the web component doesn't load, confirm you are serving over
http:// (not file://) and have internet access — the component
loads from https://creative.adcontextprotocol.org.
Related skill: adcp-creative.
For broader documentation see the AdCP docs and the integration tests.