Microsoft connectors — Outlook, SharePoint, OneDrive (one OAuth dance)

Single Microsoft Graph OAuth flow covers all three connector kinds. Delta-cursor sync per surface, encrypted token storage, refresh-token rotation handled.

Updated 2026-04-30

Three connector kinds — Outlook, SharePoint, OneDrive — share one OAuth flow because they're all Microsoft Graph endpoints. One consent screen, one token, three sync surfaces.

## Setup

Register an app in the Entra ID admin center (`https://entra.microsoft.com` → App registrations → New registration):

- **Redirect URI:** `<your-kodori-domain>/api/oauth/callback/microsoft` - **Supported account types:** Accounts in any organizational directory and personal Microsoft accounts (default for self-service) - **Required API permissions** (Microsoft Graph, delegated): - `User.Read` - `Mail.Read` - `Files.Read.All` - `Sites.Read.All` - `offline_access` (so we can refresh tokens past the 1h access-token TTL) - **Client secret:** generate one under Certificates & secrets

Set environment variables:

- `MICROSOFT_OAUTH_CLIENT_ID` — Application (client) ID - `MICROSOFT_OAUTH_CLIENT_SECRET` — the secret VALUE (not the secret ID) - `MICROSOFT_OAUTH_TENANT` (optional) — default `common` (any work / school / MSA tenant). Override to your tenant ID for single-tenant deployments.

Then click **Connect** next to Outlook, SharePoint, or OneDrive on `/integrations`. All three connect through the same OAuth route; the `?kind=` query param tells the callback which row to create.

## What gets synced

- **Outlook** → messages from your Inbox via `/me/mailFolders/inbox/messages/delta`. HTML body is stripped to plain text for indexing. - **OneDrive** → files from your personal OneDrive root via `/me/drive/root/delta`. Folders are skipped; soft-deletes are honored on subsequent runs. - **SharePoint** → files from sites you follow (Star button in SharePoint UI) via `/me/followedSites` → `/drives` → `/drives/{id}/root/delta`. Up to 10 sites + 5 drives per site per run.

All three use Graph's delta-cursor pattern, so subsequent runs return only the changes since the last `@odata.deltaLink`.

## What does NOT get synced (by design)

- File **bytes** are not mirrored to Kodori. The connector stores the file's text + URL pointer + metadata; the vendor stays the source of truth. If you delete a file in SharePoint, the next sync removes it from Kodori. - Outlook attachments (next-batch upgrade — currently the message body indexes but attachments require a second pass). - Teams / Channels / Yammer (different Graph endpoints; would be a new connector kind).

## Searching synced content

`searchExternalContent` MCP tool searches across all synced messages + documents. The agent answers "find every email and SharePoint file from the Brennan matter" with one tool call.