--- name: exchange-mcp description: >- Use this skill when the user talks about email, calendar, contacts, Exchange, EWS, corporate mail, or scheduling meetings. --- # exchange-mcp — MCP server for Microsoft Exchange This MCP server provides access to **Microsoft Exchange Server** via **Exchange Web Services (EWS)** with NTLM authentication. Supports email, calendar, contacts, and free/busy scheduling. **Use this server when the user talks about:** - Email, inbox, sent items, drafts - Calendar, events, meetings, availability - Contacts, people, colleagues, employees - Attachments, files in emails - Exchange, EWS, corporate mail **Does not support:** Microsoft 365 / Exchange Online (OAuth), IMAP/POP3/SMTP, Gmail, Outlook.com. --- ## Tools ### Auth #### `login` Authenticate to Exchange EWS via NTLM. On first use, all fields except `domain` are required. On subsequent logins, only `password` is needed — previously saved `serverUrl`, `email`, `username`, and `domain` are reused automatically. | Parameter | Type | Required | Description | | ----------- | ------ | -------- | ------------------------------------------------ | | `serverUrl` | string | no* | EWS server URL (e.g. `https://mail.example.com`) | | `email` | string | no* | Email address | | `username` | string | no* | NTLM username | | `password` | string | yes | NTLM password | | `domain` | string | no | NTLM domain (default: `corp`) | \* Required only on first login; skipped on subsequent logins (loaded from saved config). **Usage guidance:** If the user asks to log in and only provides a password (without `serverUrl`, `email`, or `username`), this is likely a *repeated* login — the previously saved config will be reused automatically. Just call the `login` tool with the password alone. #### `check_session` Check if the current session is authenticated. No parameters. Returns `{authenticated, email, serverUrl}`. #### `logout` Clear stored credentials. No parameters. --- ### Email #### `get_emails` Get emails from a folder. Supports optional text search via `query`/`queryScope`. | Parameter | Type | Default | Description | | ------------- | ------- | --------- | ----------------------------------------------------------------------------------- | | `folder` | string | `"Inbox"` | Folder name (Inbox, Sent, Drafts, Deleted, Junk, or custom; supports Russian names) | | `limit` | number | `10` | Max emails (max 50; max 500 if `idsOnly=true`) | | `offset` | number | `0` | Pagination offset | | `includeBody` | boolean | `false` | If `true`, fetches full email body | | `unreadOnly` | boolean | `false` | Only unread emails | | `idsOnly` | boolean | `false` | Return only IDs + dates + subjects (faster, higher limit) | | `query` | string | — | Text to search for within the folder | | `queryScope` | enum | `"all"` | Scope: `all`, `subject`, `body`, `from` (only when `query` is set) | #### `get_email` Get a single email with full body and details. | Parameter | Type | Required | Description | | --------- | ------ | -------- | ---------------------------- | | `itemId` | string | yes | Exchange ItemId of the email | #### `mark_email_read` Mark emails as read or unread. | Parameter | Type | Default | Description | | --------- | -------- | ------- | ------------------------------- | | `itemIds` | string[] | — | List of Exchange ItemIds | | `isRead` | boolean | `true` | `true` = read, `false` = unread | #### `download_attachments` Download all file attachments from an email to disk. | Parameter | Type | Default | Description | | -------------- | ------ | -------------------- | --------------- | | `itemId` | string | — | Exchange ItemId | | `targetFolder` | string | `"/tmp/attachments"` | Local folder | --- ### Folders #### `get_folders` List mailbox folders. | Parameter | Type | Default | Description | | ---------------- | ------- | ----------------- | ----------------------------------------------------------------- | | `parentFolderId` | string | `"msgfolderroot"` | Parent folder (supports distinguished names: `inbox`, `calendar`) | | `recursive` | boolean | `false` | Recursively traverse subfolders | --- ### Calendar #### `get_calendar_events` Get calendar events within a date range. | Parameter | Type | Required | Description | | ------------- | ------- | -------- | ----------------------------------------- | | `startDate` | string | yes | Start (`YYYY-MM-DD`) | | `endDate` | string | yes | End (`YYYY-MM-DD`) | | `includeBody` | boolean | `false` | Full details (organizer, attendees, body) | #### `download_event_attachments` Download attachments from a calendar event. Same parameters as `download_attachments`. --- ### Availability #### `find_free_time` Find free time slots in your calendar. | Parameter | Type | Default | Description | | ----------------- | ------ | ----------- | -------------------------- | | `startDate` | string | — | Start (`YYYY-MM-DD`) | | `endDate` | string | = startDate | End | | `durationMinutes` | number | `30` | Minimum slot duration | | `startHour` | number | `9` | Work day start hour (0-23) | | `endHour` | number | `18` | Work day end hour (0-23) | #### `find_meeting_time` Find common free time for multiple people. | Parameter | Type | Default | Description | | ----------------- | ------ | ----------- | --------------------------------- | | `emails` | string | — | Attendee emails (comma-separated) | | `startDate` | string | — | Start | | `endDate` | string | = startDate | End | | `durationMinutes` | number | `30` | Minimum slot duration | | `startHour` | number | `9` | Work day start hour | | `endHour` | number | `18` | Work day end hour | --- ### People #### `find_person` Search for people in the corporate directory (Active Directory). | Parameter | Type | Required | Description | | --------- | ------ | -------- | ----------------------- | | `query` | string | yes | Name, email, or keyword | Returns: name, email, job title, department, company, office, phone, manager, direct reports.