Agent-first CLI for Microsoft Outlook Mail & Calendar
msgcli is a fast, script-friendly command-line interface for Microsoft Graph API. Built for AI agents and automation, inspired by gogcli.
# What's in my inbox?
$ msgcli mail list
• 📎 John Smith RE: Project proposal Jan 17 09:42
ID: AAMkAGI2TG...
# Create a meeting
$ msgcli calendar create --subject "Sync" --start "2024-01-20T14:00" --end "2024-01-20T14:30" --attendees "team@company.com"
Event created successfully
ID: AAMkAGI2TG...
# Agent-friendly JSON output
$ msgcli mail list -o json | jq '.[0].subject'
"RE: Project proposal"- Agent-first — JSON output,
--no-inputflag, clean stdout/stderr separation - Multi-account — Switch between personal and work Microsoft accounts
- Secure — Tokens stored in OS keychain (macOS Keychain, Windows Credential Manager, Linux Secret Service)
- Simple auth — Device code flow, no client secrets, 5-minute setup
- Full CRUD — Mail and Calendar operations for real workflows
- Open Azure Portal → App registrations
- Click "New registration"
- Configure:
- Name:
msgcli - Account types: "Accounts in any organizational directory and personal Microsoft accounts"
- Redirect URI: Leave blank
- Name:
- Click Register
- Copy the Application (client) ID
- Go to Authentication → Enable "Allow public client flows" → Save
📖 Detailed guide with screenshots: docs/SETUP.md
# Option A: Go install
go install github.com/skylarbpayne/msgcli/cmd/msgcli@latest
# Option B: Build from source
git clone https://github.com/skylarbpayne/msgcli.git
cd msgcli
make build
./bin/msgcli --help# Store your client ID (one-time)
msgcli auth setup
# Enter client ID: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
# Add an account
msgcli auth add personal
# To sign in, open a browser and go to:
# https://microsoft.com/devicelogin
# Enter the code: ABCD1234# List recent emails
msgcli mail list
# Read a specific email
msgcli mail get AAMkAGI2TG...
# Send an email
msgcli mail send --to "someone@example.com" --subject "Hello" --body "Hi there!"
# List this week's events
msgcli calendar list
# Check someone's availability
msgcli calendar availability --emails "colleague@company.com" --start "2024-01-20" --end "2024-01-21"| Command | Description |
|---|---|
msgcli auth setup |
Store Azure client ID (one-time) |
msgcli auth add <alias> |
Add account via device code flow |
msgcli auth list |
List configured accounts |
msgcli auth status |
Show auth status and token validity |
msgcli auth remove <alias> |
Remove an account |
| Command | Description |
|---|---|
msgcli mail list |
List messages (default: inbox, last 25) |
msgcli mail get <id> |
Read a specific message |
msgcli mail send |
Send a new message |
msgcli mail reply <id> |
Reply to a message |
msgcli mail delete <id> |
Delete a message |
msgcli mail move <id> |
Move message to folder |
msgcli mail folders |
List mail folders |
# Examples
msgcli mail list --folder sentitems --limit 10
msgcli mail list --query "from:boss@company.com"
msgcli mail send --to "a@b.com" --cc "c@d.com" --subject "Update" --body "Here's the update..."
msgcli mail reply AAMkAGI2TG... --body "Thanks!" --all| Command | Description |
|---|---|
msgcli calendar list |
List events (default: next 7 days) |
msgcli calendar get <id> |
Get event details |
msgcli calendar create |
Create a new event |
msgcli calendar update <id> |
Update an event |
msgcli calendar delete <id> |
Delete an event |
msgcli calendar respond <id> |
Accept/decline/tentative |
msgcli calendar availability |
Check free/busy for users |
# Examples
msgcli calendar list --start 2024-01-15 --end 2024-01-31
msgcli calendar create --subject "1:1" --start "2024-01-20T10:00" --end "2024-01-20T10:30" --location "Zoom"
msgcli calendar respond AAMkAGI2TG... --response accept --comment "See you there!"
msgcli calendar delete AAMkAGI2TG... --cancel --comment "Rescheduling"-a, --account <alias> # Use specific account (default: first configured)
-o, --output json|table # Output format (default: auto-detect)
--no-input # Never prompt, fail if input neededmsgcli is designed for AI agent integration:
# Guaranteed non-interactive mode
msgcli mail list --no-input -o json
# Pipe content
echo "Meeting notes attached" | msgcli mail send --to "team@co.com" --subject "Notes" --stdin --no-input
# Check exit codes
msgcli mail list -o json && echo "Success" || echo "Failed"Exit codes:
0— Success1— Error (check stderr)2— Auth required
Output separation:
stdout— Data (JSON or table)stderr— Progress, errors, prompts
# Add multiple accounts
msgcli auth add personal # @outlook.com
msgcli auth add work # @company.com
# Use specific account
msgcli mail list -a personal
msgcli calendar list -a work
# Check all accounts
msgcli auth status| Variable | Description |
|---|---|
MSGCLI_CLIENT_ID |
Azure client ID (alternative to auth setup) |
MSGCLI_KEYRING_PASSWORD |
Keyring password for headless/CI environments |
make build # Build to ./bin/msgcli
make install # Install to $GOPATH/bin
make test # Run tests
make release # Cross-compile for all platforms- Auth: Device code flow (no client secret needed) — you authenticate in a browser, msgcli stores refresh tokens in your OS keychain
- API: Direct Microsoft Graph API calls with automatic token refresh
- Output: JSON for machines, tables for humans (auto-detected based on TTY)
PRs welcome! Please open an issue first to discuss major changes.
MIT
Built with ❤️ for AI agents everywhere.