mkt-cli 0.3.0

Multi-platform marketing CLI
mkt-cli-0.3.0 is not a library.

mkt

The ads CLI built for coding agents — and the humans who work with them. Free and open source (MIT / Apache-2.0), written in Rust. Manage ads, ad sets, audiences, organic posts, and analytics across Meta, Google Ads, TikTok, and LinkedIn from a single terminal.

Claude Code, Codex, Cursor, or any agent with a shell can drive your ad operations with mkt the same way they use the AWS or GitHub CLIs: stable JSON output on stdout, structured errors on stderr, a documented exit-code contract, --dry-run everywhere, and zero interactive prompts.

Why mkt?

Marketing teams juggle multiple ad platforms daily, each with its own dashboard, API, and workflow. mkt brings all of them under one consistent command-line interface so you — or your coding agent — can script, automate, and manage campaigns without leaving the terminal. And because this tool spends real money, safety is the default: every campaign, ad set, and boosted post is created paused; starting delivery is always an explicit step.

Features

  • Unified command structure across all platforms: mkt <provider> <domain> <action>
  • Campaign management on all four platforms (list, get, create, update, delete)
  • Meta ad sets, ad creatives, media upload, and post boosting
  • Audience management with local SHA-256 PII hashing before any upload
  • Organic post publishing (Facebook and Instagram)
  • Unified analytics (cost always in currency units) as table, JSON, or CSV
  • Agent contract: stable exit codes (0-7), structured JSON errors with recovery hints
  • Spend safety: --dry-run on every mutating command; everything is created paused
  • Reliability: automatic retries with exponential backoff honoring Retry-After — reads retry transient failures, writes never repeat a request that may have executed
  • MCP server (mkt mcp serve) for Claude Desktop / ChatGPT
  • Shell completions, profile-based multi-account config

Supported Platforms

Platform Status Domains
Meta (Facebook/Instagram) Available campaign, adset, audience, insight, post, creative, media, raw
Google Ads Available campaign, insight
TikTok for Business Available campaign, audience, insight
LinkedIn Marketing Available campaign, insight

Installation

From source

cargo install mkt-cli

From releases

Prebuilt static binaries for Linux (x86_64/aarch64 musl), macOS (Intel/Apple Silicon), and Windows are on GitHub Releases:

curl -L https://github.com/diorrego/mkt-cli/releases/latest/download/mkt-x86_64-unknown-linux-musl.tar.gz | tar xz
sudo mv mkt /usr/local/bin/

Quick Start

1. Set your credentials

Every credential resolves from an environment variable first, then from the profile in ~/.config/mkt/config.toml:

Provider Required Optional
Meta MKT_META_ACCESS_TOKEN, MKT_META_AD_ACCOUNT_ID MKT_META_PAGE_ID (posts/creatives), MKT_META_IG_USER_ID (Instagram)
Google Ads MKT_GOOGLE_DEVELOPER_TOKEN, MKT_GOOGLE_CUSTOMER_ID, and MKT_GOOGLE_ACCESS_TOKEN or the MKT_GOOGLE_CLIENT_ID/MKT_GOOGLE_CLIENT_SECRET/MKT_GOOGLE_REFRESH_TOKEN trio login_customer_id in the profile (MCC)
TikTok MKT_TIKTOK_ACCESS_TOKEN, MKT_TIKTOK_ADVERTISER_ID
LinkedIn MKT_LINKEDIN_ACCESS_TOKEN, MKT_LINKEDIN_AD_ACCOUNT_ID
export MKT_META_ACCESS_TOKEN="your-token-here"
export MKT_META_AD_ACCOUNT_ID="act_123456789"

Or create a config file at ~/.config/mkt/config.toml:

[defaults]
output = "table"
profile = "default"

[profiles.default]
provider = "meta"

[profiles.default.meta]
access_token = "your-token-here"
ad_account_id = "act_123456789"

2. Verify your setup

mkt doctor

3. Start managing campaigns

# List campaigns (works the same on meta, google, tiktok, linkedin)
mkt meta campaign list
mkt --output json google campaign list --status active

# Create campaigns — always paused until you activate them
mkt --dry-run meta campaign create --name "Test" --objective OUTCOME_TRAFFIC
mkt meta campaign create --name "Q1 Launch" --objective OUTCOME_LEADS
mkt google campaign create --name "Brand" --objective SEARCH --daily-budget 50
# (declares containsEuPoliticalAdvertising=DOES_NOT_CONTAIN… by default; override via --extra)
mkt tiktok campaign create --name "Spark" --objective TRAFFIC --daily-budget 50

# Meta ad sets and post boosting (boost ad is created PAUSED)
mkt meta adset create --campaign <id> --name "US 25-55" --status paused \
  --daily-budget 2500 --targeting '{"geo_locations":{"countries":["US"]}}'
mkt meta post promote <post_id> --adset <adset_id>

# Audiences — PII is SHA-256 hashed locally before upload
mkt meta audience add-users <audience_id> --email a@example.com

# Unified insights across platforms
mkt meta insight get --range 7d --metrics impressions,clicks,spend
mkt --output csv linkedin insight get

# Publish an Instagram post
mkt meta post create --platform instagram \
  --image-url "https://cdn.example.com/photo.jpg" --message "New product launch"

# Raw API access when you need it
mkt meta raw get "act_123/campaigns" --fields id,name,status

# MCP server for chat agents without a terminal
mkt mcp serve

Command Reference

mkt [global flags] <provider> <domain> <action> [flags]

Global flags:
  --profile <name>     Profile to use (default: "default")
  --output <format>    Output format: table, json, csv
  --verbose            Enable debug logging
  --quiet              Suppress non-error output
  --dry-run            Preview actions without executing
  --config <path>      Custom config file path

Providers:
  meta                 Meta (Facebook / Instagram)
  google               Google Ads (REST v24, GAQL)
  tiktok               TikTok for Business (API v1.3)
  linkedin             LinkedIn Marketing (versioned REST)

Domains:
  campaign             Campaign management (list, get, create, update, delete)
  adset                Ad set management (list, create)
  audience             Audience management (list, create, add-users)
  insight              Analytics and reporting (get)
  post                 Organic posts (create, promote into an ad set)
  creative             Ad creatives (create, dark-post)
  media                Media assets (upload-image, upload-video)
  raw                  Direct API access (get, post)

Meta-commands:
  mkt providers        List available providers
  mkt doctor           Verify config, credentials, and connectivity
  mkt profile list     List configured profiles
  mkt profile show     Show profile details
  mkt completions      Generate shell completions (bash, zsh, fish, ...)
  mkt mcp serve        MCP server over stdio (Claude Desktop / ChatGPT)

For coding agents

mkt is designed to be driven by AI coding agents (Claude Code, Codex, Cursor) the same way they use the AWS or GitHub CLIs: machine-readable JSON on stdout, structured JSON errors on stderr, a stable exit-code contract (0-7), --dry-run on every mutating command, and zero interactive prompts. See AGENTS.md for the full operating contract and recipes.

Architecture

mkt is built as a Cargo workspace with clear separation of concerns:

  • mkt-core: Traits, domain models, config, output formatting, rate limiting (published on crates.io as mkt-cli-core; the lib target is still mkt_core)
  • mkt-cli: CLI definitions, command dispatch, the binary itself
  • mkt-meta: Meta provider (Graph API, Marketing API, Pages API, Instagram API)
  • mkt-google: Google Ads provider (REST v24: GAQL search + mutate, OAuth2 refresh)
  • mkt-tiktok: TikTok provider (Business API v1.3: campaigns, reporting, DMP audiences)
  • mkt-linkedin: LinkedIn provider (versioned REST: Rest.li finders, PARTIAL_UPDATE, adAnalytics)
  • mkt-testkit: Shared test utilities, mocks, fixtures

Every platform implements the MarketingProvider trait from mkt-core, which means adding a new provider is just implementing that trait and registering it.

Development

# Run all tests
cargo test --workspace --all-features

# Check formatting
cargo fmt --all -- --check

# Run linter
cargo clippy --workspace --all-targets --all-features

# Run the CLI in development
cargo run -p mkt-cli -- meta campaign list

# Generate coverage report
cargo llvm-cov --workspace --html

See CONTRIBUTING.md for detailed development guidelines.

License

Licensed under either of:

at your option.