outlook-triage-mcp
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@outlook-triage-mcpGive me my daily briefing for the last 48 hours."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
outlook-triage-mcp
MCP server for Microsoft 365 mail — search, classify, and triage your inbox from Claude via Microsoft Graph: daily-briefing digest, idempotent inbox-rule provisioning, attachment extraction. Device-code auth, read-only by default.
🇺🇸 English
Your inbox, triaged by Claude — without handing anyone your password. This MCP server connects Claude (Code or Desktop) to a Microsoft 365 mailbox through Microsoft Graph, using device-code sign-in and a local token cache. It classifies mail with deterministic keyword heuristics (no LLM calls at runtime, no message content leaving your machine beyond what you ask Claude to read), builds a morning briefing, and can — only if you explicitly opt in — provision inbox rules idempotently.
Features
Daily briefing — classifies the last N hours of inbox mail into
urgent/action_needed/fyi/newsletterand renders a Markdown digest. Heuristics are deterministic and configurable (env vars or a JSON file); messages you already read are never flagged as pending.Search & read — Graph
$search/$filtermessage search in any folder; full plain-text bodies; local text extraction from PDF / DOCX / XLSX attachments (pypdf, python-docx, openpyxl — parsing is 100% local).Idempotent inbox rules —
ensure_inbox_ruleconverges mailbox state: an already-correct rule triggers zero write calls, a divergent one is patched, a missing one is created (folder included). Run it a hundred times, get one rule.Device-code auth — MSAL public-client flow: the
auth_statustool hands you a URL and a code; sign in from any browser. Tokens are cached in~/.local/share/outlook-triage-mcp/(never in the repo,0600permissions) and refreshed silently.Read-only by default — the server requests only
Mail.Read/MailboxSettings.Readscopes unless you setOUTLOOK_MCP_ENABLE_WRITE=1.Retry/backoff — Graph calls honor
Retry-Afteron 429 and back off exponentially on 5xx.
⚠️ Write access
ensure_inbox_rule is the ONLY tool that writes to your mailbox. Every other tool is strictly read-only (and annotated as such in the MCP tool metadata). Rule provisioning is disabled by default: the tool refuses to run until you start the server with OUTLOOK_MCP_ENABLE_WRITE=1 and re-authenticate with write scopes. The server never sends, deletes, moves, or marks messages.
Tools
Tool | Access | Description |
| read-only | Token state; starts device-code sign-in and returns the URL + code when login is needed |
| read-only | Search (KQL) or list messages; |
| read-only | Full body + metadata; optionally extracts text from PDF/DOCX/XLSX attachments locally |
| read-only | Markdown digest classified into urgent / action_needed / fyi / newsletter |
| read-only | Inventory of inbox rules with conditions and actions |
| WRITE | Idempotently converge one rule (sender contains X → move to folder Y); creates the folder if missing |
Example prompts once connected:
"Give me my daily briefing for the last 48 hours." "Search my inbox for messages about the Q3 invoice and read the newest one, including attachments." "Make sure there's a rule moving everything from recruiting@ to a Recruiters folder." (requires write mode)
How it works
flowchart LR
subgraph Claude["Claude (Code / Desktop)"]
C[MCP client]
end
subgraph Server["outlook-triage-mcp (local)"]
T[FastMCP tools]
H[Heuristic classifier<br/>deterministic, no LLM]
A[MSAL device-code auth<br/>token cache ~/.local/share]
G[Graph client<br/>retry + backoff]
X[Attachment extraction<br/>PDF / DOCX / XLSX, local]
end
M[(Microsoft Graph<br/>Microsoft 365 mailbox)]
C <-->|stdio JSON-RPC| T
T --> H
T --> X
T --> G
G --> A
G <-->|HTTPS, delegated scopes| MInstall
git clone https://github.com/giuseppeferretti/outlook-triage-mcp
cd outlook-triage-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[attachments]" # attachments extra enables PDF/DOCX/XLSX parsingConfigure Claude
Claude Code:
claude mcp add outlook-triage -- /path/to/.venv/bin/outlook-triage-mcpClaude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"outlook-triage": {
"command": "/path/to/.venv/bin/outlook-triage-mcp",
"env": {
"OUTLOOK_MCP_USER_EMAIL": "you@yourcompany.com"
}
}
}
}First use: ask Claude to call auth_status, open the verification URL it returns, type the code, done. The token is cached locally; you will rarely need to sign in again.
Configuration (env vars)
Variable | Default | Purpose |
| Microsoft Graph CLI public client ( | Azure AD app registration. The default is Microsoft's own Graph CLI public client, which is pre-authorized for delegated mail scopes on most tenants (the older Azure CLI client is blocked for |
|
| Restrict sign-in to a specific tenant |
| — | Your address; used to pick the cached account and to classify self-sent mail |
|
| Set |
|
| Token cache location |
| — | JSON file overriding heuristic keyword lists |
| built-in lists | Comma-separated overrides for individual heuristic lists |
|
| Attachments larger than this are listed, not parsed |
Classification file example (classify.json):
{
"urgent_keywords": ["urgent", "asap", "outage"],
"action_keywords": ["please review", "sign off"],
"vip_senders": ["ceo@yourcompany.com"],
"newsletter_sender_patterns": ["noreply@", "digest@"]
}Development
pip install -e ".[dev]"
pytest # all offline: fixture JSON + fake Graph + stdio smoke test
OUTLOOK_MCP_LIVE_TESTS=1 pytest tests/test_graph_live.py # optional, real GraphThe test suite requires no Microsoft account: classification and rule-idempotency tests run against fake Graph responses, and the MCP smoke test boots the real stdio server with the official SDK client and verifies the tool list and graceful auth-required behavior.
Provenance
This server was extracted from a production Microsoft 365 automation system — a daily-briefing robot and idempotent inbox-rule provisioner that runs every morning for a real controllership workflow. The battle-tested parts were kept (device-code auth with token cache, Graph retry/backoff, write-free classification, converge-don't-duplicate rule provisioning) and the client-specific heuristics were genericized into configurable keyword lists. Case study at portfolio.iterlabs.com.br.
Related MCP server: m365-mcp-server
🇧🇷 Português
Servidor MCP para e-mail Microsoft 365 — busque, classifique e faça triagem da sua caixa de entrada pelo Claude via Microsoft Graph. Autenticação por device-code (sem senha no servidor), token em cache local, somente leitura por padrão.
Recursos
Briefing diário: classifica as últimas N horas em
urgent/action_needed/fyi/newslettercom heurísticas determinísticas (sem LLM em runtime), configuráveis por env ou arquivo JSON. Mensagens já lidas nunca aparecem como pendentes.Busca e leitura: pesquisa Graph em qualquer pasta, corpo completo em texto e extração local de texto de anexos PDF / DOCX / XLSX.
Regras idempotentes:
ensure_inbox_ruleconverge o estado da caixa — regra já correta gera zero chamadas de escrita; nunca duplica regra nem pasta.Retry/backoff nas chamadas Graph (respeita
Retry-Afterem 429).
⚠️ Escrita
ensure_inbox_rule é a ÚNICA ferramenta que escreve na caixa. Todas as outras são somente leitura. Escrita fica desabilitada até você definir OUTLOOK_MCP_ENABLE_WRITE=1 e autenticar novamente com escopos de escrita. O servidor nunca envia, exclui, move ou marca mensagens.
Instalação e uso
git clone https://github.com/giuseppeferretti/outlook-triage-mcp
cd outlook-triage-mcp
python -m venv .venv && source .venv/bin/activate
pip install -e ".[attachments]"
claude mcp add outlook-triage -- /caminho/para/.venv/bin/outlook-triage-mcpNo primeiro uso, peça ao Claude para chamar auth_status: ele devolve uma URL e um código — abra no navegador, digite o código e pronto. O token fica em cache em ~/.local/share/outlook-triage-mcp/ (nunca no repositório).
Configuração principal: OUTLOOK_MCP_CLIENT_ID (padrão: client público do Microsoft Graph CLI; registre seu próprio app se o tenant bloquear), OUTLOOK_MCP_TENANT_ID, OUTLOOK_MCP_USER_EMAIL, OUTLOOK_MCP_ENABLE_WRITE e as listas de palavras-chave OUTLOOK_MCP_*_KEYWORDS / OUTLOOK_MCP_VIP_SENDERS.
Testes: pytest roda 100% offline (fixtures JSON + Graph falso + smoke test MCP stdio com o SDK oficial). Testes contra o Graph real são opcionais: OUTLOOK_MCP_LIVE_TESTS=1.
Origem
Extraído de um sistema de automação Microsoft 365 em produção (robô de briefing diário + provisionamento idempotente de regras), com as heurísticas do cliente genericizadas em listas configuráveis. Case em portfolio.iterlabs.com.br.
Built with AI-assisted development; designed, verified, and operated by Giuseppe Ferretti.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/giuseppeferretti/outlook-triage-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server