Install outlook-graph-mcp from PyPI
Install exact version 1.14.0. The executable name has not been verified, so it is intentionally not guessed.
python -m pip install 'outlook-graph-mcp==1.14.0'MCP server that provides 62 tools to manage Outlook mail, calendar, contacts, and tasks for personal Microsoft accounts via Microsoft Graph API
Detailed security scan evidence is not public for this MCP yet. Public identity, registry metadata, and independently observed protocol inventory remain available.
Installation and connection instructions are shown only when supported by retained package, repository, or endpoint evidence.
Install exact version 1.14.0. The executable name has not been verified, so it is intentionally not guessed.
python -m pip install 'outlook-graph-mcp==1.14.0'| Canonical slug | outlook-mcp-09d2e618 | Deployment | Local Only |
|---|---|---|---|
| Canonical package | pypi:outlook-graph-mcp | Repository | mpalermiti/outlook-mcp |
| First published | Jul 19, 2026 | Latest release | Sep 4, 2026 |
| Last security verification | — | Classification confidence | 90% |
| Publication | Draft | Official distribution | Not verified |
| Channel | Identifier | Current version | Versions | Source |
|---|---|---|---|---|
| pypi | outlook-graph-mcp | 1.14.0 | 3 | Repository |
| Package | Version | Published / observed | Inventory | Security scan |
|---|---|---|---|---|
| pypioutlook-graph-mcp | 1.14.0Current | Sep 4, 2026 | 62 toolsSucceeded · 0 resources · 0 prompts | Evidence restricted |
Independently scan the exact version your agents use, receive alerts when its risk changes, and investigate every finding with retained version evidence.
No public current-version evidence is available yet.
| Tool | Category | Annotations | Risk |
|---|---|---|---|
outlook_attach_to_draftAdd attachments to an existing draft; auto-switches to upload-session for files >3MB.
`attachment_paths` must be absolute paths to files that exist on the host. Returns new
attachment IDs for later removal via outlook_remove_draft_attachment.
Input schema{
"properties": {
"draft_id": {
"title": "Draft Id",
"type": "string"
},
"attachment_paths": {
"items": {
"type": "string"
},
"title": "Attachment Paths",
"type": "array"
}
},
"required": [
"draft_id",
"attachment_paths"
],
"type": "object",
"title": "outlook_attach_to_draftArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_auth_statusCheck authentication status. Run `outlook-mcp auth` on the host if needed.Input schema{
"properties": {},
"type": "object",
"title": "outlook_auth_statusArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_batch_triageTriage up to 20 messages in one $batch call.
`action` is "move", "flag", "categorize", or "mark_read".
Example: outlook_batch_triage(message_ids=[id1, id2], action="move", value="Archive")
`value` is the action target (folder name for move, status for flag/mark_read, category name
for categorize). Hard cap of 20.
Input schema{
"properties": {
"message_ids": {
"items": {
"type": "string"
},
"title": "Message Ids",
"type": "array"
},
"action": {
"title": "Action",
"type": "string"
},
"value": {
"title": "Value",
"type": "string"
}
},
"required": [
"message_ids",
"action",
"value"
],
"type": "object",
"title": "outlook_batch_triageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_categorize_messageSet categories on a message (replaces the full list).
Example: outlook_categorize_message(message_id=..., categories=["Follow-up", "Pricing"])
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"categories": {
"items": {
"type": "string"
},
"title": "Categories",
"type": "array"
}
},
"required": [
"message_id",
"categories"
],
"type": "object",
"title": "outlook_categorize_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_changes_sinceOne structured "since last call" digest across mail, events, and contacts.
Use this for recurring agent loops (morning brief, hourly inbox sweep) — one call
returns counts, urgent_flagged mail, by-sender rollup, plus new/cancelled events and
contacts counts. Use the three individual delta tools (outlook_list_inbox_delta,
outlook_list_events_delta, outlook_list_contacts_delta) when you need raw item lists
or per-resource control.
Example: first call: outlook_changes_since(); next:
outlook_changes_since(delta_tokens=<delta_tokens from prior response>).
First call returns a snapshot filtered to the last `fallback_window_hours` (default 24)
so the digest doesn't surface thousands of historical items; subsequent calls (tokens
passed back) return only what changed. Each resource's token is independent — drop
one stale token without re-syncing the others. If Graph 410s on a token
(`syncStateNotFound`), that resource auto-resyncs and `_meta.resync` lists which one.
`urgent_flagged` = high-importance OR flagged mail. `by_sender` = top 5 senders.
Calendar `modified[]` is reserved for future use — modified events surface in `new[]`
today (Graph delta doesn't distinguish them). Calendar `organizer_email` is also
currently empty (the v1.9.0 delta formatter surfaces the organizer name only).
Input schema{
"properties": {
"delta_tokens": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"title": "Delta Tokens"
},
"fallback_window_hours": {
"default": 24,
"title": "Fallback Window Hours",
"type": "integer"
}
},
"type": "object",
"title": "outlook_changes_sinceArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_complete_taskMark a To Do task as completed.Input schema{
"properties": {
"task_id": {
"title": "Task Id",
"type": "string"
},
"list_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "List Id"
}
},
"required": [
"task_id"
],
"type": "object",
"title": "outlook_complete_taskArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_copy_messageCopy a message to another folder (duplicates; source is unchanged).
Use outlook_move_message to remove from source. `folder` accepts display names, well-known
names, or Graph IDs — prefer names.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"folder": {
"title": "Folder",
"type": "string"
}
},
"required": [
"message_id",
"folder"
],
"type": "object",
"title": "outlook_copy_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_create_contactCreate a new contact with name and optional email, phone, company, title.Input schema{
"properties": {
"first_name": {
"title": "First Name",
"type": "string"
},
"last_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Last Name"
},
"email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Email"
},
"phone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Phone"
},
"company": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Company"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title"
}
},
"required": [
"first_name"
],
"type": "object",
"title": "outlook_create_contactArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_create_draftCreate a draft email for later review/send (pair with outlook_send_draft).
Use this when a human should review before sending; use outlook_send_message to send
immediately without review.
Pass deferred_send_datetime (ISO 8601, e.g. "2026-05-06T08:00:00Z") to schedule delayed
delivery — Exchange holds the message server-side after outlook_send_draft.
Pass reply_to to pre-populate the Reply-To header.
Input schema{
"properties": {
"to": {
"items": {
"type": "string"
},
"title": "To",
"type": "array"
},
"subject": {
"title": "Subject",
"type": "string"
},
"body": {
"title": "Body",
"type": "string"
},
"cc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Cc"
},
"bcc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Bcc"
},
"is_html": {
"default": false,
"title": "Is Html",
"type": "boolean"
},
"importance": {
"default": "normal",
"title": "Importance",
"type": "string"
},
"reply_to": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Reply To"
},
"deferred_send_datetime": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Deferred Send Datetime"
}
},
"required": [
"to",
"subject",
"body"
],
"type": "object",
"title": "outlook_create_draftArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_create_eventCreate a calendar event with optional attendees, recurrence, and Teams online meeting.
Example: outlook_create_event(subject="Q3 review", start="2026-08-15T14:00:00Z",
end="2026-08-15T15:00:00Z", attendees=["alice@acme.com"], is_online=True)
`start`/`end` are ISO 8601. `recurrence` accepts a simple string ("daily", "weekly", "monthly").
Input schema{
"properties": {
"subject": {
"title": "Subject",
"type": "string"
},
"start": {
"title": "Start",
"type": "string"
},
"end": {
"title": "End",
"type": "string"
},
"location": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Location"
},
"body": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body"
},
"attendees": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Attendees"
},
"is_all_day": {
"default": false,
"title": "Is All Day",
"type": "boolean"
},
"is_online": {
"default": false,
"title": "Is Online",
"type": "boolean"
},
"recurrence": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Recurrence"
}
},
"required": [
"subject",
"start",
"end"
],
"type": "object",
"title": "outlook_create_eventArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_create_folderCreate a mail folder; pass `parent_folder` (name or ID) to nest under an existing folder.Input schema{
"properties": {
"name": {
"title": "Name",
"type": "string"
},
"parent_folder": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Parent Folder"
}
},
"required": [
"name"
],
"type": "object",
"title": "outlook_create_folderArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_create_taskCreate a Microsoft To Do task with optional due date, importance, body, and recurrence.
Example: outlook_create_task(title="Send invoice", due="2026-09-01", importance="high")
`due` is ISO 8601. `importance` is "low", "normal", or "high". Defaults to the user's default
list when `list_id` is omitted.
Input schema{
"properties": {
"title": {
"title": "Title",
"type": "string"
},
"list_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "List Id"
},
"due": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Due"
},
"importance": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Importance"
},
"body": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body"
},
"reminder": {
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
],
"default": null,
"title": "Reminder"
},
"recurrence": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"default": null,
"title": "Recurrence"
}
},
"required": [
"title"
],
"type": "object",
"title": "outlook_create_taskArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_delete_contactDelete a contact by ID.Input schema{
"properties": {
"contact_id": {
"title": "Contact Id",
"type": "string"
}
},
"required": [
"contact_id"
],
"type": "object",
"title": "outlook_delete_contactArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_draftDelete a draft message by ID.Input schema{
"properties": {
"draft_id": {
"title": "Draft Id",
"type": "string"
}
},
"required": [
"draft_id"
],
"type": "object",
"title": "outlook_delete_draftArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_eventDelete a calendar event by ID (cancels and notifies attendees if you're the organizer).Input schema{
"properties": {
"event_id": {
"title": "Event Id",
"type": "string"
}
},
"required": [
"event_id"
],
"type": "object",
"title": "outlook_delete_eventArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_folderDelete a user-created mail folder by ID; refuses well-known folders (inbox, sentitems).Input schema{
"properties": {
"folder_id": {
"title": "Folder Id",
"type": "string"
}
},
"required": [
"folder_id"
],
"type": "object",
"title": "outlook_delete_folderArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_inbox_overrideDelete a Focused Inbox per-sender override rule by its ID.Input schema{
"properties": {
"override_id": {
"title": "Override Id",
"type": "string"
}
},
"required": [
"override_id"
],
"type": "object",
"title": "outlook_delete_inbox_overrideArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_messageDelete a message — soft delete (to Deleted Items) by default; permanent=True to hard-delete.
This is the canonical way to delete a message. Do NOT use
outlook_move_message(folder="deleteditems") for deletion.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"permanent": {
"default": false,
"title": "Permanent",
"type": "boolean"
}
},
"required": [
"message_id"
],
"type": "object",
"title": "outlook_delete_messageArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_delete_taskDelete a task from a Microsoft To Do list.Input schema{
"properties": {
"task_id": {
"title": "Task Id",
"type": "string"
},
"list_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "List Id"
}
},
"required": [
"task_id"
],
"type": "object",
"title": "outlook_delete_taskArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_download_attachmentDownload an attachment from a message and write decoded bytes to `save_path` on the host.Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"attachment_id": {
"title": "Attachment Id",
"type": "string"
},
"save_path": {
"title": "Save Path",
"type": "string"
}
},
"required": [
"message_id",
"attachment_id",
"save_path"
],
"type": "object",
"title": "outlook_download_attachmentArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_flag_messageSet the follow-up flag on a message. `status` is "flagged", "complete", or "notFlagged".Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"status": {
"title": "Status",
"type": "string"
}
},
"required": [
"message_id",
"status"
],
"type": "object",
"title": "outlook_flag_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_forwardForward an existing message to new recipients, with optional comment.Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"to": {
"items": {
"type": "string"
},
"title": "To",
"type": "array"
},
"comment": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Comment"
}
},
"required": [
"message_id",
"to"
],
"type": "object",
"title": "outlook_forwardArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_get_contactGet one full contact by ID.Input schema{
"properties": {
"contact_id": {
"title": "Contact Id",
"type": "string"
}
},
"required": [
"contact_id"
],
"type": "object",
"title": "outlook_get_contactArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_get_eventGet one full calendar event by ID, including body, attendees, organizer, and recurrence.Input schema{
"properties": {
"event_id": {
"title": "Event Id",
"type": "string"
}
},
"required": [
"event_id"
],
"type": "object",
"title": "outlook_get_eventArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_get_mail_tipsPre-send check for recipients: out-of-office, delivery limits, mailbox-full warnings.Input schema{
"properties": {
"emails": {
"items": {
"type": "string"
},
"title": "Emails",
"type": "array"
}
},
"required": [
"emails"
],
"type": "object",
"title": "outlook_get_mail_tipsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_accountsList all configured Outlook accounts and their authentication status.Input schema{
"properties": {},
"type": "object",
"title": "outlook_list_accountsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_attachmentsList attachments on a message — returns IDs, names, sizes, and content types.Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
}
},
"required": [
"message_id"
],
"type": "object",
"title": "outlook_list_attachmentsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_calendarsList all calendars available to the authenticated user (primary + secondary).Input schema{
"properties": {},
"type": "object",
"title": "outlook_list_calendarsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_categoriesList the user's master category definitions (names + colors).
Provides the valid values for outlook_categorize_message.
Input schema{
"properties": {},
"type": "object",
"title": "outlook_list_categoriesArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_contactsList contacts with cursor pagination.
Use for one-shot queries; use outlook_list_contacts_delta for polling/recurring agents.
Input schema{
"properties": {
"count": {
"default": 25,
"title": "Count",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
}
},
"type": "object",
"title": "outlook_list_contactsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_contacts_deltaList only contact changes since the last call.
Use this for polling/recurring agents — typically 10x cheaper than outlook_list_contacts after
the first call. Use outlook_list_contacts for one-shot queries.
Example: first call: outlook_list_contacts_delta(); next:
outlook_list_contacts_delta(delta_token=<token from prior response>).
is_deleted=True items are tombstones (drop cached payload). has_more=True means drain
immediately by passing the returned delta_token back.
Input schema{
"properties": {
"page_size": {
"default": 50,
"title": "Page Size",
"type": "integer"
},
"delta_token": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Delta Token"
}
},
"type": "object",
"title": "outlook_list_contacts_deltaArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_draftsList messages in the Drafts folder with cursor pagination.Input schema{
"properties": {
"count": {
"default": 25,
"title": "Count",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
}
},
"type": "object",
"title": "outlook_list_draftsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_eventsList calendar events in a date range (expands recurring instances).
Use for one-shot queries; use outlook_list_events_delta for polling/recurring agents.
Pass concise=True to drop large fields (body, attendees, organizer, categories) — ~10x fewer
tokens for day-at-a-glance scans.
Input schema{
"properties": {
"days": {
"default": 7,
"title": "Days",
"type": "integer"
},
"after": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "After"
},
"before": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Before"
},
"count": {
"default": 50,
"title": "Count",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
}
},
"type": "object",
"title": "outlook_list_eventsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_events_deltaList only calendar event changes within a window since the last call.
Use this for polling/recurring agents — typically 10x cheaper than outlook_list_events after
the first call. Use outlook_list_events for one-shot queries.
Example: first call: outlook_list_events_delta(start="2026-05-22T00:00:00Z",
end="2026-05-29T00:00:00Z"); next: outlook_list_events_delta(delta_token=<token>).
start/end (ISO 8601) required on first call only; the cursor encodes the window thereafter.
is_deleted=True items are tombstones. has_more=True means drain immediately.
Input schema{
"properties": {
"start": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Start"
},
"end": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "End"
},
"page_size": {
"default": 50,
"title": "Page Size",
"type": "integer"
},
"delta_token": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Delta Token"
}
},
"type": "object",
"title": "outlook_list_events_deltaArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_foldersList mail folders with message counts, parent_id, and child count.
Default is top-level only; pass recursive=True to walk the full tree and resolve subfolder
names.
Input schema{
"properties": {
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
},
"recursive": {
"default": false,
"title": "Recursive",
"type": "boolean"
}
},
"type": "object",
"title": "outlook_list_foldersArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_inboxList messages in one folder with structured filters (read, sender, date, category, Focused).
Use this for folder-scoped browsing; use outlook_search_mail for KQL full-text search across
all folders. For polling/recurring agents use outlook_list_inbox_delta (typically 10x cheaper
after the first call).
Example: outlook_list_inbox(folder="Junk Email", unread_only=True, count=5)
`folder` accepts display names, well-known names ("inbox", "junkemail"), or Graph IDs — prefer
names. Pass concise=True to drop large fields (preview, categories) — ~10x fewer tokens.
Pass uncategorized_only=True to return only messages with no categories assigned.
Input schema{
"properties": {
"folder": {
"default": "inbox",
"title": "Folder",
"type": "string"
},
"count": {
"default": 25,
"title": "Count",
"type": "integer"
},
"unread_only": {
"default": false,
"title": "Unread Only",
"type": "boolean"
},
"from_address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "From Address"
},
"after": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "After"
},
"before": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Before"
},
"skip": {
"default": 0,
"title": "Skip",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
},
"classification": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Classification"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
},
"uncategorized_only": {
"default": false,
"title": "Uncategorized Only",
"type": "boolean"
}
},
"type": "object",
"title": "outlook_list_inboxArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_inbox_deltaList only inbox changes since the last call.
Use this for polling/recurring agents — typically 10x cheaper than outlook_list_inbox after
the first call. Use outlook_list_inbox for one-shot snapshots.
Example: first call: outlook_list_inbox_delta(); next:
outlook_list_inbox_delta(delta_token=<token from prior response>).
is_deleted=True items are tombstones (drop cached payload). has_more=True means drain
immediately by passing the returned delta_token back.
Input schema{
"properties": {
"folder": {
"default": "inbox",
"title": "Folder",
"type": "string"
},
"page_size": {
"default": 50,
"title": "Page Size",
"type": "integer"
},
"delta_token": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Delta Token"
}
},
"type": "object",
"title": "outlook_list_inbox_deltaArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_inbox_overridesList the user's Focused Inbox per-sender override rules.
Each override forces mail from a given sender into Focused or Other regardless of Graph's
inference.
Input schema{
"properties": {},
"type": "object",
"title": "outlook_list_inbox_overridesArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_task_listsList all Microsoft To Do task lists for the current user.Input schema{
"properties": {},
"type": "object",
"title": "outlook_list_task_listsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_tasksList tasks in a To Do list with optional `status` filter.
`status`: "notStarted", "inProgress", or "completed".
Input schema{
"properties": {
"list_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "List Id"
},
"status": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Status"
},
"count": {
"default": 25,
"title": "Count",
"type": "integer"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
}
},
"type": "object",
"title": "outlook_list_tasksArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_list_threadList all messages in a conversation thread, chronological order.
Needs `conversation_id` from a message's metadata. Pass concise=True to drop large fields
(quoted prior-message text in each preview) — ~10x fewer tokens on long reply chains.
Input schema{
"properties": {
"conversation_id": {
"title": "Conversation Id",
"type": "string"
},
"count": {
"default": 50,
"title": "Count",
"type": "integer"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
}
},
"required": [
"conversation_id"
],
"type": "object",
"title": "outlook_list_threadArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_mark_readMark a single message as read or unread (set is_read=True or False).Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"is_read": {
"title": "Is Read",
"type": "boolean"
}
},
"required": [
"message_id",
"is_read"
],
"type": "object",
"title": "outlook_mark_readArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_move_messageMove a message to another folder (removes from source).
Use outlook_copy_message to duplicate without removing the source. For deletion use
outlook_delete_message (not move to "deleteditems"). `folder` accepts display names,
well-known names ("inbox", "archive", "deleteditems"), or Graph IDs — prefer names.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"folder": {
"title": "Folder",
"type": "string"
}
},
"required": [
"message_id",
"folder"
],
"type": "object",
"title": "outlook_move_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_read_messageGet one full message by ID. `format` is "text", "html", or "full" (both).
Pass include_deferred_send=True to also return the scheduled-send time (PR_DEFERRED_SEND_TIME)
as deferred_send_datetime — useful when recreating a delayed draft.
Pass concise=True to drop large fields (body, body_html) and return a 200-char body_preview —
~10x fewer tokens for triage scans.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"format": {
"default": "text",
"title": "Format",
"type": "string"
},
"include_deferred_send": {
"default": false,
"title": "Include Deferred Send",
"type": "boolean"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
}
},
"required": [
"message_id"
],
"type": "object",
"title": "outlook_read_messageArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_read_messagesBulk read up to 20 messages by ID via $batch — use NOT N outlook_read_message calls.
Per-message shape in `messages` matches outlook_read_message byte-for-byte for the same
(format, concise, include_deferred_send). Ordering follows input `message_ids`. Returns
`{messages, failures, requested, succeeded, failed}` — 404s on some IDs are surfaced in
`failures` without failing the whole call (partial-failure tolerant).
Example: outlook_read_messages(message_ids=[id1, id2, id3], concise=True)
Hard cap of 20 (Graph $batch limit).
Input schema{
"properties": {
"message_ids": {
"items": {
"type": "string"
},
"title": "Message Ids",
"type": "array"
},
"format": {
"default": "text",
"title": "Format",
"type": "string"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
},
"include_deferred_send": {
"default": false,
"title": "Include Deferred Send",
"type": "boolean"
}
},
"required": [
"message_ids"
],
"type": "object",
"title": "outlook_read_messagesArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_reclassify_messageReclassify ONE message's Focused/Other placement. `classification` is "focused" or "other".
Use this to fix a single message; use outlook_set_inbox_override for a sticky rule that affects
future messages from the same sender.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"classification": {
"title": "Classification",
"type": "string"
}
},
"required": [
"message_id",
"classification"
],
"type": "object",
"title": "outlook_reclassify_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_remove_draft_attachmentRemove a single attachment from a draft message by attachment ID.Input schema{
"properties": {
"draft_id": {
"title": "Draft Id",
"type": "string"
},
"attachment_id": {
"title": "Attachment Id",
"type": "string"
}
},
"required": [
"draft_id",
"attachment_id"
],
"type": "object",
"title": "outlook_remove_draft_attachmentArguments"
}Annotations{
"destructiveHint": true,
"readOnlyHint": false
} | — | WritesDestructive | — |
outlook_rename_folderRename a user-created mail folder by ID.Input schema{
"properties": {
"folder_id": {
"title": "Folder Id",
"type": "string"
},
"name": {
"title": "Name",
"type": "string"
}
},
"required": [
"folder_id",
"name"
],
"type": "object",
"title": "outlook_rename_folderArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_replyReply (or reply-all) to an email message.
Use this for email; use outlook_rsvp for calendar meeting invites.
Input schema{
"properties": {
"message_id": {
"title": "Message Id",
"type": "string"
},
"body": {
"title": "Body",
"type": "string"
},
"reply_all": {
"default": false,
"title": "Reply All",
"type": "boolean"
},
"is_html": {
"default": false,
"title": "Is Html",
"type": "boolean"
}
},
"required": [
"message_id",
"body"
],
"type": "object",
"title": "outlook_replyArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_rsvpRSVP to a calendar meeting invite. `response` is "accept", "decline", or "tentative".
Use this for meeting invites; use outlook_reply to reply to a regular email message.
Input schema{
"properties": {
"event_id": {
"title": "Event Id",
"type": "string"
},
"response": {
"title": "Response",
"type": "string"
},
"message": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Message"
}
},
"required": [
"event_id",
"response"
],
"type": "object",
"title": "outlook_rsvpArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_search_contactsSearch contacts by name or email using KQL query syntax.Input schema{
"properties": {
"query": {
"title": "Query",
"type": "string"
},
"count": {
"default": 25,
"title": "Count",
"type": "integer"
}
},
"required": [
"query"
],
"type": "object",
"title": "outlook_search_contactsArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_search_mailFull-text search mail with KQL across all folders (or one, if `folder` is set).
Use this for "find emails about X"; use outlook_list_inbox for structured filters scoped to a
single folder.
Example: outlook_search_mail(query="from:sarah@acme.com received>=2026-01-01", count=10)
`query` is Microsoft KQL (from:, subject:, received>=, hasattachment:true, AND/OR/NOT).
Operators must be UPPERCASE — lowercase `and` is matched as a literal term. Two terms
with no operator between them broaden the search; use AND explicitly to narrow.
Pass concise=True to drop large fields (preview, categories) — ~10x fewer tokens.
Input schema{
"properties": {
"query": {
"title": "Query",
"type": "string"
},
"count": {
"default": 25,
"title": "Count",
"type": "integer"
},
"folder": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Folder"
},
"cursor": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Cursor"
},
"concise": {
"default": false,
"title": "Concise",
"type": "boolean"
}
},
"required": [
"query"
],
"type": "object",
"title": "outlook_search_mailArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
outlook_send_draftSend an existing draft (pair with outlook_create_draft for human-review send flow).Input schema{
"properties": {
"draft_id": {
"title": "Draft Id",
"type": "string"
}
},
"required": [
"draft_id"
],
"type": "object",
"title": "outlook_send_draftArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_send_messageSend an email immediately, no human review.
For human-review workflows use outlook_create_draft + outlook_send_draft instead.
For replying to an existing message use outlook_reply; for calendar invites use outlook_rsvp.
Pass reply_to to route recipient replies to a different address (e.g. a shared team alias).
Input schema{
"properties": {
"to": {
"items": {
"type": "string"
},
"title": "To",
"type": "array"
},
"subject": {
"title": "Subject",
"type": "string"
},
"body": {
"title": "Body",
"type": "string"
},
"cc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Cc"
},
"bcc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Bcc"
},
"is_html": {
"default": false,
"title": "Is Html",
"type": "boolean"
},
"importance": {
"default": "normal",
"title": "Importance",
"type": "string"
},
"sensitivity": {
"default": "normal",
"title": "Sensitivity",
"type": "string"
},
"request_read_receipt": {
"default": false,
"title": "Request Read Receipt",
"type": "boolean"
},
"reply_to": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Reply To"
}
},
"required": [
"to",
"subject",
"body"
],
"type": "object",
"title": "outlook_send_messageArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_send_with_attachmentsSend an email with file attachments; auto-switches to upload-session for files >3MB.
`attachment_paths` must be absolute paths to files that exist on the host. Pass reply_to to
route replies to a different address.
Input schema{
"properties": {
"to": {
"items": {
"type": "string"
},
"title": "To",
"type": "array"
},
"subject": {
"title": "Subject",
"type": "string"
},
"body": {
"title": "Body",
"type": "string"
},
"attachment_paths": {
"items": {
"type": "string"
},
"title": "Attachment Paths",
"type": "array"
},
"cc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Cc"
},
"bcc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Bcc"
},
"is_html": {
"default": false,
"title": "Is Html",
"type": "boolean"
},
"importance": {
"default": "normal",
"title": "Importance",
"type": "string"
},
"reply_to": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Reply To"
}
},
"required": [
"to",
"subject",
"body",
"attachment_paths"
],
"type": "object",
"title": "outlook_send_with_attachmentsArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_set_inbox_overrideCreate or update a sticky Focused/Other rule for a sender (upsert, case-insensitive).
Use this to permanently change classification for FUTURE messages from a sender; use
outlook_reclassify_message to fix ONE existing message.
Example: outlook_set_inbox_override(sender_email="marketing@acme.com", classify_as="other")
Returns status: "created" or "updated".
Input schema{
"properties": {
"sender_email": {
"title": "Sender Email",
"type": "string"
},
"classify_as": {
"title": "Classify As",
"type": "string"
}
},
"required": [
"sender_email",
"classify_as"
],
"type": "object",
"title": "outlook_set_inbox_overrideArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_switch_accountSwitch the active Outlook account by configured `name` (from outlook_list_accounts).Input schema{
"properties": {
"name": {
"title": "Name",
"type": "string"
}
},
"required": [
"name"
],
"type": "object",
"title": "outlook_switch_accountArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_update_contactUpdate an existing contact (partial patch — only provided fields change).Input schema{
"properties": {
"contact_id": {
"title": "Contact Id",
"type": "string"
},
"first_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "First Name"
},
"last_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Last Name"
},
"email": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Email"
},
"phone": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Phone"
}
},
"required": [
"contact_id"
],
"type": "object",
"title": "outlook_update_contactArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_update_draftUpdate an existing draft (partial patch).
Pass is_html=True when body is HTML — required when overwriting a draft originally composed
as HTML (consumer Outlook rejects Text-over-HTML PATCH).
Pass reply_to=[...] to overwrite Reply-To; reply_to=[] to clear it.
Pass deferred_send_datetime (ISO 8601) to set the scheduled-send time; empty string clears it.
Input schema{
"properties": {
"draft_id": {
"title": "Draft Id",
"type": "string"
},
"subject": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Subject"
},
"body": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body"
},
"to": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "To"
},
"cc": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Cc"
},
"reply_to": {
"anyOf": [
{
"items": {
"type": "string"
},
"type": "array"
},
{
"type": "null"
}
],
"default": null,
"title": "Reply To"
},
"is_html": {
"default": false,
"title": "Is Html",
"type": "boolean"
},
"deferred_send_datetime": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Deferred Send Datetime"
}
},
"required": [
"draft_id"
],
"type": "object",
"title": "outlook_update_draftArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_update_eventUpdate fields on an existing event (partial patch — only provided fields change).Input schema{
"properties": {
"event_id": {
"title": "Event Id",
"type": "string"
},
"subject": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Subject"
},
"start": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Start"
},
"end": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "End"
},
"location": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Location"
},
"body": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body"
}
},
"required": [
"event_id"
],
"type": "object",
"title": "outlook_update_eventArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_update_taskUpdate fields on a To Do task (partial patch — only provided fields change).Input schema{
"properties": {
"task_id": {
"title": "Task Id",
"type": "string"
},
"list_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "List Id"
},
"title": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Title"
},
"due": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Due"
},
"body": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Body"
},
"importance": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"default": null,
"title": "Importance"
}
},
"required": [
"task_id"
],
"type": "object",
"title": "outlook_update_taskArguments"
}Annotations{
"destructiveHint": false,
"readOnlyHint": false
} | — | WritesNon-destructive | — |
outlook_whoamiGet the authenticated user's profile (display name, email, ID).Input schema{
"properties": {},
"type": "object",
"title": "outlook_whoamiArguments"
}Annotations{
"readOnlyHint": true
} | — | Read only | — |
| Endpoint | Transport | Authentication | Health | Observed |
|---|---|---|---|---|
| No verified remote endpoint is linked. | ||||
Install the selected package version with: python -m pip install 'outlook-graph-mcp==1.14.0'
outlook-mcp Server exposed 62 tools during independent protocol observation, including outlook_attach_to_draft, outlook_auth_status, outlook_batch_triage, outlook_categorize_message, outlook_changes_since, outlook_complete_task, outlook_copy_message, outlook_create_contact, and others.
The selected current version does not yet have completed public verification. Unknown does not mean clean or vulnerable.
These internal links are derived from strong identity fields such as the implementation name, package, repository, vendor, and listing name—not generic description prose.
Association is based on retained identity fields; it does not by itself prove first-party publication.
Curated product and capability guides containing this catalog record.