CLI Reference

Command-line interface for Mailcraft. Use for testing templates and sending batch emails.

Installation

The CLI is automatically available when you install the main Mailcraft package:

npm install @mailcraft/cli
# or
pnpm add @mailcraft/cli
# or
yarn add @mailcraft/cli

Commands

test - Test individual email templates

Test rendering and optionally send a test email.

mailcraft test <archetype> [options]

Arguments:

  • archetype - Name of the archetype to test (verification, welcome, receipt, announcement, digest)

Options:

  • --brand, -b - Path to brand profile JSON file (required)
  • --adapter - Adapter to use: "resend" or "ses" (default: resend)
  • --send - Actually send the email (default: render only)
  • --recipient, -r - Email recipient for sending (required if --send)
  • --input, -i - Path to JSON file with archetype input, or key=value pairs
  • --output, -o - Output file for rendered email (optional)
  • --html - Show only HTML output
  • --text - Show only text output
  • --verbose, -v - Show detailed output

Examples:

Test rendering a verification email:

mailcraft test verification \
  --brand brand.json \
  --input code=123456 \
  --input link=https://app.com/verify?token=xyz

Test and send a welcome email:

mailcraft test welcome \
  --brand brand.json \
  --recipient user@example.com \
  --send \
  --input title="Welcome!" \
  --input body="Thanks for signing up" \
  --input cta.label="Get Started" \
  --input cta.url="https://app.com"

Test and save to file:

mailcraft test announcement \
  --brand brand.json \
  --output rendered.html \
  --input title="New Feature" \
  --input body="We've launched X"

Test with input from JSON file:

mailcraft test receipt \
  --brand brand.json \
  --input receipt-input.json

Where receipt-input.json contains:

{
  "to": ["customer@example.com"],
  "receiptId": "RCP-001",
  "currency": "USD",
  "total": "99.99",
  "items": [
    { "name": "Premium Plan", "quantity": 1, "amount": "99.99" }
  ]
}

batch - Send emails in bulk

Send multiple emails from a configuration file.

mailcraft batch <config> [options]

Arguments:

  • config - Path to batch configuration JSON file (required)

Options:

  • --dryrun - Show what would be sent without actually sending
  • --verbose, -v - Show detailed send info

Configuration File Format:

{
  "brand": {
    "name": "Acme",
    "sender": {
      "fromEmail": "noreply@acme.com",
      "fromName": "Acme Support"
    },
    "business": {
      "legalName": "Acme Inc."
    }
  },
  "adapter": {
    "type": "resend",
    "apiKey": "re_xxx"
  },
  "sends": [
    {
      "archetype": "verification",
      "recipients": ["user1@example.com", "user2@example.com"],
      "input": {
        "code": "123456",
        "link": "https://app.com/verify?token=xyz"
      }
    },
    {
      "archetype": "welcome",
      "recipients": ["newuser@example.com"],
      "input": {
        "title": "Welcome!",
        "body": "Get started with Acme",
        "cta": {
          "label": "Explore",
          "url": "https://app.com"
        }
      }
    }
  ]
}

Examples:

Dry run a batch send:

mailcraft batch emails.json --dryrun

Send all emails:

mailcraft batch emails.json

Send with verbose output:

mailcraft batch emails.json --verbose

Brand Configuration File

The brand.json file defines your sender identity. Used by both test and batch commands.

Minimal Example:

{
  "name": "Acme",
  "sender": {
    "fromEmail": "noreply@acme.com"
  },
  "business": {
    "legalName": "Acme Inc."
  }
}

Full Example:

{
  "name": "Acme",
  "visual": {
    "logoUrl": "https://acme.com/logo.png",
    "primaryColor": "#ff5733",
    "secondaryColor": "#fff9f5",
    "stylePreset": "modern"
  },
  "voice": {
    "descriptor": "professional yet friendly",
    "examples": [
      "We're excited to help you succeed",
      "Let's build something great together"
    ],
    "antiPatterns": [
      "corporate jargon",
      "overly casual language"
    ]
  },
  "sender": {
    "fromEmail": "noreply@acme.com",
    "fromName": "Acme Support",
    "replyTo": "support@acme.com"
  },
  "business": {
    "legalName": "Acme Inc.",
    "addressLine1": "123 Main Street",
    "country": "US"
  },
  "footer": {
    "unsubscribeUrl": "https://acme.com/unsubscribe",
    "supportEmail": "support@acme.com"
  }
}

Environment Variables

Adapters

Resend:

  • RESEND_API_KEY - Your Resend API key (used by test --send if adapter is resend)

AWS SES:

  • AWS_REGION - AWS region (used by test --send if adapter is ses)
  • AWS_ACCESS_KEY_ID - AWS access key (standard AWS credential)
  • AWS_SECRET_ACCESS_KEY - AWS secret key (standard AWS credential)

Examples

# Using Resend
export RESEND_API_KEY="re_xxx"
mailcraft test welcome --brand brand.json --send --recipient user@example.com

# Using AWS SES
export AWS_REGION="us-east-1"
export AWS_ACCESS_KEY_ID="xxx"
export AWS_SECRET_ACCESS_KEY="yyy"
mailcraft test welcome --brand brand.json --send --recipient user@example.com --adapter ses

Exit Codes

  • 0 - Success
  • 1 - Batch had failures (some emails failed to send)
  • Other codes - Fatal errors (file not found, invalid JSON, etc.)

Examples

Verify Your Setup

Test that Mailcraft and your brand are configured correctly:

mailcraft test welcome \
  --brand brand.json \
  --input title="Setup Test" \
  --input body="If you see this, everything works!"

Test Before Production

Always dry-run a batch before sending:

# 1. Dry run to verify configuration
mailcraft batch batch-send.json --dryrun

# 2. If dry run looks good, actually send
mailcraft batch batch-send.json --verbose

Send Verification Codes

Create verify-codes.json:

{
  "brand": { ... },
  "adapter": { "type": "resend" },
  "sends": [
    {
      "archetype": "verification",
      "recipients": ["user1@example.com", "user2@example.com"],
      "input": {
        "code": "ABC123",
        "link": "https://app.com/verify?token=xyz"
      }
    }
  ]
}

Then send:

mailcraft batch verify-codes.json --verbose

Newsletter Digest

Create newsletter.json:

{
  "brand": { ... },
  "adapter": { "type": "resend" },
  "sends": [
    {
      "archetype": "digest",
      "recipients": ["subscriber1@example.com", "subscriber2@example.com"],
      "input": {
        "title": "Weekly Digest",
        "entries": [
          {
            "title": "Article 1",
            "body": "Summary of first article...",
            "url": "https://blog.com/article-1"
          },
          {
            "title": "Article 2",
            "body": "Summary of second article...",
            "url": "https://blog.com/article-2"
          }
        ]
      }
    }
  ]
}

Send it:

mailcraft batch newsletter.json

Troubleshooting

"Cannot find module @mailcraft/cli"

Make sure the CLI package is installed:

npm install @mailcraft/cli

"Invalid brand configuration"

Verify your brand JSON has required fields:

{
  "name": "...",
  "sender": { "fromEmail": "..." },
  "business": { "legalName": "..." }
}

"Email send failed: 401 Unauthorized"

Check that your API key is correct and has required permissions:

# Resend
echo $RESEND_API_KEY

# AWS SES
aws sts get-caller-identity

"Validation error: to is required"

Make sure recipients array is not empty in batch config, or --recipient is provided for test command:

mailcraft test welcome \
  --brand brand.json \
  --recipient user@example.com  # Add this
  --send

See Also