@chrischall/office-outlook-mcp 0.4.1 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,15 +7,15 @@
7
7
  },
8
8
  "metadata": {
9
9
  "description": "MCP server for Outlook / Microsoft 365 — mail, calendar, contacts and tasks via natural language",
10
- "version": "0.4.1"
10
+ "version": "0.5.0"
11
11
  },
12
12
  "plugins": [
13
13
  {
14
14
  "name": "office-outlook-mcp",
15
15
  "displayName": "Outlook (Microsoft 365)",
16
16
  "source": "./",
17
- "description": "MCP server for Outlook / Microsoft 365 — read mail, folders, calendar, contacts and tasks, and send mail with confirmation",
18
- "version": "0.4.1",
17
+ "description": "MCP server for Outlook / Microsoft 365 — triage unread mail, reply, answer meeting invites and schedule meetings, plus folders, calendar, contacts and tasks, with confirmation before anything is sent",
18
+ "version": "0.5.0",
19
19
  "author": {
20
20
  "name": "Chris Hall"
21
21
  },
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "office-outlook-mcp",
3
3
  "displayName": "Outlook (Microsoft 365)",
4
- "version": "0.4.1",
5
- "description": "Outlook / Microsoft 365 for Claude — read mail, folders, calendar, contacts and tasks, and send mail with confirmation, using your signed-in browser session",
4
+ "version": "0.5.0",
5
+ "description": "Outlook / Microsoft 365 for Claude — triage unread mail, reply, answer meeting invites and schedule meetings, plus folders, calendar, contacts and tasks, with confirmation before anything is sent, using your signed-in browser session",
6
6
  "author": {
7
7
  "name": "Chris Hall",
8
8
  "email": "chris.c.hall@gmail.com"
package/README.md CHANGED
@@ -107,46 +107,101 @@ Everything is optional — with nothing set, the server captures from the browse
107
107
  ## Tools
108
108
 
109
109
  **Read** — `outlook_list_folders`, `outlook_list_messages`,
110
- `outlook_get_message`, `outlook_list_attachments`, `outlook_list_events`,
111
- `outlook_get_event`, `outlook_list_calendars`, `outlook_find_meeting_times`,
110
+ `outlook_get_message`, `outlook_get_unread`, `outlook_list_attachments`,
111
+ `outlook_get_attachment`, `outlook_list_events`, `outlook_get_event`,
112
+ `outlook_list_calendars`, `outlook_find_meeting_times`,
112
113
  `outlook_get_schedule`, `outlook_get_profile`,
113
114
  `outlook_get_mailbox_settings`, `outlook_list_contacts`, `outlook_list_people`,
114
- `outlook_list_tasks`
115
-
116
- **Write** (all ask you to confirm first — see [Confirmations](#confirmations)) — `outlook_send_mail`,
117
- `outlook_create_draft`, `outlook_mark_read`, `outlook_move_message`,
118
- `outlook_create_event`, `outlook_update_event`
115
+ `outlook_list_categories`, `outlook_list_tasks`
116
+
117
+ **Write** (ask you to confirm first — see [Confirmations](#confirmations)) —
118
+ `outlook_send_mail`, `outlook_create_draft`, `outlook_mark_read`,
119
+ `outlook_update_message`, `outlook_move_message`, `outlook_create_event`,
120
+ `outlook_update_event`, `outlook_respond_to_invite`, `outlook_delete_event`,
121
+ `outlook_reply`.
122
+ Three skip the confirmation when nothing reaches anyone else:
123
+ `outlook_reply` with `draftOnly: true` (the reply stays in Drafts),
124
+ `outlook_respond_to_invite` with `sendResponse: false`, and
125
+ `outlook_delete_event` on your own appointment with no attendees or on a
126
+ meeting the organizer already cancelled (in each, only your calendar
127
+ changes).
119
128
 
120
129
  **Meetings** — `outlook_find_meeting_times` asks Outlook's Scheduling
121
130
  Assistant for slots when everyone is free, and `outlook_get_schedule` shows
122
- each person's busy blocks. `outlook_create_event` and `outlook_update_event`
123
- attach a Microsoft Teams meeting by default and return its join link; pass
124
- `teamsMeeting: false` to leave it off. Only the organizer can update a
125
- meeting.
131
+ each person's busy blocks. Each suggested slot carries `createEventArgs`,
132
+ which `outlook_create_event` accepts unchanged. `outlook_create_event` and
133
+ `outlook_update_event` attach a Microsoft Teams meeting by default and return
134
+ its join link; pass `teamsMeeting: false` to leave it off. Only the organizer
135
+ can update a meeting. `outlook_respond_to_invite` accepts, tentatively accepts
136
+ or declines an invite, by its message id or its event id.
137
+ `outlook_delete_event` deletes an event you organize — one occurrence by the
138
+ occurrence's id, or the whole series by its series master's id — and sends
139
+ any attendees a cancellation; for an invite you received it refuses and points
140
+ you at declining instead. `outlook_list_events` and `outlook_get_event` show
141
+ what that decision needs in every view: `MyResponse`, `ResponseRequested`,
142
+ `IsOrganizer`, `IsCancelled`, `Type` (SingleInstance, Occurrence, Exception or
143
+ SeriesMaster), `ShowAs` and `IsAllDay`, plus `SeriesMasterId` in the full view.
126
144
 
127
145
  **Diagnostics** — `outlook_healthcheck`
128
146
 
129
147
  Every read tool takes `view: compact | full | raw`, defaulting to **compact**.
130
- Mutating tools **write nothing** until you confirm — see
131
- [Confirmations](#confirmations). The preview shows exactly what would be sent
148
+ Mutating tools **write nothing** until you confirm (bar the cases above)
149
+ — see [Confirmations](#confirmations). The preview shows exactly what would be sent
132
150
  (action, method, path and body). (`outlook_create_event` first reads the
133
151
  mailbox time zone, so its preview can name the zone it would book in; that is
134
152
  the one read a preview makes.)
135
153
 
136
154
  Mail and event text is written by other people, so `outlook_list_messages`,
137
- `outlook_get_message`, `outlook_list_events` and `outlook_get_event` wrap every
138
- result (all views) in an untrusted-content envelope — `untrusted_content: true`
139
- plus a `note` telling the model to treat the text as data, never instructions
140
- (a `view: raw` record that carries its own `untrusted_content`/`note` key is
141
- nested under `data`, so it cannot overwrite the envelope).
155
+ `outlook_get_message`, `outlook_get_unread`, `outlook_get_attachment`,
156
+ `outlook_list_events`, `outlook_get_event`, `outlook_find_meeting_times` and
157
+ `outlook_get_schedule` wrap every result (all views) in an untrusted-content
158
+ envelope — `untrusted_content: true` plus a `note` telling the model to treat
159
+ the text as data, never instructions (a `view: raw` record that carries its
160
+ own `untrusted_content`/`note` key is nested under `data`, so it cannot
161
+ overwrite the envelope). `outlook_reply` returns a sent reply's subject — the
162
+ original sender's text — inside the same envelope.
142
163
  On a client that cannot show a confirmation prompt, the confirmToken is still
143
164
  something the model passes back itself, so keep `MCP_CONFIRM_MODE=ask-user`
144
165
  (the default) and approve each preview in chat — or use a client that asks you
145
166
  before running non-read-only tools — as the real guard on outbound sends.
146
167
 
168
+ ## Triage loop
169
+
170
+ An agent can work through new mail end to end without opening Outlook:
171
+
172
+ 1. **Read the batch** — `outlook_get_unread` returns the unread messages in a
173
+ folder (default inbox), newest first, each with its plain-text body, in one
174
+ call. It does **not** mark anything read. Each item has a `kind`: `mail`,
175
+ `meetingRequest`, `meetingCancelled` or `meetingResponse`; requests and
176
+ cancellations also carry the linked `event` (time, organizer, your current
177
+ response) — or, when the meeting is no longer on your calendar (already
178
+ declined, cancelled or deleted), a `hint` saying there is nothing to respond
179
+ to. `to` and `cc` list at most 20 addresses, with `toCount`/`ccCount` when
180
+ there are more.
181
+ 2. **Act on each item** —
182
+ - an invite: `outlook_respond_to_invite` with the message id and
183
+ `accept`, `tentative` or `decline` (and an optional comment);
184
+ - a message that needs an answer: `outlook_reply` (`reply`, `replyAll` or
185
+ `forward`), or `draftOnly: true` to leave it in Drafts for you to review;
186
+ - a request for a meeting: `outlook_find_meeting_times` for the attendees,
187
+ then pass the chosen slot's `createEventArgs` to `outlook_create_event`;
188
+ - an attachment to read: `outlook_get_attachment`.
189
+ 3. **File it** — `outlook_update_message` flags, categorises (names from
190
+ `outlook_list_categories`) and marks read up to 50 messages in one call;
191
+ `outlook_move_message` moves one to another folder.
192
+ 4. **Mark it handled** — `outlook_mark_read` (or `isRead: true` on
193
+ `outlook_update_message`), so the next `outlook_get_unread` returns only
194
+ what is still new.
195
+
196
+ Replies, forwards, invite responses and new meetings reach other people, so
197
+ each asks you to confirm first — except a reply saved with `draftOnly: true`
198
+ (it stays in Drafts until you send it) and an invite response with
199
+ `sendResponse: false` (only your calendar changes; the organizer is not told).
200
+
147
201
  ## Confirmations
148
202
 
149
- Every write asks you to confirm before anything is sent or changed. A client
203
+ Every write asks you to confirm before anything is sent or changed (except a
204
+ draft-only reply and a silent invite response — see [Tools](#tools)). A client
150
205
  that can show a confirmation prompt (Claude Code) shows one. On a client that
151
206
  cannot, the first call does nothing and returns a `confirmation-required`
152
207
  preview plus a `confirmToken`; only a repeat call with that token performs the