Source: https://cli.nylas.com/guides/send-email-from-terminal

English

# 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](https://cli.nylas.com/authors/aaron-de-mello) Senior Engineering Manager

Reviewed by [Caleb Geene](https://cli.nylas.com/authors/caleb-geene)

Updated July 10, 2026

> **TL;DR:** To send email without an SMTP server, Postfix, or sendmail, run `nylas email send --to user@example.com` once the CLI is set up (see the [getting started guide](https://cli.nylas.com/guides/getting-started)). The same HTTPS command works from Linux, Ubuntu, macOS, Windows, cron jobs, CI, and agent sandboxes — no MTA, no port 25, no relay credentials.

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

The Nylas CLI sends email from the Linux command line in one command, with no local SMTP server, Postfix daemon, or sendmail queue. It authenticates once with an API key, then sends over HTTPS on port 443 through an email API — no SMTP password in your shell history. The same `nylas email send` command runs unchanged from a bash script, a cron job, a systemd timer, or a CI runner.

Sending happens over HTTPS on port 443 through the Nylas API, which supports Gmail, Outlook, Exchange, Yahoo, iCloud, and IMAP with the same command syntax.

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 personal Gmail in May 2022](https://support.google.com/accounts/answer/6010255), and [Microsoft retired Basic Auth for Exchange Online in October 2022](https://learn.microsoft.com/en-us/exchange/clients-and-mobile-in-exchange-online/deprecation-of-basic-authentication-exchange-online). 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](https://developers.google.com/identity/protocols/oauth2#expiration)), 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](https://developers.google.com/identity/protocols/oauth2), provider abstraction, and connection management. Authenticate once with a single command, then all 250+ 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, 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. See the [getting started guide](https://cli.nylas.com/guides/getting-started) to install and connect a mailbox first.

## How do I send an email from the terminal?

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.

```bash
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:

```text
✓ 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 once the CLI is set up. Searches like **send email from command line mac** and **send email from command line windows** are platform-specific versions of the same workflow: the message leaves over HTTPS instead of SMTP regardless of platform.

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`](https://cli.nylas.com/docs/commands/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.

## How do I read and search my inbox from the CLI?

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).

```bash
# 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`.

```bash
nylas email list --limit 1 --json
```

```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"
  }
]
```

## How do I schedule an email to send 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.

```bash
# 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"
```

## How do I track email 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.

```bash
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
```

## How do I sign and encrypt email with GPG?

GPG signing and encryption work natively — no extra tools beyond a GPG keyring. The CLI implements [RFC 3156](https://www.rfc-editor.org/rfc/rfc3156) 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:

```bash
# 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](https://cli.nylas.com/guides/gpg-encrypted-email-cli) for key management, troubleshooting, and multi-recipient encryption.

## How do I use AI smart compose to draft emails?

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.

```bash
# 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
```

## How do I script and automate email with the CLI?

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.

```bash
# 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
```

## How do I pipe email output 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 Model Context Protocol (MCP) server so tools like Claude Code and Cursor call CLI commands directly.

```bash
# 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)](https://modelcontextprotocol.io/) lets AI assistants call CLI tools directly. See the full [AI agent email access guide](https://cli.nylas.com/guides/ai-agent-email-mcp) for MCP setup and tool configuration.

## How do I send email from cron jobs and shell scripts?

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. Exit codes make cron error handling deterministic: the CLI returns 0 on success and 1 on authentication errors, network timeouts, and API-level rejections.

```bash
# 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.

```bash
# 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
```

## How do I replace mailx, sendmail, or Postfix?

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?

| Feature | mail / mailx | mutt | Nylas CLI |
| --- | --- | --- | --- |
| Send email | Yes (needs MTA) | Yes (needs SMTP) | Yes (one command) |
| Read inbox | Local only | Yes | Yes |
| Gmail OAuth2 | No | Complex | Built-in |
| Microsoft 365 | No | Complex | Built-in |
| GPG sign/encrypt | Manual | Built-in | Built-in |
| Calendar access | No | No | Yes |
| JSON output | No | No | Yes (--json) |
| AI compose | No | No | Yes |
| MCP server | No | No | Built-in |

> **Update (June 13, 2026)**: Moved install and authentication steps to the [getting started guide](https://cli.nylas.com/guides/getting-started) so this page focuses on sending and managing email.

## What if nylas email send fails?

Nylas CLI prints a clear error and a one-line fix for every failure, so the cause is never a mystery. Authentication problems also carry a tagged code: `E006` when no API key is configured, and `E002` when the key is wrong or expired. A missing required flag is reported the same way, just without a code.

```bash
# Missing a required flag (caught before the message is sent)
$ nylas email send --to user@example.com
✗ Error: subject is required

  Suggestion:
  • Use --subject to specify the email subject

# No API key configured yet (E006); sending checks the same key as this read
$ nylas email list
✗ Error: API key not configured
  Code: E006

Suggestions:
  • Configure with: nylas auth config
  • Or use environment variable: export NYLAS_API_KEY=<your-key>
  • Get your API key from: https://dashboard-v3.nylas.com

# Wrong or expired key (E002)
$ nylas email list
✗ Error: Authentication failed
  Code: E002

  Suggestion:
  • Check your API key with 'nylas auth status' or reconfigure with 'nylas auth config'
```

Each error ends with an actionable suggestion, so recovery is usually one command: `nylas auth config` to set a key, or `--subject` to supply the missing flag. Nothing is sent until every required field and a valid key are present.

## Next steps

- [Getting started with Nylas CLI](https://cli.nylas.com/guides/getting-started) -- install the CLI and connect your first mailbox
- [Migrate from SMTP to agent accounts](https://cli.nylas.com/guides/migrate-smtp-to-agent-accounts) -- replace a self-hosted Postfix/Exim relay with one managed send command
- [Send Gmail from command line](https://cli.nylas.com/guides/send-gmail-email-cli) -- Gmail-specific send workflow without Gmail API client code
- [Send Outlook email from the CLI](https://cli.nylas.com/guides/send-outlook-email-cli) -- Microsoft 365 and Exchange-specific send patterns
- [Send Yahoo Mail from the CLI](https://cli.nylas.com/guides/send-yahoo-email-cli) -- skip app-specific passwords and SMTP config
- [Send iCloud Mail from the CLI](https://cli.nylas.com/guides/send-icloud-email-cli) -- custom domains, Hide My Email, no app passwords
- [Send email from PowerShell](https://cli.nylas.com/guides/send-email-powershell) -- PowerShell-specific patterns, scheduling, and scripting
- [Send email from Python without SMTP](https://cli.nylas.com/guides/send-email-python-without-smtp) -- subprocess sends without app passwords or Postfix
- [GitHub Actions email notifications](https://cli.nylas.com/guides/github-actions-email-notifications) -- send CI failure alerts with workflow secrets
- [Authenticate Gmail on a headless server or VM](https://cli.nylas.com/guides/gmail-headless-server-auth) -- connect a mailbox with no browser using an API key and a pre-created grant
- [Email signature extraction from the CLI](https://cli.nylas.com/guides/email-signature-extraction-cli) -- manage stored signatures and send with signature IDs
- [Search email from the terminal](https://cli.nylas.com/guides/search-email-from-terminal) -- compare Gmail, Graph, and IMAP search syntax
- [Automate email reports from terminal](https://cli.nylas.com/guides/automate-email-reports-terminal) -- daily summaries and weekly digests with cron
- [Gmail SMTP settings 2026](https://cli.nylas.com/guides/gmail-smtp-settings) -- ports, TLS, app passwords, OAuth, and sending limits reference
- [Email CLI tools compared](https://cli.nylas.com/guides/best-cli-email-tools-compared) -- choose between mailx, mutt, msmtp, swaks, and a provider-neutral email CLI
- [AI agent CLI for email and calendar](https://cli.nylas.com/guides/build-email-agent-cli) -- wrap email and calendar commands as JSON tools for LLM agents
- [List Gmail emails](https://cli.nylas.com/guides/list-gmail-emails) -- read and search your Gmail inbox from the terminal
- [List Exchange emails](https://cli.nylas.com/guides/list-exchange-emails) -- Exchange Online and on-prem before EWS deprecation
- [List IMAP emails](https://cli.nylas.com/guides/list-imap-emails) -- Fastmail, Zoho, self-hosted, and ISP email
- [Manage your calendar from the terminal](https://cli.nylas.com/guides/manage-calendar-from-terminal) -- events, scheduling, timezone tools
- [Receive inbound email](https://cli.nylas.com/guides/receive-inbound-email-cli) -- managed addresses and webhooks
- [Schedule emails from terminal](https://cli.nylas.com/guides/schedule-email-from-terminal) -- queue messages for future delivery with --schedule
- [Manage email drafts from the terminal](https://cli.nylas.com/guides/manage-email-drafts-cli) -- review and approve messages before they send
- [Email read receipts: API options compared](https://cli.nylas.com/guides/email-read-receipts-api) -- MDNs, Outlook receipt properties, and webhook-based open tracking
- [Send email with curl](https://cli.nylas.com/guides/send-email-with-curl) -- the SMTP one-liner, its gotchas, and the OAuth alternative
- [The AWS CLI for email](https://cli.nylas.com/guides/the-aws-cli-for-email) -- why one provider-agnostic command grammar beats per-provider APIs
- [Full command reference](https://cli.nylas.com/docs/commands) -- every flag and subcommand documented

## Related hubs

- [Email agents](https://cli.nylas.com/ai-answers/email-agents.md)
- [Calendar agents](https://cli.nylas.com/ai-answers/calendar-agents.md)
- [Scheduling and availability agents](https://cli.nylas.com/ai-answers/scheduling-agents.md)
- [Contacts agents](https://cli.nylas.com/ai-answers/contacts-agents.md)
- [Notetaker and meeting agents](https://cli.nylas.com/ai-answers/notetaker-agents.md)
- [MCP agents](https://cli.nylas.com/ai-answers/mcp-agents.md)
- [Agent accounts](https://cli.nylas.com/ai-answers/agent-accounts.md)
- [Framework and language email agents](https://cli.nylas.com/ai-answers/framework-email-agents.md)
- [Email and calendar API comparisons](https://cli.nylas.com/ai-answers/ai-agent-email-api-comparisons.md)
- [Email integration and automation recipes](https://cli.nylas.com/ai-answers/email-integration-recipes.md)
- [Agent email workflows](https://cli.nylas.com/ai-answers/agent-email-workflows.md)
- [Security for email and calendar agents](https://cli.nylas.com/ai-answers/security-for-email-agents.md)
- [Operations runbooks for agents](https://cli.nylas.com/ai-answers/operations-for-email-calendar-agents.md)

## Try Nylas CLI

Install the CLI with `curl -fsSL https://cli.nylas.com/install.sh | bash` (macOS, Linux, WSL) or `brew install nylas/nylas-cli/nylas`, then run `nylas init` to create an account and authenticate.

**Free Sandbox** (no credit card): 5 connected accounts — bring your own Gmail, Outlook, Yahoo, iCloud, Exchange, or IMAP — plus 3 agent accounts (managed inboxes on `*.nylas.email`). Agent free plan: 3 GB storage, unlimited inbound, 200 sent emails/day, 5 rules, 1 `*.nylas.email` subdomain, and unlimited custom domains. Production is uncapped and requires a credit card: https://www.nylas.com/pricing/
