CCM
/MCP
SkillsMCPMarketplacesDigestToolsAdvertise

This week in Claude

Every Monday: Claude Code, Agent SDK, MCP, and the Anthropic platform moves worth your time.

Skills by Category
Frontend DevelopmentBackend & APIsTesting & QASecurityDevOps & CI/CDGit & Pull RequestsDocumentationCode Review & QualityAI & Agent BuildingSkill Development
MCP Servers by Category
Sales & MarketingWeb & Browser AutomationDatabasesAI & LLM ToolsCloud & InfrastructureCommunication & MessagingDeveloper ToolsDesign & CreativeDocuments & KnowledgeSearch & Web Crawling
Marketplaces by Category
AI Agents & OrchestrationLLM IntegrationDevelopment ToolsFrontend & UIBackend & APIsDatabasesTesting & Code QualityDevOps & CloudSecurity & ComplianceGit & Version Control

Claude Code Marketplaces

Discover Claude Code plugins, extensions, and tools. Automatically updated directory of Anthropic Claude AI marketplaces with development tools, productivity plugins, and integrations.

Resources

  • Browse Skills
  • Browse MCP Servers
  • Browse Marketplaces
  • Skill index
  • MCP index
  • Marketplace index
  • Plugins Reference

Community

  • About
  • Tools
  • Feedback
  • Privacy Policy
  • Advertise

Built for the Claude Code community with Claude Code by mertbuilds.com

Independent project, not affiliated with Anthropic
mpalermiti avatar

Outlook MCP

mpalermiti/outlook-mcp
1551 toolsSTDIOregistry active
Summary

A comprehensive personal Outlook integration via Microsoft Graph API with 62 tools spanning mail, calendar, contacts, to-do lists, and drafts. Supports all the operations you'd expect: reading and searching messages, managing Focused Inbox classification, sending and replying to mail, creating calendar events with recurring expansion, CRUD on contacts and tasks, plus batch operations and attachment handling including large file upload sessions. Designed for personal Microsoft accounts only (Outlook.com, Hotmail, Live), not Entra ID work accounts. You bring your own Azure app registration, tokens live in your OS keyring, and there's optional read-only mode plus granular category permissions. Built for agent builders who need typed MCP tool schemas instead of parsing CLI stdout.

CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →

Tools

Public tool metadata for what this MCP can expose to an agent.

51 tools
OUTLOOK_ADD_EVENT_ATTACHMENTAdds an attachment to a specific Outlook calendar event. Use when you need to attach a file or nested item to an existing event.6 params

Adds an attachment to a specific Outlook calendar event. Use when you need to attach a file or nested item to an existing event.

Parameters* required
contentBytesstring
Base64-encoded file contents; required when '@odata.type' is fileAttachment.
event_idstring
The unique identifier of the calendar event to which the attachment will be added.
itemobject
The nested item payload; required when '@odata.type' is itemAttachment.
namestring
The display name of the attachment.
odata_typestring
Attachment type: '#microsoft.graph.fileAttachment' requires 'contentBytes'; '#microsoft.graph.itemAttachment' requires 'item'.one of #microsoft.graph.fileAttachment · #microsoft.graph.itemAttachment
user_idstring
The user's email address or 'me' for the authenticated user.default: me
OUTLOOK_ADD_MAIL_ATTACHMENTTool to add an attachment to an email message. Use when you have a message ID and need to attach a small (<3 MB) file or reference.10 params

Tool to add an attachment to an email message. Use when you have a message ID and need to attach a small (<3 MB) file or reference.

Parameters* required
contentBytesstring
Base64-encoded content of the file attachment (max size 3 MB).
contentIdstring
Content ID for inline attachments, used in HTML body references.
contentLocationstring
URL location or path for reference attachments.
contentTypestring
MIME type of the attachment (e.g., 'application/pdf').
isInlineboolean
Set to true if the attachment should appear inline in the message body.
itemobject
Embedded item (e.g., message, event) for itemAttachment; must include its own '@odata.type'.
message_idstring
Unique identifier of the email message to attach to.
namestring
Display name of the attachment (e.g., file name).
odata_typestring
The OData type of the attachment. For file attachments, use '#microsoft.graph.fileAttachment'.
user_idstring
The user's principal name or 'me' for the authenticated user.default: me
OUTLOOK_CALENDAR_CREATE_EVENTCreates a new Outlook calendar event, ensuring `start_datetime` is chronologically before `end_datetime`.13 params

Creates a new Outlook calendar event, ensuring `start_datetime` is chronologically before `end_datetime`.

Parameters* required
attendees_infoarray
A list of attendees for the event. Each attendee object requires an 'email'. 'name' and 'type' ('required', 'optional', 'resource') are optional.
bodystring
The body of the event. This can be in plain text or HTML format, as specified by the 'is_html' field.
categoriesarray
A list of categories associated with the event. These categories must already exist in the user's mailbox.
end_datetimestring
The end date and time of the event in ISO 8601 format. Time zone is specified in 'time_zone'.
is_htmlboolean
Specifies whether the 'body' content is HTML. Set to true for HTML content; otherwise, it's treated as plain text.default: false
is_online_meetingboolean
Set to true to indicate that the event is an online meeting. This will automatically generate an online meeting link if 'online_meeting_provider' is set (e.g., a Microsoft Teams link).default: false
locationstring
The physical location of the event.default:
online_meeting_providerstring
Specifies the online meeting provider. Currently, only 'teamsForBusiness' is supported. If 'is_online_meeting' is true and this is set, a meeting link for the provider will be created.
show_asstring
The status to show on the calendar for the duration of the event. Valid values are: 'free', 'tentative', 'busy', 'oof' (out of office), 'workingElsewhere', 'unknown'.default: busy
start_datetimestring
The start date and time of the event in ISO 8601 format. Time zone is specified in 'time_zone'.
subjectstring
The subject of the calendar event.
time_zonestring
The time zone for the start and end times of the event. Uses Windows time zone names (e.g., 'Pacific Standard Time') or IANA time zone names (e.g., 'America/Los_Angeles'). UTC is also a valid input.
user_idstring
The UPN (User Principal Name) or object ID of the user whose calendar the event will be created in. Use 'me' for the currently authenticated user.default: me
OUTLOOK_CREATE_ATTACHMENT_UPLOAD_SESSIONTool to create an upload session for large (>3 MB) message attachments. Use when you need to upload attachments in chunks.3 params

Tool to create an upload session for large (>3 MB) message attachments. Use when you need to upload attachments in chunks.

Parameters* required
attachmentItemobject
AttachmentItem object describing the attachment in the upload session.
message_idstring
The unique identifier of the message to attach to.
user_idstring
User ID or user principal name; use 'me' for the signed-in user.default: me
OUTLOOK_CREATE_CALENDARTool to create a new calendar in the signed-in user's mailbox. Use when organizing events into a separate calendar.4 params

Tool to create a new calendar in the signed-in user's mailbox. Use when organizing events into a separate calendar.

Parameters* required
colorstring
The theme color to assign to the calendar. Supported values: auto, lightBlue, lightGreen, lightOrange, lightGray, lightYellow, lightTeal, lightPink, lightBrown, lightPurple, lightRed.one of auto · lightBlue · lightGreen · lightOrange · lightGray · lightYellow
hexColorstring
An optional hexadecimal color code for the calendar in the format '#RRGGBB'.
namestring
The display name of the new calendar.
user_idstring
The UPN (User Principal Name) or object ID of the user where the calendar will be created. Use 'me' for the signed-in user.default: me
OUTLOOK_CREATE_CONTACTCreates a new contact in a Microsoft Outlook user's contacts folder.15 params

Creates a new contact in a Microsoft Outlook user's contacts folder.

Parameters* required
birthdaystring
The contact's birthday in 'YYYY-MM-DD' format. The time component will be set to midnight UTC (e.g., '1990-01-01' becomes '1990-01-01T00:00:00Z' in the API request).default:
businessPhonesarray
A list of business phone numbers for the contact. Each number should be a string.
categoriesarray
A list of categories to assign to the contact.
companyNamestring
The name of the company the contact is associated with.default:
departmentstring
The department the contact belongs to within their company.default:
displayNamestring
The contact's display name, typically their full name.default:
emailAddressesarray
A list of email addresses for the contact.
givenNamestring
The contact's given (first) name.default:
homePhonestring
The contact's home phone number. If provided, this will be stored in Outlook as a list containing this single number.default:
jobTitlestring
The contact's job title.default:
mobilePhonestring
The contact's mobile phone number.default:
notesstring
Personal notes about the contact. These notes are stored as 'personalNotes' in the Outlook contact details.default:
officeLocationstring
The contact's office location.default:
surnamestring
The contact's surname (last name).default:
user_idstring
Identifier for the user whose contact list will be modified. Use 'me' for the authenticated user, or provide the user's principal name (e.g., 'user@example.com').default: me
OUTLOOK_CREATE_CONTACT_FOLDERTool to create a new contact folder in the user's mailbox. Use when needing to organize contacts into custom folders.3 params

Tool to create a new contact folder in the user's mailbox. Use when needing to organize contacts into custom folders.

Parameters* required
displayNamestring
The display name of the new contact folder.
parentFolderIdstring
The ID of the parent contact folder. If omitted, created under the default contacts folder.
user_idstring
The user's principal name or object ID. Use 'me' for the authenticated user.default: me
OUTLOOK_CREATE_DRAFTCreates an Outlook email draft with subject, body, recipients, and an optional attachment. Supports creating drafts as part of existing conversation threads by specifying a conversationId; attachments require a name, mimetype, and content.8 params

Creates an Outlook email draft with subject, body, recipients, and an optional attachment. Supports creating drafts as part of existing conversation threads by specifying a conversationId; attachments require a name, mimetype, and content.

Parameters* required
attachmentstring
Optional file to attach. If provided, must include the file's content, name, and mimetype.
bcc_recipientsarray
Optional list of BCC (blind carbon copy) recipient email addresses.
bodystring
Content of the email draft; use `is_html` to specify if HTML or plain text.
cc_recipientsarray
Optional list of CC (carbon copy) recipient email addresses.
conversation_idstring
Optional conversation ID to create the draft as part of an existing email conversation thread. If provided, the draft will be part of the specified conversation instead of starting a new one.
is_htmlboolean
Specifies if the `body` is HTML. If `False`, `body` is plain text.default: false
subjectstring
Subject line for the email draft.
to_recipientsarray
List of primary 'To' recipient email addresses.
OUTLOOK_CREATE_DRAFT_REPLYCreates a draft reply in the specified user's Outlook mailbox to an existing message (identified by a valid `message_id`), optionally including a `comment` and CC/BCC recipients.5 params

Creates a draft reply in the specified user's Outlook mailbox to an existing message (identified by a valid `message_id`), optionally including a `comment` and CC/BCC recipients.

Parameters* required
bcc_emailsarray
List of email addresses to add as BCC recipients to the draft reply.
cc_emailsarray
List of email addresses to add as CC recipients to the draft reply.
commentstring
Plain text comment to include in the body of the reply draft.
message_idstring
Unique ID of the message to reply to, typically obtained from actions like 'List Messages' or 'Get Message'.
user_idstring
User's mailbox identifier (email or 'me') for the original message and new draft location.default: me
OUTLOOK_CREATE_EMAIL_RULECreate email rule filter with conditions and actions5 params

Create email rule filter with conditions and actions

Parameters* required
actionsobject
Actions to take when the rule conditions are met.
conditionsobject
Conditions that must be met for the rule to apply.
displayNamestring
Display name for the email rule.
isEnabledboolean
Whether the rule is enabled.default: true
sequenceinteger
Order in which the rule is executed (lower numbers execute first).default: 1
OUTLOOK_CREATE_MAIL_FOLDERTool to create a new mail folder. Use when you need to organize email into a new folder.3 params

Tool to create a new mail folder. Use when you need to organize email into a new folder.

Parameters* required
displayNamestring
The display name of the new mail folder.
isHiddenboolean
Indicates whether the new folder is hidden. Default is false. Once set, this property cannot be updated.default: false
user_idstring
Identifier for the user whose mailbox the folder will be created in. Use 'me' for the authenticated user or provide the user's principal name or ID.default: me
OUTLOOK_CREATE_MASTER_CATEGORYTool to create a new category in the user's master category list. Use after selecting a unique display name.2 params

Tool to create a new category in the user's master category list. Use after selecting a unique display name.

Parameters* required
colorstring
A pre-set color constant for the category. Allowed values: preset0 through preset24.one of preset0 · preset1 · preset2 · preset3 · preset4 · preset5
displayNamestring
Unique name that identifies the category in the user's mailbox.
OUTLOOK_DELETE_CONTACTPermanently deletes an existing contact, using its `contact_id` (obtainable via 'List User Contacts' or 'Get Contact'), from the Outlook contacts of the user specified by `user_id`.2 params

Permanently deletes an existing contact, using its `contact_id` (obtainable via 'List User Contacts' or 'Get Contact'), from the Outlook contacts of the user specified by `user_id`.

Parameters* required
contact_idstring
Identifier of the contact to be deleted, typically obtained from 'List User Contacts' or 'Get Contact'.
user_idstring
The UPN (User Principal Name) or ID of the user; use 'me' for the signed-in user.default: me
OUTLOOK_DELETE_EMAIL_RULEDelete an email rule1 params

Delete an email rule

Parameters* required
ruleIdstring
ID of the email rule to delete.
OUTLOOK_DELETE_EVENTDeletes an existing calendar event, identified by its unique `event_id`, from a specified user's Microsoft Outlook calendar, with an option to send cancellation notifications to attendees.3 params

Deletes an existing calendar event, identified by its unique `event_id`, from a specified user's Microsoft Outlook calendar, with an option to send cancellation notifications to attendees.

Parameters* required
event_idstring
Unique identifier of the calendar event to delete, typically obtained from event listing or retrieval actions.
send_notificationsboolean
If `True`, sends cancellation notifications to event attendees upon deletion.default: true
user_idstring
User's email address or 'me' for the current user.default: me
OUTLOOK_DELETE_MAIL_FOLDERDelete a mail folder from the user's mailbox. Use when you need to remove an existing mail folder.2 params

Delete a mail folder from the user's mailbox. Use when you need to remove an existing mail folder.

Parameters* required
folder_idstring
The unique identifier or well-known name of the mail folder to delete (e.g., folder ID or 'Drafts', 'SentItems').
user_idstring
Identifier for the user whose mailbox contains the folder to delete. Use 'me' for the authenticated user or provide the user's principal name or ID.default: me
OUTLOOK_DOWNLOAD_OUTLOOK_ATTACHMENTDownloads a specific file attachment from an email message in a Microsoft Outlook mailbox; the attachment must contain 'contentBytes' (binary data) and not be a link or embedded item.4 params

Downloads a specific file attachment from an email message in a Microsoft Outlook mailbox; the attachment must contain 'contentBytes' (binary data) and not be a link or embedded item.

Parameters* required
attachment_idstring
The unique identifier of the attachment to be downloaded. This ID is typically obtained from the message's details when an email message object is retrieved.
file_namestring
The desired filename for the downloaded attachment. This name will be assigned to the `FileDownloadable` object.
message_idstring
The unique identifier of the email message that contains the attachment to be downloaded. This ID is typically obtained when listing or retrieving messages.
user_idstring
The user's UPN (User Principal Name) or 'me' for the authenticated user. This identifies the mailbox where the message is located.default: me
OUTLOOK_GET_CALENDAR_VIEWGet events ACTIVE during a time window (includes multi-day events). Use for "what's on my calendar today/this week" or availability checks. Returns events overlapping the time range. For keyword search or filters by category, use OUTLOOK_LIST_EVENTS instead.7 params

Get events ACTIVE during a time window (includes multi-day events). Use for "what's on my calendar today/this week" or availability checks. Returns events overlapping the time range. For keyword search or filters by category, use OUTLOOK_LIST_EVENTS instead.

Parameters* required
calendar_idstring
Optional ID of a specific calendar to query. If not provided, uses the primary calendar. Get calendar IDs using LIST_CALENDARS action.
end_datetimestring
End of the time window in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ). Events active during this window will be returned.
selectarray
List of specific event properties to return (e.g., ['subject', 'start', 'end']). If omitted, returns default properties.
start_datetimestring
Start of the time window in ISO 8601 format (YYYY-MM-DDTHH:MM:SSZ). Events active during this window will be returned.
timezonestring
IANA or Windows timezone for event times (e.g., 'America/New_York'). Defaults to UTC.default: UTC
topinteger
Maximum number of events to retrieve. Default is 100.default: 100
user_idstring
Email address of the target user (or 'me' for authenticated user).default: me
OUTLOOK_GET_CONTACTRetrieves a specific Outlook contact by its `contact_id` from the contacts of a specified `user_id` (defaults to 'me' for the authenticated user).2 params

Retrieves a specific Outlook contact by its `contact_id` from the contacts of a specified `user_id` (defaults to 'me' for the authenticated user).

Parameters* required
contact_idstring
Unique identifier for the contact within the specified user's Outlook address book.
user_idstring
User's principal name (e.g., 'AdeleV@contoso.onmicrosoft.com') or 'me' for the authenticated user. Using 'me' is recommended for accessing one's own contacts.default: me
OUTLOOK_GET_CONTACT_FOLDERSTool to retrieve a list of contact folders in the signed-in user's mailbox. Use after authentication when you need to browse or select among contact folders.7 params

Tool to retrieve a list of contact folders in the signed-in user's mailbox. Use after authentication when you need to browse or select among contact folders.

Parameters* required
expandarray
Related entities to expand inline, e.g., ['contacts'].
filterstring
OData filter expression, e.g., startswith(displayName,'A').
orderbyarray
List of properties to order results by, e.g., ['displayName asc'].
selectarray
List of properties to include in the response, e.g., ['id','displayName'].
skipinteger
Number of contact folders to skip for pagination.
topinteger
Maximum number of contact folders to return.
user_idstring
User principal name or ID. Use 'me' for the authenticated user.default: me
OUTLOOK_GET_EVENTRetrieves the full details of a specific calendar event by its ID from a user's Outlook calendar, provided the event exists.2 params

Retrieves the full details of a specific calendar event by its ID from a user's Outlook calendar, provided the event exists.

Parameters* required
event_idstring
The unique identifier of the calendar event to retrieve.
user_idstring
The user's primary SMTP address, user principal name (UPN), or the alias 'me' (for the signed-in user) to identify the calendar owner.default: me
OUTLOOK_GET_MAILBOX_SETTINGSTool to retrieve mailbox settings. Use when you need to view settings such as automatic replies, time zone, and working hours for the signed-in or specified user.3 params

Tool to retrieve mailbox settings. Use when you need to view settings such as automatic replies, time zone, and working hours for the signed-in or specified user.

Parameters* required
expandarray
OData $expand query to include related entities.
selectarray
OData $select query to specify mailbox settings properties to include.
user_idstring
The user's unique identifier or principal name. Use 'me' for the signed-in user.default: me
OUTLOOK_GET_MAIL_DELTARetrieve incremental changes (delta) of messages in a mailbox. FIRST RUN: Returns ALL messages in folder (use top=50 to limit). Response has @odata.deltaLink. SUBSEQUENT: Pass stored deltaLink to get only NEW/UPDATED/DELETED messages since last sync. Properties available: id,...7 params

Retrieve incremental changes (delta) of messages in a mailbox. FIRST RUN: Returns ALL messages in folder (use top=50 to limit). Response has @odata.deltaLink. SUBSEQUENT: Pass stored deltaLink to get only NEW/UPDATED/DELETED messages since last sync. Properties available: id,...

Parameters* required
delta_tokenstring
Delta token from a previous call to get only changes since that state. If delta_token is not provided, the API returns all messages in the folder (initial sync). Use top parameter (e.g., top=50) on...
expandarray
List of related entities to expand (e.g. ['attachments']).
folder_idstring
Mail folder identifier to scope the delta query to that folder (e.g., 'Inbox' or folder ID GUID). Defaults to Inbox when omitted.
selectarray
List of message properties to include (e.g. ['subject','receivedDateTime']). Delta sync has property limitations due to response size constraints. Not available in delta: internetMessageHeaders, bo...
skip_tokenstring
Skip token for paging through large result sets during initial sync. Automatically provided in response '@odata.nextLink' when there are more results. Extract from nextLink URL and pass here for ne...
topinteger
Maximum number of items to return per page. For first run without delta_token, use top=50 or top=100 to limit results. First delta call without token returns all messages in folder. Paginate throug...
user_idstring
User identifier: 'me' for the signed-in user or the user's email/UPN.default: me
OUTLOOK_GET_MAIL_TIPSTool to retrieve mail tips such as automatic replies and mailbox full status. Use when you need to check recipient status before sending mail.3 params

Tool to retrieve mail tips such as automatic replies and mailbox full status. Use when you need to check recipient status before sending mail.

Parameters* required
EmailAddressesarray
Collection of SMTP addresses of recipients to get MailTips for.
MailTipsOptionsarray
List of mail tip types to retrieve for each recipient.
user_idstring
User principal name (UPN) or 'me' for the signed-in user.default: me
OUTLOOK_GET_MASTER_CATEGORIESTool to retrieve the user's master category list. Use when you need to get all categories defined for the user.6 params

Tool to retrieve the user's master category list. Use when you need to get all categories defined for the user.

Parameters* required
filterstring
OData $filter query to filter master categories.
orderbyarray
OData $orderby query to order master categories by property values.
selectarray
OData $select query to specify properties to include.
skipinteger
Number of master categories to skip for pagination (OData $skip).
topinteger
Maximum number of master categories to return (OData $top).
user_idstring
The user's unique identifier or principal name. Use 'me' for the signed-in user.default: me
OUTLOOK_GET_MESSAGERetrieves a specific email message by its ID from the specified user's Outlook mailbox. Use the 'select' parameter to include specific fields like 'internetMessageHeaders' for filtering automated emails.3 params

Retrieves a specific email message by its ID from the specified user's Outlook mailbox. Use the 'select' parameter to include specific fields like 'internetMessageHeaders' for filtering automated emails.

Parameters* required
message_idstring
Unique ID of the Outlook email message to retrieve.
selectarray
List of message properties to include in the response. Each item is a property name. MUST be provided as a list. Reduces data transfer and improves performance. Common fields: id, subject, from, to...
user_idstring
User's email address, UPN, or 'me' for the currently authenticated user.default: me
OUTLOOK_GET_PROFILERetrieves the Microsoft Outlook profile for a specified user.1 params

Retrieves the Microsoft Outlook profile for a specified user.

Parameters* required
user_idstring
The user's unique identifier or principal name. Use 'me' to get the profile of the authenticated user.default: me
OUTLOOK_GET_SCHEDULERetrieves free/busy schedule information for specified email addresses within a defined time window.4 params

Retrieves free/busy schedule information for specified email addresses within a defined time window.

Parameters* required
EndTimeobject
The end date, time, and time zone for the period for which to retrieve schedules. The period can be up to 62 days.
Schedulesarray
A list of SMTP email addresses for users, distribution lists, or resources whose schedules are to be retrieved. Maximum of 20 addresses.
StartTimeobject
The start date, time, and time zone for the period for which to retrieve schedules.
availabilityViewIntervalstring
The duration of each time slot in the availability view, specified in minutes. Minimum: 5, Maximum: 1440. Default: 30.default: 30
OUTLOOK_GET_SUPPORTED_LANGUAGESTool to retrieve supported languages in the user's mailbox. Use when you need to display or select from available mailbox languages.1 params

Tool to retrieve supported languages in the user's mailbox. Use when you need to display or select from available mailbox languages.

Parameters* required
user_idstring
The user's unique identifier or principal name. Use 'me' for the signed-in user.default: me
OUTLOOK_GET_SUPPORTED_TIME_ZONESTool to retrieve supported time zones in the user's mailbox. Use when you need a list of time zones to display or choose from for event scheduling.1 params

Tool to retrieve supported time zones in the user's mailbox. Use when you need a list of time zones to display or choose from for event scheduling.

Parameters* required
timeZoneStandardstring
Specifies the time zone format to return. Supported values: 'Windows' or 'Iana'. Default is 'Windows' if not specified.one of Windows · Iana
OUTLOOK_LIST_CALENDARSTool to list calendars in the signed-in user's mailbox. Use when you need to retrieve calendars with optional OData queries.6 params

Tool to list calendars in the signed-in user's mailbox. Use when you need to retrieve calendars with optional OData queries.

Parameters* required
filterstring
OData filter expression (OData $filter).
orderbyarray
Order by expressions (OData $orderby).
selectarray
Properties to include (OData $select).
skipinteger
Number of calendars to skip (OData $skip).
topinteger
Maximum number of calendars to return (OData $top).
user_idstring
User ID or userPrincipalName. Use 'me' for the signed-in user.default: me
OUTLOOK_LIST_CONTACTSRetrieves a user's Microsoft Outlook contacts, from the default or a specified contact folder.6 params

Retrieves a user's Microsoft Outlook contacts, from the default or a specified contact folder.

Parameters* required
contact_folder_idstring
ID of a specific contact folder. If omitted, contacts are retrieved from the default contact folder.
filterstring
OData V4 filter expression for targeted retrieval.
orderbyarray
List of properties to sort results by. Each item is a string like 'displayName asc' or 'createdDateTime desc'. MUST be provided as a list, even for single sort criteria. 'asc' is default.
selectarray
List of specific contact properties to retrieve. Each item is a property name. MUST be provided as a list. If empty, a default set of properties is returned.
topinteger
Maximum number of contacts to retrieve.default: 10
user_idstring
User Principal Name (UPN) or ID of the user. 'me' refers to the authenticated user.default: me
OUTLOOK_LIST_EMAIL_RULESList all email rules from inbox1 params

List all email rules from inbox

Parameters* required
topinteger
Number of rules to retrieve. Default is 100.
OUTLOOK_LIST_EVENT_ATTACHMENTSTool to list attachments for a specific Outlook calendar event. Use when you have an event ID and need to view its attachments.7 params

Tool to list attachments for a specific Outlook calendar event. Use when you have an event ID and need to view its attachments.

Parameters* required
event_idstring
The unique identifier of the calendar event to retrieve attachments for.
filterstring
OData filter string to filter the attachments (OData $filter).
orderbyarray
Order by clauses to sort the results (OData $orderby).
selectarray
List of attachment properties to include (OData $select).
skipinteger
Number of attachments to skip (OData $skip).
topinteger
Maximum number of attachments to return (OData $top).
user_idstring
The user's primary SMTP address, UPN, or 'me' for the signed-in user.default: me
OUTLOOK_LIST_EVENTSRetrieves events from a user's Outlook calendar via Microsoft Graph API. Supports primary/secondary/shared calendars, pagination, filtering, property selection, sorting, and timezone specification. Use calendar_id to access non-primary calendars.9 params

Retrieves events from a user's Outlook calendar via Microsoft Graph API. Supports primary/secondary/shared calendars, pagination, filtering, property selection, sorting, and timezone specification. Use calendar_id to access non-primary calendars.

Parameters* required
calendar_idstring
Optional ID of a specific calendar to retrieve events from.If not provided, uses the primary calendar. Get calendar IDs using LIST_CALENDARS action. Useful for accessing secondary calendars, shared...
expand_recurring_eventsboolean
When true, automatically expands recurring events to show actual occurrences within the filtered date range instead of series masters. When false (default), returns series masters as before.default: false
filterstring
OData query string to filter events (e.g., "start/dateTime ge 'YYYY-MM-DDTHH:MM:SSZ'"); string literals use single quotes.default:
orderbyarray
List of properties to sort results by. Each item is a string like 'start/dateTime desc' or 'subject asc'. MUST be provided as a list, even for single sort criteria. Use 'asc' (default) or 'desc' fo...
selectarray
List of specific event property names to return. Each item is a property name like 'subject' or 'start'. MUST be provided as a list. If omitted, a default set of properties is returned.
skipinteger
Number of initial events to bypass, used for pagination.default: 0
timezonestring
Preferred IANA or Windows timezone for event start/end times (e.g., 'America/New_York'); defaults to UTC if unspecified/invalid.default: UTC
topinteger
Maximum number of events to retrieve per page for pagination.default: 10
user_idstring
Email address of the target user (or 'me' for authenticated user), identifying the calendar for event listing.default: me
OUTLOOK_LIST_MAIL_FOLDERSTool to list a user's top-level mail folders. Use when you need folders like Inbox, Drafts, Sent Items; set include_hidden_folders=True to include hidden folders.2 params

Tool to list a user's top-level mail folders. Use when you need folders like Inbox, Drafts, Sent Items; set include_hidden_folders=True to include hidden folders.

Parameters* required
include_hidden_foldersboolean
Include hidden mail folders (isHidden=true) when set to true.default: false
user_idstring
User's id, userPrincipalName, or 'me' for the signed-in user.default: me
OUTLOOK_LIST_MESSAGESRetrieves a list of email messages from a specified mail folder in an Outlook mailbox, with options for filtering (including by conversationId to get all messages in a thread), pagination, and sorting; ensure 'user_id' and 'folder' are valid, and all date/time strings are in I...22 params

Retrieves a list of email messages from a specified mail folder in an Outlook mailbox, with options for filtering (including by conversationId to get all messages in a thread), pagination, and sorting; ensure 'user_id' and 'folder' are valid, and all date/time strings are in I...

Parameters* required
categoriesarray
Filter by categories (case-sensitive); matches if tagged with any specified category.
conversationIdstring
Filter messages by conversation ID to retrieve all messages in a specific email thread.
folderstring
ID or well-known name of the mail folder. Well-known names: inbox, sentitems, drafts, deleteditems, outbox, junkemail. Or use a valid folder ID.default: inbox
from_addressstring
Filter by the sender's exact email address. NOTE: This filter is applied client-side on the returned results, not server-side.
has_attachmentsboolean
Filter by attachment presence: 'true' for messages with attachments, 'false' for those without. NOTE: This filter is applied client-side on the returned results.
importancestring
Filter by importance: 'low', 'normal', or 'high'.
is_readboolean
Filter by read status: 'true' for read, 'false' for unread. Unspecified means no filter by read status.
orderbyarray
List of properties to sort results by, with direction. Each item is a string like 'receivedDateTime desc' or 'subject asc'. Default is 'receivedDateTime desc'. Cannot be used with sentDateTime filt...
received_date_time_gestring
Filter messages received on or after this ISO 8601 timestamp.
received_date_time_gtstring
Filter messages received after this ISO 8601 timestamp (e.g., '2023-01-01T00:00:00Z').
received_date_time_lestring
Filter messages received on or before this ISO 8601 timestamp.
received_date_time_ltstring
Filter messages received before this ISO 8601 timestamp.
selectarray
List of message properties to include. Valid properties: id, subject, from, toRecipients, ccRecipients, bccRecipients, receivedDateTime, sentDateTime, hasAttachments, importance, isRead, body, body...
sent_date_time_gtstring
Filter messages sent after this ISO 8601 timestamp.
sent_date_time_ltstring
Filter messages sent before this ISO 8601 timestamp.
skipinteger
Number of messages to skip from the beginning of the result set, for pagination.default: 0
subjectstring
Filter by exact match of the subject line. Special characters like apostrophes, brackets will be automatically escaped. For complex subject searches, consider using 'Search Messages' instead.
subject_containsstring
Filter messages where the subject contains the specified case-insensitive substring. NOTE: This filter is applied client-side on the returned results. For better performance, use 'Search Messages'...
subject_endswithstring
Filter messages where the subject ends with the specified case-insensitive string. NOTE: This filter is applied client-side on the returned results. For better performance, use 'Search Messages' in...
subject_startswithstring
Filter messages where the subject starts with the specified case-insensitive string.

+2 more parameters. See the server's own documentation for the full schema.

OUTLOOK_LIST_OUTLOOK_ATTACHMENTSLists metadata (like name, size, and type, but not `contentBytes`) for all attachments of a specified Outlook email message.2 params

Lists metadata (like name, size, and type, but not `contentBytes`) for all attachments of a specified Outlook email message.

Parameters* required
message_idstring
The unique identifier of the email message from which to retrieve attachments. This ID is specific to the Outlook message.
user_idstring
The unique identifier of the user. Use the user's UPN (e.g., 'AdeleV@contoso.onmicrosoft.com') or 'me' for the currently authenticated user. This specifies the mailbox to query.default: me
OUTLOOK_LIST_REMINDERSTool to retrieve reminders for events occurring within a specified time range. Use when you need to see upcoming reminders between two datetimes.3 params

Tool to retrieve reminders for events occurring within a specified time range. Use when you need to see upcoming reminders between two datetimes.

Parameters* required
endDateTimestring
The end date and time in ISO 8601 format defining the window for reminders. Example: '2023-10-26T20:00:00.0000000'.
startDateTimestring
The start date and time in ISO 8601 format defining the window for reminders. Example: '2023-10-26T19:00:00.0000000'.
userIdstring
User Principal Name or ID. Use 'me' to indicate the signed-in user.default: me
OUTLOOK_LIST_USERSTool to list users in Microsoft Entra ID. Use when you need to retrieve a paginated list of users, optionally filtering or selecting specific properties.4 params

Tool to list users in Microsoft Entra ID. Use when you need to retrieve a paginated list of users, optionally filtering or selecting specific properties.

Parameters* required
filterstring
OData filter expression to restrict returned users (OData $filter).
selectarray
List of user properties to include in the response (OData $select).
skipinteger
Number of users to skip (OData $skip) for pagination.
topinteger
Maximum number of users to return (OData $top). Default page size is 100, maximum is 999.
OUTLOOK_MOVE_MESSAGEMove a message to another folder within the specified user's mailbox. This creates a new copy of the message in the destination folder and removes the original message.3 params

Move a message to another folder within the specified user's mailbox. This creates a new copy of the message in the destination folder and removes the original message.

Parameters* required
destination_idstring
The destination folder ID, or a well-known folder name (e.g., 'inbox', 'deleteditems', 'drafts', 'sentitems').
message_idstring
Unique ID of the Outlook email message to move.
user_idstring
User's email address, UPN, or 'me' for the currently authenticated user.default: me
OUTLOOK_QUERY_EMAILSPrimary tool for querying Outlook emails with custom OData filters. Build precise server-side filters for dates, read status, importance, subjects, attachments, and conversations. Best for structured queries on message metadata. Returns up to 100 messages per request with pagi...7 params

Primary tool for querying Outlook emails with custom OData filters. Build precise server-side filters for dates, read status, importance, subjects, attachments, and conversations. Best for structured queries on message metadata. Returns up to 100 messages per request with pagi...

Parameters* required
filterstring
OData $filter query string to filter email messages. Syntax: 'field operator value' combined with 'and', 'or', 'not'. **Operators:** eq, ne, lt, le, gt, ge, startswith(), endswith(), conta...
folderstring
ID or well-known name of the mail folder. Well-known names: 'inbox', 'sentitems', 'drafts', 'deleteditems', 'outbox', 'junkemail' (case-insensitive). Or use a valid folder ID.default: inbox
orderbystring
Comma-separated sort keys with direction. Format: 'field asc' or 'field desc'. Common fields: receivedDateTime, sentDateTime, subject, importance, from. NOTE: Ordering may be automatically disabled...default: receivedDateTime desc
selectarray
List of message properties to include in the response. Reduces data transfer and improves performance. Common fields: id, subject, from, toRecipients, ccRecipients, receivedDateTime, sentDateTime,...
skipinteger
Number of messages to skip for pagination. NOTE: For large result sets, prefer using '@odata.nextLink' from responses instead of manual skip.default: 0
topinteger
Maximum number of messages to return per request (1-1000). Default is 100. IMPORTANT: For large mailboxes, always check response['@odata.nextLink'] to fetch remaining messages. Pagination example:...default: 100
user_idstring
Target user's email or 'me' for authenticated user. IMPORTANT: 'me' uses the currently connected account. For cross-mailbox access, ensure you have Mail.Read or Mail.ReadWrite permissions on the ta...default: me
OUTLOOK_REPLY_EMAILSends a plain text reply to an Outlook email message, identified by `message_id`, allowing optional CC and BCC recipients.5 params

Sends a plain text reply to an Outlook email message, identified by `message_id`, allowing optional CC and BCC recipients.

Parameters* required
bcc_emailsarray
List of email addresses for BCC recipients.
cc_emailsarray
List of email addresses for CC recipients.
commentstring
The plain text body of the reply email.
message_idstring
The unique ID of the message to reply to. This ID can be obtained from the `OUTLOOK_LIST_MESSAGES` action.
user_idstring
The user's email address or 'me' to indicate the authenticated user. This specifies the mailbox from which the reply will be sent.default: me
OUTLOOK_SEARCH_MESSAGESSearch Outlook messages using powerful KQL syntax. Supports sender (from:), recipient (to:, cc:), subject, date filters (received:, sent:), attachments, and boolean logic. Only works with Microsoft 365/Enterprise accounts (no @hotmail.com/@outlook.com). Examples: 'from:user@ex...7 params

Search Outlook messages using powerful KQL syntax. Supports sender (from:), recipient (to:, cc:), subject, date filters (received:, sent:), attachments, and boolean logic. Only works with Microsoft 365/Enterprise accounts (no @hotmail.com/@outlook.com). Examples: 'from:user@ex...

Parameters* required
enable_top_resultsboolean
If `true`, sorts results by relevance; otherwise, sorts by date in descending order (newest first).default: false
fromEmailstring
Filter messages by sender email address or domain. Supports exact email ('user@example.com') or domain matching ('example.com'). Legacy parameter - prefer using 'from:email@example.com' in the quer...
from_indexinteger
The 0-based starting index for pagination. To paginate: check response['value'][0]['hitsContainers'][0]['moreResultsAvailable']. If true, call again with from_index += size (e.g., 0 → 25 → 50). Mes...default: 0
hasAttachmentsboolean
Filters messages based on the presence of attachments. Legacy parameter - prefer using 'hasattachment:yes' or 'hasattachment:no' in the query parameter.
querystring
KQL (Keyword Query Language) search query string. Supports advanced syntax for precise searches. **Basic Syntax:** - Simple keywords: 'budget report' - Exact phrases: '"quarterly review"' - Boolea...default:
sizeinteger
The maximum number of search results to return per page. Use with from_index for pagination.default: 25
subjectstring
Text to search for within the message subject line. Legacy parameter - prefer using 'subject:text' in the query parameter for more control. Example: Instead of subject='invoice', use query='subject...
OUTLOOK_SEND_DRAFTTool to send an existing draft message. Use after creating a draft when you want to deliver it to recipients immediately. Example: Send a draft message with ID 'AAMkAG…'.2 params

Tool to send an existing draft message. Use after creating a draft when you want to deliver it to recipients immediately. Example: Send a draft message with ID 'AAMkAG…'.

Parameters* required
message_idstring
The unique identifier of the draft message to send.
user_idstring
The user's email address or 'me' to represent the authenticated user.default: me
OUTLOOK_SEND_EMAILSends an email with subject, body, recipients, and an optional attachment via Microsoft Graph API. Supports comma-separated email addresses in the to_email field for multiple recipients. Attachments require a non-empty file with valid name and mimetype.11 params

Sends an email with subject, body, recipients, and an optional attachment via Microsoft Graph API. Supports comma-separated email addresses in the to_email field for multiple recipients. Attachments require a non-empty file with valid name and mimetype.

Parameters* required
attachmentstring
Optional file to attach. If provided, its name, mimetype, and content must be valid and non-empty.
bcc_emailsarray
List of email addresses for BCC recipients. Each email should be a separate string in the array. Do NOT pass comma-separated values as a single string.
bodystring
The content of the email body, plain text or HTML based on `is_html`.
cc_emailsarray
List of email addresses for CC recipients. Each email should be a separate string in the array. Do NOT pass comma-separated values as a single string.
fromstring
Optional From address to set on the message (send as/on behalf). Provide a single email address. Requires appropriate mailbox permissions.
is_htmlboolean
Specifies if the email body is HTML; `True` for HTML, `False` for plain text.default: false
save_to_sent_itemsboolean
Indicates if the email should be saved in 'Sent Items'.default: true
subjectstring
The subject line of the email.
to_emailstring
The primary recipient's email address(es). You can provide a single email or multiple emails separated by commas. For CC/BCC recipients, use the respective fields.
to_namestring
The display name of the primary recipient.
user_idstring
The user's email address or the alias 'me' to represent the authenticated user.default: me
OUTLOOK_UPDATE_CALENDAR_EVENTUpdates specified fields of an existing Outlook calendar event. Implementation note: To avoid unintentionally clearing properties, the action first fetches the existing event, merges only the provided fields, and then PATCHes the merged updates. Unspecified fields remain uncha...11 params

Updates specified fields of an existing Outlook calendar event. Implementation note: To avoid unintentionally clearing properties, the action first fetches the existing event, merges only the provided fields, and then PATCHes the merged updates. Unspecified fields remain uncha...

Parameters* required
attendeesarray
Attendee list for the event. If provided, replaces the existing attendees. If omitted, attendees remain unchanged.
bodyobject
Event body with content type ('Text' or 'HTML') and the content. If omitted, the existing body remains unchanged.
categoriesarray
Category names to associate with the event. If provided (even empty), replaces the existing categories. If omitted, categories remain unchanged.
end_datetimestring
New end date and time for the event. Provide together with a time zone, or the current event's time zone will be used. Must be after start_datetime if both are provided. If omitted, the end time re...
event_idstring
The unique identifier of the calendar event to be updated. This ID can be obtained from the OUTLOOK_LIST_EVENTS action.
locationobject
Event location as a dictionary. If provided, replaces the existing primary location. Omit to leave unchanged.
show_asstring
Availability status for the event. Valid values: 'free', 'tentative', 'busy', 'oof'. If omitted, the existing status remains unchanged.
start_datetimestring
New start date and time for the event. Provide together with a time zone, or the current event's time zone will be used. If omitted, the start time remains unchanged.
subjectstring
New subject for the event. If provided as an empty string, the subject will be cleared. If omitted, the existing subject remains unchanged.
time_zonestring
Time zone for the provided start_datetime and/or end_datetime (IANA or Windows time zone names). If omitted, the existing event's time zone is used.
user_idstring
The identifier of the user whose calendar event is to be updated. Accepts the user's principal name, ID, or 'me' for the currently authenticated user.default: me
OUTLOOK_UPDATE_CONTACTUpdates an existing Outlook contact, identified by `contact_id` for the specified `user_id`, requiring at least one other field to be modified.16 params

Updates an existing Outlook contact, identified by `contact_id` for the specified `user_id`, requiring at least one other field to be modified.

Parameters* required
birthdaystring
Contact's birthday (YYYY-MM-DD format).default:
businessPhonesarray
Contact's business phone numbers.
categoriesarray
Categories for organizing the contact.
companyNamestring
Contact's company name.default:
contact_idstring
Unique identifier of the contact to update.
departmentstring
Contact's department.default:
displayNamestring
Contact's full display name.default:
emailAddressesarray
Contact's email addresses.
givenNamestring
Contact's given (first) name.default:
homePhonesarray
Contact's home phone numbers.
jobTitlestring
Contact's job title.default:
mobilePhonestring
Contact's mobile phone number.default:
notesstring
Personal notes about the contact (maps to 'personalNotes' in Microsoft Graph API).default:
officeLocationstring
Contact's office location.default:
surnamestring
Contact's surname (last name).default:
user_idstring
User's identifier; 'me' for the signed-in user, or user's principal name/ID.default: me
OUTLOOK_UPDATE_EMAILUpdates specified properties of an existing email message; `message_id` must identify a valid message within the specified `user_id`'s mailbox.9 params

Updates specified properties of an existing email message; `message_id` must identify a valid message within the specified `user_id`'s mailbox.

Parameters* required
bcc_recipientsarray
List of BCC recipients; replaces all existing BCCs. Omitting this field removes all current BCC recipients.
bodyobject
New body content (Text or HTML). If omitted, the existing message body remains unchanged.
cc_recipientsarray
List of CC recipients; replaces all existing CCs. Omitting this field removes all current CC recipients.
importancestring
New importance level ('low', 'normal', 'high'). If omitted, importance is set to 'normal'.default: normal
is_readboolean
Mark message as read (True) or unread (False). If omitted, read status remains unchanged.
message_idstring
The unique identifier of the email message to be updated. This ID is typically obtained from listing messages or creating/sending a message.
subjectstring
New subject line. If omitted, the existing subject remains unchanged. Provide empty string to clear the subject.
to_recipientsarray
List of TO recipients; replaces all existing TOs. Omitting this field removes all current TO recipients.
user_idstring
The UPN (User Principal Name) of the user whose mailbox contains the message, or 'me' for the currently authenticated user. This determines whose message is updated.default: me
OUTLOOK_UPDATE_EMAIL_RULEUpdate an existing email rule6 params

Update an existing email rule

Parameters* required
actionsobject
Updated actions to take when the rule conditions are met.
conditionsobject
Updated conditions that must be met for the rule to apply.
displayNamestring
Updated display name for the email rule.
isEnabledboolean
Whether the rule should be enabled or disabled.
ruleIdstring
ID of the email rule to update.
sequenceinteger
Updated order in which the rule is executed (lower numbers execute first).
OUTLOOK_UPDATE_MAILBOX_SETTINGSTool to update mailbox settings for the signed-in user. Use when you need to configure automatic replies, default time zone, language, or working hours. Example: schedule automatic replies for vacation.4 params

Tool to update mailbox settings for the signed-in user. Use when you need to configure automatic replies, default time zone, language, or working hours. Example: schedule automatic replies for vacation.

Parameters* required
automaticRepliesSettingobject
Configuration for automatic replies.
languageobject
Locale preferences for date/time formatting.
timeZonestring
Default mailbox time zone (e.g., 'Pacific Standard Time').
workingHoursobject
Working hours configuration for the user.

outlook-mcp

MCP server for Microsoft Outlook personal accounts via Microsoft Graph API.

PyPI Python License: MIT MCP Registry

Personal Microsoft accounts only — @outlook.com, @hotmail.com, @live.com. Work/school accounts (Entra ID) are not supported in v1.

Disclaimer: Independent open-source project. Not affiliated with, endorsed by, or supported by Microsoft Corporation. "Outlook" and "Microsoft Graph" are trademarks of Microsoft.


Who this is for

You'll like this if you're:

  • An agent builder wiring Outlook into your own infra (OpenClaw, Claude Code, Cursor, custom MCP host) and want a typed tool surface — not stdout you have to parse
  • Building on personal Microsoft accounts (Outlook.com / Hotmail / Live) and want full control: BYO Azure app, no enterprise consent flow, no shared client ID
  • Looking for real coverage — mail, calendar, contacts, to-do, drafts, folders, batch ops, threading — instead of a mail-only or calendar-only wrapper
  • Security-conscious: tokens in the OS keyring (Keychain on macOS, libsecret on Linux -- never cleartext unless you opt in), granular allow_categories, optional read_only mode, zero telemetry

This isn't for you if you need work/school M365 accounts (use Microsoft's official tooling — Entra ID auth and admin-consent flows are out of scope here), or if a basic mail-only client would suffice (this has 68 tools — way more than you need for "read my inbox").

How it differs from other Outlook tools you'll find

This is the only first-class MCP server in the personal-Outlook space — most alternatives are bash scripts or skill-shaped CLI wrappers the agent shells out to. That distinction matters: the agent gets typed tool schemas with structured args/returns, not stdout it has to parse. Other things you won't find elsewhere: /$batch-optimized triage (10-20× faster on bulk ops), recursive folder ops with name resolution, granular per-category permissions, multiple mailboxes (one server per account via OUTLOOK_MCP_CONFIG_DIR), and full attachment write paths including >3MB upload sessions for drafts.


What This Enables

Give your AI agent full Outlook access. Example prompts that just work:

  • "Summarize my unread email from the past 24 hours and flag anything time-sensitive."
  • "What's in my Focused Inbox right now? Anything in Other that looks like it belongs up top?"
  • "Any shipping updates in my inbox? Track what I'm waiting on and when it's supposed to arrive."
  • "Scan my email for upcoming subscription renewals — what's about to auto-charge in the next two weeks?"
  • "I've got a trip to Seattle next week — check my calendar for the itinerary and create a To Do task with a packing checklist."
  • "Draft a reply to the last message from my sister saying I'll call her this weekend."
  • "Move all newsletter and promotional email from this week to a 'Read Later' folder — batch 20 at a time."

The server exposes 68 discrete tools so the agent can compose its own workflow — read, triage, write, schedule, track tasks — without hardcoded macros.

Works With

  • OpenClaw — native MCP support, available via ClawHub
  • Claude Code — add to ~/.claude/settings.json under mcpServers
  • Cursor — MCP-compatible
  • Any MCP client — it's a standard stdio MCP server

Listed on the official MCP Registry as io.github.mpalermiti/outlook-mcp.


Features

68 tools across 13 categories:

  • Auth (1) -- auth status check (login is via CLI)
  • Mail Read (7) -- list inbox (with Focused Inbox and uncategorized filters), read message, bulk read by ID via $batch, search (KQL), list folders, delta-sync inbox changes, composed "since last call" digest across mail/events/contacts
  • Mail Write (3) -- send, reply/reply-all, forward
  • Mail Triage (9) -- move, delete (soft by default), flag, categorize, mark read/unread, reclassify (Focused Inbox), list/set/delete per-sender Focused Inbox overrides
  • Calendar Read (3) -- list events (with recurring expansion), get event details, delta-sync event changes
  • Calendar Write (4) -- create, update, delete, RSVP (accept/decline/tentative)
  • Contacts (7) -- list, search, get, create, update, delete, delta-sync changes
  • To Do (14) -- task lists, tasks (list/get/create/update/complete/delete), checklist items (add/update/delete), task attachments (list/download/upload/delete)
  • Drafts (5) -- list, create, update, send, delete
  • Attachments (5) -- list, download, send-with-attachments, attach-to-draft, remove-draft-attachment
  • Folder Management (3) -- create, rename, delete mail folders
  • Threading and Batch (3) -- list thread, copy message, batch triage
  • User and Admin (4) -- whoami, list calendars, list categories, mail tips

Design principles:

  • BYOID -- Bring Your Own ID. You register your own Azure AD app. No shared client ID.
  • Zero telemetry -- no analytics, no local caching, no third-party calls.
  • Token storage -- OS keyring via azure-identity (macOS Keychain, Windows Credential Store, Linux Secret Service).
  • Input validation -- all inputs validated (email, Graph IDs, OData, KQL, datetimes) before any API call.
  • Read-only mode -- set read_only: true in config to block all write operations. Note this limits the tools, not the token -- see What read_only does and does not do.
  • Soft delete -- delete moves to Deleted Items by default. Hard delete requires explicit permanent: true.
  • Timezone-aware -- calendar operations respect your configured IANA timezone.
  • Relative dates -- every datetime parameter takes ISO 8601 or an offset: 7d is seven days ago, +7d is seven days from now, now is this moment. Units: m, h, d, w.
  • Bounded attachments -- attachment reads and writes are confined to attachments_dir, so a message that asks an agent to mail a file elsewhere on disk cannot be obeyed.
  • Bounded delta cursors -- a delta_token is caller-held state, so it is untrusted input. Every URL that would carry a Graph bearer token is parsed and required to be https on graph.microsoft.com, which is what stops a poisoned cursor from redirecting your mailbox token to someone else. Its path must also be the delta endpoint of the tool it was handed to, so a cursor cannot point a delta tool at some other part of the mailbox.
  • Workflow prompts -- morning_brief, triage_folder and catch_up ship as MCP prompts, so the common sequences do not have to be reconstructed call by call.

Agent-friendly shape (1.8.0)

Two pure-code upgrades that make the same 57 tools cheaper and more recoverable for AI agents:

  • Concise mode — pass concise=True to the five high-volume read tools (outlook_list_inbox, outlook_read_message, outlook_search_mail, outlook_list_events, outlook_list_thread) to drop bulky fields: full message bodies, quoted prior-message text in threads, body previews and categories on inbox listings — typical payload reduction ~10×. On outlook_list_events the trade is different and smaller: the attendee list becomes a count, and organizer, response_status, type and show_as come off, so a concise scan cannot tell a recurring occurrence from a one-off. Default concise=False preserves the existing response shape — strict backward compat.

  • Structured Graph errors — every tool wraps msgraph SDK exceptions into {code, message, action} responses with operator-friendly recovery hints: re-auth on 401, a link to the repo's ROADMAP dead-ends list on 403/ErrorAccessDenied, re-list on 404/ErrorItemNotFound, back-off on 429, retry on 503. OutlookMCPError subclasses and validation errors pass through unchanged.


Azure AD App Registration

You need to register a free Azure AD app to get a client ID.

Prerequisites (Personal Microsoft Accounts)

Microsoft has deprecated app registration for personal accounts without an Azure AD tenant. You need to create a free Azure account first:

  1. Go to azure.microsoft.com/free and sign up with your personal @outlook.com account. Requires a credit card for identity verification but won't charge you. This creates a proper Azure AD tenant.

Register the App

  1. Go to App Registrations and sign in with your @outlook.com account.

  2. Click "+ New registration" and fill in:

    • Name: anything except Microsoft-branded terms (e.g. mp-outlook-mcp — names like "Outlook MCP" will be rejected)
    • Supported account types: select "Personal Microsoft accounts only"
    • Redirect URI: leave blank
  3. Click Register. Copy the Application (client) ID from the overview page.

  4. Go to Authentication (Preview) → Settings tab → toggle "Allow public client flows" to Yes → Save.

  5. Go to API permissions → Add a permission → Microsoft Graph → Delegated permissions → add:

    • Mail.ReadWrite, Mail.Send
    • Calendars.ReadWrite
    • Contacts.ReadWrite, Tasks.ReadWrite
    • MailboxSettings.Read
    • User.Read, offline_access

No client secret is needed. The device code flow uses public client auth.


Quick Start

Install

Option A — from PyPI (recommended):

uv tool install outlook-graph-mcp
# or: pipx install outlook-graph-mcp
# or: pip install outlook-graph-mcp

Option B — from source:

git clone https://github.com/mpalermiti/outlook-mcp.git
cd outlook-mcp
uv sync

Configure

Create ~/.outlook-mcp/config.json:

{
  "client_id": "YOUR_APPLICATION_CLIENT_ID",
  "tenant_id": "consumers",
  "timezone": "America/Los_Angeles",
  "read_only": true,
  "attachments_dir": "~/.outlook-mcp/attachments"
}

The only required field is client_id. Everything else has sensible defaults. Start with read_only: true — flip to false when you're comfortable.

Register with your MCP client

If installed from PyPI:

{
  "mcpServers": {
    "outlook": {
      "command": "outlook-mcp"
    }
  }
}

If installed from source:

{
  "mcpServers": {
    "outlook": {
      "command": "uv",
      "args": ["--directory", "/path/to/outlook-mcp", "run", "outlook-mcp"]
    }
  }
}

For OpenClaw, use the openclaw mcp CLI — it writes to mcp.servers in ~/.openclaw/openclaw.json for you:

# If installed from PyPI:
openclaw mcp set outlook '{"command":"outlook-mcp"}'

# If installed from source:
openclaw mcp set outlook '{"command":"uv","args":["--directory","/path/to/outlook-mcp","run","outlook-mcp"]}'

# Verify:
openclaw mcp list
openclaw mcp show outlook --json

Restart the OpenClaw gateway after registering. See the OpenClaw MCP docs for SSE/HTTP transport variants.

Authenticate

Run this once on the machine where the MCP server will run:

uv run outlook-mcp auth

You'll get a URL and a code. Open the URL in any browser, enter the code, and sign in with your Microsoft account. Tokens are cached in the OS keyring — the MCP server picks them up automatically.

The consent screen lists the full read-write set (Mail.ReadWrite, Mail.Send, Calendars.ReadWrite, Contacts.ReadWrite, Tasks.ReadWrite, MailboxSettings.Read, User.Read) — even when the config starts with read_only: true, because read_only gates the tools, not the token (see What read_only does and does not do), and the scopes a first consent leaves out can never be granted later without logging in again. (The one exception is read_only_consent: true, which asks for the read permissions only; it exists for a separate read-only app, described under the same heading.) Every request afterwards — silent refresh and each Graph call — uses the .default scope, which on an already-consented account means exactly "the set you granted". That ordering is deliberate: on personal accounts a first consent asking only for .default can land a session with no delegated permissions, which then can't be redeemed (AADSTS70000) without logging in again (#82).

Other CLI commands:

uv run outlook-mcp status   # Check auth status
uv run outlook-mcp logout   # Clear credentials
uv run outlook-mcp serve    # Start MCP server (default, used by OpenClaw/Claude)

Troubleshooting

me-token-to-replace is invalid on every call

You're on 1.22.0 installed after 2026-09-18. A fresh install of that version resolves microsoft-kiota-* 1.13 or later, which msgraph-core doesn't yet handle, so every /me request reaches Graph as /users/me-token-to-replace. Fixed in 1.22.1, which caps kiota below 1.13 (#80):

uv tool upgrade outlook-graph-mcp
# or: pipx upgrade outlook-graph-mcp
# or: pip install --upgrade outlook-graph-mcp

Your config and sign-in are untouched; no re-auth needed.

SSL: CERTIFICATE_VERIFY_FAILED on Linux

If auth fails with [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificate, your Python environment can't find the system CA bundle. This is common on minimal/container Linux images and with the isolated venv from uv tool install.

Point Python at your system CA bundle. Set both variables — auth (via azure-identity → requests) reads REQUESTS_CA_BUNDLE, while the delta/$batch paths (via httpx) read SSL_CERT_FILE:

export SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt      # httpx + Python ssl
export REQUESTS_CA_BUNDLE=/etc/ssl/certs/ca-certificates.crt  # azure-identity auth

The path varies by distro: Debian/Ubuntu use /etc/ssl/certs/ca-certificates.crt; RHEL/Fedora use /etc/pki/tls/certs/ca-bundle.crt. If the file is missing, install your distro's CA package (ca-certificates). Set these in the same environment your MCP client launches the server from so they apply at runtime, not just to the one-time auth command.

Token cache stored unencrypted (Linux)

A one-time startup warning about the token cache falling back to plaintext means libsecret/PyGObject isn't importable — see Privacy and Security for the fix.


Tool Reference

Dates. Every datetime parameter (after, before, start, end, due, deferred_send_datetime) accepts ISO 8601 — 2026-10-22 or 2026-10-22T14:30:00Z — or a relative offset: 7d is seven days ago, +7d is seven days from now, and now is this moment. Units are m, h, d, w. Bare means ago, matching the usual CLI convention, so a due date in the future needs the +. Zone-less input is interpreted in your configured timezone; responses are always UTC.

Auth

ToolDescription
outlook_auth_statusCheck if authenticated and whether read-only mode is active.

Note: Authentication is handled via the CLI (outlook-mcp auth), not through MCP tools. See Authenticate above.

Mail Read

ToolDescription
outlook_list_inboxList messages in a folder. folder accepts display names, well-known names, or Graph IDs. Filter by read status, sender, date range, Focused Inbox classification. Pagination via skip.
outlook_read_messageGet full message by ID. Format: text, html, or full (both). Pass include_deferred_send=True to also surface the draft's scheduled delivery time.
outlook_read_messagesBulk read up to 20 messages by ID via Graph $batch in one round-trip. Per-message shape matches outlook_read_message byte-for-byte for the same (format, concise, include_deferred_send). Partial-failure tolerant: 404s on some IDs surface in failures[] without failing the whole call. Use NOT N outlook_read_message calls.
outlook_search_mailSearch mail using KQL query. Optionally scope to a folder by name or ID.
outlook_list_foldersList mail folders with counts, parent_id, and child_count. Pass recursive=true to walk the full folder tree (subfolders included).
outlook_list_inbox_deltaList only inbox changes since the last call. First call returns a full snapshot plus a delta_token; subsequent calls (token passed back) return only added/updated/deleted items. Deletes come back as {id, is_deleted: True}. Cursor is stateless — agent persists and replays.
outlook_changes_sinceOne structured "since last call" digest composing mail/events/contacts deltas. Returns counts + urgent_flagged mail + top-5 by_sender + new/cancelled events. Each resource has an independent delta_token; stale-token recovery (HTTP 410) auto-resyncs that resource and surfaces _meta.resync. First-call snapshot is filtered to fallback_window_hours (default 24). Designed for recurring agent loops.

Mail Write

ToolDescription
outlook_send_messageSend email. Supports TO/CC/BCC, HTML body, importance level.
outlook_replyReply or reply-all to a message.
outlook_forwardForward a message to one or more recipients with optional comment.

Mail Triage

ToolDescription
outlook_move_messageMove a message to a folder by name or ID.
outlook_delete_messageDelete a message. Soft delete (Deleted Items) by default. permanent: true for hard delete.
outlook_flag_messageSet follow-up flag: flagged, complete, or notFlagged.
outlook_categorize_messageSet categories on a message.
outlook_mark_readMark a message as read or unread.
outlook_reclassify_messageMove a message between Focused Inbox and Other (focused / other).
outlook_list_inbox_overridesList Focused Inbox per-sender override rules.
outlook_set_inbox_overrideUpsert a per-sender Focused Inbox override (focused / other). Case-insensitive sender matching; PATCH-if-exists, else POST.
outlook_delete_inbox_overrideDelete a Focused Inbox override by ID.

Calendar Read

ToolDescription
outlook_list_eventsList events in a date range. Expands recurring events. Each event carries type — occurrence or exception for an instance of a series, singleInstance for a one-off — so a listing tells recurring work apart without a second call. A seriesMaster never appears here: calendarView returns expanded instances, so use outlook_get_event to see a master. Each event also carries show_as, the free/busy status Outlook labels "Show as". Configurable via days, after, before. calendar selects which calendar to read: omit (or "primary") for the default, otherwise a display name (case-insensitive; not-found and ambiguous errors name what exists) or an ID from outlook_list_calendars. A cursor continues the listing it came from, so later pages need neither calendar nor a second lookup. concise=True omits type and show_as.
outlook_get_eventGet full event details: attendees, body, online meeting URL, recurrence, type (singleInstance / seriesMaster / occurrence / exception), show_as.
outlook_list_events_deltaList only event changes inside a window since the last call. start and end (ISO 8601) required on the first call (Graph constraint — no whole-calendar sync). Each changed event carries every field the default outlook_list_events listing returns, type and show_as included, plus is_deleted (concise=True has its own narrower shape, which the delta tool does not mirror). Unlike the listing, this endpoint does return seriesMaster items, so a caller seeding from outlook_list_events should expect ids here that the seed never held. Deletes come back as {id, is_deleted: True} and nothing else. Cursor is stateless.

Calendar Write

ToolDescription
outlook_create_eventCreate event with location and attendees. (is_online has no effect on personal accounts — Graph ignores isOnlineMeeting for consumer mailboxes.) Pass recurrence to create a series: a shorthand (daily, weekdays, weekly, monthly, yearly, anchored on start) or a full Graph recurrence object for anything else. range.startDate defaults to the event's start date. show_as sets the free/busy status Outlook labels "Show as" — free, tentative, busy, oof (out of office), workingElsewhere, or unknown; omit it and Graph applies its own default of busy.
outlook_update_eventUpdate event fields (subject, time, location, body, attendees, all-day, show_as). Only patches changed fields. Pass recurrence to turn a single event into a series, or remove_recurrence=True to turn a series back into a single event. attendees replaces the whole guest list and emails invitations/cancellations; is_all_day needs start+end in the same call, while show_as patches on its own. Patching a time keeps the zone the event is anchored in; timezone (with start+end) re-anchors it elsewhere, which is how a series created before zones existed gets repaired. A start, end or recurrence patch to a series with edited or deleted occurrences is refused, naming them — Graph would silently discard every one.
outlook_delete_eventDelete a calendar event.
outlook_rsvpRSVP to an event: accept, decline, or tentative. Optionally include a message.

Contacts

ToolDescription
outlook_list_contactsList contacts with cursor pagination. Summaries carry categories; outlook_search_contacts omits the key because Graph's $search does not return it.
outlook_search_contactsSearch contacts by name or email.
outlook_get_contactGet full contact details by ID, including home/business/other addresses, categories and personal notes.
outlook_create_contactCreate a new contact.
outlook_update_contactUpdate contact fields. home_address, business_address and other_address take the shape outlook_get_contact returns — any subset of street, city, state, postal_code, country_or_region — and replace that whole address, so pass back every part you want to keep. Omit one to leave it untouched.
outlook_delete_contactDelete a contact.
outlook_list_contacts_deltaList only contact changes since the last call. Deletes come back as {id, is_deleted: True}. Cursor is stateless.

To Do

ToolDescription
outlook_list_task_listsList To Do lists.
outlook_list_tasksList tasks with status filter and pagination.
outlook_get_taskGet full task details: notes (body), checklist items (ordered unchecked-first), due, recurrence flag.
outlook_create_taskCreate task with due date, importance, recurrence.
outlook_update_taskUpdate task fields.
outlook_complete_taskMark task as completed.
outlook_delete_taskDelete a task.
outlook_add_checklist_itemAdd a checklist item (sub-step) to a task.
outlook_update_checklist_itemUpdate a checklist item — mark done (is_checked) or rename (partial patch).
outlook_delete_checklist_itemDelete a checklist item from a task.
outlook_list_task_attachmentsList attachments on a To Do task (id, name, size, content_type) with pagination.
outlook_download_task_attachmentDownload a task attachment's content to a local file (confined to attachments_dir).
outlook_upload_task_attachmentAttach a local file (from attachments_dir) to a task via inline base64 POST (1 byte – 20 MiB).
outlook_delete_task_attachmentRemove an attachment from a To Do task.

Drafts

ToolDescription
outlook_list_draftsList draft messages with pagination.
outlook_create_draftCreate a draft. Supports scheduled delivery via deferred_send_datetime (server-side, Outlook-desktop-compatible "Delay Delivery").
outlook_update_draftUpdate draft fields. Accepts is_html=True for HTML bodies and deferred_send_datetime to set or clear the scheduled delivery time.
outlook_send_draftSend an existing draft.
outlook_delete_draftDelete a draft.

Attachments

Since 1.20.0, these tools only reach attachments_dir (default ~/.outlook-mcp/attachments). A bare filename resolves inside it; a path outside it is refused, including via a symlink. To email a file, move it there first — or widen attachments_dir, understanding that anything reachable from it can be sent. Before 1.20.0 these tools could read any file the server process could read, which meant an email asking an agent to attach one could be obeyed.

The same fence covers the To Do attachment tools (outlook_upload_task_attachment, outlook_download_task_attachment): uploads read from attachments_dir and downloads write into it, so neither can sweep arbitrary files off disk. (Downloads are not todo_write-gated — they are reads, like outlook_download_attachment; the fence, not the category, is what confines them.)

ToolDescription
outlook_list_attachmentsList attachments on a message.
outlook_download_attachmentDownload an attachment and save decoded bytes into attachments_dir.
outlook_send_with_attachmentsSend a message with attachments read from attachments_dir (auto upload session for >3MB).
outlook_attach_to_draftAdd attachments from attachments_dir to an existing draft (auto upload session for >3MB).
outlook_remove_draft_attachmentRemove a single attachment from a draft.

Folder Management

ToolDescription
outlook_create_folderCreate mail folder (top-level or nested).
outlook_rename_folderRename a mail folder.
outlook_delete_folderDelete a mail folder (refuses well-known folders).

Threading and Batch

ToolDescription
outlook_list_threadGet all messages in a conversation thread.
outlook_copy_messageCopy a message to another folder.
outlook_batch_triageBatch move/flag/categorize/mark_read (max 20 per call). Single Graph /$batch round-trip — 10-20× faster than per-message calls for large triage.

User and Admin

ToolDescription
outlook_whoamiGet current user profile.
outlook_list_calendarsList available calendars.
outlook_list_categoriesList category definitions with colors.
outlook_get_mail_tipsPre-send check (OOF, delivery restrictions).

Prompts

Three workflows ship as MCP prompts, so the common sequences do not have to be reconstructed call by call. Any MCP client that supports prompts will list them; in most clients they appear as slash commands or a prompt picker.

PromptArgumentsWhat it does
morning_brieffolder (default inbox)Today's events, unread mail and tasks due, in the cheapest order — one scan each, concise=True, batched reads.
triage_folderfolder (default inbox), count (default 50)One cheap scan of a folder, sorted into reply / archive / junk, applied with a single outlook_batch_triage call rather than one call per message.
catch_upsince (default 24h)What changed in mail, calendar and contacts, via the delta path — roughly ten times cheaper than re-scanning on a schedule.

They cost nothing until invoked: prompts/list carries only a name and one line each, and the body is fetched on use.


Configuration

Config lives at ~/.outlook-mcp/config.json (created with 0600 permissions on macOS and Linux; see Config permissions below for Windows). It is read as UTF-8 on every platform, and a byte-order mark is accepted. Set the OUTLOOK_MCP_CONFIG_DIR environment variable to move that settings directory (config.json, auth record, and the attachments default move with it) — see Two accounts, two instances below.

FieldTypeDefaultDescription
client_idstringnullAzure AD application (client) ID. Required for auth.
tenant_idstring"consumers"Azure AD tenant. Use "consumers" for personal Microsoft accounts.
timezonestring"UTC"IANA timezone (e.g. "America/New_York"). Interprets zone-less dates, and anchors every event you create — a recurring event is expanded in this zone, so on the default "UTC" a 09:00 weekly meeting shifts an hour when the clocks change. Set it to where you are.
read_onlyboolfalseWhen true, all write tools (send, reply, move, delete, create, update, RSVP) return an error. Gates the tools, not the Microsoft token -- see below.
read_only_consentboolfalseWhen true, outlook-mcp auth asks Microsoft for the read permissions only, instead of the read-write set. For a second, read-only app registration -- see What read_only does and does not do. Requires read_only: true; the config is refused without it.
attachments_dirstring"~/.outlook-mcp/attachments"The only directory the attachment tools may read from or write to. Every path an agent supplies is resolved and must land inside it — a symlink out or a .. is refused. Widen it only if you understand that anything reachable can be emailed.
allow_categorieslist[string][]Optional. Restrict write tools to specific categories (see below). Empty list = all writes allowed when read_only: false.
allow_unencrypted_token_cacheboolfalsePermit the OAuth token cache to be written in cleartext when the platform has no encrypted store (Linux without libsecret). Off by default: authentication stops with an explanation rather than silently persisting a reusable Graph token in plaintext. macOS and Windows always encrypt and are unaffected.

Toolset selection (optional) — OUTLOOK_MCP_TOOLSETS

All 68 tool schemas load into the client's context every turn (the chars/4 proxy test_tool_surface_budget.py measures with; a different yardstick than the ~8.6k o200k figure in ROADMAP for the 62-tool surface). A client that only needs part of the surface can set the OUTLOOK_MCP_TOOLSETS environment variable to a comma-separated list of tool groups, and only those load. The account group (auth / identity) is always available.

# e.g. a recurring mail + calendar agent: ~30 tools instead of 68 (~55% fewer tool tokens/turn)
OUTLOOK_MCP_TOOLSETS="mail,calendar,digest,delta"

Groups: mail, drafts, attachments, calendar, contacts, todo, folders, digest, delta, admin. Unset (the default) loads everything — fully backward compatible. This only affects which tools are advertised; enabled tools behave identically.

Two accounts, two instances (optional) — OUTLOOK_MCP_CONFIG_DIR

One server process serves one mailbox. To work against two accounts, register two client entries and give each its own settings directory with OUTLOOK_MCP_CONFIG_DIR — pair it with OUTLOOK_MCP_TOOLSETS so each instance also only loads the tool groups it needs:

{
  "mcpServers": {
    "outlook-net": {
      "command": "outlook-mcp",
      "env": {
        "OUTLOOK_MCP_TOOLSETS": "mail,calendar,contacts",
        "OUTLOOK_MCP_CONFIG_DIR": "~/.outlook-mcp-net"
      }
    },
    "outlook-neko": {
      "command": "outlook-mcp",
      "env": {
        "OUTLOOK_MCP_TOOLSETS": "todo",
        "OUTLOOK_MCP_CONFIG_DIR": "~/.outlook-mcp-neko"
      }
    }
  }
}

Then run outlook-mcp auth once per instance, with the same env set, to write each auth record in its own directory. Each instance reads its own config.json (own client_id, timezone, permissions) from its own directory.

Only move the config directory — never HOME. The token cache is not in it: it stays in the OS keyring, and on macOS every azure-identity cache on the host shares one Keychain item, coordinated through a signal file — on this server, ~/.IdentityService/outlook-mcp.nocae (azure-identity appends .nocae to every non-CAE cache name; a CAE cache would be a different file over the same item). Both processes must keep consulting that same signal file so their cache writes lock and merge into the one shared entry — which is exactly what moving the config directory preserves and redirecting HOME (or the cache location) would break: two signal files that each believe they own the Keychain item overwrite each other's token. OUTLOOK_MCP_CONFIG_DIR deliberately moves only where config.json, the auth record, and attachments live; unset or empty keeps the default ~/.outlook-mcp.

What read_only does and does not do

read_only: true stops outlook-mcp's write tools from running. Ask it to send mail and it refuses.

It does not make your Microsoft credential read-only. The first sign-in consents the full read-write set, even with read_only: true in the config — the scopes a first consent leaves out can never be added without logging in again (every refresh afterwards uses .default -- "everything this account has already consented" -- so a session granted only read scopes would fail every write with 403 no matter what the config says). The stored token can send mail whether read_only is on or off, and a session consented before you turned read_only on keeps its write scopes.

Two consequences worth understanding:

  • read_only is a line in a text file. Anything able to edit ~/.outlook-mcp/config.json turns it off and has write access immediately -- no re-authentication, no new consent prompt.
  • The enforcement lives in this server's Python code. Any other process holding the cached token is unaffected by it.

So treat read_only as a guardrail against an agent doing something rash, not as a security boundary. If you want a credential that genuinely cannot write, have Microsoft enforce it rather than us:

  1. Register a second Azure app and give it the read permissions only: Mail.Read, Calendars.Read, Contacts.Read, Tasks.Read, MailboxSettings.Read, User.Read. It has to be an app this account has never granted write access to. Microsoft remembers consent per app, and a refresh returns everything that app was ever granted.

  2. Point client_id at it and set both keys:

    { "client_id": "<the read-only app>", "read_only": true, "read_only_consent": true }
    
  3. Run outlook-mcp auth. With read_only_consent the consent screen lists the read permissions only. Without it, sign-in would ask this app for the read-write set too.

read_only_consent is refused without read_only: true: a sign-in that asked only for read access cannot write, so a server expecting writes would fail on every one. And a sign-in belongs to the app it was made with. After client_id changes, the server will not use the old one — outlook-mcp status and outlook_auth_status say so until you run outlook-mcp auth again.

Granular Write Permissions (optional)

By default, read_only: false unlocks all write tools. For finer control, set allow_categories to restrict write access to specific categories. Read tools (list, search, get) are always allowed — allow_categories only narrows the write surface.

Available categories:

CategoryToolsRisk
mail_draftscreate/update/delete draftSafe — drafts only, no send
mail_triagemove, delete (soft), flag, categorize, mark read, copy, batchModerate — reversible except hard delete
mail_folderscreate/rename/delete folderModerate
mail_sendsend, reply, forward, send_draft, send_with_attachmentsDangerous — sends email on your behalf
calendar_writecreate/update/delete event, RSVPModerate — your own calendar. The parts that email other people text the agent wrote need mail_send as well: inviting attendees, rewording (subject, body, location) any event that already has them, and adding a message to an RSVP. A bare RSVP, a time change and a cancellation still notify the people involved, but carry nothing the agent wrote
contacts_writecreate/update/delete contactModerate
todo_writecreate/update/complete/delete task, checklist items; upload/delete task attachmentsModerate — your own task list, but outlook_upload_task_attachment reads local files from attachments_dir and pushes their bytes to Graph, and task/checklist/attachment deletes are irreversible. Listing and downloading attachments are plain reads, gated like every other read (not at all) and fenced to attachments_dir

Example policies:

Draft-only assistant (agent can compose drafts, you review and send):

{ "read_only": false, "allow_categories": ["mail_drafts", "mail_triage", "todo_write"] }

(Note that todo_write includes the write-side task-attachment tools — file reads from attachments_dir, uploads to Graph, and irreversible deletes. Listing and downloading task attachments are reads and are not write-gated, like the mail attachment reads — see the table above.)

Calendar-only (agent can manage your schedule, nothing else):

{ "read_only": false, "allow_categories": ["calendar_write"] }

(It cannot invite anyone. An invitation is an email, so attendees need mail_send too — add it if the agent should set up meetings with other people, not just block out your own time.)

Full write access (agent can do everything):

{ "read_only": false }

Read-only (safest default, no writes):

{ "read_only": true }

When allow_categories is set, any tool in a non-allowed category returns a permission-denied error (PermissionDeniedError) naming the blocked category. When allow_categories is empty (or unset) and read_only is false, all write tools are permitted. read_only: true always takes precedence — if set, all writes are blocked regardless of allow_categories. Unknown category names are rejected at config load time with a validation error; only the seven names above are accepted.


Privacy and Security

  • Zero telemetry. No analytics, no tracking, no usage data collected.
  • Zero local caching. Every call goes directly to Microsoft Graph. No local email/calendar storage. (One carve-out: the To Do default-list id is resolved once per process and kept for the session — an id, not content; see outlook_list_tasks.)
  • Zero third-party calls. The server only talks to graph.microsoft.com and login.microsoftonline.com.
  • Token storage. OAuth tokens are persisted via azure-identity's TokenCachePersistenceOptions. On macOS the OS Keychain is used; on Windows, DPAPI; on Linux with PyGObject/libsecret available, gnome-keyring. On Linux without libsecret (e.g. the isolated venv created by uv tool install), tokens fall back to a 0600 plaintext file at ~/.IdentityService/ and the MCP logs a one-time warning at startup. For encrypted storage on Linux, install python3-gi gnome-keyring libsecret-1-0 and re-create the venv with --system-site-packages.
  • No logging of sensitive data. Message bodies, recipient addresses, and tokens are never logged.
  • Config permissions. On macOS and Linux the config directory is created 0700 and the config file 0600, and a loose mode on the file is repaired on load. On Windows those POSIX modes cannot be enforced — os.chmod there sets only the read-only attribute — so access is governed by the path's Windows ACL, including whatever it inherits from the directory it was created under, which this server neither applies nor verifies. Symlinked configs are rejected on every platform.
  • Input validation. All user inputs (email addresses, Graph IDs, OData filters, KQL queries, datetimes) are validated and sanitized before reaching the Graph API.

Development

# Install dev dependencies
uv sync --extra dev

# Run tests
uv run pytest

# Lint
uv run ruff check src/ tests/ scripts/

# Format (CI fails if `ruff format --check` would change a file)
uv run ruff format src/ tests/ scripts/

# Run server locally (stdio)
uv run outlook-mcp

Requirements: Python 3.10+


Roadmap

  • Inbox Rules -- list, create, delete rules
  • Advanced mail -- raw MIME export, internet message headers
  • Calendar -- cancel event (with attendee notification)
  • Enterprise (Entra ID) -- work/school account support

License

MIT. See LICENSE.

Featured
CodeRabbit
CodeRabbit
AI writes the code. CodeRabbit catches the slop.
Try For Free →
Lid closed, agents working
Lid closed, agents working
Keeps your Mac awake while Claude Code, Codex or Cursor works. Lets it sleep when they are done.
Try free for 7 days →
Block distraction from your iPhone for freeBlock distraction from your iPhone for free
Block distraction from your iPhone for free
Block distracting apps from your iPhone permanently without a 3rd party app. Free and open source.
Block now (100% free) →
Granola, the best AI meeting recorder
Granola, the best AI meeting recorder
Notes, actions and memory. Without a meeting bot. First month 100% off.
Download for free →
belt - the only tool your agent needs
belt - the only tool your agent needs
belt cli automatically finds the best tools and skills for your agent. image, video, music, tts...
one prompt install →
Open Steps
Open Steps
Free an open-source skills that make AI coding agents easier to understand, verify, and control.
Download for free →
AppSignal
AppSignal
Monitor with ease. Code with confidence.
Start Free Trial →
Agent, connect blockchain
Agent, connect blockchain
Connect your Claude agent to live crypto prices and trading routes via 1inch
Get the MCP →
Categories
Communication & MessagingProductivity & Office
Registryactive
Packageoutlook-graph-mcp
TransportSTDIO
UpdatedMay 23, 2026
View on GitHub

Related Communication & Messaging MCP Servers

View all →
gx-55 avatar
Multi Gmail Mcp

gx-55/multi-gmail-mcp

Manage multiple Gmail accounts in Claude Desktop — search, send, reply, draft, and organize.
11
rlrghb avatar
Outlook

io.github.rlrghb/outlook

Outlook & OneDrive MCP: personal & enterprise tools for mail, calendar, contacts, tasks, files
11
pasympa avatar
Discord Mcp

pasympa/discord-mcp

A lightweight, multi-guild Discord MCP server with 95+ tools
11
mintmcp avatar
Gmail

com.mintmcp/gmail

A MCP server for Gmail that lets you search, read, and draft emails and replies.
8
mintmcp avatar
Outlook Calendar

com.mintmcp/outlook-calendar

A MCP server that works with Outlook Calendar to manage event listing, reading, and updates.
8
mindstone avatar
Slack

io.github.mindstone/mcp-server-slack

Slack MCP server: channels, messages, threads, reactions, users, files, and scheduled messages
8