The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Outlook Assistant listing page.
MCP server for Outlook email, calendar, and contacts — let your AI assistant manage your inbox directly from the conversation.
Outlook Assistant connects AI assistants to your Microsoft Outlook account through the Model Context Protocol. Ask your AI assistant to search your inbox, send emails, schedule meetings, manage contacts, and configure mailbox settings — without leaving the conversation. Works with Claude, Cursor, Windsurf, and any MCP-compatible client.
Works with personal Outlook.com and work/school Microsoft 365 accounts.
| Without Outlook Assistant | With Outlook Assistant |
|---|---|
| Switch between your AI tool and Outlook to manage email | Read, search, send, and export emails directly from your AI assistant |
| Manually search and export email threads | Full email tools including search, threading, and bulk export |
| Context-switch for calendar and contacts | Manage calendar events, contacts, and settings in one place |
| Copy-paste email content into conversations | Your AI assistant reads your emails natively with full context |
| No programmatic access to mailbox rules or categories | Create inbox rules, manage categories, configure auto-replies |
| Manually check each email for phishing red flags | Forensic header analysis — DKIM, SPF, DMARC, spam scores, and delivery chain in one call |
| Poll your inbox to check for new mail | Delta sync returns only changes since your last check, with tokens for continuous polling |
| Module | Tools | What You Can Do |
|---|---|---|
| 8 | search-emails (list/search/delta/conversations), read-email (content + forensic headers), send-email (with dry-run + mail tips), draft (create/update/send/delete/reply/forward), update-email (read status, flags), attachments, export, get-mail-tips | |
| Calendar | 3 | list-events, create-event, manage-event (update/decline/cancel/delete) |
| Contacts | 2 | manage-contact (list/search/get/create/update/delete), search-people |
| Categories | 3 | manage-category (CRUD), apply-category, manage-focused-inbox |
| Settings | 1 | mailbox-settings (get/set auto-replies/set working hours) |
| Folder | 1 | folders (list/create/move/stats/delete) — nested folders addressable by path (Parent/Child) or ID |
| Rules | 1 | manage-rules (list/create/update/reorder/delete) |
| Advanced | 2 | access-shared-mailbox, find-meeting-rooms |
| Auth | 1 | auth (status/authenticate/about) |
22 tools total — consolidated from 55 for optimal AI performance. See the Tools Reference for complete parameter details.
Format support varies by target:
| Format | Extension | target=message (single) | target=messages (batch) | target=conversation (thread) |
|---|---|---|---|---|
mime / eml | .eml | ✅ | – | ✅ |
mbox | .mbox | – | – | ✅ |
markdown | .md | ✅ | ✅ | ✅ |
json | .json | ✅ | ✅ | ✅ |
html | .html | – | – | ✅ |
csv | .csv | ✅ | ✅ | ✅ |
Export individual emails, search results, or entire conversation threads — use target=messages with a search query (or the query shortcut) to batch-export without manually collecting IDs.
Outlook Assistant works with both personal and work/school Microsoft accounts, but some features behave differently:
| Feature | Personal (Outlook.com) | Work/School (Microsoft 365) |
|---|---|---|
| Email read, send, search | Full support | Full support |
| Calendar events | Full support | Full support |
| Contacts CRUD | Full support | Full support |
| Inbox rules | Full support | Full support |
| Folders | Full support | Full support |
Free-text query search | Limited — progressive fallback; subject, from, to filters are more direct | Full $search support |
| Categories | Full support | Full support |
| Mailbox settings | Full support | Full support |
| Focused Inbox | API works (overrides stored) but mail routing not affected | Full support |
| Shared mailboxes | Not available | Requires Mail.Read.Shared |
| Meeting room search | Not available | Requires Place.Read.All + admin consent |
Note: On personal accounts, Microsoft's
$searchAPI has limited support for free-text queries. Outlook Assistant handles this automatically with progressive search — if your query returns no results, it falls back through OData filters, boolean filters, and recent message listing to find your emails. For the most direct results on personal accounts, use the structured filter parameters (from,subject,to,receivedAfter).
$search API is limited, Outlook Assistant automatically falls back through up to 4 search strategies to find your emails, and reports which one answered in _meta.searchMetadata along with any filter it could not honour (droppedFilters). Most Graph API wrappers fail silently; this one adapts and tells you.Outlook Assistant is designed with safety-first principles for AI-driven email access:
Destructive action safeguards — Every tool carries MCP annotations (readOnlyHint, destructiveHint, idempotentHint) so AI clients can auto-approve safe reads and prompt for confirmation on destructive operations like sending email or deleting events.
Send-email protections — The send-email tool includes:
checkRecipients: true) — check recipients for out-of-office, mailbox full, delivery restrictions before sendingdryRun: true) — preview composed emails without sendingOUTLOOK_MAX_EMAILS_PER_SESSION (default: unlimited)OUTLOOK_ALLOWED_RECIPIENTSRecommended setup: enable both safety belts in your
.mcp.jsonfrom day one. They're off by default;auth action=aboutreports their state and prints a setup hint when unset. See.mcp.json.examplefor a copy-paste template.
Draft protections — The draft tool shares send-email safety controls: dry-run preview, recipient allowlist, mail-tips validation, and rate limiting. The send action shares the send-email rate limit counter, preventing circumvention via the draft-then-send pathway.
Token-optimised architecture — Tools are consolidated using the STRAP (Single Tool, Resource, Action Pattern) approach. 22 tools instead of 55 reduces per-turn overhead by ~11,000 tokens (~64%), keeping more of the AI's context window available for your actual conversation. Fewer tools also means the AI selects the right tool more accurately — research shows tool selection degrades beyond ~40 tools.
Important: These safeguards are defence-in-depth measures that reduce risk, but they are not a guarantee against unintended actions. AI-driven access to your email is inherently sensitive — always review tool calls before approving, particularly for sends and deletes. No automated guardrail is foolproof, and you remain responsible for actions taken through your mailbox.
Or run directly without installing:
To check which version you have, or to see the available options:
With no arguments the server speaks the Model Context Protocol over stdio. It's normally launched by your MCP client rather than run by hand — started from a terminal it will simply wait on stdin.
You need a Microsoft Azure app registration to authenticate. See the Azure Setup Guide for a detailed walkthrough (including first-time Azure account creation), or if you've done this before:
nativeclient URIhttp://localhost:3333/auth/callback — only needed for browser auth flowAdd to your MCP client config:
claude_desktop_config.json)Then set environment variables in your .env or shell.
~/.codeium/windsurf/mcp_config.json)outlook-assistant-auth (or npx @littlebearapps/outlook-assistant-auth)auth tool with action=authenticate to get an OAuth URLNote: The auth server needs
OUTLOOK_CLIENT_IDandOUTLOOK_CLIENT_SECRETenvironment variables. Your MCP client's"env"config only applies to the MCP server process — when running the auth server separately, ensure these are set in a.envfile or exported in your shell.
| Option | What it does |
|---|---|
-v, --version | Print the version to stdout and exit 0 |
-h, --help | Print usage, options and key environment variables, and exit 0 |
| (none) | Start the MCP server on stdio — the normal mode, invoked by your MCP client |
An unrecognised argument is reported on stderr and exits 1, rather than starting a server that would ignore it.
First time with Azure? The Azure Setup Guide covers everything from creating an account to your first authentication, including billing setup and common pitfalls.
http://localhost:3333/auth/callbackoffline_access — refresh tokens between sessionsUser.Read — basic profileMail.Read, Mail.ReadWrite, Mail.Send — email operationsCalendars.Read, Calendars.ReadWrite — calendar operationsContacts.Read, Contacts.ReadWrite — contact managementMailboxSettings.ReadWrite — settings, auto-replies, categoriesPeople.Read — people searchMail.Read.Shared — shared mailbox accessPlace.Read.All — meeting room search (requires admin consent)Create a .env file from the example:
Edit with your Azure credentials:
Note: The server also accepts
MS_CLIENT_IDandMS_CLIENT_SECRETfor backwards compatibility.
Optional overrides (v3.8.0+) — see .env.example for the full list with commented worked examples:
| Variable | Purpose | Default |
|---|---|---|
OUTLOOK_AUTH_AUDIENCE | OAuth audience: common, consumers (personal-only Azure apps), organizations, or single-tenant GUID. Fixes AADSTS9002331 for personal-only app registrations. | common |
OUTLOOK_DEFAULT_TIMEZONE | IANA timezone applied to calendar events when callers don't pass one (e.g. Europe/London, America/New_York). | Australia/Melbourne |
OUTLOOK_MAX_EMAILS_PER_SESSION | Cap on send-email + draft send per MCP server lifetime. | unlimited |
OUTLOOK_ALLOWED_RECIPIENTS | Comma-separated allowlist of domains/addresses for sends, drafts, and rule forwards. | unrestricted |
OUTLOOK_SEARCH_SCAN_LIMIT | How many recent messages the client-side search fallback scans. Personal accounts match to locally within this window, so the default caps how far back a to search reaches. Max 5000. | 500 |
See Quick Start — Configure Your MCP Client above for Claude Desktop, Claude Code, Cursor, and Windsurf configs.
If installed from source, use node instead of npx:
No auth server needed. Works everywhere, including remote/headless environments.
auth tool with action=authenticate)microsoft.com/devicelogin) on any browser, any deviceauth with action=device-code-complete)~/.outlook-assistant-tokens.json and refresh automaticallyPrerequisite: Enable "Allow public client flows" in Azure Portal > your app > Authentication > Advanced settings.
Server restarts (v3.7.2+): Device code state is persisted to
~/.outlook-assistant-pending-auth.json, sodevice-code-completeworks even if the MCP server restarts between steps 1 and 4 (e.g., Untether/Telegram bridge, Claude Desktop session changes).
For localhost development or if you prefer the traditional OAuth flow:
This starts a local server on port 3333 to handle the OAuth callback.
auth tool with action=authenticate, method=browserNote: The auth server reads
OUTLOOK_CLIENT_IDandOUTLOOK_CLIENT_SECRETfrom environment variables. Your MCP client's"env"config only applies to the MCP server process, not a separately-started auth server.
You're using the Secret ID instead of the Secret Value. Go to Azure Portal > Certificates & secrets and copy the Value column into OUTLOOK_CLIENT_SECRET.
The Value is shown only once, when the secret is created — if you've navigated away it can't be read again, so create a new secret. An expired secret produces this same error, so check the Expires column too.
Since v3.11.0 the server detects this error and appends the explanation to Microsoft's original message, so you see both the raw error code and what to do about it.
If using browser flow: start the auth server first with npm run auth-server. If using device code flow: visit microsoft.com/devicelogin instead.
Enable "Allow public client flows" in Azure Portal > App registrations > Authentication > Advanced settings.
Fixed in v3.7.2. Earlier versions sent client_secret in token refresh requests for device-code auth, which Microsoft rejects for public client flows. Update to v3.7.2+ or re-authenticate.
Check authentication status with the auth tool (action=status). Tokens may have expired — re-authenticate if needed.
Run with mock data (no real API calls):
tasks/)index.jsTOOLS array in main index.jstest/docs/quickrefs/tools-reference.md| Guide | Description |
|---|---|
| Getting Started | Install, configure, and authenticate — start here |
| Azure Setup Guide | Azure account creation, app registration, permissions, and secrets |
| How-To Guides | 29 practical guides for email, calendar, contacts, and settings |
| Roadmap | Active milestones (v3.11.2, v3.8.x, v3.12.0+) and recent releases |
| Troubleshooting & FAQ | Common problems, re-authentication, and frequently asked questions |
| Tools Reference | All 22 tools with parameters |
| AI Agent Guide | Tool selection and workflow patterns for AI agents |
Full documentation: docs/
query and the raw searchExpression (formerly kqlQuery) rely on Microsoft's $search API, which has limited support on personal Outlook.com accounts. query mitigates this with progressive fallback (OData filters, boolean filters, then a client-side scan). Field-scoped $search (e.g. subject:"…") is rejected outright there; since v3.10.0 from:/to:/subject: expressions are translated into the closest equivalent OData filters and retried, but boolean operators, grouping, wildcards and other field prefixes are not — those still terminate with an explicit no-results rather than a silent broader search. Structured filters (from, subject, to, receivedAfter) remain the most direct route. Cross-folder search (searchAllFolders: true) returns a superset of inbox-only results. Note that query and searchExpression are not interchangeable there: searchExpression goes to $search, which matches the whole message including the body and ranks by relevance rather than date, while query falls back to a subject substring match that never reads bodies.to search depth on personal accounts: the server-side recipient filter is rejected, so to is matched locally over the 500 most recent messages (OUTLOOK_SEARCH_SCAN_LIMIT, max 5000). On a large archive that excludes older mail — pair to with receivedAfter/receivedBefore. Since v3.11.1 the response says so whenever the scan was truncated, whether or not it matched.Mail.Read.Shared permission and a work/school account.Place.Read.All permission with admin consent (work/school accounts only).savePath or outputDir to specify a different location.Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
For security concerns, please see our Security Policy. Do not open public issues for vulnerabilities.
See CHANGELOG.md for version history.
Built and maintained by Little Bear Apps. Outlook Assistant is open source under the MIT License.