outlook-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| outlook_auth_statusA | Check authentication status. Run |
| outlook_list_inboxA | List 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)
|
| outlook_read_messageA | Get one full message by ID. 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. |
| outlook_read_messagesA | Bulk read up to 20 messages by ID via $batch — use NOT N outlook_read_message calls. Per-message shape in Example: outlook_read_messages(message_ids=[id1, id2, id3], concise=True) Hard cap of 20 (Graph $batch limit). |
| outlook_search_mailA | Full-text search mail with KQL across all folders (or one, if 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)
|
| outlook_list_foldersA | List 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. |
| outlook_list_inbox_deltaA | List 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=). is_deleted=True items are tombstones (drop cached payload). has_more=True means drain immediately by passing the returned delta_token back. |
| outlook_send_messageA | Send 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). |
| outlook_replyB | Reply (or reply-all) to an email message. Use this for email; use outlook_rsvp for calendar meeting invites. |
| outlook_forwardA | Forward an existing message to new recipients, with optional comment. |
| outlook_move_messageA | Move 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"). |
| outlook_delete_messageA | Delete 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. |
| outlook_flag_messageA | Set the follow-up flag on a message. |
| outlook_categorize_messageA | Set categories on a message (replaces the full list). Example: outlook_categorize_message(message_id=..., categories=["Follow-up", "Pricing"]) |
| outlook_mark_readC | Mark a single message as read or unread (set is_read=True or False). |
| outlook_reclassify_messageA | Reclassify ONE message's Focused/Other placement. Use this to fix a single message; use outlook_set_inbox_override for a sticky rule that affects future messages from the same sender. |
| outlook_list_inbox_overridesA | List 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. |
| outlook_set_inbox_overrideA | Create 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". |
| outlook_delete_inbox_overrideB | Delete a Focused Inbox per-sender override rule by its ID. |
| outlook_list_eventsA | List 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 for day-at-a-glance scans: drops organizer, response_status, type and show_as; adds is_organizer and attendees_count; spells is_online as is_online_meeting.
|
| outlook_get_eventA | Get one event by ID: body, attendees, organizer, recurrence, type, show_as, anchor zone.
|
| outlook_list_events_deltaA | List 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=). 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. |
| outlook_create_eventA | Create a calendar event with optional attendees, recurrence, busy status, 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"])
|
| outlook_update_eventA | Update fields on an existing event (partial patch — only provided fields change).
|
| outlook_delete_eventA | Delete a calendar event by ID (cancels and notifies attendees if you're the organizer). |
| outlook_rsvpA | RSVP to a calendar meeting invite. Use this for meeting invites; use outlook_reply to reply to a regular email message. |
| outlook_list_contactsA | List contacts with cursor pagination. Use for one-shot queries; use outlook_list_contacts_delta for polling/recurring agents. |
| outlook_search_contactsA | Search contacts by name or email using KQL query syntax. |
| outlook_get_contactA | Get one full contact by ID. |
| outlook_create_contactC | Create a new contact with name and optional email, phone, company, title. |
| outlook_update_contactA | Update an existing contact (partial patch — only provided fields change). An address takes the shape outlook_get_contact returns — any subset of {"street", "city", "state", "postal_code", "country_or_region"} — and REPLACES that whole address, so pass back every part you want to keep. Omit it to leave it untouched. |
| outlook_delete_contactC | Delete a contact by ID. |
| outlook_list_contacts_deltaA | List 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=). is_deleted=True items are tombstones (drop cached payload). has_more=True means drain immediately by passing the returned delta_token back. |
| outlook_changes_sinceA | One 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=).
First call returns a snapshot filtered to the last |
| outlook_list_task_listsA | List all Microsoft To Do task lists for the current user. |
| outlook_list_tasksB | List tasks in a To Do list with optional
|
| outlook_get_taskA | Get full To Do task details: notes ( Use this for one task's sub-steps and notes; use outlook_list_tasks for
overviews. |
| outlook_create_taskA | Create 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")
|
| outlook_update_taskA | Update fields on a To Do task (partial patch — only provided fields change). |
| outlook_complete_taskC | Mark a To Do task as completed. |
| outlook_delete_taskB | Delete a task from a Microsoft To Do list. |
| outlook_add_checklist_itemC | Add a checklist item (sub-step) to a To Do task. |
| outlook_update_checklist_itemA | Update a checklist item (partial patch — only provided fields change).
|
| outlook_delete_checklist_itemB | Delete a checklist item from a To Do task. |
| outlook_list_task_attachmentsA | List attachments on a To Do task (id, name, size, content_type) with pagination. Use |
| outlook_download_task_attachmentA | Download a To Do task attachment's content to a local file.
|
| outlook_upload_task_attachmentA | Attach a local file to a To Do task via inline base64 POST (1 byte – 20 MiB).
|
| outlook_delete_task_attachmentC | Remove an attachment from a To Do task. |
| outlook_list_draftsA | List messages in the Drafts folder with cursor pagination. |
| outlook_create_draftA | Create 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. |
| outlook_update_draftA | Update 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. |
| outlook_send_draftB | Send an existing draft (pair with outlook_create_draft for human-review send flow). |
| outlook_delete_draftB | Delete a draft message by ID. |
| outlook_list_attachmentsA | List attachments on a message — returns IDs, names, sizes, and content types. |
| outlook_download_attachmentB | Download an attachment and write the decoded bytes to
|
| outlook_send_with_attachmentsA | Send an email with file attachments; auto-switches to upload-session for files >3MB.
|
| outlook_attach_to_draftA | Add attachments to an existing draft; auto-switches to upload-session for files >3MB.
|
| outlook_remove_draft_attachmentB | Remove a single attachment from a draft message by attachment ID. |
| outlook_create_folderA | Create a mail folder; pass |
| outlook_rename_folderB | Rename a user-created mail folder by ID. |
| outlook_delete_folderA | Delete a user-created mail folder by ID; refuses well-known folders (inbox, sentitems). |
| outlook_list_threadA | List all messages in a conversation thread, chronological order. Needs |
| outlook_copy_messageA | Copy a message to another folder (duplicates; source is unchanged). Use outlook_move_message to remove from source. |
| outlook_batch_triageA | Triage up to 20 messages in one $batch call.
Example: outlook_batch_triage(message_ids=[id1, id2], action="move", value="Archive")
|
| outlook_whoamiA | Get the authenticated user's profile (display name, email, ID). |
| outlook_list_calendarsA | List all calendars available to the authenticated user (primary + secondary). |
| outlook_list_categoriesA | List the user's master category definitions (names + colors). Provides the valid values for outlook_categorize_message. |
| outlook_get_mail_tipsA | Pre-send check for recipients: out-of-office, delivery limits, mailbox-full warnings. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| morning_brief | Today's calendar, unread mail and tasks due, in one pass. |
| triage_folder | Scan one folder cheaply and act on it in a single batch. |
| catch_up | What changed in mail, calendar and contacts since a point in time. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 68 tools
Many tools are differentiated by scope (single vs batch, delta vs one-shot, individual vs combined digest), and descriptions explicitly cross-reference each other. However, overlaps such as batch_triage vs individual move/flag/categorize/mark_read and multiple list/read/delta variants mean an agent must read descriptions carefully to avoid misselection.
Names use a consistent snake_case convention with an `outlook_` prefix and mostly follow a verb_noun pattern (list_events, create_task, delete_folder). A few exceptions (auth_status, whoami, changes_since) slightly break the verb_noun pattern, but overall readability and predictability are high.
68 tools is far beyond the typical 3-15 range and exceeds the 50-tool threshold for extreme mismatch. Even though the server covers a broad domain, the sheer count creates a large selection and context burden for an agent.
The surface covers mail, calendar, contacts, tasks, folders, attachments, drafts, focused inbox, and delta sync with strong CRUD coverage across these areas. Some secondary Outlook operations are missing (e.g., category management, calendar creation, out-of-office settings), but core agent workflows have no obvious dead ends.