outlook-mcp
This server enables controlling the Microsoft Outlook desktop app via COM automation — managing emails, calendar events, and contacts without needing a cloud API or Azure registration. Requires Windows with the classic Outlook desktop app (not the new Outlook).
Email – Read & Search
List all mail folders across every account/store
List recent emails (with optional unread-only filter) and read full email content by EntryID
Search emails by subject, sender, body, or all fields
List and save attachments to a local directory
Email – Write & Management
Send new emails (with CC/BCC, HTML body, file attachments, or scheduled delivery) or save as draft
Reply, reply-all, or forward emails, optionally saving as draft
Manage drafts (list, update, send, delete)
Mark emails as read/unread, move to folders, or delete
Calendar & Scheduling
List, search, and retrieve full details of calendar events
Create appointments, meeting invites, Teams meetings, and recurring meetings
Update or cancel events (single occurrences or full series)
Check attendee availability and find common free meeting times
Schedule Out-of-Office status on the calendar
Read shared calendars
Meeting Invitations
List pending meeting invitations and respond (accept/tentative/decline)
Contacts & Accounts
List and search contacts by name, email, or company
List all configured sending accounts and mail stores
Other
Recipient validation (resolves names, rejects ambiguous ones unless overridden)
Explicit timezone handling for meeting creation
Outlook health diagnostics
Items addressed by Outlook EntryID; folders referenced by name (e.g.
Inbox) or slash path (e.g.Inbox/Receipts)
Note: Cannot directly set automatic email replies (auto-responder); Teams meeting link injection depends on Outlook settings.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@outlook-mcp Show my unread emails"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Outlook MCP Server (win32com)
An MCP server that controls the Microsoft Outlook desktop app through COM
automation (win32com). It does not use Microsoft Graph — there is no
Azure app registration, no OAuth, no API keys. It operates on whatever
account(s) your local Outlook client is already signed into, which makes it
ideal for corporate environments where Graph API access is locked down.
Requirements
Windows (COM automation is Windows-only)
Classic Outlook desktop installed and configured with an account. The "new Outlook" (the web-based rewrite) does not expose the COM object model and will not work — switch the toggle back to classic Outlook.
Python 3.10+
Related MCP server: outlook-classic-mcp
Installation
git clone <this-repo>
cd outlook_mcp
pip install -e .This installs mcp and pywin32 and registers the outlook-mcp command.
Configure Claude Desktop / Claude Code
Claude Desktop (%APPDATA%\Claude\claude_desktop_config.json):
{
"mcpServers": {
"outlook": {
"command": "outlook-mcp"
}
}
}Claude Code:
claude mcp add outlook -- outlook-mcpIf Outlook is not running, the first tool call starts it automatically.
Tools
Mail — read & search
Tool | Description |
| Tree of all mail folders across every account/store |
| Recent emails in a folder (newest first, optional unread-only) |
| Full email by |
| Filtered search: text, sender/recipient, date range, unread/flagged/importance/attachments, across all folders or subfolders |
| List an email's attachments (index, size, inline vs. real, MIME) |
| Save attachments safely (sanitized names, no collisions, size limit, SHA-256) |
Mail — write, drafts & management
Tool | Description |
| Send/draft — HTML, attachments, importance/sensitivity/categories, send-as/on-behalf, scheduled delivery, read receipt |
| Reply / reply-all — HTML, attachments |
| Forward — CC/BCC, validated recipients, attachments |
| List messages in the Drafts folder |
| Edit a saved draft (subject/body/recipients/attachments) |
| Send an existing draft (re-validates recipients) |
| Delete a draft |
| Remove one attachment from a draft/item |
| Mark read / unread |
| Move an email to another folder |
| Move an email to Deleted Items |
Calendar & scheduling
Tool | Description |
| Events in a window around today (recurrences expanded) |
| Full event details — attendees + responses, recurrence, join links, categories |
| Filter events by subject/organizer/location/category/Teams/recurring/attachments |
| Create an appointment or send a meeting invite (timezone-aware) |
| Send a meeting invite (Teams link via org setting, see below) |
| Send a recurring series (daily/weekly/monthly/yearly, timezone-aware) |
| Update a whole event/series; add/remove attendees, optionally re-invite |
| Edit one occurrence of a recurring series |
| Cancel a meeting you organize (notifies attendees) |
| Cancel one occurrence of a series |
| Delete an event with no notice |
| Show attendees' free/busy timeline for a day |
| Find slots when all attendees are free, across a date range |
| Block your calendar with Out-of-Office status |
| Guidance only — auto-replies aren't COM-settable (see below) |
Meeting invitations, contacts & accounts
Tool | Description |
| Meeting requests in your Inbox — response state + calendar conflicts |
| Accept / tentative / decline an invitation |
| Read another person's calendar (if shared to you) |
| List/search the default Contacts folder |
| List sending accounts and mail stores in the profile |
| Diagnostics: Outlook version, user, store, connection mode |
Emails and events are addressed by their Outlook EntryID, which the list/
search tools return — pass it to get_email, reply_to_email,
update_calendar_event, etc. Folders accept well-known names (Inbox,
Sent Items, Drafts, ...) or slash paths like Inbox/Receipts or
you@company.com/Inbox to target a specific account.
Example prompts
"Show my unread emails"
"Search my inbox for emails from Alice about the Q3 budget"
"Reply to that email saying I'll review it by Friday"
"Save the attachments from that email to C:\Users\me\Downloads"
"What's on my calendar this week?"
"Check if alice@corp.com and bob@corp.com are free Thursday afternoon"
"Find a 30-minute slot next Monday when the whole team is available"
"Set up a 30-minute meeting with bob@example.com tomorrow at 2pm"
"Mark me out of office next Friday through the following Wednesday"
Time zones (recommended for meetings)
The meeting-creation tools (create_calendar_event, create_teams_meeting,
create_recurring_meeting) accept an optional timezone_name. Give it an IANA
name (Asia/Kolkata), a Windows ID (India Standard Time), or a common
abbreviation (IST). The start time you pass is treated as wall-clock time in
that zone, and the result reports both the local and UTC times.
This matters most for recurring meetings: without an explicit zone, a
series pinned to "12:00" can shift by an hour when it crosses a daylight-saving
boundary, because Outlook interprets the time in whatever zone the profile
happens to be in. Passing timezone_name sets the appointment's
StartTimeZone/EndTimeZone in COM so occurrences stay put. (Note: on Windows,
Python needs the tzdata package for this — it's declared as a dependency.)
Recipient validation
send_email (and the meeting tools) add each recipient individually and call
ResolveAll() before sending. If any name is ambiguous or unknown, the send is
rejected with the offending entries listed — pass allow_unresolved=True
to override. Results list every recipient's canonical SMTP address (Exchange
EX addresses are resolved to real SMTP), so you can confirm exactly who will
receive the message before trusting it.
Development & tests
pip install -e ".[dev]"
pytestThe pure-logic layer (date/timezone parsing, DST conversion, recurrence, recipient resolution) is covered by mock-based tests that run on any platform — no Windows or Outlook required. COM interaction itself can only be exercised on Windows. CI runs the suite on Python 3.10–3.12.
Checking other people's availability
check_availability and find_meeting_times read free/busy data — the
same busy/free blocks Outlook shows in the Scheduling Assistant. In most
Exchange/Microsoft 365 organizations every user can see everyone else's
free/busy by default (busy times only, not the meeting subjects), so no
special mailbox permissions are needed. If a person has restricted their
free/busy sharing, their slots come back as unavailable and the tools say so.
Teams meetings and invitations
Responding to invites works fully.
list_meeting_invitationsshows pending requests in your Inbox;respond_to_invitationaccepts, tentatively accepts, or declines them (with an optional note, and an option to respond without notifying the organizer).Reading others' meetings (
list_shared_calendar) works when that person has shared their calendar with you at Reviewer permission or higher. It shows real subjects/times, unlikecheck_availability, which shows only free/busy.Creating a Teams meeting is partial. COM cannot inject a Teams join link — the link is produced by the Teams Meeting Add-in/service, not the Outlook Object Model.
create_teams_meetingsends the invite and relies on the mailbox setting File > Options > Calendar > "Add online meeting to all meetings"; with that ON, sent meetings automatically become Teams meetings. With it OFF, an ordinary meeting invite is sent and you'd add the Teams link manually."Propose new time" is not available via COM. The Object Model has no propose-new-time method. To suggest another slot, decline with a message (or use
find_meeting_timesto pick a slot and send a fresh invite).Recurring meetings are supported.
create_recurring_meetingsends a full series — daily, weekly (with specific weekdays likeMon,Wed,Fri), monthly, or yearly, with aninterval(e.g. every 2 weeks) and an end defined by a number of occurrences (count) or an end date (until). Attendees receive the series and accept it as a series. Recurring invites you receive are accepted/declined as a whole series byrespond_to_invitation.
Out of office: what works and what doesn't
schedule_out_of_officeworks — it creates a calendar block with "Out of Office" availability status, so you show as away in other people's free/busy and Scheduling Assistant.Automatic replies (the auto-responder email) cannot be set via COM. The Outlook Object Model simply does not expose Out-of-Office reply settings.
set_automatic_repliestherefore only returns guidance. To turn on the auto-responder, either flip it on manually (File > Automatic Replies) or use Exchange Web Services (SetUserOofSettings) / Microsoft Graph (mailboxSettings.automaticRepliesSetting) — both of which are outside COM.
Notes & troubleshooting
Security prompts: depending on your organization's policy, Outlook may show an "Allow access?" dialog when a program reads addresses or sends mail programmatically. Your admin controls this via Group Policy ("Programmatic Access" settings in Trust Center).
"New Outlook" toggle: if tool calls fail with "class not registered" or Outlook opens but nothing happens, you are likely on new Outlook. Switch back to classic Outlook.
Bitness/permissions: run the MCP server as the same user (and not elevated differently) as Outlook, or COM will refuse to connect to the running instance.
Available Tools
14 toolscreate_calendar_eventA
Create a calendar event, optionally sending invites to attendees.
Args: subject: Event title. start: Start time as "YYYY-MM-DD HH:MM". duration_minutes: Length of the event in minutes. location: Optional location. body: Optional description. attendees: Optional semicolon-separated attendee addresses; if given, the event is sent as a meeting invitation.
Inputs: start (required), subject (required), body, location, +2 more. Returns: result
delete_emailC
Delete an email (moves it to Deleted Items).
Inputs: entry_id (required). Returns: result
forward_emailA
Forward an email (attachments included).
Args: entry_id: EntryID of the email to forward. to: Recipient address(es), semicolon-separated. comment: Optional text placed above the forwarded message. save_as_draft: Save to Drafts instead of sending.
Inputs: to (required), entry_id (required), comment, save_as_draft. Returns: result
get_emailA
Read a full email by its entry_id (from list_emails/search_emails).
Args: entry_id: The Outlook EntryID of the email. body_max_chars: Truncate the body after this many characters.
Inputs: entry_id (required), body_max_chars. Returns: result
list_calendar_eventsA
List calendar events in a date window around today.
Args: days_ahead: How many days into the future to include. days_back: How many days into the past to include.
Inputs: days_back, days_ahead. Returns: result
list_contactsB
List contacts from the default Contacts folder, optionally filtered.
Args: search: Optional substring to match against name/email/company. count: Maximum contacts to return (1-200).
Inputs: count, search. Returns: result
list_emailsA
List recent emails in a folder, newest first.
Args: folder: Folder name or path, e.g. "Inbox", "Sent Items", "Inbox/Receipts". count: Maximum number of emails to return (1-100). unread_only: Only return unread emails.
Inputs: count, folder, unread_only. Returns: result
list_foldersA
List all mail folders across every account/store in Outlook.
Inputs: no named parameters. Returns: result
mark_emailB
Mark an email as read or unread.
Inputs: entry_id (required), read. Returns: result
move_emailB
Move an email to another folder.
Args: entry_id: EntryID of the email to move. target_folder: Destination folder name or path.
Inputs: entry_id (required), target_folder (required). Returns: result
reply_to_emailA
Reply to an email. The original message is quoted below your reply.
Args: entry_id: EntryID of the email to reply to. body: Your reply text. reply_all: Reply to all recipients instead of just the sender. save_as_draft: Save to Drafts instead of sending.
Inputs: body (required), entry_id (required), reply_all, save_as_draft. Returns: result
save_attachmentsA
Save all attachments of an email to a local directory.
Args: entry_id: The email's EntryID. save_dir: Directory to save into (created if missing).
Inputs: entry_id (required), save_dir (required). Returns: result
search_emailsA
Search emails in a folder by subject, sender, or body text.
Args: query: Text to search for. folder: Folder to search in. count: Maximum results (1-100). search_in: One of "subject", "from", "body", "all".
Inputs: query (required), count, folder, search_in. Returns: result
send_emailA
Send a new email (or save it as a draft) through Outlook.
Args: to: Recipient address(es), separated by semicolons. subject: Email subject. body: Email body text (or HTML if html=True). cc: CC address(es), semicolon-separated. bcc: BCC address(es), semicolon-separated. html: Treat body as HTML. attachments: Absolute paths of files to attach. save_as_draft: Save to Drafts instead of sending.
Inputs: to (required), body (required), subject (required), cc, +4 more. Returns: result
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 14 tools
Each tool targets a distinct operation (email, calendar, contacts, folders) with clear boundaries. There is no overlap; for example, 'send_email' and 'reply_to_email' are distinct actions, and 'list_emails' and 'search_emails' serve different purposes.
All tools follow a consistent verb_noun pattern (e.g., create_calendar_event, delete_email, list_folders). The naming is uniform and predictable, making it easy for an agent to infer the action from the name.
With 14 tools, the set is well-scoped for an Outlook integration covering emails, calendar, contacts, and folders. It provides sufficient functionality without being overwhelming or too sparse.
Email operations are comprehensive (CRUD, search, forward, reply, mark, move, save attachments). However, calendar and contacts are limited: calendar only has create and list (missing update/delete), contacts only have list. This leaves minor but notable gaps.
Related MCP Connectors
Manage Microsoft 365 email, calendar, contacts and inbox rules via the Graph API with OAuth 2.0.
Hosted email MCP for your own Gmail, Outlook.com, Microsoft 365, iCloud or IMAP inbox: read, search, draft, reply in thread, forward and file mail. It moves or flags up to 500 messages in one call, and a send leaves exactly one copy in Sent. A calendar is a separate connection, and connecting one adds diary and scheduling tools.
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Search Gmail and Outlook, save drafts, manage email rules, and view email stats.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Microsoft Outlook emails, calendar events, contacts, and folders via COM automation.1MIT
- AlicenseNot gradedqualityBmaintenanceEnables MCP-aware agents to interact with the classic Outlook desktop client for mail, calendar, contacts, tasks, and Out-of-Office settings via the COM API, without Azure or OAuth.954 PyPI39MIT
- FlicenseNot gradedqualityCmaintenanceReads and searches your local Microsoft Outlook desktop mailbox via COM, supporting folder listing, message/thread retrieval, attachment saving, bulk export, and draft creation without sending, requiring no OAuth or admin consent.-
- FlicenseAqualityCmaintenanceEnables local automation of classic Outlook for Windows via COM, allowing email search, folder listing, calendar leave block creation, and contact/recipient management without needing cloud APIs or admin approval.8-