| authA | Manage authentication with the Microsoft Graph API. action=status (default) returns the current auth state and auto-refreshes the access token if it's expired but the refresh token is still valid (~90-day window) — call this first to check before other tools. action=authenticate starts the OAuth flow: with method: "device-code" (default, works headlessly) it returns a code + URL for the user to visit; with method: "browser" it opens the local auth server on :3333 (run npm run auth-server first). Pass force: true to re-authenticate over an existing valid session. action=device-code-complete finishes device-code auth after the user enters the code in their browser — call this once authentication shows as successful in the browser. action=about returns server version, configured audience, scope list, and other diagnostic info. Tokens persist to ~/.outlook-assistant-tokens.json and survive server restarts. |
| list-eventsA | List upcoming calendar events for the signed-in user (read-only). Returns an array of events with id, subject, start/end, attendees, location, organiser, and webLink. Use count (default 10, max 50) to control page size; this tool does not filter — use the Outlook UI or specific date ranges via Graph for filtered queries. Times are returned in the configured timezone (default Australia/Melbourne; override with OUTLOOK_DEFAULT_TIMEZONE). |
| create-eventA | Create a new calendar event on the signed-in user's default calendar. Returns the created event with its id, webLink, and (if attendees are present) an auto-generated online-meeting URL — attendees receive invitations on save. Times use the configured timezone (default Australia/Melbourne; override with OUTLOOK_DEFAULT_TIMEZONE); omit the Z suffix to send local time. Use manage-event action=update to modify an event after creation, or manage-event action=cancel/delete to remove it. |
| manage-eventA | Manage an existing calendar event (destructive: covers update/decline/cancel/delete — use dryRun where supported to preview). action=update edits fields in place via PATCH (subject, start, end, attendees, body, location, isOnlineMeeting, sensitivity, showAs, importance, categories, reminderMinutesBeforeStart) — only fields you pass are changed; pass dryRun: true to preview the PATCH payload. action=decline declines an invitation (optional comment). action=cancel cancels an event you organised and notifies attendees. action=delete permanently removes the event. Returns the updated event on update; status confirmation otherwise. Note: there is no accept action — accept invitations in the Outlook UI (Graph's accept verb is unreliable across personal/M365). |
| search-emailsA | Search, list, delta-sync, or thread-group emails — six modes selected by parameters (read-only). With no params: lists recent emails in folder (default inbox). With query/from/to/subject/date filters: full search (combines via OData filter). With kqlQuery: raw Keyword Query Language for advanced server-side search. With deltaMode: true: returns current state plus a deltaToken; pass the token back on the next call for incremental changes only — ideal for inbox monitoring. With groupByConversation: true: returns conversation threads. With conversationId: returns all messages in a single thread. With internetMessageId: looks up a message by its RFC Message-ID header. Personal Outlook.com accounts have limited $search support — this tool falls back through OData filters / boolean filters / recent listing automatically, but structured filters (from/subject/receivedAfter/hasAttachments/unreadOnly) return cleaner results. Returns paged messages with id/subject/from/receivedDateTime/preview by default; use outputVerbosity to expand. |
| read-emailA | Read a single email by id (read-only). Default: returns the full message body (HTML stripped to text by default), subject, from/to/cc, receivedDateTime, conversationId, attachments metadata, and webLink as Markdown. With headersMode: true: returns RFC-822 forensic headers instead (DKIM, SPF, DMARC, Received chain, Message-ID, Authentication-Results) — pair with importantOnly: true for the security-relevant subset, groupByType: true for category-bucketed view, or raw: true for JSON instead of Markdown. With includeHeaders: true (non-headers-mode): adds basic headers alongside body. Use outputVerbosity (minimal/standard/full) to control field count. |
| send-emailA | Compose and send an email immediately (destructive: sends external comms). Returns a confirmation with the saved-message id. Safety controls: dryRun: true returns the composed message for review without sending; checkRecipients: true runs get-mail-tips first to flag out-of-office / mailbox-full / delivery-restricted / external recipients; combine both for a full pre-send review. Subject to session rate limits (OUTLOOK_MAX_EMAILS_PER_SESSION env) and recipient allowlist (OUTLOOK_ALLOWED_RECIPIENTS env) when configured — calls outside the allowlist fail before any Graph request. For multi-step compose/review workflows prefer draft (action=create → update → send) since drafts can be inspected in Outlook before sending. Comma-separated recipient strings or arrays both accepted. |
| draftA | Full draft lifecycle for review-before-send workflows (destructive: covers send and delete). action=create saves a new draft in the Drafts folder and returns its id (use dryRun: true to preview without saving; checkRecipients: true runs mail-tips first). action=update patches an existing draft by id (only fields passed are changed). action=send dispatches an existing draft — shares the rate limit with send-email. action=delete removes a draft permanently. action=reply/reply-all creates a reply draft from a message id (use comment to prepend text — mutually exclusive with body). action=forward creates a forward draft (requires id and to). Recipient allowlist applies to create/update/forward. Returns the draft object on create/update/reply/forward; status confirmation on send/delete. |
| update-emailA | Update message state without modifying content (idempotent — safe to retry). action=mark-read/mark-unread toggles the isRead flag on a single message by id. action=flag sets a follow-up flag with optional dueDateTime/startDateTime (ISO 8601). action=unflag clears the flag. action=complete marks the flag as done. Flag/unflag/complete accept either id (single) or ids (batch array) — batch operations use Graph $batch for efficiency. Returns status confirmation per message. |
| attachmentsA | Inspect or retrieve email attachments. action=list (default) returns metadata for all attachments on messageId (id, name, contentType, size, isInline) — read-only. action=view returns inline content for text/JSON/XML attachments via attachmentId; binary types require download. action=download saves the attachment to disk at outputDir (default system tmpdir, auto-created) and returns the saved file path. messageId is required for all actions; attachmentId is required for view/download. Use outputVerbosity to control list field count. |
| exportA | Export emails to file formats for archival, forensics, or programmatic processing. target=message (default) exports a single email by id to savePath — accepts mime/eml/markdown/json/csv. target=messages batch-exports either an explicit emailIds array or messages matching searchQuery (or query shortcut) into outputDir — accepts markdown/json/csv. target=conversation exports a full thread by conversationId into outputDir (chronological by default; pass order: "reverse" for newest-first) — accepts eml/mbox/markdown/json/html/csv. target=mime returns raw RFC-822 MIME bytes for id (use headersOnly for just headers, base64 for encoded transport, maxSize to cap at default 1MB). includeAttachments defaults to true for single-message exports and false for batch. Format support varies by target — see the format param enum. |
| get-mail-tipsA | Pre-send recipient validation via Graph POST /me/getMailTips (read-only; uses the existing Mail.Read scope — no extra permissions). Returns per-recipient tips covering automatic replies (out-of-office), mailbox full status, custom admin mail tips, delivery restrictions, moderation requirements, external-vs-internal scope, max message size, and group member counts (total + external). Use ahead of send-email or draft action=create to catch issues like OOO replies or external-recipient warnings before the message goes out; send-email/draft accept checkRecipients: true to invoke this automatically. Accepts either a comma-separated string or an array of addresses; tipTypes filters which tips are requested (defaults to all). |
| foldersA | Manage mail folders (tool-level destructiveHint=true because delete permanently removes a folder; list and stats are read-only sub-actions despite the annotation). action=list (default) returns the folder tree with id/displayName/parentFolderId (toggle includeItemCounts for unread/total, includeChildren for hierarchy). action=create makes a new folder under the inbox (or under folder/folderId/folderName) and returns its id. action=move relocates emails (emailIds array) into targetFolder. action=stats returns counts (totalItemCount/unreadItemCount) suitable for pagination planning — pair with outputVerbosity to limit noise. action=delete permanently removes a folder and its contents — there is no recycle-bin recovery. |
| manage-rulesA | Server-side inbox rule CRUD (destructive: covers delete; supports dryRun on create/update for preview). Rules run on the Exchange server regardless of which client is open. action=list (default) returns rules with id/name/sequence — pass includeDetails: true to expand conditions/actions/exceptions. action=create builds a new rule from condition params (12 supported: fromAddresses, containsSubject, bodyContains, hasAttachments, importance, sentTo, sensitivity, etc.), action params (9 supported: moveToFolder, forwardTo, redirectTo, assignCategories, markAsRead, delete, etc.), and optional except* exceptions. action=update patches the named fields by ruleId. action=reorder changes execution priority via sequence (lower = earlier). action=delete removes a rule. Recipient allowlist applies to forwardTo/redirectTo. permanentDelete action is intentionally omitted (too dangerous for AI use — use the Outlook UI). Subject to session rate limits (OUTLOOK_MAX_MANAGE_RULES_PER_SESSION). |
| manage-contactA | Full CRUD over the signed-in user's personal Outlook contacts (destructive: covers delete action). action=list (default) returns contacts with pagination via skip/count (default 50). action=search returns contacts matching query against name/email (default 25). action=get returns full contact detail by id. action=create adds a new contact and returns its id. action=update patches the given fields by id (only fields passed are changed). action=delete permanently removes the contact by id. Use outputVerbosity (minimal/standard/full) on list/search to control field count. Prefer search-people for cross-source relevance ranking (contacts + directory + recent comms) — this tool only searches your personal contact store. |
| search-peopleA | Relevance-ranked search across personal contacts, organisation directory, and recent communications via the Microsoft Graph People API (read-only). Returns people objects with displayName, emailAddresses, companyName, jobTitle, and relevance metadata — ideal for "who is X?" or "who do I email about Y?" lookups. Use manage-contact action=search instead when you specifically need entries from your personal contact store only. |
| manage-categoryA | Manage the user's master category list (the colour-coded labels available across mail/calendar/contacts). action=list (default) returns categories with id/displayName/color. action=create adds a new category — displayName required, color optional (preset0-preset24, e.g. preset0=Red, preset7=Blue). action=update (alias set — deprecated) changes name/colour by id. action=delete removes a category — this does NOT untag messages already labelled with it; existing messages retain the orphaned label until manually cleaned. Use apply-category to tag/untag specific messages. |
| apply-categoryA | Tag or untag email messages with master categories (those created via manage-category). action=set (default) replaces the message's category set with the supplied categories array. action=add appends categories to whatever's already on the message. action=remove removes only the named categories, leaving the rest. Accepts either messageId (single) or messageIds (batch via Graph $batch). categories are matched by display name — names must already exist in the master list (create via manage-category first). Returns per-message confirmation. |
| manage-focused-inboxA | Manage Focused Inbox sender overrides — explicit rules that force messages from a given sender into Focused or Other regardless of the ML classifier. action=list (default) returns existing overrides with id/sender/classifyAs. action=set creates or updates an override for emailAddress (optional name), routing future mail to focused (default) or other. action=delete removes the override for emailAddress. Note: this only works on accounts that have Focused Inbox enabled — personal Outlook.com accounts without it return an empty list. |
| mailbox-settingsA | Read or update mailbox-level settings (idempotent — safe to retry; sets are PATCH-style and merge with existing state). action=get (default) returns settings — use section to filter (language, timeZone, workingHours, automaticRepliesSetting, or all). action=set-auto-replies configures out-of-office: enabled true/false, optional startDateTime/endDateTime (ISO 8601) for scheduled mode, internalReplyMessage and (optionally) externalReplyMessage. action=set-working-hours updates the schedule: startTime/endTime (HH:MM) and daysOfWeek (array of monday..sunday). Returns the updated settings object on set actions. |
| access-shared-mailboxA | List emails from a shared mailbox the signed-in user has been granted access to (read-only). Returns paged messages from the named sharedMailbox (or alias email) and folder (default inbox) with id/subject/from/receivedDateTime/preview — same shape as search-emails list mode. Requires that the shared mailbox has been delegated to the signed-in user in Exchange (admin-configured). Use outputVerbosity to control field count and count (default 25, max 50) for page size. For full search/filter capability over a shared mailbox, prefer search-emails with a folder path scoped to the shared mailbox. |
| find-meeting-roomsA | Discover bookable meeting rooms in the user's organisation via the Graph rooms endpoint (read-only). Returns room resources with displayName, emailAddress, building, floor, capacity, and bookingType — suitable for piping into create-event as attendees. Filter by query (matches name/email), building, floor, or minimum capacity. Returns empty list on personal accounts (the rooms endpoint is M365-only). Use outputVerbosity to control field count. |