Local CLI bridge for Outlook Classic automation on Windows via COM. Includes a Claude Code Skill for AI-assisted email and calendar management.
TL;DR: Can't access Exchange via Microsoft Graph API? No problem. Control Outlook directly through COM automation on your Windows workstation. Let Claude help manage your email and calendar - no API keys, no OAuth, just your existing Outlook session.
outlookctl is a local automation tool that controls the Outlook desktop client already running on your Windows workstation. It:
- Uses your existing Outlook session - No separate authentication, API keys, or OAuth tokens
- Operates entirely locally - No network calls to external services, no cloud dependencies
- Controls the desktop client via COM - Same automation interface used by VBA macros and Office add-ins
- Respects your security context - Runs with your existing permissions, subject to Outlook's security settings
This is not a workaround or bypass - it's the standard Windows COM automation interface that Microsoft provides for programmatic Outlook access. The same technology powers countless enterprise tools, email archivers, and Office integrations.
- AI-assisted email triage - Let Claude help summarize and categorize your inbox
- Automated drafting - Generate draft responses with AI assistance, review before sending
- Email search and retrieval - Find specific messages across your mailbox
- Attachment management - Bulk save attachments to disk
- View upcoming meetings - List events across date ranges
- Create meetings - Schedule meetings with attendees (draft-first workflow)
- Respond to invitations - Accept, decline, or tentatively accept meeting requests
- Shared calendars - Access colleagues' calendars (with permissions)
Full documentation is available at gmickel.github.io/outlookctl:
- CLI Reference - Complete command reference
- JSON Schema - Output format documentation
- Security & Data Handling - Security model and best practices
- Troubleshooting - Common issues and solutions
- Windows workstation with Classic Outlook (not "New Outlook")
- Outlook running and logged into your account
- Python 3.12+ and uv
git clone https://github.com/gmickel/outlookctl.git
cd outlookctl
uv syncuv run python -m outlookctl.cli doctorAll checks should pass. If not, see Troubleshooting.
# List recent emails
uv run python -m outlookctl.cli list --count 5
# Search emails
uv run python -m outlookctl.cli search --from "[email protected]" --since 2025-01-01
# Create a draft email
uv run python -m outlookctl.cli draft --to "[email protected]" --subject "Test" --body-text "Hello"
# List upcoming calendar events (next 7 days)
uv run python -m outlookctl.cli calendar list
# Create a calendar event
uv run python -m outlookctl.cli calendar create --subject "Focus Time" --start "2025-01-20 14:00" --duration 60| Command | Description |
|---|---|
doctor |
Validate environment and prerequisites |
list |
List messages from a folder |
get |
Get a single message by ID |
search |
Search messages with filters |
draft |
Create a draft message |
send |
Send a draft or new message |
move |
Move message to another folder |
delete |
Delete a message |
mark-read |
Mark message as read/unread |
forward |
Create a forward draft |
attachments save |
Save attachments to disk |
| Command | Description |
|---|---|
calendar list |
List events in a date range |
calendar get |
Get event details by ID |
calendar create |
Create an event or meeting |
calendar send |
Send meeting invitations |
calendar respond |
Accept/decline/tentative response |
calendar update |
Update an existing event |
calendar delete |
Delete/cancel an event |
See CLI Reference for full documentation.
The skill enables AI assistants (Claude Code, OpenAI Codex, or VS Code) to assist with email and calendar operations safely.
Note: Agent Skills support in VS Code is currently in preview and only available in VS Code Insiders. Enable the
chat.useAgentSkillssetting to use Agent Skills.
uv run python tools/install_skill.py --personalInstalls to: ~/.claude/skills/outlook-automation/
uv run python tools/install_skill.py --projectInstalls to: .claude/skills/outlook-automation/
uv run python tools/install_skill.py --codexInstalls to: ~/.codex/skills/outlook-automation/
Note: Codex skills require the experimental
skillsfeature flag. Add[features]\nskills = trueto~/.codex/config.tomland restart Codex.
uv run python tools/install_skill.py --verify --personal # Claude Code
uv run python tools/install_skill.py --verify --codex # OpenAI Codexoutlookctl is designed with safety as a priority:
- Draft-First Workflow - Create drafts/meetings, review, then send
- Explicit Confirmation - Sending emails/meeting invites requires
--confirm-send YES - Metadata by Default - Body content only retrieved on explicit request
- Audit Logging - Send operations logged to
%LOCALAPPDATA%/outlookctl/audit.log
# 1. Create draft
uv run python -m outlookctl.cli draft \
--to "[email protected]" \
--subject "Project Update" \
--body-text "Here is the update..."
# 2. Review the draft in Outlook or via CLI
# 3. Send with explicit confirmation
uv run python -m outlookctl.cli send \
--draft-id "<entry_id from step 1>" \
--draft-store "<store_id from step 1>" \
--confirm-send YESAll commands output JSON:
{
"version": "1.0",
"folder": {"name": "Inbox"},
"items": [
{
"id": {"entry_id": "...", "store_id": "..."},
"subject": "Meeting Tomorrow",
"from": {"name": "Jane", "email": "[email protected]"},
"unread": true,
"has_attachments": false
}
]
}See JSON Schema for details.
outlookctl/
├── pyproject.toml # Project configuration (uv/hatch)
├── README.md # This file
├── CLAUDE.md # Development guide for AI assistants
├── src/outlookctl/ # Python package
│ ├── __init__.py
│ ├── cli.py # CLI entry point (argparse)
│ ├── models.py # Dataclasses for JSON output
│ ├── outlook_com.py # COM automation wrapper
│ ├── safety.py # Send confirmation gates
│ └── audit.py # Audit logging
├── skills/
│ └── outlook-automation/
│ ├── SKILL.md # Claude Code Skill definition
│ └── reference/ # Skill documentation
│ ├── cli.md
│ ├── json-schema.md
│ ├── security.md
│ └── troubleshooting.md
├── tools/
│ └── install_skill.py # Skill installer
├── tests/ # pytest test suite
│ ├── test_models.py
│ ├── test_calendar_models.py
│ └── test_safety.py
└── evals/ # Skill evaluation scenarios
├── eval_summarize.md
├── eval_draft_reply.md
└── eval_refuse_send.md
- Python 3.12+
- uv package manager
- Windows with Classic Outlook
uv syncuv run python -m pytest tests/ -vuv run python -m outlookctl.cli <command> [options]uv run python tools/install_skill.py --personalWindows COM (Component Object Model) is Microsoft's standard interface for inter-process communication. Outlook exposes its functionality through the Outlook.Application COM object, which:
- Is the same interface used by VBA macros inside Outlook
- Is how enterprise tools integrate with Outlook
- Runs in the security context of the logged-in user
- Is subject to Outlook's Trust Center settings
Classic Outlook (the traditional desktop app) supports COM automation.
New Outlook (the modern, web-based app) does not support COM automation - it requires Microsoft Graph API with OAuth authentication.
This tool only works with Classic Outlook. Check which version you have:
- Classic: Has File menu, Trust Center settings
- New: Toggle at top-right says "New Outlook"
- No API keys or tokens stored
- No network calls to external services
- Uses Windows authentication (your logged-in session)
- Outlook may show security prompts for programmatic access
- All operations logged locally for audit
- Classic Outlook Only - New Outlook requires Microsoft Graph API
- Windows Only - COM is a Windows technology
- Same Session - Must run in same Windows session as Outlook
- Security Prompts - Outlook may show security dialogs
| Issue | Solution |
|---|---|
| "Outlook COM unavailable" | Start Classic Outlook (not New Outlook) |
| "pywin32 not installed" | Run uv sync |
| "Message not found" | IDs expire; re-run list/search |
| Permission denied on CLI | Use uv run python -m outlookctl.cli instead |
See Troubleshooting Guide for more.
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Run tests (
uv run python -m pytest tests/ -v) - Commit (
git commit -m 'Add amazing feature') - Push (
git push origin feature/amazing-feature) - Open a Pull Request
MIT License - see LICENSE for details.
- Built for use with Claude Code
- Powered by pywin32 for COM automation
- Package management via uv