Guide
Exchange CLI: Read Emails from Terminal
Use an Exchange CLI to list, search, and read Exchange Online or on-prem email from terminal. Exchange email access has three paths right now: EWS, PowerShell modules, or the Microsoft Graph API. The CLI collapses that setup behind one command surface.
Written by Caleb Geene Director, Site Reliability Engineering
Reviewed by Hazik
How do you use an Exchange CLI from terminal?
Connect Exchange Online or on-prem Exchange once, then run nylas email list, nylas email search, and nylas email read. This gives Exchange a terminal workflow without writing EWS SOAP, Exchange PowerShell scripts, or Microsoft Graph API clients.
EWS is dying for Exchange Online. Here's what that means.
Microsoft announced the deprecation of Exchange Web Services for Exchange Online in message center post MC862873. The timeline: EWS will be fully disabled for Exchange Online tenants by October 2026. According to Microsoft's migration guidance, all EWS integrations must move to Microsoft Graph API before that date.
This affects roughly 345 million paid Microsoft 365 seats worldwide (Microsoft FY2024 earnings). If you have scripts that call FindItem, GetItem, or SyncFolderItems against Exchange Online, they'll break.
On-premises Exchange Server is not affected. EWS continues to work on Exchange Server 2016 and 2019. But if you're running a hybrid deployment, your cloud mailboxes will lose EWS access while your on-prem mailboxes keep it.
The Graph API alternative isn't simple
Microsoft Graph API is Microsoft's official replacement for EWS on Exchange Online, but it adds significant setup overhead. A working Graph mail integration requires Azure AD app registration, OAuth2 flow configuration, token management, and pagination handling -- roughly 6 steps before you can read a single message.
- Register an application in Azure Active Directory
- Configure API permissions (Mail.Read, Mail.ReadWrite, or Mail.Read.Shared for shared mailboxes)
- Set up an OAuth2 authorization flow with redirect URIs
- Handle token acquisition, caching, and refresh (access tokens expire in 3600 seconds)
- Implement the Graph API calls with proper pagination using
$topand$skip - Parse the JSON response format, which differs from EWS XML
For a single GET /me/messages call, you need approximately 80 lines of code in Python or Node.js, not counting error handling or token refresh logic.
1. Install the Nylas CLI
The Nylas CLI installs in under 2 minutes on macOS, Linux, or Windows and connects to Exchange Online and on-premises Exchange Server without requiring Azure AD app registration or the ExchangeOnlineManagement PowerShell module. Homebrew is the fastest method on macOS and Linux.
The Homebrew formula pulls the latest release binary (currently around 25 MB) from GitHub, verifies a SHA-256 checksum, and places the nylas binary on your PATH.
brew install nylas/nylas-cli/nylasOther install methods (shell script, PowerShell, Go) are in the getting started guide.
2. Connect your Exchange account
Connecting an Exchange account to the Nylas CLI takes about 3 minutes. The process works for both Exchange Online (Microsoft 365) and on-premises Exchange Server, covering the full range of Exchange deployments that span an estimated 400,000 organizations worldwide.
Create an application at dashboard-v3.nylas.com and connect your Exchange account. Then configure authentication locally:
nylas auth config
# Paste your API key when prompted
# Verify the connection
nylas auth whoami
# => Authenticated as you@company.com (Exchange)3. List your Exchange inbox
The nylas email list command retrieves messages from an Exchange mailbox in a single terminal call. It returns the 10 most recent messages by default, with subject, sender, date, and read status. The same command works identically across Exchange Online and on-premises Exchange Server.
The CLI formats output as a human-readable table by default or as structured JSON when you pass --json. Filtering by unread status avoids pulling all messages, which matters for Exchange mailboxes that can hold over 50 GB under the default Microsoft 365 quota.
# List recent messages
nylas email list
# Show only unread messages
nylas email list --unread
# Limit to 20 results
nylas email list --limit 20Exchange Online vs on-premises: what differs
The Nylas CLI uses the same nylas email list command for both Exchange Online and on-premises Exchange Server. Behind the scenes, Nylas routes Exchange Online requests through the Microsoft Graph API and on-premises requests through EWS with autodiscover. This distinction matters because Microsoft still supports roughly 30,000 on-premises Exchange Server deployments alongside its cloud offering.
| Aspect | Exchange Online (M365) | On-premises Exchange |
|---|---|---|
| Protocol used by Nylas | Microsoft Graph API | EWS with autodiscover |
| Authentication | OAuth2 via Microsoft identity platform | NTLM or Basic Auth |
| Admin consent needed? | Only if tenant restricts third-party apps | No (user-level auth) |
| Autodiscover | Cloud-based (login.microsoftonline.com) | DNS SRV or SCP lookup |
| EWS deprecation impact | Nylas migrated to Graph automatically | Not affected |
| Hybrid deployments | Both mailbox types work through the same CLI commands | |
Shared mailboxes and room calendars
The Nylas CLI accesses shared mailboxes, room mailboxes, and equipment mailboxes by connecting each as a separate grant in the Nylas dashboard. Exchange environments typically have three special mailbox types: shared mailboxes for teams (support@, sales@), room mailboxes for meeting rooms, and equipment mailboxes. About 67% of Exchange Online organizations use at least one shared mailbox, according to Microsoft's 365 admin adoption data.
The --grant flag switches between connected mailboxes without re-authenticating. Each shared mailbox is connected once in the dashboard and then accessible by its email address.
# Connect a shared mailbox as a separate grant in the Nylas dashboard,
# then switch between personal and shared mailboxes:
nylas email list --grant "support@company.com" --limit 10
# Check another shared mailbox
nylas email list --grant "sales@company.com" --unread
# Search across a specific shared mailbox
nylas email search "refund request" --grant "support@company.com"For room mailboxes, the pattern is the same. Connect the room mailbox as a grant and list its messages to see booking confirmations and meeting requests.
PowerShell comparison: Get-ExoMailbox vs Nylas CLI
The ExchangeOnlineManagement PowerShell module requires admin credentials and role-based access control permissions, while the Nylas CLI works with user-level OAuth2 credentials and needs no module installation. PowerShell's New-ComplianceSearch cmdlet alone requires the Compliance Search role, which fewer than 5% of users in a typical Exchange tenant have assigned.
The side-by-side comparison covers two common tasks: listing folder statistics and searching messages. The PowerShell path requires module installation and admin-level connection, while the Nylas CLI runs with a single command and user-level access.
# PowerShell: List mailbox contents (requires ExchangeOnlineManagement module)
# Install-Module ExchangeOnlineManagement
# Connect-ExchangeOnline -UserPrincipalName admin@company.com
# Get-MailboxFolderStatistics -Identity user@company.com |
# Select-Object Name, ItemsInFolder
# Nylas CLI: Same information, no admin module needed
nylas folder list
# Shows folder names and message counts
# PowerShell: Search messages (requires Compliance Search role)
# New-ComplianceSearch -Name "Q1 Reports" \
# -ExchangeLocation user@company.com \
# -ContentMatchQuery "subject:Q1 AND sent>=2026-01-01"
# Start-ComplianceSearch -Identity "Q1 Reports"
# Nylas CLI: Search without admin privileges
nylas email search "subject:Q1" --limit 20The difference: PowerShell's Get-ExoMailbox and New-ComplianceSearch require the ExchangeOnlineManagement module, admin credentials, and role-based access control permissions. The Nylas CLI works with user-level OAuth2 credentials.
EWS migration scenarios
Organizations migrating off EWS before the October 2026 deadline face three common integration patterns: inbox monitoring, compliance searches, and distribution list tracking. Microsoft estimates that over 100,000 EWS applications need to migrate to Graph API or an alternative. The Nylas CLI covers each pattern with standard commands that work across Exchange Online and on-premises deployments.
Automated inbox monitoring
EWS pattern: SubscribeToStreamingNotifications or polling with FindItem in a loop. Graph replacement: /subscriptions endpoint with webhooks. Nylas CLI approach:
# Poll for new messages in a cron job or CI pipeline
nylas email list --unread --json | jq length
# Returns count of unread messages
# Get unread messages with full metadata
nylas email list --unread --json --limit 50 | \
jq -r '.[] | "\(.received_at) \(.from[0].email): \(.subject)"'Compliance and audit searches
EWS pattern: SearchMailboxes with discovery management role. In Exchange Online, Microsoft replaced this with the Purview compliance portal. The CLI handles standard user-scoped searches:
# Search for sensitive terms across your mailbox
nylas email search "confidential" --json --limit 100 | \
jq '[.[] | {date: .date, from: .from[0].email, subject: .subject}]'
# Filter by date range for audit windows
nylas email search "after:2026-01-01 before:2026-03-31" --json | \
jq length
# => 847 messages in Q1 2026Distribution list monitoring
Exchange distribution lists (DLs) and Microsoft 365 Groups both deliver to member mailboxes. To track messages sent to a specific DL:
# Find emails sent to the engineering distribution list
nylas email search "to:engineering@company.com" --limit 20
# Count DL traffic over the past month
nylas email search "to:all-hands@company.com after:2026-03-01" --json | \
jq lengthExchange folder structure
Exchange mailboxes use a folder hierarchy distinct from Gmail labels or Yahoo folders. A default Exchange Online mailbox ships with 13 system folders including Inbox, Sent Items, Deleted Items, Junk Email, Conversation History, and Clutter. Exchange also supports Public Folders shared across an organization and In-Place Archive mailboxes for long-term retention.
The nylas folder list command returns every folder in the mailbox with its display name and message count. Filtering messages by folder with --folder lets you target Exchange-specific folders that don't exist in other providers.
# List all folders in your Exchange mailbox
nylas folder list
# Common Exchange-specific folders
nylas email list --folder "Inbox"
nylas email list --folder "Sent Items"
nylas email list --folder "Deleted Items"
nylas email list --folder "Junk Email"
# Check Conversation History (Skype/Teams saved messages)
nylas email list --folder "Conversation History" --limit 5EWS vs Graph API vs Nylas CLI
Three approaches exist for programmatic Exchange email access: EWS (deprecated for Exchange Online in October 2026), the Microsoft Graph API, and the Nylas CLI. Setup time ranges from approximately 5 minutes with the CLI to 60 minutes with Graph API, primarily because Graph requires Azure AD app registration and OAuth2 configuration. The following comparison covers 9 dimensions.
| Concern | EWS | Microsoft Graph | Nylas CLI |
|---|---|---|---|
| Setup time | ~30 min (SOAP endpoint config) | ~60 min (Azure AD app + OAuth2) | ~5 min (dashboard + API key) |
| Lines of code | ~50 (SOAP XML) | ~80 (REST + auth) | 0 |
| Authentication | NTLM, Basic, or OAuth2 | OAuth2 only | Handled by Nylas |
| Exchange Online support | Until Oct 2026 | Yes | Yes |
| On-prem support | Yes | No | Yes (via EWS) |
| Shared mailbox support | Yes (impersonation) | Yes (Mail.Read.Shared) | Yes (multi-grant) |
| Pagination | IndexedPageItemView | $top / $skip / @odata.nextLink | --limit flag |
| Search syntax | AQS / RestrictionType SOAP | $search / $filter OData | nylas email search |
| Deprecation risk | High (Oct 2026) | Low | None (Nylas abstracts) |
JSON output for Exchange automation
The --json flag on nylas email list outputs structured JSON that pipes directly into jq, Python, or any scripting language. Each message object includes over 15 fields: subject, from, to, cc, bcc, date, received_at, thread_id, labels, folders, and more. This makes it straightforward to build cron-based monitors, compliance exports, or alerting scripts for Exchange mailboxes.
Three common Exchange automation patterns follow: daily unread monitoring for shared mailboxes, sender auditing across the last 100 messages, and external domain detection.
# Daily unread count for a shared mailbox (run via cron)
COUNT=$(nylas email list --unread --json --grant "support@company.com" | jq length)
echo "$(date +%Y-%m-%d) support@ unread: $COUNT" >> /var/log/mailbox-stats.log
# Extract all senders from the last 100 messages for audit
nylas email list --limit 100 --json | \
jq -r '[.[] | .from[0].email] | unique | .[]' | sort
# Flag messages from external domains
DOMAIN="company.com"
nylas email list --limit 50 --json | \
jq --arg d "$DOMAIN" '[.[] | select(.from[0].email | endswith($d) | not)]' | \
jq length | xargs -I{} echo "External messages: {}"Next steps
- Exchange Calendar CLI: Manage Events — create events, book rooms, check availability
- Send email from the terminal — compose and send from Exchange
- List Outlook emails — for personal Outlook.com and Microsoft 365 accounts
- List Gmail emails — same CLI, different provider
- Yahoo Mail CLI: Read Emails from Terminal — same workflow for Yahoo
- iCloud Mail CLI: Read Emails from Terminal — same workflow for Apple
- List IMAP emails — for Fastmail, Zoho, self-hosted, and more
- EWS to Graph migration guide — timeline, auth changes, and feature gaps before October 2026
- Give AI agents email access via MCP
- Full command reference
- Microsoft: Basic auth deprecation in Exchange Online — the policy change that broke most legacy EWS scripts and forces OAuth
- Microsoft Graph: List messages — the recommended replacement surface for Exchange Online mail access