Microsoft 365 MCP Server
An MCP server that exposes Microsoft 365 operations as tools, backed by Microsoft Graph — SharePoint, OneDrive, Mail, Calendar, Users & Directory, and Groups — plus text extraction from Office/PDF documents and mail attachments.
It is stateless and does not do any OAuth: your application already holds a valid Microsoft Graph access token, and it supplies that token with each request. No re-authentication, no token exchange, no gateway.
Why this exists
If you already obtained a Microsoft Graph delegated access token
(aud = https://graph.microsoft.com) via a 3LO flow in your app, you cannot feed
that token into an On-Behalf-Of (OBO) exchange — Entra requires the OBO assertion
to target a middle-tier app, not Graph itself. This server avoids the problem
entirely by calling Graph directly with the token you already have.
Install & run with uvx
The server ships as a uvx-runnable package. uv
builds and runs it in an isolated environment on demand — no manual pip install.
Once published to an index you can run it by name:
uvx keos-microsoft365-mcp
Providing the access token
The token is resolved per request in this order:
- Explicit argument — pass
access_tokenin the tool call arguments. - Bearer header — when running over HTTP, send
Authorization: Bearer <token>. - Environment —
GRAPH_ACCESS_TOKEN(or the legacySHAREPOINT_ACCESS_TOKEN).
The token must be a Microsoft Graph delegated access token
(aud = https://graph.microsoft.com). Grant the scopes for the tools you use:
| Area | Delegated scopes |
|---|---|
| SharePoint / OneDrive / Groups files | Sites.Read.All / Sites.ReadWrite.All, Files.Read.All / Files.ReadWrite.All, Group.Read.All |
Mail.Read, Mail.ReadWrite, Mail.Send |
|
| Calendar | Calendars.ReadWrite |
| Users & Directory | User.Read.All, Directory.Read.All |
Tokens are short-lived (~1 hour). This server never refreshes them — supplying a fresh token is the caller's responsibility.
Tools
Identity
| Tool | Description |
|---|---|
test_token |
Verify the token by fetching the signed-in user's profile |
get_me |
Get the signed-in user's full profile |
SharePoint
| Tool | Description |
|---|---|
list_sites |
List or search SharePoint sites |
get_site |
Get a site by Graph site ID |
get_site_by_path |
Resolve a site by hostname + server-relative path |
list_drives |
List document libraries (drives) in a site |
list_items |
List folders/files in a drive or folder |
get_item |
Get file/folder metadata by path or item ID |
read_file |
Download a file's content (text when decodable) |
extract_file |
Download and extract text from docx/xlsx/pptx/pdf/text |
list_sharepoint_lists |
Get SharePoint lists in a site |
get_list_items |
Get items (with fields) from a list |
search_files |
Search files within a drive |
search_query |
Cross-service keyword/KQL search (Microsoft Search API) |
OneDrive
| Tool | Description |
|---|---|
get_my_drive |
Get the signed-in user's OneDrive metadata |
get_user_drive |
Get another user's OneDrive by id/UPN |
list_my_drive_items |
List files/folders in the user's OneDrive |
The drive tools (
read_file,extract_file,get_item,list_items) work against OneDrive and Group/Teams drives too — pass the relevantdrive_id.
| Tool | Description |
|---|---|
list_messages |
List or search messages (by folder or across mailbox) |
get_message |
Get a single message with body |
list_attachments |
List a message's attachments (metadata) |
extract_mail_attachment |
Download an attachment and extract its text |
send_mail |
Send an email |
reply_to_message |
Reply / reply-all to a message |
create_draft |
Create a draft message |
move_message |
Move a message to another folder |
list_mail_folders |
List mail folders |
Calendar
| Tool | Description |
|---|---|
list_events |
List events (or a calendarView window) |
create_event |
Create an event |
update_event |
Patch an event |
delete_event |
Delete an event |
get_schedule |
Free/busy availability for one or more mailboxes |
Users & Directory
| Tool | Description |
|---|---|
get_user |
Get a user by id/UPN |
list_users |
List or search directory users |
get_manager |
Get a user's manager |
get_direct_reports |
Get a user's direct reports |
Groups
| Tool | Description |
|---|---|
list_groups |
List or search Microsoft 365 groups |
list_group_members |
List a group's members |
get_group_drive |
Get a group's document library (the Teams "Files" store) |
Document extraction
extract_file and extract_mail_attachment return readable text from binary
formats that read_file cannot decode:
- Word
.docx, Excel.xlsx, PowerPoint.pptx— parsed with the Python standard library (no third-party dependency). - PDF
.pdf— viapypdf(a declared dependency, installed automatically). - Text family
.txt .csv .tsv .json .md .xml .html .yaml, etc.
Legacy binary formats (.doc, .xls, .ppt) are not supported — convert to the
OpenXML equivalent or PDF first.
Response shape
Every tool returns a normalized object:
// success
{ "ok": true, "data": { /* Graph response, or extracted text */ } }
// failure
{ "ok": false, "error": "graph_error", "status_code": 403, "message": "...", "body": { } }
Extraction failures use "error": "extraction_error"; a missing token uses
"error": "missing_token".
Notes
- The server never stores or logs tokens.
- Token expiry/refresh is the caller's responsibility — this server only forwards what it is given.
- Write and send operations (
send_mail,create_event,move_message, ...) act as the signed-in user. Guard them withautoApprovecare in your client.
Metadata
Release files for keos-microsoft365-mcp 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| keos_microsoft365_mcp-0.1.1.tar.gz | 17.2 kB | Without provenance | Details for keos_microsoft365_mcp-0.1.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| keos_microsoft365_mcp-0.1.1-py3-none-any.whl | Python 3 | none | any | Details for keos_microsoft365_mcp-0.1.1-py3-none-any.whl |
Total release size: 37.9 kB
Release files / keos_microsoft365_mcp-0.1.1.tar.gz
| Download URL | keos_microsoft365_mcp-0.1.1.tar.gz |
|---|---|
| Size | 17.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8032ef7ec04a1d66228ced7947a89e1506d921e161e99eaec58511d7e5226ff4
|
|
BLAKE2b-256 checksum How to use checksums |
69b79040d295f55bb7695a2005059f0096568ebdcae9bbd4b70a98197092e991
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / keos_microsoft365_mcp-0.1.1-py3-none-any.whl
| Download URL | keos_microsoft365_mcp-0.1.1-py3-none-any.whl |
|---|---|
| Size | 20.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e1ec3265e9b7abc002a862e90e395c8e03d53179eb77728285b4b46c480770ca
|
|
BLAKE2b-256 checksum How to use checksums |
5103181158ef0f0c7e629943d832362e102286e4592f89d0b6079e5ada7c2786
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for keos-microsoft365-mcp 0.1.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.