Guide

Send Email from Linux Command Line Without SMTP Server or Postfix

Most command-line email tools require a local SMTP server or relay such as Postfix or sendmail, or only work with one provider. Nylas CLI sends email from Linux, Ubuntu, macOS, and Windows terminals with built-in OAuth2, JSON output, and zero SMTP server setup.

Written by Aaron de Mello Senior Engineering Manager

Reviewed by Caleb Geene

VerifiedCLI 3.1.1 · Gmail, Outlook, Yahoo · last tested April 11, 2026

How do you send email from the Linux command line without an SMTP server?

Use a CLI that sends through an authenticated email API instead of a local mail transfer agent. With Nylas CLI, the Linux command-line workflow is one install, one auth step, and one nylas email send command. There is no Postfix daemon, no sendmail queue, and no SMTP password in your shell history.

The mail command has shipped on Unix systems since 1977, and mailx since the early 1980s — but neither supports OAuth2. That's a problem: Google disabled “less secure app” passwords for Gmail in September 2024, and Microsoft retired Basic Auth for Exchange Online in October 2022. If your CLI tool doesn't handle OAuth2 token refresh (Gmail access tokens expire every 3,600 seconds per Google's OAuth 2.0 documentation), it can't reliably send email through these providers.

The Nylas CLI bypasses all of this. It talks directly to the Nylas API, which handles OAuth2 token refresh, provider abstraction, and connection management. Authenticate once with a single command, then all 72+ commands work across Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP on any platform.

What does "send email without SMTP server" mean?

Sending email without an SMTP server means your script does not connect to a local MTA, a relay host, or provider SMTP ports such as 25, 465, or 587. Instead, the CLI sends over HTTPS on port 443 through an authenticated API. That avoids Postfix setup, blocked outbound SMTP ports, app passwords, and relay credentials in shell scripts.

This is the right fit for Linux servers, Ubuntu cron jobs, GitHub Actions runners, and AI sandboxes where SMTP is blocked or not worth maintaining. If a workflow only needs to send a report, alert, test message, or approval email, configuring a full mail server is unnecessary operational surface area.

How do you send email from Ubuntu command line?

To send email from Ubuntu command line, install the CLI, authenticate the mailbox once, and call nylas email send from bash, cron, systemd timers, or CI. The command does not require apt install postfix, mailutils, sendmail, or SMTP relay configuration.

1. Install

Installing Nylas CLI takes under 60 seconds on macOS, Linux, or WSL. Homebrew is the fastest path — it pulls a prebuilt binary with SHA-256 verification, so there's no compile step. The Go option builds from source and requires Go 1.23 or later. Both methods place the nylas binary on your $PATH automatically.

# macOS / Linux (Homebrew)
brew install nylas/nylas-cli/nylas

# Or build from source (requires Go 1.23+)
go install github.com/nylas/cli/cmd/nylas@latest

2. Authenticate your mailbox

Authentication takes under 60 seconds. Create an application at dashboard-v3.nylas.com, connect your mailbox via OAuth, and grab your API key. The CLI stores credentials in your OS keyring (macOS Keychain, GNOME Keyring, or Windows Credential Manager), encrypted at rest. Run this once — all 72 commands use the same stored credential:

nylas auth config
# Paste your API key when prompted

# Verify it works
nylas auth whoami
# => Authenticated as you@company.com (Google Workspace)

Running nylas auth config stores credentials in your system keyring. You can verify the connection at any time:

Authentication Status

Current Account:
  Email: dev@example.com
  Provider: google
  Grant ID: d3f4a5b6-c7d8-9e0f-a1b2-c3d4e5f6g7h8
  Status: ✓ Valid

Configuration:
  Region: us
  Config Path: /home/dev/.config/nylas/config.yaml
  Secret Store: system keyring

3. Send an email

The nylas email send command delivers a message through the Nylas API in a single invocation. It accepts --to, --subject, and --body as required flags, with optional --cc and --bcc for additional recipients. The CLI prompts for confirmation before sending unless you pass --yes, which is useful in scripts where no terminal is attached. Delivery typically completes in under 3 seconds for messages up to 25 MB.

nylas email send \
  --to "colleague@company.com" \
  --subject "Quarterly report attached" \
  --body "Hi -- please review the Q4 numbers before Friday."

# Skip the confirmation prompt
nylas email send --to user@example.com --subject "Quick note" --body "..." --yes

# CC and BCC
nylas email send \
  --to alice@team.com \
  --cc bob@team.com \
  --bcc manager@team.com \
  --subject "Sprint update" \
  --body "All tasks on track."

After a successful send, the CLI confirms delivery:

✓ Email sent successfully

  Message ID: abc123def456
  To: jamie@example.com
  Subject: Deployment complete
  Sent at: 2026-03-25T15:30:00-04:00

Can you send email from command line on Linux, macOS, or Windows?

Yes. The same nylas email send syntax works on Linux, Ubuntu, macOS, Windows PowerShell, WSL, and CI runners after the CLI is installed and authenticated. Searches like send email from command line mac and send email from command line windows are platform-specific versions of the same workflow: install the binary, authenticate the mailbox, then send over HTTPS instead of SMTP.

If you need to send email from command line Linux with attachment workflows, keep the send path on this page and pair it with the nylas email send command reference for the exact flags supported by your installed CLI version. The important operational difference is that the message still leaves through the provider API, not a local Postfix or SMTP relay.

Inbox access from the terminal covers four operations: listing recent messages, filtering by read state, searching by keyword, and reading individual message bodies. The nylas email list command returns the 50 most recent messages by default. Add --unread to filter to unread only, or --limit to control how many results come back (maximum 200 per request).

# List recent emails
nylas email list --limit 10

# Only unread
nylas email list --unread

# Search by keyword
nylas email search "invoice" --limit 5

# Read a specific message
nylas email read msg_abc123

# Read the raw MIME source
nylas email read msg_abc123 --mime

Adding --json to any list command outputs RFC 8259-compliant JSON, which you can pipe into jq for filtering or feed directly to an AI agent. Each message object includes 12 fields: id, grant_id, thread_id, subject, from, to, snippet, date, unread, starred, folders, and object.

nylas email list --limit 1 --json
[
  {
    "id": "a1b2c3d4e5f6g7h8",
    "grant_id": "d3f4a5b6-c7d8-9e0f-a1b2-c3d4e5f6g7h8",
    "thread_id": "a1b2c3d4e5f6g7h8",
    "subject": "Re: Project Atlas — Q2 launch timeline",
    "from": [{"name": "Sarah Chen", "email": "sarah@example.com"}],
    "to": [{"name": "Alex Rivera", "email": "alex@example.com"}],
    "snippet": "The staging environment is ready. I've attached the test results from Friday's run...",
    "date": "2026-03-25T14:22:18-04:00",
    "unread": true,
    "starred": false,
    "folders": ["INBOX"],
    "object": "message"
  }
]

5. Schedule emails for later

Email scheduling queues a message server-side so it sends at a future time without keeping your terminal open. The --schedule flag accepts relative offsets like 2h or 30m, natural-language times like "tomorrow 9am", and ISO 8601 timestamps. Scheduled messages support delays from 1 minute to 30 days, and you can cancel a scheduled send before its delivery window by deleting the draft.

# Send in 2 hours
nylas email send --to team@company.com --subject "Reminder" --body "..." --schedule 2h

# Send tomorrow morning
nylas email send --to team@company.com --subject "Standup" --body "..." --schedule "tomorrow 9am"

# Send on a specific date
nylas email send --to client@example.com --subject "Follow-up" --body "..." --schedule "2026-03-01 14:30"

6. Track opens and clicks

Open and click tracking embeds a 1x1 tracking pixel and rewrites links so the Nylas API records engagement events. The --track-opens flag enables pixel tracking, --track-links wraps each URL in a redirect, and --track-label assigns a campaign tag for filtering. Tracking events fire within 5 seconds of the recipient's action and arrive as webhook payloads on the message.opened and message.link_clicked triggers.

nylas email send \
  --to prospect@company.com \
  --subject "Proposal attached" \
  --body "Here is our proposal for Q2." \
  --track-opens \
  --track-links \
  --track-label "q2-outreach"

# Tracking events are delivered via webhooks:
nylas webhook create \
  --url https://your-server.com/hooks \
  --triggers message.opened,message.link_clicked

7. Sign and encrypt with GPG

GPG signing and encryption work natively — no extra tools beyond a GPG keyring. The CLI implements RFC 3156 PGP/MIME, adding approximately 200 milliseconds of overhead per message for signing and 400 milliseconds for encryption. Public keys are auto-fetched from keyservers when encrypting to a recipient for the first time:

# Sign with your GPG key
nylas email send --to legal@partner.com --subject "Contract" --body "..." --sign

# Encrypt with recipient's public key (auto-fetched from keyservers)
nylas email send --to legal@partner.com --subject "Contract" --body "..." --encrypt

# Both (recommended for maximum security)
nylas email send --to legal@partner.com --subject "Contract" --body "..." --sign --encrypt

# Decrypt and verify a received message
nylas email read msg_xyz789 --decrypt --verify

See the full GPG encrypted email guide for key management, troubleshooting, and multi-recipient encryption.

8. AI-powered smart compose

Smart compose generates email drafts from a natural-language prompt without leaving the terminal. The nylas email smart-compose command sends your prompt to the Nylas AI endpoint and returns a formatted draft in under 2 seconds. Pass --message-id to generate a context-aware reply to a specific thread. The ai analyze subcommand scans unread messages and returns summaries, categories, and urgency levels.

# Generate a draft from a prompt
nylas email smart-compose --prompt "Thank them for the meeting and confirm next steps"

# Generate a reply to a specific message
nylas email smart-compose --message-id msg_abc123 --prompt "Accept the invitation politely"

# AI inbox analysis
nylas email ai analyze --unread
# => Summary, categories, action items, urgency levels

9. Scripting and automation

Shell scripting with the Nylas CLI turns email operations into composable building blocks. Every subcommand supports --json, which outputs structured data you can pipe into jq, awk, or any processing tool. The example below shows a morning inbox summary script that counts unread messages, flags urgent ones by subject-line keywords, and bulk-sends personalized emails from a CSV file. Adding a 2-second sleep between CSV sends avoids hitting the default rate limit of 50 requests per minute.

# Morning inbox summary script
#!/bin/bash
echo "=== Inbox Summary ==="
unread=$(nylas email list --unread --json | jq length)
echo "Unread: $unread"

# Urgent check
nylas email list --unread --json \
  | jq '[.[] | select(.subject | test("urgent|asap"; "i"))]' \
  | jq 'length' \
  | xargs -I{} echo "Urgent: {}"

# Bulk send from a CSV
while IFS=, read -r email name; do
  nylas email send \
    --to "$email" \
    --subject "Hello $name" \
    --body "Your account is ready." \
    --yes
  sleep 2
done < contacts.csv

10. Pipe to AI agents

Piping CLI output to AI agents turns the terminal into an email automation layer. Every nylas email subcommand supports --json, which outputs RFC 8259-compliant JSON that agents can parse without transformation. You can feed inbox data to a triage agent, generate replies with an LLM, or install the built-in MCP server so tools like Claude Code and Cursor call CLI commands directly.

# Agent triages your inbox
nylas email list --unread --json | agent triage --rules ./inbox-rules.yml

# Agent drafts a reply, CLI sends it
nylas email send \
  --to sarah@team.io \
  --subject "Re: Follow-up" \
  --body "$(agent draft --context msg_a1f2)" \
  --yes

# Start the built-in MCP server for Claude, Cursor, or VS Code
nylas mcp install --assistant claude-code

Model Context Protocol (MCP) lets AI assistants call CLI tools directly. See the full AI agent email access guide for MCP setup and tool configuration.

11. Cron jobs, here-docs, and shell-native automation

Cron-based email automation lets you fire off scheduled alerts, reports, and health checks without a running daemon or GUI. Bash here-docs solve the multi-line body problem — cat <<'EOF' passes arbitrary text to --body without escaping quotes or newlines. The CLI exits with code 0 on success and non-zero on failure, so wrapping sends in if ! blocks gives cron jobs reliable error handling. A typical nightly report cron entry adds about 4 lines to your crontab.

# Use a here-doc for longer email bodies in shell scripts
nylas email send \
  --to ops@company.com \
  --subject "Nightly backup report" \
  --body "$(cat <<'EOF'
Backups completed successfully.

- Cluster: prod-a
- Duration: 18m
- Snapshot age: 24h
EOF
)" \
  --yes

For cron jobs, wrapping the send in an if ! block ensures failures surface instead of disappearing silently. The CLI returns exit code 1 on authentication errors, network timeouts, and API-level rejections.

# Cron-friendly check with explicit exit handling
if ! nylas email send --to alerts@company.com --subject "Disk warning" --body "Disk usage > 90%" --yes; then
  echo "email send failed" >&2
  exit 1
fi

12. mailx, sendmail, and Postfix replacement

Replacing mailx, sendmail, or Postfix with the Nylas CLI eliminates the local MTA stack entirely. A Postfix relay requires maintaining TLS certificates, managing a mail queue, and monitoring a long-running daemon — roughly 15-20 config files in /etc/postfix/ for a production setup. The mailx command depends on a functioning MTA underneath, and sendmail's config syntax (sendmail.cf) hasn't changed meaningfully since the 1990s. The CLI replaces all of this with a single binary and an API key.

If your scripts currently pipe text into mailx -s "subject" user@example.com, the migration is straightforward: swap mailx for nylas email send --to user@example.com --subject "subject" --body "$(cat)". No relay, no queue, no daemon to restart after config changes.


How does Nylas CLI compare to other CLI email tools?

Featuremail / mailxmuttNylas CLI
Send emailYes (needs MTA)Yes (needs SMTP)Yes (one command)
Read inboxLocal onlyYesYes
Gmail OAuth2NoComplexBuilt-in
Microsoft 365NoComplexBuilt-in
GPG sign/encryptManualBuilt-inBuilt-in
Calendar accessNoNoYes
JSON outputNoNoYes (--json)
AI composeNoNoYes
MCP serverNoNoBuilt-in

Next steps