Microsoft 365 MCP
Eigener MCP-Server unter mcp-m365 (~/source/mcps/mcp-m365). Zugriff auf SharePoint-Sites, Drive-Files, Excel-Workbooks (lesen/schreiben), Lists und Outlook-Mail via Microsoft Graph API.
Kernentscheidung: Service-Principal (App-Only) statt Delegated Auth — der Agent laeuft headless beim Kunden, kein User-Login noetig. Trade-off: Tenant-Admin muss einmalig App-Registration, Permissions und (je nach Modul) Sites.Selected-Grants bzw. ApplicationAccessPolicy anlegen.
Vergleich mit existierenden MCPs (Softeria ms-365-mcp-server, Microsoft Work IQ, Arcade) ergab: alle nur Delegated → Eigenbau noetig.
Tools (24)
Sites & Files
list_sites, get_site, list_drive_items, search_files, get_drive_item, download_file
Excel Workbook
read_excel_workbook_metadata, read_excel_range, read_excel_used_range, read_excel_table, write_excel_range, add_excel_worksheet
Lists
list_lists, query_list_items
Mail (Outlook, neu in v0.2.0)
list_mail_folders, list_messages, get_message, search_messages, send_mail, reply_message, create_draft, send_draft, list_attachments, download_attachment
user_id ist immer der UPN (christoph@vibe-factory.de) oder Object-ID der Mailbox — Application-Auth kennt kein „me”.
Setup beim Kunden — Entra App Registration
-
Entra Admin Center → App registrations → New registration
-
Certificates & secrets → New client secret → Value direkt kopieren (nur einmal angezeigt)
-
API permissions → Microsoft Graph → Application permissions:
Modul Minimal-Permission Hinweis SharePoint / Files / Excel / Lists Sites.Selectedleast privilege, pro Site explizit whitelisten Files site-uebergreifend Files.ReadWrite.Alltenant-weit Mail lesen / Drafts / Attachments Mail.ReadWritetenant-weit — Einschraenkung via ApplicationAccessPolicy Mail senden Mail.Sendtenant-weit — gleiches Muster -
Grant admin consent klicken — braucht Tenant-Admin
Sites.Selected pro Ziel-Site freischalten
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
"https://graph.microsoft.com/v1.0/sites/<site-id>/permissions" \
-d '{
"roles": ["write"],
"grantedToIdentities": [{"application": {"id": "<client-id>", "displayName": "mcp-m365"}}]
}'ApplicationAccessPolicy fuer Mail (empfohlen)
Mail.* ist per Default tenant-weit. Einschraenkung ueber Exchange Online PowerShell:
Connect-ExchangeOnline
New-DistributionGroup -Name "mcp-m365-allowed" -Type Security -Members @(
"christoph@vibe-factory.de", "agent@vibe-factory.de"
)
New-ApplicationAccessPolicy `
-AppId "<client-id>" `
-PolicyScopeGroupId "mcp-m365-allowed@vibe-factory.de" `
-AccessRight RestrictAccess `
-Description "mcp-m365 darf nur diese Mailboxes lesen/senden"
Test-ApplicationAccessPolicy -Identity "ceo@vibe-factory.de" -AppId "<client-id>"
# erwartet: DeniedPolicy greift innerhalb ~1h. Beim Kunden IMMER setzen bevor Mail.* live geht.
Install + Start
uv tool install --force --editable ~/source/mcps/mcp-m365
cp ~/source/mcps/mcp-m365/.env.local.example ~/source/mcps/mcp-m365/.env.local
# .env.local befuellen: TENANT_ID, CLIENT_ID, CLIENT_SECRET
~/source/mcps/mcp-m365/start.sh
# HTTP-Server auf http://127.0.0.1:8765/mcpIn ~/.claude.json registrieren:
"m365": { "type": "http", "url": "http://127.0.0.1:8765/mcp" }Gotchas
user_idist Pflicht bei allen Mail-Tools — Application-Auth kennt keinme.$search+$filternicht mischbar. Modul bevorzugtsearchwenn gesetzt.Mail.Sendist tenant-weit ohne ApplicationAccessPolicy — DSGVO-Risiko fuer Kunden.- 403-Meldungen werden umgeschrieben mit Hinweis welche Permission vermutlich fehlt — macht Kunden-Debugging leichter.
- Attachments > 3 MB brauchen Upload-Session (Graph-Limit).
download_attachmentnutztcontentBytesdirekt — nur fuer kleine Anhaenge. - Pagination via
@odata.nextLink— alsnext_linkan Folge-Call uebergeben.
Related
- mcp-m365 — Source
- papierkram, ticketpay — Parallel-MCPs fuer den Vibe-Factory-Stack
- mcp-vf-hosted — wenn M365 im Mono-MCP-Wrapper fuer Kunden laeuft
- Microsoft Graph — Mail API
- Sites.Selected Permission-Modell
- ApplicationAccessPolicy