How to read, search, filter, send, reply, forward, and manage Outlook email via the Microsoft Graph CLI (mgc). Use this skill whenever the user wants to work with email in Microsoft 365 / Outlook — searching messages, checking unread mail, sending emails, downloading attachments, managing folders, or handling the Focused Inbox.
How to read, search, filter, send, reply, forward, and manage Outlook email via the Microsoft Graph CLI (mgc). Use this skill whenever the user wants to work with email in Microsoft 365 / Outlook — searching messages, checking unread mail, sending emails, downloading attachments, managing folders, or handling the Focused Inbox.
Microsoft Graph CLI — Email
Binary
./mgc-cli/mgc
Use --user-id me in all commands to target the currently signed-in user.
Global flags (quick reference)
Flag
Purpose
--select <fields>
OData $select — comma-separated field names
--filter <expr>
OData $filter
--orderby <field>
OData $orderby
--top <n>
Page size
--all
Auto-paginate all results
--search <term>
Full-text search
--query <jmespath>
Client-side JMESPath filter on the JSON response
--output JSON|TABLE|TEXT|RAW_JSON|NONE
Output format. RAW_JSON is compact and best for scripting
--debug
Print full HTTP request/response
Searching and filtering messages
Two complementary mechanisms exist:
--search — server-side full-text search (subject, body, sender, recipients). Fast, searches across all fields at once.
--filter — server-side OData filter on specific properties. Precise, composable, supports date comparisons.
--query — client-side JMESPath filter applied after the response. Use when OData doesn't support what you need.
Keyword search
# Search across all message fields (subject, body, from, to, …)
mgc users messages list --user-id me --search "project kickoff"# Exact phrase — wrap in inner double quotes to prevent tokenization errors# (without inner quotes, "Bestellung 4500711166" fails with a syntax error)
mgc users messages list --user-id me --search '"Bestellung 4500711166"'# Search within a specific folder
mgc users mail-folders messages list --user-id me \
--mail-folder-id Inbox --search "budget approval"# Search + select specific fields for a compact result
mgc users messages list --user-id me \
--search "invoice" \
--select"id,subject,from,receivedDateTime"
--search restrictions — cannot be combined with --filter or --orderby (the API rejects it). For filtering + sorting, use --filter with OData functions instead. KQL field-scoped syntax like subject: or from: does not work with this endpoint.
Date and time filters
# Messages received after a date
mgc users messages list --user-id me \
--filter "receivedDateTime ge 2026-04-01T00:00:00Z" \
--select"id,subject,from,receivedDateTime" \
--orderby "receivedDateTime desc"# Messages received in a specific date range
mgc users messages list --user-id me \
--filter "receivedDateTime ge 2026-03-01T00:00:00Z and receivedDateTime lt 2026-04-01T00:00:00Z" \
--select"id,subject,from,receivedDateTime"# Messages received today (compute the timestamp in the shell)
TODAY=$(date -u +"%Y-%m-%dT00:00:00Z")
mgc users messages list --user-id me \
--filter "receivedDateTime ge $TODAY" \
--select"id,subject,from,receivedDateTime,isRead" \
--orderby "receivedDateTime desc"
Filter by sender, read status, importance, Focused Inbox
Every message has an inferenceClassification property (focused or other) reflecting the Outlook Focused Inbox classification — fully filterable via OData.
# Unread messages only
mgc users messages list --user-id me \
--filter "isRead eq false" \
--select"id,subject,from,receivedDateTime"# From a specific sender
mgc users messages list --user-id me \
--filter "from/emailAddress/address eq 'alice@example.com'" \
--select"id,subject,receivedDateTime"# High-importance messages
mgc users messages list --user-id me \
--filter "importance eq 'high'" \
--select"id,subject,from,receivedDateTime"# Has attachments
mgc users messages list --user-id me \
--filter "hasAttachments eq true" \
--select"id,subject,from,receivedDateTime"# Focused Inbox only
mgc users messages list --user-id me \
--filter "inferenceClassification eq 'focused'" \
--select"id,subject,from,receivedDateTime,isRead" \
--orderby "receivedDateTime desc"# Other inbox only
mgc users messages list --user-id me \
--filter "inferenceClassification eq 'other'" \
--select"id,subject,from,receivedDateTime,isRead" \
--orderby "receivedDateTime desc"# Combine freely — e.g. unread Focused messages received today
TODAY=$(date -u +"%Y-%m-%dT00:00:00Z")
mgc users messages list --user-id me \
--filter "inferenceClassification eq 'focused' and isRead eq false and receivedDateTime ge $TODAY" \
--select"id,subject,from,receivedDateTime"
Focused Inbox overrides
Classify all future messages from a given sender:
# Always put messages from this sender in Focused
mgc users inference-classification overrides create --user-id me --body '{
"classifyAs": "focused",
"senderEmailAddress": { "name": "Alice", "address": "alice@example.com" }
}'# Always put messages from this sender in Other
mgc users inference-classification overrides create --user-id me --body '{
"classifyAs": "other",
"senderEmailAddress": { "name": "Newsletter", "address": "news@example.com" }
}'# List all overrides
mgc users inference-classification overrides list --user-id me
# Update an existing override
mgc users inference-classification overrides patch --user-id me \
--inference-classification-override-id <id> \
--body '{ "classifyAs": "focused" }'# Delete an override
mgc users inference-classification overrides delete --user-id me \
--inference-classification-override-id <id>
Caveats:
Overrides affect future incoming messages only — past messages are not reclassified retroactively
There is no API to reclassify a single existing message
Max 1,000 overrides per mailbox; keyed on sender SMTP address
The Focused Inbox on/off toggle is not available via Graph API v1.0
Subject-line filters
# Subject contains a keyword (server-side)
mgc users messages list --user-id me \
--filter "contains(subject, 'invoice')" \
--select"id,subject,from,receivedDateTime"# Subject starts with a prefix
mgc users messages list --user-id me \
--filter "startsWith(subject, 'RE:')" \
--select"id,subject,from,receivedDateTime"# Combine with other filters
mgc users messages list --user-id me \
--filter "contains(subject, 'Bestellung') and receivedDateTime ge 2026-03-01T00:00:00Z" \
--select"id,subject,from,receivedDateTime" \
--orderby "receivedDateTime desc"
For complex client-side filtering:
mgc users messages list --user-id me \
--select"id,subject,from,receivedDateTime" \
--query "value[?contains(subject, 'meeting')]"
Pagination
# Get first 50 messages
mgc users messages list --user-id me \
--select"id,subject,from,receivedDateTime" \
--orderby "receivedDateTime desc" --top 50
# Retrieve ALL messages matching a filter (auto-paginate)
mgc users messages list --user-id me \
--filter "isRead eq false" \
--select"id,subject,from,receivedDateTime" \
--all
Searching in specific folders
# List available folders (get IDs)
mgc users mail-folders list --user-id me --select"id,displayName"# Search within a folder by well-known name
mgc users mail-folders messages list --user-id me \
--mail-folder-id SentItems --search "contract"# Filter within a folder by date
mgc users mail-folders messages list --user-id me \
--mail-folder-id Archive \
--filter "receivedDateTime ge 2026-01-01T00:00:00Z" \
--select"id,subject,from,receivedDateTime"
Two kinds of attachments exist: file attachments (isInline: false, flagged by hasAttachments: true) and inline images (isInline: true, embedded via cid: in the HTML body — these do NOT set hasAttachments).
List attachments on a message:
mgc users messages attachments list --user-id me --message-id <id> \
--select"id,name,contentType,size,isInline" --output RAW_JSON
Download all attachments (file + inline) using the bundled script: