adport
Health Warn
- License — License: Apache-2.0
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 5 GitHub stars
Code Warn
- network request — Outbound network request in apps/cloud/app/account-selection/provider-account-picker.tsx
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
Open-source multi-platform ads management for AI agents — connect your ad accounts, manage them via MCP + CLI with policy-guarded writes
adport
The open control plane for paid media. Manage 11 ad providers from the terminal or any AI agent—with every write previewed first.
I built adport because I wanted an agent to help with ad operations, but I did not want a prompt to be the only thing standing between the agent and an expensive change.
adport is an Apache-2.0 CLI, local MCP server, and locally runnable cloud application. It connects to your ad accounts, gives every client the same typed tools, normalizes reporting across providers, and makes every write show a preview before the exact approved change can run. The released CLI remains self-hosted with credentials on your machine and no telemetry; the cloud application is implemented for local verification but is not yet a public production service.
Google Ads, Apple Ads, and Microsoft Advertising have been exercised against live accounts. Meta and TikTok are implemented, but still need more testing with advertisers who use them day to day. If that is you, I would love to test and improve the integration with you.
Install
Requires Node.js 22.13 or newer.
npm install -g adport
adport --version
Connect a provider and confirm the account is available:
adport connect google
adport accounts
adport doctor
Adport fails closed when no provider credentials are available: it exposes the core/audit tool definitions, but account, report, and audit operations return NOT_CONNECTED. It never substitutes demo accounts in a normal runtime.
To explore synthetic data explicitly, opt into demo mode:
adport --demo accounts
adport --demo report --range last_7_days
adport --demo mcp
For an MCP host that configures environment variables instead of arguments, ADPORT_DEMO=true enables the same isolated mock provider. Mock tools are always named mock_* and never call an advertising platform.
Then pull a normalized report:
adport report --provider google --metrics spend,clicks,conversions,roas --range last_7_days
Supported connection commands:
adport connect google
adport connect meta
adport connect tiktok
adport connect apple
adport connect microsoft
adport connect reddit
adport connect snapchat
adport connect spotify
adport connect pinterest
adport connect linkedin
adport connect x
These are deliberately local/BYO connections. You create and own each provider app, developer token, or API key; the CLI talks directly to the provider and writes secrets only to ${ADPORT_HOME:-~/.config/adport}/credentials.json with mode 0600. Adport Cloud and its hosted OAuth broker are not involved. Provider review, consent warnings, and tenant policies therefore belong to your provider app. Remove a stored connection with adport disconnect <provider>; revoke the credential separately at the provider when necessary.
The cloud application in apps/cloud is a separate flow. Its hosted browser-based OAuth broker supports all 11 providers; tenants never paste application secrets. Each provider must be configured and approved for its intended rollout before its connection is enabled. Snapchat, Spotify, Pinterest, LinkedIn and X also support an organization-specific testing allowlist. Apple Ads uses a service-provider authorization-code flow and stores the tenant's encrypted refresh token. Providers share an encrypted tenant vault and the remote REST/MCP runtime. See the hosted onboarding guide.
The complete credential and authorization checklist is in docs/providers.md. Never commit provider tokens, app secrets, refresh tokens, or private keys.
Use it with Claude Code
After installing adport and connecting a provider:
claude mcp add adport -- adport mcp
Restart Claude Code, then ask it to list your ad accounts or report campaign performance. The same stdio server works with other MCP clients:
{
"mcpServers": {
"adport": {
"command": "adport",
"args": ["mcp"]
}
}
}
The CLI is not a separate implementation. adport accounts, adport report, and adport tools run use the same tool registry and policy engine exposed through MCP.
What happens before a write
Every mutation uses the same two-step contract:
- The first call can only return a dry-run preview.
- The preview includes the proposed changes, coercions, budget deltas, and a short-lived
pending_operation_id. - Applying requires a second call with that ID and identical arguments.
Changed arguments, expired approvals, protected accounts, and budget-cap violations are rejected. New campaigns are created paused, coercions are always reported, and applied changes are written to an append-only local audit log.
Use the CLI to inspect the active policy and audit trail:
adport policy
adport audit show
Policy lives at ~/.config/adport/policy.yaml; credentials live at ~/.config/adport/credentials.json with local-only file permissions.
Provider status
| Provider | Reads | Writes | Provider-side validation | Current validation |
|---|---|---|---|---|
| Google Ads | GAQL and normalized reports | campaigns, ad groups, keywords, RSAs, budgets, bidding | validate_only |
exercised against a live account |
| Meta Ads | Insights and normalized reports | campaigns, ad sets, budgets, status | execution_options=["validate_only"] |
needs more real-account testing |
| TikTok Ads | reporting and normalized reports | campaigns, budgets, status | client-side preview; sandbox available | needs sandbox and production testers |
| Apple Ads | campaign reports and normalized reports | campaigns, budgets, status | client-side preview | exercised against a live account |
| Microsoft Advertising | asynchronous reports and normalized reports | campaigns, budgets, status | client-side preview; sandbox available | exercised against a live account |
| Reddit Ads | v3 reports and normalized reports | campaigns, CBO budgets, status | client-side preview | wire schemas verified; needs a real-account tester |
| Snapchat Ads | discovery and normalized reports | campaigns, budgets, status | client-side preview | contract tests; cloud discovery and empty report verified |
| Spotify Ads | discovery and normalized reports | unpublished drafts, campaign status, ad-set budget/delivery | client-side preview | contract tests; cloud discovery returned no accounts |
| Pinterest Ads | discovery and normalized reports | campaigns, budgets, status | client-side preview | contract tests; cloud discovery returned no accounts |
| LinkedIn Ads | discovery and normalized reports | campaigns, budgets, status | client-side preview | contract tests; cloud approval pending |
| X Ads | discovery and normalized reports | campaigns, budgets, status | client-side preview | contract tests; Standard Ads API app access approved |
Apple Campaign Management API v5 sunsets in January 2027. Its client is version-isolated so the future Ads Platform API migration does not leak into the shared tool layer.
Help test a provider
If you currently run ads on Meta, TikTok, Apple, Microsoft, or Google, practical workflow feedback is more useful than a star.
Start with connection health and reads, or use a provider sandbox where available:
adport connect <provider>
adport doctor
adport accounts --provider <provider>
adport report --provider <provider> --range last_7_days
If something fails or a workflow is missing, open an issue with the provider, command, expected result, and sanitized error. Do not include credentials, account details, access tokens, or private request data. I am especially interested in working with active advertisers on authentication edge cases, reporting fields, safe write previews, and the first useful provider-specific audit rules.
Findings instead of an account score
adport audit run evaluates pluggable rule packs over normalized campaign data and persists concrete findings such as zero-conversion spend, low CTR, CPA outliers, and below-break-even ROAS.
adport audit run
adport recommendations list
Recommendations remain open until they are dismissed or applied. Any proposed fix goes through the normal preview-and-approve gate. There is deliberately no account score: a concrete finding with evidence is more useful than a gameable number.
Reporting and audit semantics
Normalized metric definitions, currency behavior, date boundaries, attribution limits, and safe cross-provider comparison rules are documented in docs/reporting-semantics.md. Provider reporting is not silently currency-converted and does not erase platform attribution differences.
Write-audit entries are append-only JSONL locally. Inspect or export them without changing the source log:
adport audit show --limit 50
adport audit export --format jsonl > adport-audit.jsonl
adport audit export --format json > adport-audit.json
The policy contract and audit event schema are documented in docs/write-safety.md.
Self-hosted and cloud modes
The CLI and stdio MCP server remain local and BYO. They do not contact Adport Cloud.
The repository now also contains a Next.js/Supabase cloud control center with tenant authentication and roles, RLS, encrypted multi-provider credentials, a hosted OAuth broker for Google, Meta, TikTok, Apple, Microsoft, and Reddit (PKCE where supported, one-time state, revocation or manual-revocation guidance on disconnect), MCP OAuth 2.1 with S256 PKCE and workspace consent, optional scoped API keys, a remote MCP endpoint, persistent pending approvals/audit events, retention, revocation, and organization deletion. It reuses the same provider modules, tool registry, and policy engine; it does not create a second write path. The implementation is local-first and still has explicit production gates. See docs/deployment-model.md and docs/cloud-local-development.md.
Development
git clone https://github.com/ynnickw/adport.git
cd adport
corepack enable
pnpm install
pnpm build
pnpm test
pnpm typecheck
# Optional local cloud stack
supabase start
supabase db reset --local --yes
pnpm --filter @adport/cloud dev
Repository layout:
packages/
core/ shared tool registry, policy engine, audit harness, credentials
google/ Google Ads provider
meta/ Meta Marketing API provider
tiktok/ TikTok Business API provider
apple/ Apple Ads provider
microsoft/ Microsoft Advertising provider
reddit/ Reddit Ads API v3 provider
snapchat/ Snapchat Marketing API provider
spotify/ Spotify Ads API provider
pinterest/ Pinterest Ads API provider
linkedin/ LinkedIn Marketing API provider
x/ X Ads API provider
mcp/ stdio MCP adapter over the shared registry
cli/ npm CLI over the shared registry
apps/
cloud/ Next.js/Supabase tenant dashboard, OAuth broker, REST, and remote MCP
supabase/
migrations/ tenant schema, RLS, backend grants, retention, and database tests
Provider tests assert outgoing API wire formats, unit conversions, headers, and validation behavior. Every new write path must go through the shared policy engine.
License
Apache-2.0. Contributions require a DCO sign-off (git commit -s); see CONTRIBUTING.md.
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found