name: o365-email-browser description: Read-only Office 365 mail browsing/searching via a single Python script.
Email Browser for Office 365 (Python)
When to use
- User asks to browse, search, or read Office 365 emails.
- User wants to download attachments from specific messages.
Safety / scope
- Read-only operations only. Do not send, delete, move, or mark mail.
- Keep outputs small; use limits and date ranges.
Prerequisites
- Python 3.9+
- pip package:
cryptography - Script:
scripts/o365client.py - User must provide their Azure app
client_id(Application ID) for login.
Setup
Ensure the script is executable (optional):
chmod +x scripts/o365client.py
Auth flow (two-step to avoid timeouts)
Use device code login in two steps (run from skill directory):
python3 scripts/o365client.py auth start --client-id <client_id> --tenant <tenant_id>
Then wait for the user to complete the browser login, and finish:
python3 scripts/o365client.py auth finish --session-key <session_key>
If tenant is not provided, common is used.
The auth start and auth login commands print a Session key. Store it securely and pass it on every subsequent call using --session-key or the O365CLIENT_SESSION_KEY environment variable. If the key is lost, re-authenticate.
Core commands
- List folders:
python3 scripts/o365client.py folders list --session-key <session_key>- List messages (default: last 7 days):
python3 scripts/o365client.py messages list --session-key <session_key> --folder-id <id> --from YYYY-MM-DD --to YYYY-MM-DD --limit 200- Search messages:
python3 scripts/o365client.py messages search --session-key <session_key> --query "invoice" --from YYYY-MM-DD --to YYYY-MM-DD --limit 200- Get full message body:
python3 scripts/o365client.py messages get --session-key <session_key> --id <message-id>- List attachments:
python3 scripts/o365client.py attachments list --session-key <session_key> --message-id <message-id>- Download attachments:
python3 scripts/o365client.py attachments download --session-key <session_key> --message-id <message-id> --out ./attachments/<message-id>/
Workflow (recommended)
- If not logged in, ask the user to provide their Azure app
client_id, then run theauth logincommand. - If folder is unknown, run
folders listand pick the folder id. - Use
messages listormessages searchwith a date range and limit. - For promising items, call
messages get --idfor full body. - If
hasAttachmentsis true, runattachments listand thenattachments download. - Report results with message ids, subjects, and attachment paths.
Output notes
- Commands return JSON.
- Default body preview length: 500 characters; set
--preview-len 0to disable. - Message list/search output omits large IDs (like
@odata.etag,internetMessageId,conversationId,parentFolderId) to keep output compact; usemessages getfor full metadata. - Attachment downloads default to
./attachments/<message-id>/.
Example task
Find invoicing emails in last 30 days and download attachments:
python3 scripts/o365client.py messages search --session-key <session_key> --query "invoice" --from 2025-12-31 --to 2026-01-30 --limit 200
For each matching id with hasAttachments=true:
python3 scripts/o365client.py attachments download --session-key <session_key> --message-id <id>
Quick test
Verify the script works:
python3 scripts/o365client.py help
You can also use argparse's built-in help:
python3 scripts/o365client.py --help