Salesagent
A media sales agent that implements the AdCP Media Buy protocol
Installation
npx salesagentAsk AI about Salesagent
Powered by Claude Β· Grounded in docs
I know everything about Salesagent. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
Prebid Sales Agent
A reference implementation of the Ad Context Protocol (AdCP) sales agent, enabling AI agents to buy advertising inventory through a standardized MCP interface. This codebase is maintained under Prebid.org as the Prebid Sales Agent reference implementation.
What is this?
The Prebid Sales Agent is a server that:
- Exposes advertising inventory to AI agents via MCP (Model Context Protocol) and A2A (Agent-to-Agent)
- Integrates with ad servers like Google Ad Manager
- Provides an admin interface for managing inventory and campaigns
- Handles the full campaign lifecycle from discovery to reporting
Choose Your Path
| I want to... | Start here |
|---|---|
| Deploy my own sales agent (publisher) | Quickstart Guide |
| Evaluate or develop locally | Quick Start below |
| Run a multi-tenant platform | Deployment Guide |
Quick Start (Evaluation)
Try the sales agent locally:
# Clone and start
git clone https://github.com/prebid/salesagent.git
cd salesagent
docker compose up -d
# Test the MCP interface
uvx adcp http://localhost:8000/mcp/ --auth test-token list_tools
uvx adcp http://localhost:8000/mcp/ --auth test-token get_products '{"brief":"video"}'
Access services at http://localhost:8000:
- Admin UI:
/adminor just click "Log in to Dashboard" (test credentials:test123) - MCP Server:
/mcp/ - A2A Server:
/a2a
For production deployment, see the Quickstart Guide.
Publisher Deployment
Publishers deploy their own sales agent. Choose based on your needs:
| Platform | Time | Difficulty | Guide |
|---|---|---|---|
| Docker (local/on-prem) | 2 min | Easy | quickstart.md |
| Fly.io (cloud) | 10-15 min | Medium | fly.md |
| Google Cloud Run | 15-20 min | Medium | gcp.md |
Docker is the fastest - it bundles PostgreSQL and just works. Cloud platforms require separate database setup.
After Deployment
Configure via the Admin UI:
- Configure your ad server (Settings β Adapters)
- Set up products that match your GAM line items
- Add advertisers who will use the MCP API
- Set your custom domain (Settings β General)
Development Setup
git clone https://github.com/prebid/salesagent.git
cd salesagent
make setup # One command: installs deps, starts Docker, verifies health
See the Getting Started guide for prerequisites, manual setup steps, testing workflows, and common operations.
Google Ad Manager Setup
For GAM integration, choose your authentication method:
Service Account (Recommended for Production):
- No OAuth credentials needed
- Configure service account JSON in Admin UI
- See GAM Adapter Guide for setup
OAuth (Development/Testing):
- Create OAuth credentials at Google Cloud Console
- Add to .env:
GAM_OAUTH_CLIENT_ID=your-client-id.apps.googleusercontent.com GAM_OAUTH_CLIENT_SECRET=your-client-secret - Configure in Admin UI: Settings β Adapters β Google Ad Manager
Using with Claude Desktop
Add to your Claude config (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"adcp": {
"command": "uvx",
"args": ["mcp-remote", "http://localhost:8000/mcp/", "--header", "x-adcp-auth: YOUR_TOKEN"]
}
}
}
Get your token from Admin UI β Advertisers β (select advertiser) β API Token.
Troubleshooting
Container won't start?
docker compose logs adcp-server | head -50
GAM OAuth error?
- Verify
GAM_OAUTH_CLIENT_IDandGAM_OAUTH_CLIENT_SECRETin.env - Restart:
docker compose restart
More help: Troubleshooting Guide
Documentation
Deployment Guides
- Quickstart - Docker deployment (2 min)
- Fly.io - Cloud deployment (10-15 min)
- Google Cloud Run - GCP deployment (15-20 min)
- Single-Tenant - Single publisher deployment
- Multi-Tenant - Platform deployment
Reference
- Development Guide - Local development and contributing
- Architecture - System design and database schema
- Troubleshooting Guide - Monitoring and debugging
Key Features
For AI Agents
- Product Discovery - Natural language search for advertising products
- Campaign Creation - Automated media buying with targeting
- Creative Management - Upload and approval workflows
- Performance Monitoring - Real-time campaign metrics
For Publishers
- Multi-Tenant System - Isolated data per publisher
- Adapter Pattern - Support for multiple ad servers
- Real-time Dashboard - Live activity feed with Server-Sent Events (SSE)
- Workflow Management - Unified system for human-in-the-loop approvals
- Operations Monitoring - Track all media buys, workflows, and system activities
- Admin Interface - Web UI with Google OAuth
- Audit Logging - Complete operational history
For Developers
- MCP Protocol - Standard interface for AI agents
- A2A Protocol - Agent-to-Agent communication via JSON-RPC 2.0
- REST API - Programmatic tenant management
- Docker Deployment - Easy local and production setup
- Comprehensive Testing - Unit, integration, and E2E tests
Protocol Support
MCP (Model Context Protocol)
The primary interface for AI agents to interact with the Prebid Sales Agent. Uses FastMCP with HTTP/SSE transport.
A2A (Agent-to-Agent Protocol)
JSON-RPC 2.0 compliant server for agent-to-agent communication:
- Endpoint:
/a2a(also available at port 8091) - Discovery:
/.well-known/agent.json - Authentication: Bearer tokens via Authorization header
- Library: Built with standard
python-a2alibrary
Testing Backend
The mock server provides comprehensive AdCP testing capabilities for developers:
Testing Headers Support
- X-Dry-Run: Test operations without real execution
- X-Mock-Time: Control time for deterministic testing
- X-Jump-To-Event: Skip to specific campaign events
- X-Test-Session-ID: Isolate parallel test sessions
- X-Auto-Advance: Automatic event progression
- X-Force-Error: Simulate error conditions
Response Headers
- X-Next-Event: Next expected campaign event
- X-Next-Event-Time: Timestamp for next event
- X-Simulated-Spend: Current campaign spend simulation
Testing Features
- Campaign Lifecycle Simulation: Complete event progression (creation β completion)
- Error Scenario Testing: Budget exceeded, delivery issues, platform errors
- Time Simulation: Fast-forward campaigns for testing
- Session Isolation: Parallel test execution without conflicts
- Production Safety: Zero real spend during testing
# Example: Test with time simulation
headers = {
"x-adcp-auth": "your_token",
"X-Dry-Run": "true",
"X-Mock-Time": "2025-02-15T12:00:00Z",
"X-Test-Session-ID": "test-123"
}
# Use with any MCP client for safe testing
See examples/mock_server_testing_demo.py for complete testing examples.
Using the MCP Client
from fastmcp.client import Client
from fastmcp.client.transports import StreamableHttpTransport
# Connect to server
headers = {"x-adcp-auth": "your_token"}
transport = StreamableHttpTransport(
url="http://localhost:8000/mcp/",
headers=headers
)
client = Client(transport=transport)
# Discover products
async with client:
products = await client.tools.get_products(
brief="video ads for sports content"
)
# Create media buy
result = await client.tools.create_media_buy(
product_ids=["ctv_sports"],
total_budget=50000,
flight_start_date="2025-02-01",
flight_end_date="2025-02-28"
)
Project Structure
salesagent/
βββ src/ # Source code
β βββ core/ # Core MCP server components
β β βββ main.py # MCP server implementation
β β βββ schemas.py # API schemas and data models
β β βββ config_loader.py # Configuration management
β β βββ audit_logger.py # Security and audit logging
β β βββ database/ # Database layer
β β βββ models.py # SQLAlchemy models
β β βββ database.py # Database initialization
β β βββ database_session.py # Session management
β βββ services/ # Business logic services
β β βββ ai_product_service.py # AI product management
β β βββ targeting_capabilities.py # Targeting system
β β βββ gam_inventory_service.py # GAM integration
β βββ adapters/ # Ad server integrations
β β βββ base.py # Base adapter interface
β β βββ google_ad_manager.py # GAM adapter
β β βββ mock_ad_server.py # Mock adapter
β βββ admin/ # Admin UI (Flask)
β βββ app.py # Flask application
β βββ blueprints/ # Flask blueprints
β β βββ tenants.py # Tenant dashboard
β β βββ tasks.py # Task management (DEPRECATED - see workflow system)
β β βββ activity_stream.py # Real-time activity feed
β βββ server.py # Admin server
βββ scripts/ # Utility scripts
β βββ setup/ # Setup and initialization
β βββ dev/ # Development tools
β βββ ops/ # Operations scripts
β βββ deploy/ # Deployment scripts
βββ tests/ # Test suite
β βββ unit/ # Unit tests
β βββ integration/ # Integration tests
β βββ e2e/ # End-to-end tests
βββ docs/ # Documentation
βββ examples/ # Example code
βββ tools/ # Demo and simulation tools
βββ alembic/ # Database migrations
βββ templates/ # Jinja2 templates
βββ config/ # Configuration files
βββ nginx/ # Nginx configuration files
Requirements
- Python 3.12+
- Docker and Docker Compose (for easy deployment)
- PostgreSQL (Docker Compose handles this automatically)
- Google OAuth credentials (for Admin UI)
- Gemini API key (for AI features)
Contributing
We welcome contributions! Please see our Development Guide for:
- Setting up your development environment
- Running tests
- Code style guidelines
- Creating pull requests
Important: Database Access Patterns
When contributing, please follow our standardized database patterns:
# β
CORRECT - Use context manager
from database_session import get_db_session
with get_db_session() as session:
# Your database operations
session.commit()
# β WRONG - Manual management
conn = get_db_connection()
# operations
conn.close() # Prone to leaks
See Contributing Guide for details.
Admin Features
Multi-Tenant User Access
Users can belong to multiple tenants with the same email address (like GitHub, Slack, etc.):
- Sign up for multiple publisher accounts with one Google login
- Different roles per tenant (admin in one, viewer in another)
- No "email already exists" errors - users are tenant-scoped
Migration: Database schema updated with composite unique constraint (tenant_id, email). See alembic/versions/aff9ca8baa9c_allow_users_multi_tenant_access.py
Tenant Deactivation (Soft Delete)
Deactivate test or unused tenants without losing data:
How to deactivate:
- Go to Settings β Danger Zone
- Type tenant name exactly to confirm
- Click "Deactivate Sales Agent"
What happens:
- β All data preserved (media buys, creatives, principals)
- β Hidden from login and tenant selection
- β API access blocked
- βΉοΈ Can be reactivated by super admin
Reactivation (super admin only):
POST /admin/tenant/{tenant_id}/reactivate
Self-Signup
New users can self-provision tenants:
- Google OAuth authentication
- GAM-only for self-signup (other adapters via support)
- Auto-creates tenant, user, and default principal
- Available at
/signupon main domain
Support
- Issues: GitHub Issues
- Discussions: GitHub Discussions
- Documentation: docs/
License
Apache 2.0 License - see LICENSE file for details.
Related Projects
- AdCP Specification - Protocol specification
- MCP SDK - Model Context Protocol tools
- FastMCP - MCP server framework
