MaxyDocs
View as markdown →

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

  1. Register an Entra app once per Maxy install — see platform/plugins/outlook/references/auth.md for full steps. Set OUTLOOK_CLIENT_ID (and OUTLOOK_TENANT_ID, default common) in the operator's environment.
  2. 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.
  3. 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).
  4. Done. Subsequent tool calls (mail, calendar, contacts) use the persisted refresh token transparently.

Tools

ToolPurpose
outlook-account-registerRun the PKCE flow for this account. One-time per account; re-run if tokens expire (90 days) or consent is revoked.
outlook-mail-listRecent mail. Default top=25, folder=Inbox.
outlook-mail-searchMicrosoft Graph $search over the mailbox.
outlook-calendar-listCalendar events in next rangeDays days (default 7, max 365).
outlook-calendar-eventFull detail of a single event by id.
outlook-contacts-listTop contacts. Default top=50.
outlook-mailbox-infoHealth 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:

EventLine shape
Auth initauth-init account=<id> codeChallenge=<sha256-prefix-8> redirectPath=<callback-path>
Auth callbackauth-callback account=<id> elapsedMs=<N>
Auth okauth-ok account=<id> graphUserId=<id> scopes=<csv> tokenExpSec=<N>
Token refreshedtoken-refreshed account=<id> oldExpSec=<N> newExpSec=<N>
Refresh failedtoken-refresh-failed account=<id> reason=<err> (terminal)
Mail listmail-list account=<id> folder=<id-or-Inbox> count=<N> elapsedMs=<N>
Mail searchmail-search account=<id> query=<trunc-32> count=<N> elapsedMs=<N>
Calendar listcalendar-list account=<id> rangeDays=<N> count=<N> elapsedMs=<N>
Calendar eventcalendar-event account=<id> eventId=<trunc-12> elapsedMs=<N>
Contacts listcontacts-list account=<id> count=<N> elapsedMs=<N>
Mailbox infomailbox-info account=<id> tokenWithinRefreshWindow=<bool> folderCount=<N>
Graph errorgraph-error account=<id> status=<N> code=<graphErrorCode> retryAfterMs=<N-or-null>
On-prem rejectedon-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 messageCauseFix
Outlook not connected for account=X; run outlook-account-registerTokens never savedRun register tool
Outlook refresh token expired for account=X; run outlook-account-register>90 days since last refresh, or consent revokedRun register tool
Outlook token refresh failed for account=X; re-auth requiredNetwork down at refresh time, or refresh token invalidatedVerify network; re-register
Outlook auth expired for account=X; run outlook-account-registerRefresh-then-retry still got 401Re-register
Outlook rate-limited without Retry-After hintGraph 429 with no backoff guidanceWait + retry; if persistent, file bug
Microsoft Graph does not support on-premises Exchange. Use earlier platform fixes (IMAP).Mailbox is on hybrid ExchangeUse 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.