---
name: outlook
description: "Microsoft 365 / Outlook.com via Microsoft Graph (read-only). Use when the user asks about their Outlook mail, calendar, or contacts — listing, searching, or checking events. First-time use requires outlook-account-register; subsequent use is transparent. Tools — outlook-mail-list / outlook-mail-search (inbox), outlook-calendar-list / outlook-calendar-event (calendar), outlook-contacts-list (contacts), outlook-mailbox-info (health), outlook-account-register (PKCE register)."
---

# Outlook (Microsoft Graph)

Read-only access to the user's Outlook.com or Microsoft 365 mailbox via Microsoft Graph. Per-account OAuth, encrypted token storage, refresh handled automatically.

## When to activate

Activate when the user asks about:

- Their Outlook / Office 365 / Hotmail mail (recent messages, search by keyword/sender)
- Their Outlook calendar (upcoming events, specific event details, free/busy windows)
- Their Outlook contacts

Do **not** activate for:

- IMAP-only providers (Gmail, iCloud, custom domains not on Microsoft 365) — use the `email` plugin instead.
- On-premises Exchange — Microsoft Graph deprecated hybrid REST 2023-07. The plugin detects on-prem mailboxes and emits a clear error pointing to the IMAP path.
- Sending / drafting / modifying messages or events — out of scope. Read-only.

## First-time setup (one-time per account)

The Outlook plugin needs an **Entra app registration** in the operator's Microsoft tenant. This is a one-time-per-install step (not per-account), documented at [`references/auth.md`](references/auth.md).

Once the Entra app exists and `OUTLOOK_CLIENT_ID` is set in the Maxy installation, run:

1. **`outlook-account-register`** — the tool returns an `authUrl`. The operator opens this URL in the VNC browser, signs in with the Microsoft account they want to connect, and consents to the requested scopes (`offline_access`, `User.Read`, `Mail.Read`, `Calendars.Read`, `Contacts.Read`).
2. Tool returns `{ status: "registered", graphUserId, scopes, tokenExpSec }` once consent completes.

Subsequent tool calls use the persisted refresh token to mint access tokens transparently. Re-register is only needed if the refresh token expires (90 days) or the user revokes consent.

## Reading mail

- `outlook-mail-list` — recent mail, default top=25, folder=Inbox.
- `outlook-mail-search query=<keyword>` — Microsoft Graph `$search` over the mailbox.

## Reading calendar

- `outlook-calendar-list rangeDays=<N>` — events in the next N days (default 7, max 365).
- `outlook-calendar-event eventId=<id>` — single event with full body and attendees.

## Reading contacts

- `outlook-contacts-list` — top contacts, default top=50.

## Health check

- `outlook-mailbox-info` — quick state probe: is the account registered? Are tokens within the refresh window? How many folders are visible? Useful when troubleshooting a tool that returned `auth-required`.

## What can go wrong

| Error | Meaning | Operator action |
|---|---|---|
| `auth-required` | Account not registered, or refresh token expired | Run `outlook-account-register` |
| `Outlook token refresh failed` | Network down or refresh token invalidated | Verify connectivity; re-run register if persistent |
| `Microsoft Graph does not support on-premises Exchange` | Mailbox is on hybrid Exchange | Use the `email` plugin (IMAP) |
| `Outlook rate-limited without Retry-After hint` | Graph 429 with no backoff guidance | Retry later; if persistent, file a bug |

## Reference files

- [`references/auth.md`](references/auth.md) — Entra app registration + PKCE flow + re-vendor procedure
- [`references/graph-surfaces.md`](references/graph-surfaces.md) — Graph endpoint and response shape per tool
