Spring til hovedindhold
All Outlook tools are read-only and are called via tools/call over POST /outlook/mcp. The connector reads the connected user’s own Exchange Online mailbox and calendars through Microsoft Graph, and is connected through OAuth with a Microsoft work or school account (see Connect Outlook). Your organization needs access to Outlook (a subscription, or a plan that covers it, see What decides access), and your user must hold a seat or plan licence (assigned under Team in the portal, see Team).
Endpoint: https://mcp.consile.ai/outlook/mcp. Outlook is its own named connector with only its own tools. Tool names are namespaced outlook__<tool> (e.g. outlook__search_messages); the bare names are used below for readability. A bare name in a request returns Unknown tool.The connector is multi-instance: one instance is one connected mailbox. An administrator adds further connections (agreements, aftaler, in the portal), each served at its own endpoint, e.g. https://mcp.consile.ai/outlook-2/mcp, with tools named outlook-2__<tool>. A user with access to Outlook can call every instance of the organization, so every member with Outlook access can read every connected mailbox.
For an account with access to Outlook, tools/list returns the ten outlook__* tools plus the unprefixed system tool connect_account. Without access only connect_account is listed, and the initialize result includes instructions explaining how to get access. A user without a seat still sees the tools, but every call is refused. Every tool has a title and the annotations readOnlyHint: true, destructiveHint: false and openWorldHint: false. A successful result contains the payload twice: as JSON text in content and as the same object in structuredContent. The examples below show that payload.

Authorization and read-only enforcement

The account is connected through Microsoft’s OAuth sign-in. Only work or school accounts can connect; Microsoft refuses a personal Microsoft account. The requested delegated Microsoft Graph permissions are:
  • Mail.Read (the signed-in user’s own mail)
  • Calendars.Read (the signed-in user’s own calendars)
  • User.Read (the signed-in user’s profile, used to name the connection)
  • offline_access (keeps the connection alive)
All three Graph permissions are read-only, so a token issued on this consent cannot send, move or delete mail or change a calendar. On top of that, the connector has no write tools and Consile sends only read requests to Microsoft Graph. The connect is rejected if Microsoft’s grant does not include the three Graph permissions. Many organizations require an administrator’s consent for Mail.Read and Calendars.Read; see Connect Outlook. Access is renewed automatically. Consile never hands the token to the MCP client, and the MCP client’s own token is never forwarded to Microsoft.

Data handling

Every tool is a live pass-through: the answer is read from Microsoft Graph while the call runs and returned to the MCP client. Consile stores no copy of a message, an attachment or an event, and keeps no index or cache of mailbox content. Arguments and results are not logged; only technical metadata about the call is (tool, time, duration, outcome). See Security & data.

Shared conventions

Ids

Graph addresses a mailbox with opaque ids: a mail folder id, a message id, an attachment id inside a message, a conversation id, a calendar id and an event id. Take them from a previous result and pass them back unchanged. They cannot be derived from names. Instead of a folder id, the well-known names inbox, sentitems, drafts, deleteditems, archive and junkemail are accepted.

Paging

integer
standard:"50"
Rows per page, 1 to 500. On the listing tools that page.
string
Opaque continuation token from a previous result’s nextCursor. Omit it for the first page and never construct or edit one. Pass it back to the same tool. When cursor is set, every other argument except pageSize is ignored, including filter, folderId and timeZone, and the result has only count, items and nextCursor.
string | null
Token for the next page, or null when the collection is exhausted. There is no total count.
A cursor that is not a continuation token from a previous call is refused with Invalid cursor for Outlook: pass the nextCursor from a previous page of the same tool.

Message shape

list_messages, search_messages and get_conversation return messages with these fields. get_message returns the same fields plus more.
string
Message id.
string | null
object | null
{ "name", "address" }.
array
Recipients, each { "name", "address" }.
array
Cc recipients, same shape.
string | null
ISO 8601, UTC.
string | null
ISO 8601, UTC.
boolean | null
boolean | null
string | null
low, normal or high.
string | null
A short text preview as Outlook stores it.
string | null
The thread id get_conversation takes.
Link that opens the message in Outlook on the web.
string | null
The message’s Message-ID header.

Bodies

Message and event bodies are requested from Microsoft as plain text, not HTML, and capped before they are returned: 20,000 characters on get_message and get_event, 5,000 characters per message on get_conversation. bodyTruncated is true when the text was cut. Reading a message does not mark it as read.

Time zones

string
standard:"Europe/Copenhagen"
On the calendar tools that return events. The time zone event start and end are rendered in, e.g. Europe/Copenhagen or UTC. 1 to 100 characters: letters, digits, /, _, +, -, . and spaces.
Message timestamps (receivedDateTime, sentDateTime) are always UTC.

list_mail_folders

Lists the top-level folders of the mailbox (Inbox, Sent Items, Archive, the user’s own folders) with the folder id list_messages and search_messages take. Subfolders are not listed; childFolderCount shows that a folder has some.
integer
standard:"50"
string
array
Each item has id, displayName, parentFolderId, childFolderCount, unreadItemCount and totalItemCount.

list_messages

Lists the messages of one folder, newest first (by receivedDateTime), in the message shape. For free-text search use search_messages; for the full body use get_message.
string
standard:"inbox"
Folder id from list_mail_folders, or a well-known name (inbox, sentitems, drafts, deleteditems, archive, junkemail).
string
OData $filter over the message properties, e.g. isRead eq false, receivedDateTime ge 2026-10-01T00:00:00Z or from/emailAddress/address eq 'name@example.com'. String literals are single-quoted. Microsoft can refuse a filter it finds too complex; the 400 text is returned (see Errors).
boolean
Only unread messages. Adds isRead eq false to any filter.
integer
standard:"50"
string
The result echoes folderId on the first page.

search_messages

Full-text search across the whole mailbox, including subfolders, or within one folder. Returns the message shape in relevance order. The results cannot be sorted or filtered further; use list_messages with a filter for that.
string
påkrævet
Search text. Plain words match subject and body. KQL-style properties narrow the search, e.g. from:name, subject:invoice, hasAttachments:true, received:2026-10-01. Double quotes are removed from the text. A query that is empty after that is refused.
string
Folder id or well-known name to search within. Omit for the whole mailbox.
integer
standard:"50"
string
The result echoes query (and folderId, when given) on the first page.

get_message

Reads one message in full: the message shape plus the body, the reply-to and bcc recipients and the list of attachments.
string
påkrævet
Message id from list_messages, search_messages or get_conversation.
array
Each { "name", "address" }.
array
Each { "name", "address" }. Usually only set on messages the user sent.
string | null
The body as plain text, at most 20,000 characters.
boolean
true when the body was cut.
array
Each item has id (the attachmentId for download_attachment), name, contentType, size (bytes) and isInline.

get_conversation

Reads a whole thread in one call: every message in the mailbox with the given conversationId, oldest first, each in the message shape with body (at most 5,000 characters) and bodyTruncated. Use get_message on one of them for a longer body or its attachments.
string
påkrævet
conversationId of any message in the thread.
integer
standard:"50"
string
The result echoes conversationId on the first page.

download_attachment

Reads one attachment of a message.
string
påkrævet
string
påkrævet
Attachment id from get_message.
string
fileAttachment, itemAttachment (an attached Outlook item, e.g. a forwarded message or an invitation), referenceAttachment (a link to a file in OneDrive or SharePoint) or unknown.
string | null
utf8 for text-like files, base64 for everything else, null when there is no content.
string | null
The file content. Text-like files (MIME type text/*, JSON, XML, YAML, CSV, RTF, or a text extension such as .txt, .csv, .md, .html, .ics) come back as UTF-8 text; PDF, Office files, images and other binaries come back base64-encoded. null for an item or reference attachment, together with a note explaining why.
The result also has messageId, id, name, contentType, size and isInline. Attachments larger than 5 MB (5,242,880 bytes) are refused with The attachment is <size> bytes, above the 5242880-byte limit of download_attachment.

list_calendars

Lists the user’s calendars with the calendar id list_events takes. The default calendar has isDefaultCalendar: true; the event tools use it when no calendarId is given. Calendars that others have shared with the user can appear in the list, but the connector only holds Calendars.Read, which covers the user’s own calendars, so their events cannot be expected to be readable. The result is a single page without a cursor. Arguments: none.
array
Each item has id, name, color, isDefaultCalendar, canEdit and owner ({ "name", "address" }).

list_events

Lists the events in a calendar between two date-times, ordered by start. It is a calendar view: a recurring meeting appears as its individual occurrences in the window.
string
påkrævet
Window start, ISO 8601 date-time, e.g. 2026-11-01T00:00:00Z or 2026-11-01T00:00:00+01:00.
string
påkrævet
Window end, ISO 8601 date-time, after start and at most 92 days later.
string
Calendar id from list_calendars. Omit for the default calendar.
string
standard:"Europe/Copenhagen"
integer
standard:"50"
string
array
Each event has id, subject, start and end (each { "dateTime", "timeZone" }), isAllDay, isCancelled, location (display name), organizer ({ "name", "address" }), attendees (each name, address, type and response), showAs (free/busy state), importance, onlineMeetingUrl, webLink, bodyPreview, seriesMasterId (set on an occurrence of a recurring meeting) and recurrence (the pattern on a series, or null).
The first page echoes calendarId (default when omitted), start, end and timeZone.

get_event

Reads one event in full: the list_events fields plus body (the invitation text as plain text, at most 20,000 characters) and bodyTruncated. An occurrence of a recurring meeting has its own id; seriesMasterId points at the series.
string
påkrævet
Event id from list_events or list_upcoming_events.
string
standard:"Europe/Copenhagen"

list_upcoming_events

The user’s events in the default calendar from now and a number of days ahead, ordered by start, in the same shape as list_events. For another calendar or an explicit window, use list_events.
integer
standard:"7"
Days ahead from now, 1 to 31.
string
standard:"Europe/Copenhagen"
integer
standard:"50"
string
The first page echoes start and end (UTC, computed from the time of the call), days and timeZone.

connect_account

connect_account is a system tool that the Outlook endpoint lists next to the ten tools. It takes no arguments and its name has no outlook__ prefix. It returns { "connect_url": "…", "instructions": "…" }. The user opens connect_url in a browser and is sent to Microsoft to sign in and approve access. The link expires after 10 minutes. It only works for accounts that subscribe to Outlook and for users who have accepted Consile’s terms in the portal. Use it to reconnect after the access expired or was removed: completing the link connects the account again with the new Microsoft sign-in, and the mailbox of the account that signs in is the one the connection reads afterwards.
Request
Replacing an existing connection requires a Consile administrator; for other users the link is refused.

Errors

Tool failures come back as a normal tools/call result with isError: true and one text block, not as a JSON-RPC error. The connector returns explanatory messages for the common failures:

Limits

  • Page size: default 50, maximum 500 rows.
  • Body text: 20,000 characters on get_message and get_event, 5,000 per message on get_conversation.
  • Attachments: 5 MB.
  • Calendar windows: 92 days on list_events, 31 days on list_upcoming_events.
  • Microsoft Graph throttles requests per user and per organization. Narrow a search or a filter instead of paging through a whole mailbox.
Requests to the endpoint are also rate-limited per account and connector. When the limit is exceeded you get HTTP 429 (JSON-RPC error -32029, Retry-After: 1) instead of a tool result. See Errors & limits for the current limits and the protocol-level errors shared by all connectors.