Skip to main content
Glama
README.md
# mariana-outlook-mcp

A custom MCP (Model Context Protocol) server that gives Claude Code access to Outlook Mail, Calendar, and Contacts via Microsoft Graph — with safety-first defaults. Sibling of [mariana-google-mcp](https://github.com/marianasmall/mariana-google-mcp), same architecture pointed at Microsoft accounts (M365 work/school and personal Outlook/Hotmail).

## Design Philosophy

Built for an operator who wants AI help managing their mailbox without risk of accidental damage:

- **No sending email — enforced by Microsoft, not just this code.** The server never requests the `Mail.Send` permission, so its tokens are physically incapable of sending. You draft; you send from Outlook.
- **No deleting anything.** Mail moves to a "To Be Deleted" folder (reversible). Calendar events get "DELETE - " prepended to the title. You review and confirm in the Outlook UI.
- **Every mutation is logged.** An append-only JSONL action log records every write with timestamps, tool name, account, and summary.
- **Multi-account support.** Work and personal Microsoft accounts under named aliases.
- **No client secret.** Desktop PKCE flow — the only credential is a public Application ID.

## Setup

**Easiest path:** paste this one line into Claude Code and it runs the entire setup for you, including guiding you through the Azure clicks:

> Fetch https://raw.githubusercontent.com/marianasmall/mariana-outlook-mcp/main/SETUP-PROMPT.md and follow the instructions in it.

The manual steps below cover the same ground.

### 1. Azure App Registration

1. Go to [portal.azure.com](https://portal.azure.com) → search "App registrations" → **New registration**
2. Name: "Claude Code". Supported account types: **Accounts in any organizational directory and personal Microsoft accounts** (the option that includes personal accounts)
3. Redirect URI: platform **Public client/native (mobile & desktop)**, value `http://localhost`
4. Register, then copy the **Application (client) ID** from the Overview page
5. Under **Authentication**, set "Allow public client flows" to **Yes**

No client secret is created — this is a PKCE public client.

### 2. Install and Build

```bash
git clone https://github.com/marianasmall/mariana-outlook-mcp.git
cd mariana-outlook-mcp
npm install
npm run build
```

### 3. Add to Claude Code

```bash
claude mcp add outlook --scope user \
  -e MS_CLIENT_ID="<application-client-id>" \
  -- node /FULL/PATH/TO/mariana-outlook-mcp/dist/index.js
```

Optional: set `MS_TENANT` to a specific tenant ID (defaults to `common`, which accepts both work and personal accounts). Restart Claude Code after adding.

### 4. Authenticate

Run the `microsoft_auth` tool with a friendly account name (e.g. `consulting`, `personal`). A browser window opens for consent; approve as the matching Microsoft account. Repeat per account. Verify with `microsoft_status`.

## Available Tools (20)

### Authentication & Status
| Tool | Description |
|------|-------------|
| `microsoft_auth` | Authenticate a Microsoft account via OAuth browser flow (PKCE) |
| `microsoft_status` | Live connection health for all configured accounts |

### Mail (10 tools)
| Tool | Description |
|------|-------------|
| `outlook_search` | Search messages (KQL: from:, subject:, or keywords) |
| `outlook_read` | Read a specific message by ID (plain-text body + attachment names) |
| `outlook_draft` | Create a draft — plain text or rich HTML body, attachments (≤3MB/file), optional reply-in-thread (does NOT send) |
| `outlook_list_folders` | List mail folders with unread counts |
| `outlook_list_categories` | List categories (the Gmail-labels equivalent) |
| `outlook_create_category` | Create a category |
| `outlook_apply_category` | Apply a category to messages |
| `outlook_remove_category` | Remove a category from messages |
| `outlook_create_rule` | Create an inbox rule (the Gmail-filter equivalent) |
| `outlook_move_to_delete` | Soft-delete: move messages to a "To Be Deleted" folder |

### Calendar (7 tools)
| Tool | Description |
|------|-------------|
| `calendar_list` | List upcoming events |
| `calendar_search` | Search events by title keyword |
| `calendar_get` | Full details of one event |
| `calendar_create` | Create an event (attendees NOT invited by default) |
| `calendar_update` | Modify an event (attendee-notification caveat in tool description) |
| `calendar_flag_delete` | Soft-delete: prepend "DELETE - " to the title |
| `calendar_availability` | Free/busy blocks for a date range |

### Contacts (2 tools)
| Tool | Description |
|------|-------------|
| `contacts_search` | Search contacts by name, email, or phone |
| `contacts_list` | List contacts, optionally filtered |

## Multi-Account Support

```
microsoft_auth account_name: "consulting"
microsoft_auth account_name: "personal"
```

Most tools accept an optional `account` parameter; omitted, they use the default (first-connected) account. `microsoft_status` shows all accounts and their health.

## Configuration Files

All state lives in `~/.config/mariana-outlook-mcp/`:

| File | Purpose |
|------|---------|
| `config.json` | Account registry (aliases, email hashes, default) |
| `tokens/<hash>.json` | OAuth tokens per account (never leave this machine) |
| `action-log.jsonl` | Append-only log of every write operation |

## Graph-vs-Gmail Differences Worth Knowing

- **Categories ≈ labels; folders ≈ folders.** Outlook has both. Categories apply like Gmail labels; soft-delete uses a folder because that's the native Outlook idiom.
- **Reply drafts** take a `reply_to_message_id` (Graph threads replies from a message, not a thread ID).
- **Moved messages get new IDs** — Graph reassigns message IDs on folder moves.
- **Attendee invitations**: Outlook sends invitation/update emails itself when an event has attendees; `calendar_create` therefore defaults to NOT attaching attendees (names go in the description) unless `send_invites=true`.
- **Refresh tokens** last ~90 days sliding for personal accounts — regular use keeps them alive indefinitely; a long-unused account may need re-auth.

## License

MIT

TDQS

A3.6/5.0

Scored across 21 tools

Disambiguation4/5

Most tools have clear, distinct purposes within their domains, but 'calendar_search' and 'calendar_list' both retrieve calendar events and could be confused. The soft-delete tools for mail and calendar share a similar pattern but are separated by domain.

Naming Consistency5/5

All tools follow a consistent 'domain_action' pattern, using lowercase with underscores (e.g., outlook_read, calendar_create, contacts_search). The use of compound actions like 'flag_delete' and 'move_to_delete' still maintains a uniform style without mixing conventions.

Tool Count4/5

With 21 tools, the server is slightly above the typical well-scoped range, but the breadth is justified by covering mail, calendar, contacts, and authentication. The tools are not excessively fragmented for the wide scope.

Completeness3/5

Mail and calendar have decent coverage, but contacts only support search and list with no create/update/delete operations. The lack of hard delete for messages/events and exclusion of sending email are notable gaps that limit full lifecycle management.

Maintenance

ActivityMaintained
ResponsivenessNo issues