Skip to content

TeamCadenceAI/mailchimp-cli

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

mailchimp-cli

A comprehensive Rust CLI for MailChimp marketing automation, designed for scripting and AI agent integration. JSON-first output with TSV fallback for human readability.

Features

  • Full campaign lifecycle — create, content, test, schedule, send, and report
  • Audience management — lists, members, tags, segments, batch operations
  • Template browsing — list templates and export HTML
  • Campaign analytics — opens, clicks, growth reports
  • OAuth2 authentication — browser-based login with multi-account support
  • Secure token storage — system keyring (macOS Keychain, Linux Secret Service) with file fallback
  • Structured output — JSON/NDJSON (default) and TSV (--plain) for easy parsing
  • Shell completions — Bash, Zsh, Fish, PowerShell
  • AI agent skill — ships with a Claude Code / Codex skill for natural language access

Installation

Requires Rust (edition 2024).

Quick install

The install script builds the binary, copies it to ~/.local/bin, and installs the AI agent skill to any detected agents (Claude Code, Codex):

./install.sh

Manual install

# Build
cargo build --release

# Install binary
mkdir -p ~/.local/bin
cp ./target/release/mailchimp ~/.local/bin/mailchimp

# Install Claude Code skill (optional)
mkdir -p ~/.claude/skills/mailchimp
ln -sf "$(pwd)/skills/mailchimp/SKILL.md" ~/.claude/skills/mailchimp/SKILL.md
ln -sfn "$(pwd)/skills/mailchimp/docs" ~/.claude/skills/mailchimp/docs

Make sure ~/.local/bin is in your PATH:

export PATH="$HOME/.local/bin:$PATH"

Quick Start

# Authenticate (opens browser for OAuth)
mailchimp auth login

# Or use a token directly
mailchimp --token mc-XXXXXXXX audiences list

# List your audiences
mailchimp audiences list

# List subscribers
mailchimp members list <audience_id>

# Create and send a campaign
mailchimp campaigns create --audience <aud_id> --subject "Newsletter"
mailchimp campaigns content <campaign_id> --html-file email.html
mailchimp campaigns test <campaign_id> "you@example.com"
mailchimp campaigns send <campaign_id>

Commands

Auth

mailchimp auth login                     # OAuth browser flow
mailchimp auth logout                    # Remove credentials
mailchimp auth accounts                  # List authenticated accounts
mailchimp auth switch us19               # Switch default account
mailchimp auth status                    # Current auth state

Audiences (alias: a)

mailchimp audiences list                 # All audiences
mailchimp audiences list --sort-members  # Sort by subscriber count
mailchimp audiences info <id>            # Audience details
mailchimp audiences info '#My Audience'  # Lookup by name

Members (alias: m)

mailchimp members list <aud> --status subscribed --limit 100
mailchimp members add <aud> user@example.com --merge-fields '{"FNAME":"Jo"}'
mailchimp members update <aud> user@example.com --status unsubscribed
mailchimp members remove <aud> user@example.com --force
mailchimp members unsubscribe <aud> user@example.com
mailchimp members search "john" --audience <aud>

Tags (alias: t)

mailchimp tags list <aud>                        # All tags with counts
mailchimp tags add <aud> user@example.com "vip,beta"
mailchimp tags remove <aud> user@example.com "beta"
mailchimp tags members <aud> "vip"               # Members with tag

Segments (alias: seg)

mailchimp segments list <aud>
mailchimp segments info <aud> <segment_id>
mailchimp segments members <aud> <segment_id>
mailchimp segments create <aud> --name "Active" --conditions '<json>'
mailchimp segments update <aud> <seg_id> --name "New Name"
mailchimp segments delete <aud> <seg_id> --force

Campaigns (alias: c)

mailchimp campaigns list --status sent --sort-sent
mailchimp campaigns info <id>
mailchimp campaigns create --audience <aud> --subject "Newsletter"
mailchimp campaigns content <id> --html-file email.html
mailchimp campaigns test <id> "test@example.com"
mailchimp campaigns schedule <id> --time "tomorrow at 10am"
mailchimp campaigns unschedule <id>
mailchimp campaigns send <id> --force
mailchimp campaigns delete <id> --force

Templates

mailchimp templates list --type user --sort-recent
mailchimp templates info <id>
mailchimp templates info <id> --html-only          # Raw HTML to stdout
mailchimp templates info <id> --output tpl.html    # Save HTML to file

Reports (alias: r)

mailchimp reports campaign <id>                    # Full campaign stats
mailchimp reports clicks <id>                      # Click details
mailchimp reports opens <id> --limit 100           # Open details
mailchimp reports growth <aud> --period month --months 12

Shell Completions

# Add to ~/.bashrc or ~/.zshrc
eval "$(mailchimp completions bash)"
eval "$(mailchimp completions zsh)"

# Or save to file
mailchimp completions fish > ~/.config/fish/completions/mailchimp.fish

Output Modes

By default, output is JSON (single objects) or NDJSON (one JSON object per line for lists). Use --plain for TSV with a header row:

# JSON (default)
mailchimp audiences list

# TSV output
mailchimp audiences list --plain

Common patterns

# Count subscribers
mailchimp members list <aud> --plain | tail -n +2 | wc -l

# Extract a field with jq
mailchimp audiences info <id> | jq '.member_count'

# Export subscriber emails
mailchimp members list <aud> --plain | cut -f1 | tail -n +2

Global Flags

Flag Env Var Description
--plain TSV output instead of JSON
-a, --account <prefix> MAILCHIMP_ACCOUNT Use specific account (server prefix, e.g. us19)
--token <token> MAILCHIMP_TOKEN API token (bypasses keyring)
-v, --verbose Verbose logging to stderr
--help Show help
--version Show version

Environment Variables

Variable Description
MAILCHIMP_TOKEN Default API token (overrides keyring)
MAILCHIMP_ACCOUNT Default account (server prefix)
MAILCHIMP_TOKEN_STORE_PATH Use file-based token storage instead of keyring
MAILCHIMP_API_BASE_URL Override API base URL (for testing)
MAILCHIMP_CLIENT_ID OAuth app client ID
MAILCHIMP_CLIENT_SECRET OAuth app client secret

Exit Codes

Code Meaning
0 Success
1 General error
2 Authentication required
3 Invalid arguments
4 API error
5 Rate limited
6 Network error

Destructive Operations

Commands that delete or send require confirmation. Use --force to skip the prompt:

  • members remove — permanent deletion
  • segments delete — removes segment
  • campaigns send — sends to all recipients
  • campaigns delete — removes campaign

Multi-Account Usage

# List all authenticated accounts
mailchimp auth accounts

# Run a command against a specific account
mailchimp -a us19 audiences list

# Set the default account
mailchimp auth switch us19

Guides

Batch Operations

Batch commands process multiple subscribers from CSV files, making per-row API calls with immediate feedback.

CSV format

email,FNAME,LNAME,status,tags
alice@example.com,Alice,Smith,subscribed,"vip,beta"
bob@example.com,Bob,Jones,pending,
Column Required Notes
email Yes Valid email address
FNAME No First name merge field
LNAME No Last name merge field
status No subscribed (default), pending, unsubscribed
tags No Comma-separated, quoted if they contain commas

Commands

# Batch add subscribers from CSV
mailchimp members batch-add <aud> --file subscribers.csv

# Batch update existing subscribers
mailchimp members batch-update <aud> --file updates.csv

# Bulk tag from email list (one email per line)
mailchimp members batch-tag <aud> --emails emails.txt --tags "vip,premium"

Exit codes for batch commands: 0 = all succeeded, 1 = some row errors (partial success), 4 = fatal error (aborted).

Campaign Workflows

Full lifecycle for creating and sending campaigns:

# 1. Create draft
CAMPAIGN_ID=$(mailchimp campaigns create \
  --audience abc123 \
  --subject "March Newsletter" \
  --from-name "Acme Inc" \
  --reply-to news@acme.com \
  --preview-text "What's new this month..." \
  | jq -r '.id')

# 2. Set content from HTML file
mailchimp campaigns content "$CAMPAIGN_ID" --html-file ./newsletter.html

# 3. Send test
mailchimp campaigns test "$CAMPAIGN_ID" "team@acme.com"

# 4. Schedule for later
mailchimp campaigns schedule "$CAMPAIGN_ID" --time "tomorrow at 10am"

# 5. Check results after sending
mailchimp reports campaign "$CAMPAIGN_ID"

Content sources (exactly one required):

Flag Description
--html-file PATH HTML from file (most common)
--html TEXT Inline HTML string
--plain-text TEXT Plain text content
--template-id ID Use MailChimp template (optional: --template-sections JSON)

Schedule accepts ISO 8601 (2024-12-01T14:00:00Z), datetime (2024-12-01 14:00), or natural language (tomorrow at 10am).

Segments and Conditions

Create segments to target subscriber subsets:

# Active subscribers who signed up this year
mailchimp segments create <aud> \
  --name "2024 Signups" \
  --conditions '{
    "match": "all",
    "conditions": [
      {
        "condition_type": "DateMerge",
        "field": "timestamp_opt",
        "op": "greater",
        "value": "2024-01-01"
      }
    ]
  }'

Condition JSON structure:

{
  "match": "all | any",
  "conditions": [
    {
      "condition_type": "TextMerge | DateMerge | Aim | MemberRating | StaticSegment | ...",
      "field": "merge0 | merge1 | timestamp_opt | aim | member_rating | ...",
      "op": "is | not | contains | greater | less | open | click | ...",
      "value": "..."
    }
  ]
}

Common condition types:

Type Field Operations
TextMerge merge0 (email), merge1 (FNAME), merge2 (LNAME) is, not, contains, starts, ends, blank
DateMerge timestamp_opt is, not, greater, less, blank
Aim aim open, click, sent, noopen, noclick
MemberRating member_rating greater, less, is
StaticSegment static_segment static_is, static_not

Development

# Build
cargo build

# Run tests
cargo test

# Lint (must pass clean)
cargo clippy --all-targets --all-features -- -D warnings

# Format check
cargo fmt --check

# Run locally
cargo run -- audiences list --token TOKEN

All three checks (test, clippy, fmt) must pass before submitting changes.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors