From c112c9b330019e1c67463d8c47f2c98616623ad5 Mon Sep 17 00:00:00 2001 From: Seton Carmichael Date: Tue, 25 Aug 2026 15:02:08 -0400 Subject: [PATCH] =?UTF-8?q?docs:=20update=20README=20for=20v1.1.0=20?= =?UTF-8?q?=E2=80=94=2022=20tools,=20mailbox=20params,=20architecture,=20s?= =?UTF-8?q?hared=20scopes,=20.gitignore=20accuracy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index e2537eb..dbb77f6 100644 --- a/README.md +++ b/README.md @@ -186,7 +186,7 @@ Each instance gets its own MSAL cache — no account-selection conflicts. ## Tools Reference -The server exposes **21 tools** across five categories. +The server exposes **22 tools** across six categories (21 when `OUTLOOK_ENABLE_SHARED_MAILBOXES=false`). ### Authentication (3 tools) @@ -200,12 +200,12 @@ The server exposes **21 tools** across five categories. | Tool | Key Parameters | Description | |---|---|---| -| `list-emails` | `folder`, `count`, `dateFrom`, `dateTo`, `dateRange` | Lists emails from a folder with date filtering. Results include `conversationId`. | -| `search-emails` | `query`, `from`, `to`, `subject`, `hasAttachments`, `unreadOnly`, `count` | Progressive search with KQL fallback strategies. Results include `conversationId`. | -| `read-email` | `id` | Reads a single email with full body (auto-cleaned HTML → text) | -| `read-emails` | `ids` (max 10) | Reads multiple emails concurrently | -| `send-email` | `to`, `cc`, `bcc`, `subject`, `body`, `importance`, `saveToSentItems` | Sends an email (plain text or HTML) | -| `get-email-thread` | `conversationId` (preferred) or `ids` (max 20) | Fetches a complete conversation across all folders (inbox + sent), strips quoted replies, deduplicates signatures per sender | +| `list-emails` | `folder`, `count`, `dateFrom`, `dateTo`, `dateRange`, `mailbox` | Lists emails from a folder with date filtering. Results include `conversationId`. Pass `mailbox` to target a shared mailbox. | +| `search-emails` | `query`, `from`, `to`, `subject`, `hasAttachments`, `unreadOnly`, `count`, `strict`, `mailbox` | Progressive search with KQL fallback strategies. Results include `conversationId`. Pass `mailbox` for shared mailbox search. Use `strict: true` to disable fallback to recent emails. | +| `read-email` | `id`, `mailbox` | Reads a single email with full body (auto-cleaned HTML → text). Pass the same `mailbox` used when listing/searching. | +| `read-emails` | `ids` (max 10), `mailbox` | Reads multiple emails concurrently | +| `send-email` | `to`, `cc`, `bcc`, `subject`, `body`, `importance`, `saveToSentItems`, `mailbox`, `from`, `onBehalfOf` | Sends an email (plain text or HTML). When `mailbox` is set, sends as that shared mailbox via `users/{mailbox}/sendMail` (requires Send As + `Mail.Send.Shared`). Set `onBehalfOf: true` for Send on Behalf via `me/sendMail` with `from` set. | +| `get-email-thread` | `conversationId` (preferred) or `ids` (max 20), `mailbox` | Fetches a complete conversation across all folders (inbox + sent), strips quoted replies, deduplicates signatures per sender. Pass `mailbox` when the conversation is in a shared mailbox. | **Date filtering** supports both ISO dates (`2024-06-15`) and relative ranges (`today`, `yesterday`, `last7days`, `last30days`, `thisweek`, `lastweek`, `thismonth`, `lastmonth`). @@ -226,9 +226,9 @@ The server exposes **21 tools** across five categories. | Tool | Key Parameters | Description | |---|---|---| -| `list-folders` | `includeItemCounts`, `includeChildren` | Lists mail folders (flat list or hierarchical tree) | -| `create-folder` | `name`, `parentFolder` | Creates a new mail folder (optionally nested under a parent) | -| `move-emails` | `emailIds`, `targetFolder`, `sourceFolder` | Moves emails to a target folder by name | +| `list-folders` | `includeItemCounts`, `includeChildren`, `mailbox` | Lists mail folders (flat list or hierarchical tree). Pass `mailbox` for a shared mailbox's folders. | +| `create-folder` | `name`, `parentFolder`, `mailbox` | Creates a new mail folder (optionally nested under a parent). There is no delete-folder tool — avoid test folders on shared mailboxes. | +| `move-emails` | `emailIds`, `targetFolder`, `sourceFolder`, `mailbox` | Moves emails to a target folder by name within the same mailbox | ### Inbox Rules (3 tools) @@ -238,6 +238,12 @@ The server exposes **21 tools** across five categories. | `create-rule` | `name`, `fromAddresses`, `containsSubject`, `hasAttachments`, `moveToFolder`, `markAsRead`, `isEnabled`, `sequence` | Creates a new inbox rule | | `edit-rule-sequence` | `ruleName`, `sequence` | Changes the execution order of an existing rule | +### Mailbox (1 tool, hidden when `OUTLOOK_ENABLE_SHARED_MAILBOXES=false`) + +| Tool | Key Parameters | Description | +|---|---|---| +| `list-mailboxes` | `candidates` | Probes primary mailbox + `OUTLOOK_SHARED_MAILBOXES` seeds + local cache + optional `candidates[]` for read/folder access. Reports `sendAs` as `unverified` until a successful send. Graph cannot enumerate all mailboxes the user has rights to. | + ## Architecture ``` @@ -274,6 +280,10 @@ folder/ create.js # create-folder handler move.js # move-emails handler +mailbox/ + index.js # Tool definition for list-mailboxes + list.js # list-mailboxes handler — probes primary, seeds, cache, candidates + rules/ index.js # Tool definitions for rules tools + edit-rule-sequence handler list.js # list-rules handler + getInboxRules() utility @@ -283,9 +293,12 @@ tools/ get-email-thread.js # get-email-thread tool — conversationId-based thread fetcher utils/ - graph-api.js # callGraphAPI() — HTTPS client for Microsoft Graph + graph-api.js # callGraphAPI() — HTTPS client for Microsoft Graph (429/503 retry/backoff) + mailbox.js # normalizeMailbox(), buildPath(), withMailboxHeaders() — shared mailbox routing bodyParser.js # HTML → text conversion, boilerplate/banner/legal block stripping, signature handling threadBuilder.js # Quote-boundary detection, unique-content extraction, chronological thread formatting + time-formatter.js # Timezone-aware timestamp formatting for email/calendar display + timezone-mapper.js # Maps Windows timezone names to IANA for Intl-based date operations odata-helpers.js # OData filter building, date parsing, relative date ranges mock-data.js # Test mode mock responses ``` @@ -324,8 +337,8 @@ Launches the [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspecto - **Token cache**: The `.outlook-mcp-tokens.json` file contains access and refresh tokens. It's in `.gitignore` by default. Protect it like a password. - **No client secret in code**: For public client apps, no secret is needed. If you use a confidential client app, set `MS_CLIENT_SECRET` in the environment (not in the code). -- **Scopes are hardcoded**: The OAuth scopes are defined in `config.js` and include read/write for mail and calendar. Adjust if you need fewer permissions. -- **`.gitignore` covers**: `node_modules/`, `.env*`, `*.token.json`, `*.pem`, `*.key`, `.outlook-mcp-tokens.json` +- **Scopes are conditional**: The OAuth scopes are defined in `config.js`. When `OUTLOOK_ENABLE_SHARED_MAILBOXES` is not `false`, the scope set includes `Mail.Read.Shared`, `Mail.ReadWrite.Shared`, and `Mail.Send.Shared`. Disable shared mailboxes to request a narrower scope set. +- **`.gitignore` covers**: `node_modules/`, `.env` / `.env.*`, `*.pem`, `*.key`, `*.cert`, `*.token.json`, `.outlook-mcp-tokens.json` ## Known Issues