Outlook Plugin — Operator Guide
The outlook plugin gives the admin agent read-only access to Microsoft 365 / Outlook.com via Microsoft Graph. Per-account OAuth (Auth Code + PKCE), encrypted token storage, automatic refresh.
Quickstart
- Register an Entra app once per Maxy install — see
platform/plugins/outlook/references/auth.mdfor full steps. SetOUTLOOK_CLIENT_ID(andOUTLOOK_TENANT_ID, defaultcommon) in the operator's environment. - Per account: register the Outlook account — in admin chat, ask the agent to "register my Outlook account". The agent runs
outlook-account-register, which prints an authorization URL. - Open the URL in the VNC browser — sign in to your Microsoft account, consent to the requested scopes (
offline_access,User.Read,Mail.Read,Calendars.Read,Contacts.Read). - Done. Subsequent tool calls (mail, calendar, contacts) use the persisted refresh token transparently.
Tools
| Tool | Purpose |
|---|---|
outlook-account-register | Run the PKCE flow for this account. One-time per account; re-run if tokens expire (90 days) or consent is revoked. |
outlook-mail-list | Recent mail. Default top=25, folder=Inbox. |
outlook-mail-search | Microsoft Graph $search over the mailbox. |
outlook-calendar-list | Calendar events in next rangeDays days (default 7, max 365). |
outlook-calendar-event | Full detail of a single event by id. |
outlook-contacts-list | Top contacts. Default top=50. |
outlook-mailbox-info | Health probe — auth state, refresh-window, folder count. |
Observability
All log lines start with [outlook-mcp] and write to server.log. They are key=value, account-scoped:
| Event | Line shape |
|---|---|
| Auth init | auth-init account=<id> codeChallenge=<sha256-prefix-8> redirectPath=<callback-path> |
| Auth callback | auth-callback account=<id> elapsedMs=<N> |
| Auth ok | auth-ok account=<id> graphUserId=<id> scopes=<csv> tokenExpSec=<N> |
| Token refreshed | token-refreshed account=<id> oldExpSec=<N> newExpSec=<N> |
| Refresh failed | token-refresh-failed account=<id> reason=<err> (terminal) |
| Mail list | mail-list account=<id> folder=<id-or-Inbox> count=<N> elapsedMs=<N> |
| Mail search | mail-search account=<id> query=<trunc-32> count=<N> elapsedMs=<N> |
| Calendar list | calendar-list account=<id> rangeDays=<N> count=<N> elapsedMs=<N> |
| Calendar event | calendar-event account=<id> eventId=<trunc-12> elapsedMs=<N> |
| Contacts list | contacts-list account=<id> count=<N> elapsedMs=<N> |
| Mailbox info | mailbox-info account=<id> tokenWithinRefreshWindow=<bool> folderCount=<N> |
| Graph error | graph-error account=<id> status=<N> code=<graphErrorCode> retryAfterMs=<N-or-null> |
| On-prem rejected | on-prem-rejected account=<id> mailServer=<host> (terminal) |
Diagnostic paths
# All outlook lines for one account, last 50
ssh laptop 'grep -E "^\[outlook-mcp\]" ~/.maxy/logs/server.log | grep "account=<id>" | tail -50'
# Token-leak audit — must always return zero
grep -rn -iE "Bearer |access_token=" ~/.maxy/logs/server.log | head
Latency triage: mail-list count=0 elapsedMs<200 consistent → permissions issue; elapsedMs > 5000 → Graph slowness or DNS.
Failure modes
| Operator-visible message | Cause | Fix |
|---|---|---|
Outlook not connected for account=X; run outlook-account-register | Tokens never saved | Run register tool |
Outlook refresh token expired for account=X; run outlook-account-register | >90 days since last refresh, or consent revoked | Run register tool |
Outlook token refresh failed for account=X; re-auth required | Network down at refresh time, or refresh token invalidated | Verify network; re-register |
Outlook auth expired for account=X; run outlook-account-register | Refresh-then-retry still got 401 | Re-register |
Outlook rate-limited without Retry-After hint | Graph 429 with no backoff guidance | Wait + retry; if persistent, file bug |
Microsoft Graph does not support on-premises Exchange. Use earlier platform fixes (IMAP). | Mailbox is on hybrid Exchange | Use the email plugin |
Out of scope
Write tools (send, draft, move, flag), OneDrive / Files, push notifications, on-premises Exchange, M365 admin scopes (User.Read.All, AuditLog.Read.All), public-agent exposure, multi-tenant federation. See platform/plugins/outlook/PLUGIN.md for the full out-of-scope list.