Skip to content

jeffstall/outlook-cli

Repository files navigation

outlook-cli

Cross-platform CLI for Microsoft Outlook via the Microsoft Graph API, with dual implementations in Node.js and .NET NativeAOT.

Features

  • 📧 Email — inbox, read, search, draft, reply, forward, send, move, flag, mark-read
  • 📅 Calendar — today, week, date range, view, create events, list calendars
  • 👥 Contacts — search contacts and GAL, manage aliases (fredfreddie@outlook.com)
  • 👤 Multi-account — personal + work accounts, parent chains, per-account permissions
  • 👥 Delegate access — read and send on behalf of other users (--as fred)
  • 👀 Watch mode — real-time change tracking via delta queries, rules engine for channel delivery
  • 🔐 Security — AES-256-GCM encrypted token cache, configurable permissions, forbidden scopes, send_to whitelist, defense-in-depth token validation
  • 🖥️ Cross-platform — Mac, Linux, Windows; device code flow for headless VMs
  • 📊 Multiple output formats — text, json, markdown, html
  • 🤖 AI agent integration — OpenClaw / NanoClaw dual-mode (Skill + Channel Factory)
  • 🌉 COM Bridge — For enterprise environments where Graph API is blocked, connect via Outlook Desktop COM automation on Windows

Quick Start

1. Clone and Build

git clone https://github.com/jeffstall/outlook-cli.git
cd outlook-cli
.\build.ps1 all

build.ps1 runs npm install automatically and builds both Node.js and .NET NativeAOT for your current OS/architecture. Both implementations share the same config directory (~/.outlook-cli/) and can be used interchangeably. See docs/architecture.md for details.

2. Set Up Accounts

You need an Azure App Registration (free). See docs/AZURE-SETUP.md for step-by-step instructions. Both accounts below can share the same client ID — each user authenticates independently.

# Add a read/write account
node bin/outlook-cli.js account add work --client-id YOUR_CLIENT_ID
node bin/outlook-cli.js auth login --account work

# Add a read-only account (can read mail but cannot send, draft, move, or delete)
node bin/outlook-cli.js account add monitor --client-id YOUR_CLIENT_ID --read-only
node bin/outlook-cli.js auth login --account monitor

Each auth login opens a browser to sign in with a different Microsoft account. Read-only is enforced at two layers: the token only contains read scopes, and the CLI blocks write commands before they reach the API. See docs/usage/account.md for details.

3. Read Your Inbox

# List recent messages for the read/write account
node bin/outlook-cli.js mail inbox --account work

# Read message #1 (short IDs are assigned by inbox/search commands)
node bin/outlook-cli.js mail read 1 --account work

4. Send a Message

# Compose and send a message from "work" to "monitor"
node bin/outlook-cli.js mail draft --to "monitor@example.com" --subject "Hello from CLI" --body "Testing outlook-cli!" --send --yes --account work

Replace monitor@example.com with the actual email address of the monitor account. Use --send to compose and send in one step, or omit it to create a draft you can review first.

5. Verify It Arrived

# Check the read-only account's inbox
node bin/outlook-cli.js mail inbox --account monitor

Managing Accounts

# List all accounts
node bin/outlook-cli.js account list

# Remove a single account (deletes config and cached tokens)
node bin/outlook-cli.js account remove monitor

# Reset to clean state — remove the entire config directory
# (Windows)
rmdir /s /q "%USERPROFILE%\.outlook-cli"
# (Mac/Linux)
rm -rf ~/.outlook-cli

See docs/usage/account.md for the full account command reference.

Documentation

Document Description
docs/usage.md Complete command-line reference with examples
docs/architecture.md Architecture, config formats, security model, integration
docs/src-node.md Building and testing the Node.js implementation
docs/src-dotnet.md Building and testing the .NET implementation
docs/src-tests.md Test architecture and conventions
docs/AZURE-SETUP.md Azure App Registration setup guide
docs/SECURITY.md Security model and threat analysis
docs/MULTI-ACCOUNT.md Multi-account configuration guide
docs/DELEGATE-ACCESS.md Delegate access setup and usage
docs/WATCH-MODE.md Watch mode and rules engine
docs/JSON-INPUT.md JSON input file schemas for all commands
docs/DIRECTORY-STRUCTURE.md Project directory layout
docs/self-hosting.md Self-hosting guide including COM Bridge deployment

Architecture Overview

┌──────────────────────────────────────────────────────┐
│                     outlook-cli                      │
├──────────────────────┬───────────────────────────────┤
│  Node.js (ESM)       │  .NET 8 (NativeAOT)          │
│  Commander.js CLI    │  System.CommandLine CLI       │
│  @azure/msal-node   │  MSAL.NET                     │
│  Direct HTTP Graph   │  Direct HTTP Graph            │
├──────────────────────┴───────────────────────────────┤
│                 Shared Configuration                 │
│  ~/.outlook-cli/accounts.json                        │
│  ~/.outlook-cli/aliases.json                         │
│  ~/.outlook-cli/cache-*.enc (AES-256-GCM)            │
│  ~/.outlook-cli/delta-*.json                         │
└──────────────┬───────────────────────────────────────┘
               │ (provider = "bridge" in accounts.json)
┌──────────────▼───────────────────────────────────────┐
│              COM Bridge (optional)                   │
│  src/bridge/ — Windows-only ASP.NET Core server      │
│  COM automation → Outlook Desktop → Exchange         │
│  HMAC-SHA256 authenticated HTTP API                  │
└──────────────────────────────────────────────────────┘

Both implementations produce identical CLI behavior and share all configuration files. You can switch between them freely.

Azure App Registration

You need a free App Registration in Microsoft Entra ID. See docs/AZURE-SETUP.md for step-by-step instructions.

Required permissions:

Permission Purpose
User.Read Read user profile
Mail.Read Read email messages
Mail.ReadWrite Create drafts, move, flag, mark-read
Calendars.Read Read calendar events
Calendars.ReadWrite Create calendar events
offline_access Refresh tokens for persistent sessions

Optional permissions:

Permission Purpose
Mail.Send Send email from own account
Mail.Send.Shared Send on behalf of delegate mailbox owner
Mail.Read.Shared Read delegate mailbox
Mail.ReadWrite.Shared Write to delegate mailbox
Calendars.Read.Shared Read delegate calendar

Security note: Permissions are configurable per account via accounts.json. The security model supports forbidden scopes and send_to recipient whitelists. See docs/SECURITY.md.

Security Model

  • Read-only accounts — Restrict accounts to read-only operations with --read-only (setup guide)
  • Configurable permissions — Each account defines allowed/forbidden scopes in accounts.json
  • Forbidden scopes — Block specific permissions (e.g., Mail.Send) at the config level
  • send_to whitelist — Restrict which recipients can receive mail from a given account
  • Defense-in-depth token validation — Tokens are inspected at runtime to enforce permission policy
  • Encrypted token cache — AES-256-GCM encryption, PBKDF2 SHA-512 with 310,000 iterations
  • Confirmation prompts — Write operations require confirmation (bypass with --yes for scripting)

See docs/SECURITY.md for the full threat model.

AI Agent Integration (OpenClaw / NanoClaw)

outlook-cli operates in two modes for AI agent integration:

  • Skill mode — Agents invoke CLI commands and parse JSON output
  • Channel Factory mode — Watch rules engine normalizes incoming emails to channel messages, delivered via stdout / webhook / exec / file
# OpenClaw — symlink as a skill
ln -s /path/to/outlook-cli/skill ~/.openclaw/skills/outlook

# NanoClaw — install in container
git clone https://github.com/jeffstall/outlook-cli.git /opt/outlook-cli
cd /opt/outlook-cli && npm install && npm link

See skill/SKILL.md and skill/NANOCLAW.md.

Configuration

Environment Variables

Variable Description Default
OUTLOOK_CLI_CLIENT_ID Azure app client ID (none)
OUTLOOK_CLI_TENANT_ID Azure AD tenant ID common
OUTLOOK_CLI_PASSPHRASE Token cache encryption passphrase Machine-derived
OUTLOOK_CLI_LOG_LEVEL Logging level warn

Config Directory

All configuration is stored in ~/.outlook-cli/:

File Purpose
accounts.json Account definitions, permissions, defaults
aliases.json Contact aliases
cache-*.enc Encrypted MSAL token cache
delta-*.json Watch mode delta tokens
config.json Optional global configuration

Development

# Node.js
npm install
npm test                          # 160+ tests via vitest
node bin/outlook-cli.js --help

# .NET
dotnet build src/dotnet/OutlookCli.csproj
dotnet run --project src/dotnet -- --help

# Both (unified build script)
.\build.ps1 all

See docs/src-node.md, docs/src-dotnet.md, and docs/src-tests.md.

License

MIT — see LICENSE

About

Outlook CLI took for Claw environments

Resources

License

Security policy

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors