Use Python 3.11+ and uv:
uv sync
uv run paid-media-agent demo --with-proposalFor setup with a coding agent, use the onboarding skill.
The optional uv run paid-media-agent setup console configures keys, accounts, and deployment.
Business context is Markdown in workspace/skills/company-context/; see
Customization.
Keep keys in .env or deployment secrets. Use config show for masked configuration. Commands
load allowlisted keys from the project .env; nonblank saved values take precedence over the
shell. The console is local-only. Do not expose its port as a hosted admin panel.
Add --help for options and --json where supported for machine-readable output.
| Command | Purpose |
|---|---|
uv run paid-media-agent setup |
Optional browser setup for connections and deployment |
uv run paid-media-agent config show |
Inspect masked configuration |
uv run paid-media-agent config set KEY=VALUE |
Save local configuration |
uv run paid-media-agent config generate KEY |
Generate an API token or approval signing key |
uv run paid-media-agent models --provider langsmith --json |
Read the provider's current model list |
uv run paid-media-agent test model |
Send a short request to the configured model |
uv run paid-media-agent test pipeboard |
Check connected tool catalogs |
uv run paid-media-agent accounts discover |
Discover accessible accounts |
uv run paid-media-agent accounts list |
Show configured aliases |
uv run paid-media-agent catalog show |
Inspect tool admission and schemas |
uv run paid-media-agent policy validate |
Validate the write policy against the current catalog |
uv run paid-media-agent doctor |
Check configuration, dependencies, and runtime prerequisites |
uv run paid-media-agent demo --with-proposal |
Offline analysis and simulated approved change |
uv run paid-media-agent ask "Compare campaign performance last week" |
Run a question with your configured model |
uv run paid-media-agent report --cadence weekly |
Render a report without a model |
uv run paid-media-agent writes kill-switch on |
Stop mutations |
uv run paid-media-agent mda check |
Validate the local MDA project |
uv run paid-media-agent sandbox test --json |
Probe an explicitly configured sandbox snapshot |
uv run paid-media-agent serve |
Start the self-hosted API |
uv run paid-media-agent slack |
Start the self-hosted Slack Socket Mode adapter |
Requires a LangSmith organization with MDA access, a deployment API key, and a model-provider key. MDA is available in US LangSmith Cloud. See the current quickstart.
uv run paid-media-agent mda check
uv run mda deploy .MDA builds the project, syncs instructions and runtime skills to Context Hub, provisions the sandbox, and configures the native Slack channel. If prompted, open the Slack authorization link, authorize your workspace, and return to the terminal. The console offers Continue deployment for the same handoff. After success, open the printed LangSmith deployment URL or the agent's Slack DM.
MDA's deployment status and a successful agent response establish readiness. Local preflight does
not verify your cloud permissions. Hosting is paid.
uv run mda delete removes the deployment and its managed sandboxes and snapshots.
For development, uv run mda dev . opens the managed runtime in LangSmith Studio. Inspect model
calls, tool results, and approval interrupts there.
identity.py uses LangSmith API-key authentication. Anyone with that workspace key can call the
agent. For end-user private conversations, configure MDA's
Supabase identity.
Approval authority remains a separate host-owned configuration.
Durable memory is off by default. Enable MDA's native memory.py declaration only when all callers
may share learned knowledge. See Customization.
Edit channels/slack.py or save these optional values with config set, then redeploy:
| Setting | Default |
|---|---|
PAID_MEDIA_SLACK_NAME |
Paid Media Agent |
PAID_MEDIA_SLACK_DESCRIPTION |
Cross-account campaign analysis description |
PAID_MEDIA_SLACK_BACKGROUND_COLOR |
Platform default |
PAID_MEDIA_SLACK_TRIGGER_ON_ALL_MESSAGES |
false: mentions, direct messages, and active-thread replies |
PAID_MEDIA_SLACK_ALLOW_BOT_TRIGGERS |
false |
A custom icon is channels/slack-icon.png: a 512 × 512 PNG under 1 MB. The console can upload it.
MDA supplies Slack rendering and approve/reject interactions. This project does not add custom
paid-media cards to the managed channel.
schedules/weekly_report.py and schedules/monthly_report.py are native MDA declarations. By
default, they run Monday at 13:00 UTC and the first day of the month at 13:00 UTC. The weekly report
compares two 7-day windows; the monthly report compares two 28-day windows. Remove a schedule file
and redeploy to disable it. Use the delivery example
to post the final response to your Slack channel. Without deliver_to, results stay in LangSmith.
Edit the static cron, timezone, prompt, and destination in those files. The console also supports
time/day changes through PAID_MEDIA_REPORT_TIME, PAID_MEDIA_REPORT_TIMEZONE,
PAID_MEDIA_WEEKLY_REPORT_DAY (0 Monday to 6 Sunday), and PAID_MEDIA_MONTHLY_REPORT_DAY (1–28).
Use config set for these environment settings so their schedule declarations stay synchronized.
A waited mda deploy . reconciles schedules; --no-wait skips that step.
The local report command uses known campaign-performance adapters. Other provider schemas can
be explored through ask; they need a normalization mapping before inclusion in typed reports.
HTML reports render on the host. PDF rendering requires WeasyPrint and its native libraries in the
host process. A sandbox snapshot does not install libraries into that process. Automatic Slack
PDF uploads are not included. Use the self-hosted artifact API or local output files for downloads.
MDA bakes sandbox/setup.sh automatically and reuses the resulting snapshot for new threads.
The recipe installs Python tools and PDF libraries. Changes to the recipe rebuild the snapshot;
existing thread sandboxes retain their files until expiry. MDA owns provisioning and cleanup.
The model reads synced skills under /skills and uses /workspace for thread scratch files.
Host-created analysis artifacts stay on the host and are accessed through analysis tools. The
current tool policy exposes filesystem operations but no arbitrary shell or subagent execution.
Optional standalone snapshot tools:
uv run paid-media-agent sandbox publish --name paid-media-agent-sandbox
uv run paid-media-agent sandbox test --jsonpublish builds the same recipe, saves the snapshot ID locally, and updates the sandbox bake base.
The probe needs an explicit snapshot; it does not resolve MDA's deployment-owned recipe snapshot.
Install self-host, slack, and reports extras, or use the Docker image. Follow
Self-hosting for API credentials, Postgres, Slack tokens, and hosting.
Compose includes PDF libraries and persists checkpoints and local artifacts. Your scheduler runs
the report command; MDA cron declarations are not a self-hosted scheduler.
The API and Slack share the same model, catalog, analysis, reports, and approval rules as MDA. Slack uses native status and streaming with generic tool progress. Keep any customization in the shared tools and skills, not tool-specific message renderers.
Pipeboard connects Google Ads, Meta Ads, TikTok Ads, Pinterest Ads, Snap Ads, Reddit Ads, LinkedIn Ads, and Google Analytics. Catalogs load concurrently; tool selection keeps full schemas out of every model request. Account discovery is host-side. Unknown or unscoped tools are excluded.
X Ads and OpenAI Ads have read-only direct adapters. Set their keys in .env, then run
accounts discover and map the accounts. X uses OAuth 1.0a. OpenAI Ads requires advertiser API
access. LinkedIn connects through Pipeboard.
Do not infer a connection from a saved key. Check the catalog and one real read before relying on it.
PAID_MEDIA_MODEL accepts provider:model. Anthropic and OpenAI ship with the base install.
The LangSmith Gateway uses langsmith:provider/model. Other providers have optional extras:
google, groq, xai, mistral, and deepseek.
For an OpenAI-compatible endpoint, set PAID_MEDIA_MODEL_BASE_URL and
PAID_MEDIA_MODEL_API_KEY_ENV to the name of its key environment variable. Native tool search is
used only for verified models and endpoints; other models use the portable tool selector.
Account changes are disabled by default. The live-write runbook covers reviewed tool policies, approver identities, catalog pinning, and the kill switch. MDA's approval interrupt does not replace the host's policy or digest checks.
Proposal/receipt repositories in the default MDA profile are process-local. A restart loses pending proposals and they must be recreated; the code fails closed. Use the self-hosted Postgres profile when durable proposal records are required. Managed thread persistence alone does not persist these application repositories.
uv sync --all-extras --dev
make check
uv run paid-media-agent demo --with-proposalTests are offline by default. PAID_MEDIA_LIVE_TESTS=1 uv run pytest tests/integration -q opts into
read-only integration checks with your configured credentials. No automated test executes a live
provider mutation. Synthetic data is anchored two days before today; set
PAID_MEDIA_FIXTURE_ANCHOR=2026-08-28 to reproduce the shipped windows.
Refer to official sources before changing provider or MDA contracts.