office-365-mcp
14 min read
office-365-mcp
Documentation Disclaimer
This feature is EXPERIMENTAL and under active development. It may change significantly, be discontinued, or have breaking changes without notice.
Overview
office-365-mcp is a Python MCP server, built on FastMCP, that connects Microsoft 365 to MCP clients through the Microsoft Graph API. It reaches Outlook mail and calendar, Microsoft Teams, SharePoint and OneDrive, OneNote, and user identity. The server has 60 tools in total. A deployment turns on a fixed subset of these 60 tools (never all of them, unless a preset or a list names every one). This document explains what each tool does, how a deployment picks its tools, and how sign-in and consent work.
Tools
office-365-mcp has 60 tools, across six areas: identity, Microsoft Teams, Outlook mail, Outlook calendar, SharePoint and OneDrive, and OneNote. One tool, get_me, is always on, in every configuration. The Kind column is a hint to the calling client about the kind of change a tool makes. It does not control access to the tool.
Identity
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| No | The answer is the signed-in user's own Microsoft 365 profile: id, display name, email address, sign-in name, and job title. |
Microsoft Teams
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| No | The signed-in user's Teams chats (1:1, group, meeting), newest last message first. |
| Read |
| No | The teams that the signed-in user is a member of. |
| Read |
| No | The channels of one team that the signed-in user can access. |
| Read |
| Yes | One Teams channel's posts, with their newest replies. |
| Read |
| Yes | A full-text search across every Teams message, in chats and channels, that the signed-in user can see. |
| Read |
| Yes | One Microsoft Teams message in full, from a handle that another tool minted. |
| Read |
| Yes | Whether a Teams meeting has a transcript, and a handle for each one. |
| Read |
| Yes | One page of a Teams meeting transcript, as timestamped turns with the speaker named, not the whole file at once. |
| Read |
| Yes | Whether a meeting recording exists, how long it runs, and who can download it. The answer is metadata only, never the video itself. |
| Write, adds |
| No | Posts one plain-text message to an existing Teams chat, after the user approves it. |
| Write, adds |
| No | Posts one plain-text message to an existing Teams channel, after the user approves it. |
Outlook mail
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| No | Finds a message anywhere in the signed-in user's own mailbox, or, with |
| Read |
| No | One message's full text, from a handle that another tool minted, in the signed-in user's own mailbox or, with |
| Read |
| No | One level of the mail folder tree, and a handle for each folder, in the signed-in user's own mailbox or, with |
| Read |
| No | The email address behind a display name. A draft therefore goes to the real address, not a guess. |
| Read |
| No | Every message of one conversation, in the signed-in user's own mailbox or, with |
| Read |
| No | The newest messages of one folder, in receipt order, in the signed-in user's own mailbox or, with |
| Read |
| No | What acts quietly on this mailbox — the rules, the automatic reply, and the categories — and what this tool cannot show. |
| Read |
| No | Every category that this mailbox can use to tag mail, events, and contacts, with each category's name and color. |
| Write, changes or removes |
| No | The read status, the follow-up flag, and the importance, on up to twenty messages, in the signed-in user's own mailbox or, with |
| Write, changes or removes |
| No | Moves messages into another folder, in the signed-in user's own mailbox or, with |
| Write, adds |
| No | A new message, composed into Drafts, in the signed-in user's own mailbox or, with |
| Write, adds |
| No | A reply or a forward, composed into Drafts and left there, in the signed-in user's own mailbox or, with |
| Write, changes or removes |
| No | The only tool in this connector that puts mail on the wire. It sends a draft that this connector composed, in the signed-in user's own mailbox or, with |
| Write, safe to repeat |
| No | Turns the out-of-office reply on for a fixed period, or off. The reply never runs with no end date. |
| Write, safe to repeat |
| No | Turns one existing inbox rule off, and nothing else. |
Outlook calendar
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| No | Every calendar that this mailbox reaches — the user's own and each one delegated — and a handle for each one. |
| Read |
| No | One calendar's occurrences over a window, never a recurrence rule. |
| Read |
| No | One event in full, from a handle that another tool minted, with every attendee and each one's reply. |
| Read |
| No | Reads free/busy status for one or more mailboxes over a time window. It does not book, invite, or change anything. |
| Read |
| No | Asks Microsoft to suggest meeting times for the signed-in user and one or more attendees. It does not book, invite, or hold a time. |
| Write, adds |
| No | One new event on the user's own calendar. The tool creates it and sends invitations in one call. |
| Write, adds |
| No | Changes the subject, time, location, or attendee list of one event that the signed-in user organizes. A change that reaches an attendee mails the attendee a notice that the meeting changed. |
| Write, changes or removes |
| No | Cancels one event that the signed-in user organizes, moves the event to Deleted Items, and mails any attendees a cancellation. Refuses an event that the signed-in user did not organize. |
| Write, adds |
| No | Accepts, declines, or tentatively accepts a calendar invitation that the signed-in user received. By default, it notifies the organizer. |
| Write, adds |
| No | One event on a calendar delegated by another person, sent under that person's own name. |
SharePoint and OneDrive
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| Yes | Searches the files and folders that the signed-in user can see, across OneDrive and SharePoint. |
| Read |
| Yes | Lists every item directly inside one folder, in OneDrive or SharePoint, one level only. |
| Read |
| Yes | The answer is the content of one file, in its original format, or converted to PDF. |
OneNote
Tool | Kind | Permission | Admin consent | What it does |
|---|---|---|---|---|
| Read |
| No | Every notebook that the user owns, or that is shared with the user, with each notebook's sections. |
| Read |
| No | Finds pages by title, across notebooks or in one section. Microsoft Graph has no full-text search for OneNote. |
| Read |
| No | Reads the HTML of one page, exactly as Microsoft stores it. |
| Write, adds |
| No | Writes a new page into the signed-in user's OneNote. No attachments or images. |
| Write, adds |
| No | Adds HTML to the end of one page. It cannot insert, edit, or erase existing content. |
| Read |
| No | A short snippet, up to 300 characters, of one page, plus a preview image address. |
| Read |
| No | Fetches the bytes of one image or file that is embedded in a page, with its real media type. |
| Read |
| No | Resolves a OneNote web address into a notebook handle. |
| Read |
| No | Notebooks that the signed-in user opened recently, per Microsoft's own record. |
| Read |
| No | Sections and section groups directly under one notebook or section group, one level at a time. |
| Write, adds |
| No | Creates a new, empty notebook for the signed-in user. |
| Write, adds |
| No | Creates a new, empty section directly under a notebook or section group. |
| Write, adds |
| No | Creates a new, empty section group directly under a notebook or another section group. |
| Write, changes or removes |
| No | Adds content next to an element on one page, or replaces one, through 1 to 20 batched commands. |
| Write, changes or removes, safe to repeat |
| No | Changes the title of one page, and nothing else. |
| Write, adds |
| No | Starts a copy of one page into another section, on Microsoft's own systems. The answer is a handle for the operation. |
| Write, adds |
| No | Starts a copy of one section into another notebook or section group. The answer is a handle for the operation. |
| Write, adds |
| No | Starts a copy of a whole notebook into the user's own OneDrive, on Microsoft's own systems. The answer is a handle for the operation. |
| Read |
| No | Polls a copy operation, started by |
| Write, changes or removes, safe to repeat |
| No | Erases one page outright. The tool always asks the user to approve this first, because Microsoft Graph keeps no recycle bin for OneNote. |
Presets
A deployment turns tools on in one of two ways:
A preset. One of the 21 named bundles in the table below.
An exact list. The
TOOLS_ENABLEDconfiguration, which names every wanted tool.
A deployment must pick exactly one way:
It must not set both, and it must not leave both unset.
Three places enforce this rule: the Helm chart schema, the Terraform module, and the server's own startup check.
This is not a preset plus an add-on. It is two ways to name one choice.
The tool
get_meis always on, in every configuration, so no preset or list needs to name it.A deployment cannot start from a preset and then add or remove one tool. For a mix of tools that no preset covers, name every wanted tool in the exact list instead.
There are 21 presets. This table names each preset's tools, besides get_me, and gives a short description.
Preset | Tools | Description |
|---|---|---|
|
| Every Teams tool this server has. |
|
| The list of the signed-in user's Teams chats. It cannot read a chat message. |
|
| Finds a message anywhere, and reads it in full. |
|
| Walks a team's channels, and reads the posts in one channel. |
|
| Finds a meeting, and reads the transcript of it. |
|
| Says whether a meeting was recorded, and who can get the recording. |
|
| Both transcripts and recordings, for one meeting. |
|
| Finds a chat or a channel, and posts a new message to either. |
|
| Finds a message, reads it in full, walks the folder tree, reads a thread, lists a folder, and resolves a name to an address. |
|
| Everything in |
|
| Everything in |
|
| Shows what quietly acts on the mailbox — the rules and the automatic reply — and lists every category with its name and color. |
|
| Everything in |
|
| Names every calendar that the mailbox reaches, reads what sits on one, and checks or suggests free time. |
|
| Everything in |
|
| Everything in |
|
| Finds a file in OneDrive or on a SharePoint site, and lists one level of a folder. |
|
| Everything in |
|
| Lists notebooks, sections, and pages, and reads or previews a page. |
|
| Everything in |
|
| Everything in |
Note: Terraform (in another repository) writes the Entra application registration, and Argo (in another repository) writes the pod's active tool selection. Nothing compares the two on its own.
Permissions
Each tool needs one or more Microsoft Graph permissions, and the Tools section names each one. Microsoft's own reference lists what each permission grants. A deployment asks for the union of every active tool's permissions, one time, at sign-in. It never asks again per call, and it never asks later for a permission that no tool requested at sign-in. After sign-in, each call draws the one permission it needs from this already-granted set, for the signed-in user. It does not ask again.
Admin consent
Some permissions need a tenant administrator to grant them, before any user in that tenant can sign in. The Tools section marks these. Microsoft's own overview explains this step in more detail.
Three tenants matter here:
Tenant D, or Tenant U. The tenant that owns the Entra App registration. Unique supports both: a customer's own dedicated tenant (Tenant D), or Unique's own shared tenant (Tenant U).
Tenant C. The customer's own tenant. It is always external to Tenant D or Tenant U, and it is where the customer's real users sign in.
This deployment always sets sign_in_audience to AzureADMultipleOrgs. A user from any tenant can then sign in, not only the tenant that owns the App registration.
A customer's own administrator, in Tenant C, must always grant admin consent:
Terraform's own grant, through the
service_principal_configurationinput, only ever covers the tenant that owns the App registration. It cannot reach Tenant C.To grant it, Tenant C's own administrator uses the Entra portal, or the module's own
admin_consent_urloutput, which works for any tenant.The administrator sees the result as a new Enterprise Application in Tenant C. This is separate from the App registration, which stays in Tenant D or Tenant U.
Deployment
A deployment sets its tool surface under mcpConfig.tools, in the Helm chart's values file. It sets exactly one of two keys, preset or enabled. It never sets both, and it never leaves both unset.
mcpConfig:
tools:
preset: teams # or: enabled: get_me,teams_list_chatsThe preset key names one of the 21 presets in the Presets table. The enabled key names an exact, comma-separated list of tool names instead. A deployment that needs a mix that no preset covers uses enabled, and names every wanted tool. Granting admin consent is a separate step, covered in Admin consent.
Terraform writes the Entra application registration. Argo writes the deployed pod's tool selection, through the chart values in this section. No automatic step compares these two. A mismatch is possible, and it produces no warning. A registration narrower than the pod fails every sign-in at the authorize step, with nothing in the pod's own logs to explain why.
The check is manual, and it is repeatable:
Run
curl $PUBLIC_BASE_URL/manifestagainst the deployed pod. It answers with the resolved tool selection and the exact permission list, in the tool registry's order.Run
terraform output tool_surfacein the Terraform module. It answers with the same shape: the preset, the tools, the permissions, and which permissions need admin consent, in the same order.Compare the two permission lists, line for line.
Two things can go wrong:
If the pod's list names a permission that the Terraform output does not, every sign-in fails at the authorize step.
If the Terraform output names more permissions than the pod uses, the tenant carries standing access that no tool spends.
Limitations
office-365-mcp is meant to replace two other services: teams-mcp and outlook-semantic-mcp. It works differently: every tool call reaches Microsoft Graph directly, and it stores nothing beyond an OAuth token. The tables below name what a reader gains and loses against each service. Neither service has a formal deprecation date yet, and both remain in active development. This section is a comparison of the current state, not a finished handover. A comment in teams-mcp's message data states that its fields were "shaped to match the fields" office-365-mcp uses for the same resource.
Compared to teams-mcp
Capability | office-365-mcp | teams-mcp |
|---|---|---|
Capture a transcript into Unique's knowledge base | No | Yes, opt-in, needs a database |
Read the replies inside a channel thread | Yes | No, root posts only |
Read a transcript, or a recording's metadata, live, with no configuration | Yes | No, ingest only |
Plain, normalized text, not raw HTML | Yes | No |
Compared to outlook-semantic-mcp
Capability | office-365-mcp | outlook-semantic-mcp |
|---|---|---|
Read a shared or delegated mailbox | Yes, one mailbox per call | Yes, own and delegated in one search |
Search the words inside an attachment | No, file name only | Yes |
Change an event's agenda or add a Teams meeting | No | Yes |
Add an attachment from Unique's knowledge base to a draft | No | Yes |
Send a message outright | Yes | No, draft only |
Mark a message read or unread, set its flag or importance, or move it | Yes | No |
Read a whole conversation across folders, in one call | Yes | No, one message at a time |
Read and change the automatic reply, or turn off a rule | Yes | No |