A lightweight, fast command-line email client for sending and reading emails via SMTP/IMAP. Built with Go for cross-platform compatibility.
- 📤 Send emails via SMTP with support for:
- Multiple recipients (To, CC, BCC)
- HTML and plain text bodies
- File attachments (max 5 files, 10MB each)
- Reply threading (In-Reply-To header)
- Body from file or command line
- 📥 Read emails via IMAP with:
- Mailbox listing with filters (unread, limit)
- Full message reading with body and attachments
- JSON output for scripting
- 🔒 Environment-based configuration - no credentials stored in code
- 🤖 JSON output mode for easy integration with scripts and agents
- 🎨 Colored terminal output (can be disabled)
- 🖥️ Cross-platform - works on Linux, macOS, and Windows
- Installation
- Configuration
- Commands
- Environment Variables
- Examples
- JSON Output
- Troubleshooting
- Development
- License
go install github.com/user/ghostmail-cli/cmd/ghostmail@latestDownload the latest release for your platform from the Releases page.
# Linux
curl -L https://github.com/user/ghostmail-cli/releases/latest/download/ghostmail-linux-amd64 -o ghostmail
chmod +x ghostmail
sudo mv ghostmail /usr/local/bin/
# macOS
curl -L https://github.com/user/ghostmail-cli/releases/latest/download/ghostmail-darwin-amd64 -o ghostmail
chmod +x ghostmail
sudo mv ghostmail /usr/local/bin/
# Windows (PowerShell)
Invoke-WebRequest -Uri https://github.com/user/ghostmail-cli/releases/latest/download/ghostmail-windows-amd64.exe -OutFile ghostmail.exegit clone https://github.com/user/ghostmail-cli.git
cd ghostmail-cli
make buildGhostmail uses environment variables for configuration. No credentials are ever stored in code or config files.
# Copy example configuration
eval "$(ghostmail config example)"
# Or export manually
export GHOSTMAIL_SMTP_HOST="smtp.gmail.com"
export GHOSTMAIL_SMTP_PORT="587"
export GHOSTMAIL_SMTP_USERNAME="your-email@gmail.com"
export GHOSTMAIL_SMTP_PASSWORD="your-app-password"
export GHOSTMAIL_SMTP_FROM="your-email@gmail.com"
export GHOSTMAIL_IMAP_HOST="imap.gmail.com"
export GHOSTMAIL_IMAP_PORT="993"
export GHOSTMAIL_IMAP_USERNAME="your-email@gmail.com"
export GHOSTMAIL_IMAP_PASSWORD="your-app-password"For Gmail, you'll need to use an App Password:
- Enable 2-Factor Authentication on your Google account
- Go to Google Account → Security → 2-Step Verification → App passwords
- Generate an App Password for "Mail"
- Use that password instead of your regular password
Verify your configuration:
ghostmail config checkSend an email via SMTP.
ghostmail send --to recipient@example.com --subject "Hello" --body "World"Required Flags:
| Flag | Short | Description |
|---|---|---|
--to |
-t |
Recipient email address (repeatable) |
--subject |
-s |
Email subject |
--body |
-m |
Email body text (or use --body-file) |
Optional Flags:
| Flag | Short | Description |
|---|---|---|
--cc |
-c |
CC recipient (repeatable) |
--bcc |
-b |
BCC recipient (repeatable) |
--attach |
-a |
File attachment (repeatable, max 5 files, 10MB each) |
--body-file |
Read body from file | |
--html-file |
Read HTML body from file | |
--in-reply-to |
Message-ID to reply to (for threading) |
Examples:
# Simple text email
ghostmail send --to recipient@example.com --subject "Hello" --body "World"
# With CC and BCC
ghostmail send \
--to recipient@example.com \
--cc cc@example.com \
--bcc bcc@example.com \
--subject "Hello" \
--body "World"
# Multiple recipients
ghostmail send \
-t user1@example.com \
-t user2@example.com \
-s "Hello" \
-b "World"
# With attachments
ghostmail send \
--to recipient@example.com \
--subject "Documents" \
--body "Please find attached" \
--attach document.pdf \
--attach image.png
# HTML email with plain text fallback
ghostmail send \
--to recipient@example.com \
--subject "Newsletter" \
--html-file newsletter.html \
--body "Plain text version"
# Body from file
ghostmail send \
--to recipient@example.com \
--subject "Report" \
--body-file report.txt
# Reply to a message (enables threading)
ghostmail send \
--to recipient@example.com \
--subject "Re: Original Subject" \
--body "My reply text" \
--in-reply-to "<original-message-id@example.com>"List emails from a mailbox.
ghostmail inbox [flags]Flags:
| Flag | Short | Description | Default |
|---|---|---|---|
--limit |
-l |
Maximum messages to show (0 = all) | 20 |
--unread |
-u |
Show only unread messages | false |
--mailbox |
-m |
Mailbox to list | INBOX |
Examples:
# List last 20 emails (default)
ghostmail inbox
# List with custom limit
ghostmail inbox --limit 10
# Show only unread messages
ghostmail inbox --unread
# List from specific mailbox
ghostmail inbox --mailbox "Sent Items"
# JSON output for scripting
ghostmail inbox --limit 50 --json
# Get unread count (with jq)
ghostmail inbox --unread --json | jq '.messages | length'Read a specific email by UID.
ghostmail read --uid <UID>Flags:
| Flag | Short | Description |
|---|---|---|
--uid |
-u |
Message UID (required) |
--mailbox |
-m |
Mailbox to read from |
--raw |
Show raw/preview only (faster) |
Examples:
# Read email with UID 12345
ghostmail read --uid 12345
# Read from specific mailbox
ghostmail read --uid 12345 --mailbox Archive
# Quick preview (faster, no body parsing)
ghostmail read --uid 12345 --raw
# Get JSON for scripting
ghostmail read --uid 12345 --json
# Extract subject using jq
ghostmail read --uid 12345 --json | jq -r '.message.subject'Configuration helper commands.
# Print example configuration
ghostmail config example
# Check current configuration
ghostmail config check
# Source example config (edit first!)
eval "$(ghostmail config example)"All configuration is done via environment variables with the GHOSTMAIL_* prefix.
| Variable | Description | Default |
|---|---|---|
GHOSTMAIL_SMTP_HOST |
SMTP server hostname | (required) |
GHOSTMAIL_SMTP_PORT |
SMTP server port | 587 |
GHOSTMAIL_SMTP_USERNAME |
SMTP username | (required) |
GHOSTMAIL_SMTP_PASSWORD |
SMTP password | (required) |
GHOSTMAIL_SMTP_FROM |
Default sender email | (same as username) |
GHOSTMAIL_SMTP_USE_TLS |
Use TLS (instead of STARTTLS) | false |
GHOSTMAIL_SMTP_STARTTLS |
Use STARTTLS | true |
| Variable | Description | Default |
|---|---|---|
GHOSTMAIL_IMAP_HOST |
IMAP server hostname | (required) |
GHOSTMAIL_IMAP_PORT |
IMAP server port | 993 |
GHOSTMAIL_IMAP_USERNAME |
IMAP username | (required) |
GHOSTMAIL_IMAP_PASSWORD |
IMAP password | (required) |
GHOSTMAIL_IMAP_USE_TLS |
Use TLS for IMAP | true |
GHOSTMAIL_IMAP_MAILBOX |
Default mailbox | INBOX |
# ~/.ghostmail-env
export GHOSTMAIL_SMTP_HOST="smtp.gmail.com"
export GHOSTMAIL_SMTP_PORT="587"
export GHOSTMAIL_SMTP_USERNAME="your.email@gmail.com"
export GHOSTMAIL_SMTP_PASSWORD="xxxx xxxx xxxx xxxx"
export GHOSTMAIL_SMTP_FROM="your.email@gmail.com"
export GHOSTMAIL_IMAP_HOST="imap.gmail.com"
export GHOSTMAIL_IMAP_PORT="993"
export GHOSTMAIL_IMAP_USERNAME="your.email@gmail.com"
export GHOSTMAIL_IMAP_PASSWORD="xxxx xxxx xxxx xxxx"
export GHOSTMAIL_IMAP_MAILBOX="INBOX"Source it: source ~/.ghostmail-env
These flags work with all commands:
| Flag | Short | Description |
|---|---|---|
--json |
-j |
Output in JSON format |
--no-color |
Disable colored output | |
--verbose |
-v |
Enable verbose output |
--help |
-h |
Show help |
--version |
Show version |
All commands support JSON output with the --json flag for easy integration:
ghostmail send --to test@example.com -s "Test" -b "Body" --json{
"success": true,
"message": "Email sent successfully"
}ghostmail inbox --limit 5 --json{
"success": true,
"messages": [
{
"uid": 12345,
"subject": "Hello",
"from": "sender@example.com",
"to": ["recipient@example.com"],
"date": "2024-01-15T10:30:00Z",
"flags": ["\\Seen"]
}
],
"total": 1
}ghostmail read --uid 12345 --json{
"success": true,
"message": {
"uid": 12345,
"subject": "Hello",
"from": "sender@example.com",
"to": ["recipient@example.com"],
"cc": [],
"bcc": [],
"date": "2024-01-15T10:30:00Z",
"body": "Email body content...",
"body_preview": "Email body...",
"flags": ["\\Seen"]
}
}#!/bin/bash
# Load configuration
source ~/.ghostmail-env
# Send daily report
ghostmail send \
--to "boss@example.com" \
--cc "team@example.com" \
--subject "Daily Report $(date +%Y-%m-%d)" \
--body-file report.txt \
--attach daily-report.pdfimport subprocess
import json
import os
# Set environment
os.environ['GHOSTMAIL_IMAP_HOST'] = 'imap.gmail.com'
os.environ['GHOSTMAIL_IMAP_USERNAME'] = 'user@gmail.com'
os.environ['GHOSTMAIL_IMAP_PASSWORD'] = 'app-password'
# Get unread emails
result = subprocess.run(
['ghostmail', 'inbox', '--unread', '--json'],
capture_output=True,
text=True
)
emails = json.loads(result.stdout)
for msg in emails['messages']:
print(f"From: {msg['from']}, Subject: {msg['subject']}")# Check for unread emails every 15 minutes
*/15 * * * * source $HOME/.ghostmail-env && ghostmail inbox --unread --json | /usr/local/bin/notify.sh
# Send daily backup report
0 9 * * * source $HOME/.ghostmail-env && ghostmail send -t admin@example.com -s "Backup Status" -b "Backup completed""SMTP host is required"
Error: SMTP host is required (set GHOSTMAIL_SMTP_HOST)
- Solution: Set the
GHOSTMAIL_SMTP_HOSTenvironment variable - Example:
export GHOSTMAIL_SMTP_HOST="smtp.gmail.com"
"IMAP host is required"
Error: IMAP host is required (set GHOSTMAIL_IMAP_HOST)
- Solution: Set the
GHOSTMAIL_IMAP_HOSTenvironment variable - Example:
export GHOSTMAIL_IMAP_HOST="imap.gmail.com"
"too many attachments"
Error: too many attachments: maximum is 5 (you have 7)
- Solution: Attachments are limited to 5 files maximum
- Combine files into a zip archive or send multiple emails
"attachment is too large"
Error: attachment file.pdf is too large: 15.2MB (max 10MB)
- Solution: Individual attachments are limited to 10MB
- Use a file sharing service for large files
- Verify SMTP host and port are correct
- For Gmail: Use App Password, not your regular password
- Check if your ISP blocks port 587 (try 465 with TLS)
- Verify
GHOSTMAIL_SMTP_STARTTLSis set correctly for your provider
- Verify IMAP is enabled in your email provider settings
- Some providers require "Less Secure Apps" to be enabled
- Check firewall settings
- For Gmail: Use App Password instead of regular password
Use --verbose flag to see detailed error messages:
ghostmail send --to test@example.com -s "Test" -b "Body" --verboseAll commands include detailed help:
ghostmail --help
ghostmail send --help
ghostmail inbox --help
ghostmail read --help
ghostmail config --helpghostmail-cli/
├── cmd/ghostmail/ # Main application entry point
├── internal/
│ ├── cli/ # CLI commands (cobra)
│ ├── config/ # Configuration management
│ ├── email/ # SMTP/IMAP clients
│ └── output/ # Output formatting
├── pkg/email/ # Public types/interfaces
├── go.mod
├── go.sum
├── Makefile
└── README.md
# Build for current platform
make build
# Build for all platforms
make build-all
# Run tests
make test
# Clean build artifacts
make clean| Target | Description |
|---|---|
build |
Build binary for current platform |
build-linux |
Build for Linux (amd64) |
build-darwin |
Build for macOS (amd64, arm64) |
build-windows |
Build for Windows (amd64) |
build-all |
Build for all platforms |
test |
Run tests |
clean |
Clean build artifacts |
install |
Install to $GOPATH/bin |
- Never commit credentials to version control
- Use environment variables or a secrets manager
- For Gmail, always use App Passwords
- Consider using a dedicated email account for automation
- The
config checkcommand masks passwords in output
MIT License - see LICENSE file for details.
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request