Server For Multiple Outlook Accounts
FreeNot checkedEnables AI assistants to manage multiple Outlook/Microsoft 365 mailboxes simultaneously through MCP tools, with local OAuth token storage.
About
Enables AI assistants to manage multiple Outlook/Microsoft 365 mailboxes simultaneously through MCP tools, with local OAuth token storage.
README
A local, single-connector Model Context Protocol server that lets an AI assistant operate several Outlook / Microsoft 365 mailboxes at once — searching, reading, drafting, sending, and organising mail — through one safety-annotated tool surface, with OAuth tokens that never leave your machine.
This is the Outlook / Microsoft Graph provider variant of a provider-neutral specification.
- 📄 doc/business-specification.md — provider-neutral business + functional spec (the contract).
- 🔌 doc/provider-mapping.md — how neutral requirements bind to Microsoft Graph.
- 🏗️ doc/architecture.md — how this variant is designed and built.
- ✅ doc/traceability-matrix.md — every requirement → module → test.
- 🚀 doc/ONBOARDING.md — operator guide: register an Entra app, handle consent, connect a mailbox.
- ✅ doc/LIVE-ACCEPTANCE.md — live acceptance runbook +
npm run live-smoke(the remaining work). - 🤝 doc/CONTRIBUTING.md — handoff guide: how we work, workflow, and the per-phase record.
- 📋 doc/HANDOVER.md — handover snapshot: what's done and the outstanding-work checklist.
Project status: feature-complete (offline build)
Built with TypeScript 6.0.3; build, typecheck, tests (179), and format all green. All eight capabilities are implemented and the offline build is feature-complete. What exists today:
- ✅ Architecture design + requirements traceability matrix (
doc/). - ✅ Auth core: Entra credential-source discovery, MSAL public-client (consent + silent refresh),
secure token store (
0600/0700, atomic + cross-process-locked), account-selection registry. - ✅ Account-management CLI:
outlook-mcp-auth connect | list | remove. - ✅ Microsoft Graph client: thin
fetchwrapper with a per-request timeout, bounded jittered retry (with the no-duplicate-send policy), and actionable error mapping. - ✅ Read tools:
list_accounts(C1),search_conversations(C2),read_conversation(C3) — with Gmail-style search-operator translation and bounded, truncating output. - ✅ Write tools:
create_draft(C4) andsend_message(C5) — recipient parsing (Display Name <addr>), header-injection stripping, allow-listed/TOCTOU-safe attachments, local outgoing-size validation, and reply threading. Small attachments ride inline; large ones (> ~3 MB) upload to the draft via a Graph upload session, so send becomes create-draft → upload → send with the final/sendunder thenonDuplicableretry policy — a retry can never double-deliver. - ✅ Organise tools:
list_labels(C6),create_label(C7), andorganize_mail(C8) — the label-decomposition fan-out that maps one neutral organise request to the right mix of Graph category-PATCH / read-state /movecalls (archive, trash, junk — mutually exclusive), applied per message across a conversation under a bounded concurrency limit, reporting the union of resulting labels.list_labelsenumerates folders recursively (full paths). - ✅ Hardening + onboarding: a secret-redaction boundary so tokens/credentials can never reach the logs (NFR-SEC-6), and the operator onboarding guide (Entra app registration, unverified-app consent, the connect CLI).
Remaining: the live acceptance runs (real browser consent + real Graph calls) that the
operator performs against an Entra app registration + Outlook mailbox. See doc/architecture.md §13.
Tests mock Microsoft Graph and MSAL. Live
§13acceptance — real browser consent and Graph calls — requires an Entra app registration + Outlook mailboxes and is run locally by the operator.
Capabilities (spec §5)
| Tool | Purpose | Destructive? | Status |
|---|---|---|---|
list_accounts |
List connected mailboxes | No | ✅ live |
search_conversations |
Search a mailbox (paged) | No | ✅ live |
read_conversation |
Read a full conversation | No | ✅ live |
create_draft |
Compose a draft (not sent) | No | ✅ live |
send_message |
Send immediately | Yes | ✅ live |
list_labels |
List categories + folders | No | ✅ live |
create_label |
Create a category/folder | No | ✅ live |
organize_mail |
Tag / move / read-state | Yes | ✅ live |
Plus an out-of-band account-management CLI (outlook-mcp-auth connect | list | remove).
Development
Requires Node.js ≥ 18 (developed on Node 22).
npm install
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
npm test # vitest (Graph/MSAL mocked)
npm run format:check # prettier
Configuration
All operational knobs are environment variables (see .env.example):
| Env var | Meaning | Default |
|---|---|---|
OUTLOOK_MCP_DATA_DIR |
tokens + app-registration configs | ~/.outlook-mcp |
OUTLOOK_OAUTH_CREDENTIALS |
pin one app registration (disables discovery) | unset |
OUTLOOK_MCP_ATTACHMENTS_DIR |
allow-list for path attachments |
unset (disabled) |
OUTLOOK_MCP_LOCK_TIMEOUT_MS |
token-store lock wait | 12000 |
OUTLOOK_MCP_REQUEST_TIMEOUT_MS |
per-Graph-call timeout | 30000 |
Connecting a mailbox
For the full walkthrough — Entra app registration, the unverified-app consent policy, and troubleshooting — see doc/ONBOARDING.md. The short version:
Register a public-client app in Entra ID with the redirect URI
http://localhostand the delegated scopesMail.ReadWrite,Mail.Send,User.Read,offline_access.Drop a
credentials*.jsoninto the data dir (or pointOUTLOOK_OAUTH_CREDENTIALSat it):{ "clientId": "<application-client-id>", "tenant": "common" }Multiple
credentials*.jsonfiles are auto-discovered, so accounts under different app registrations each refresh with the client that authorised them.Connect, list, and remove mailboxes:
outlook-mcp-auth connect # opens the browser for consent outlook-mcp-auth connect --source acme # pick a specific app registration outlook-mcp-auth list outlook-mcp-auth remove [email protected]
Security posture
OAuth tokens are stored only on the local machine (file mode 600 in a 700 data dir). Reading
local files by path for attachments is disabled by default and only allowed from an explicit
allow-list. The server never logs tokens, credentials, or message content. See
doc/architecture.md §9.
License
MIT — see LICENSE.
from github.com/uaixo/MCP-Server-For-Multiple-Outlook-Accounts
Installing Server For Multiple Outlook Accounts
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/uaixo/MCP-Server-For-Multiple-Outlook-AccountsFAQ
Is Server For Multiple Outlook Accounts MCP free?
Yes, Server For Multiple Outlook Accounts MCP is free — one-click install via Unyly at no cost.
Does Server For Multiple Outlook Accounts need an API key?
No, Server For Multiple Outlook Accounts runs without API keys or environment variables.
Is Server For Multiple Outlook Accounts hosted or self-hosted?
Self-hosted: the server runs locally on your machine via the install command above.
How do I install Server For Multiple Outlook Accounts in Claude Desktop, Claude Code or Cursor?
Open Server For Multiple Outlook Accounts on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Gmail
Read, send and search emails from Claude
by GoogleSlack
Send, search and summarize Slack messages
by SlackRunbear
No-code MCP client for team chat platforms, such as Slack, Microsoft Teams, and Discord.
Discord Server
A community discord server dedicated to MCP by [Frank Fiegel](https://github.com/punkpeye)
Compare Server For Multiple Outlook Accounts with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All communication MCPs
