This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
OutlookCLI is a .NET command-line tool for managing Outlook emails and calendar events via local Outlook COM Interop. It is designed to be AI-agent friendly with JSON output by default.
- .NET 8+ - Target framework (Windows only)
- Late-binding COM Interop - No PIAs required, uses
dynamicfor Outlook automation - System.CommandLine - CLI argument parsing and command structure
- No Azure app registration required
- No admin consent needed
- Uses existing Outlook credentials/session
- Full offline access to cached mail
- Tradeoff: Windows-only, requires Outlook installed
Uses late-binding COM interop (no PIAs required), which avoids assembly version conflicts:
var outlookType = Type.GetTypeFromProgID("Outlook.Application");
dynamic app = Activator.CreateInstance(outlookType);
dynamic ns = app.GetNamespace("MAPI");
try
{
// work with Outlook objects using dynamic
}
finally
{
Marshal.ReleaseComObject(ns);
Marshal.ReleaseComObject(app);
}Key folder constants (OlDefaultFolders values):
olFolderInbox = 6olFolderCalendar = 9olFolderSentMail = 5olFolderDrafts = 16olFolderDeletedItems = 3olFolderContacts = 10
Item class constants (for type checking):
olMail = 43olAppointment = 26
| Option | Description |
|---|---|
--human / -H |
Human-readable output instead of JSON |
--no-confirm |
Skip confirmation dialogs for destructive actions |
--full |
Include full details (e.g., mail body) in list operations |
# List and read
outlook mail folders # List available mail folders
outlook mail list [--folder <name>] [--unread] [--limit <n>] [--full]
outlook mail read <entry-id> # Read specific email
outlook mail open <entry-id> # Open email in Outlook GUI
outlook mail search --query <text> [--from <email>] [--after <date>] [--before <date>] [--folder <name>]
# Send and draft
outlook mail send --to <emails> [--cc <emails>] --subject <text> [--body <text>] [--body-file <path>] [--html] [--signature-file <path>] [--attachment <files>]
outlook mail draft --to <emails> --subject <text> [--body <text>] [--html] [--signature-file <path>] [--attachment <files>]
# Reply, forward, and conversation
outlook mail reply <entry-id> --body <text> [--reply-all] [--draft] [--html] [--signature-file <path>]
outlook mail forward <entry-id> --to <emails> [--body <text>] [--draft] [--html] [--signature-file <path>]
outlook mail conversation <entry-id> [--limit <n>] # Get all emails in same thread
# Organize
outlook mail delete <entry-id> [--no-confirm] # Moves to Deleted Items
outlook mail move <entry-id> --to-folder <name>
outlook mail mark-read <entry-id> # Mark as read
outlook mail mark-unread <entry-id> # Mark as unread
outlook mail categorize <entry-id> --list # Show categories
outlook mail categorize <entry-id> --add <name> # Add a category
outlook mail categorize <entry-id> --remove <name> # Remove a category
outlook mail categorize <entry-id> --set <names> # Replace all categories
outlook mail categorize <entry-id> --clear # Remove all categories
# Attachments and signatures
outlook mail save-attachments <entry-id> [--output <dir>]
outlook mail extract-signature <entry-id> [--output <file>]outlook calendar list [--start <date>] [--end <date>] [--limit <n>] [--full]
outlook calendar get <entry-id>
outlook calendar open <entry-id> # Open event in Outlook GUI
outlook calendar create --subject <text> --start <datetime> --end <datetime> [--location <text>] [--body <text>] [--all-day]
outlook calendar update <entry-id> [--subject <text>] [--start <datetime>] [--end <datetime>] [--location <text>] [--body <text>]
outlook calendar delete <entry-id> [--no-confirm]
outlook calendar respond <entry-id> --accept|--decline|--tentative [--message <text>]
# Availability
outlook calendar free-busy --email <email> [--start <date>] [--end <date>]
outlook calendar find-slots --emails "a@co.com,b@co.com" [--start <date>] [--end <date>] [--duration <min>] [--include-self]# List unread emails
outlook mail list --unread --limit 10
# Mark as read after processing
outlook mail mark-read <entry-id># Extract signature once from a sent email
outlook mail extract-signature <sent-email-id> --output signature.html
# Send emails with signature
outlook mail send --to user@example.com --subject "Hello" --body "<p>Message</p>" --html --signature-file signature.htmloutlook mail draft --to user@example.com --subject "Review needed" --body "Draft content" --attachment report.pdfoutlook calendar respond <meeting-id> --accept --message "Looking forward to it!"outlook mail save-attachments <entry-id> --output ./downloadsdotnet build
dotnet run --project src/OutlookCLI -- <command> [options]
dotnet test
dotnet publish -c Release -r win-x64 # Framework-dependent (~1 MB, requires .NET 8 Runtime)
dotnet publish -c Release -r win-x64 --self-contained # Self-contained (~150 MB, no runtime needed)Releases are automated via GitHub Actions (.github/workflows/release.yml).
git tag v1.0.0
git push origin v1.0.0The workflow will:
- Build and test on
windows-latest - Publish a framework-dependent single-file exe (requires .NET 8 Runtime on user's machine)
- Zip it as
OutlookCLI-<version>-win-x64.zip - Create a GitHub Release with auto-generated release notes and the zip attached
.github/workflows/ci.ymlruns build + test on every push tomainand on PRs
master- stable releases, CI runs heredev- active development branch
All commands return consistent JSON structure:
{
"success": true,
"command": "mail list",
"data": [...],
"error": null,
"metadata": {
"count": 10,
"timestamp": "2024-01-15T10:30:00Z"
}
}Human-readable formatted output for terminal use.
- Confirmation Guard: Destructive actions (delete) show a console prompt
[y/N]unless--no-confirmis set - Deleted Items Protection: Cannot delete items already in Deleted Items folder (returns
DELETED_ITEMS_PROTECTEDerror)
- Outlook must be installed and configured on the machine
- The CLI will use whatever account is active in Outlook
- If Outlook prompts for security (accessing address book, sending mail), consider running Outlook as admin or adjusting Trust Center settings
- Signature extraction looks for
<div id="Signature">or common greeting patterns