SharePoint Sites.Selected — Permission pro Site granten
Die mcp-m365-App-Registration nutzt Sites.Selected als App-Permission auf Microsoft Graph — das ist least-privilege, die App sieht nur Sites die explizit granted wurden. Pro Kunde + pro Ziel-Site muss der Grant einmalig vom Tenant-Admin/Site-Owner ausgefuehrt werden. Die App kann das nicht selbst — das ist Sites.Selected by design.
Wer kann den Grant ausfuehren
Erfuellt mindestens eine Bedingung:
- Tenant-Global-Admin im Ziel-Tenant
- SharePoint-Admin im Ziel-Tenant
- Site-Owner der konkreten Site (bei Sites.Selected oft ausreichend)
Marvin’s Tenant-Admin-Rolle reicht uebrigens NICHT automatisch fuer SharePoint-Site-Content-Zugriff — siehe Abschnitt „Klassischer Stolperstein” unten.
Vorbereitung — was du brauchst
-
Client-ID der mcp-m365-App im Kunden-Tenant. Liegt in
~/source/mcps/mcp-m365/.env.localalsM365_CLIENT_ID. Beim Kunden ist das die App-Registration die im Setup der mcp-m365 angelegt wurde. Bei VF: beginnt mitfd71afb5-. -
Site-URL der Ziel-Site. Format:
https://<tenant>.sharepoint.com/sites/<sitename>.
Schritt 1 — Graph Explorer oeffnen + einloggen
URL: https://developer.microsoft.com/en-us/graph/graph-explorer
Oben rechts „Sign in” — mit einem Account der Tenant-Admin oder Site-Owner im Ziel-Tenant ist. Beim ersten Schreib-Call fragt Graph Explorer nach Permissions-Consent — zustimmen.
Schritt 2 — Site-ID rausholen
In Graph Explorer:
- Method GET
- URL:
https://graph.microsoft.com/v1.0/sites/<tenant>.sharepoint.com:/sites/<sitename> - „Run query”
Aus der JSON-Antwort id kopieren. Format: <hostname>,<site-guid>,<web-guid> (zwei Kommas).
Schritt 3 — Write-Permission granten
In Graph Explorer:
- Method POST
- URL:
https://graph.microsoft.com/v1.0/sites/<SITE-ID-AUS-2>/permissions - Request Body:
{ "roles": ["write"], "grantedToIdentities": [ { "application": { "id": "<CLIENT-ID>", "displayName": "mcp-m365" } } ] } - „Run query”
Erwartung: HTTP 201, Body mit dem neuen Permission-Objekt.
Roles-Wahl:
read— App darf nur lesenwrite— App darf lesen + schreiben + Ordner anlegen + Files hochladen (Standard fuer KI-Operating-System-Sites)manage— plus Listen/Berechtigungen verwalten (selten noetig)owner— Vollzugriff (nicht empfohlen fuer App-Permissions)
Schritt 4 — Validieren
Von einem System mit dem mcp-m365 verbunden:
# Site-Metadata lesen
m365_get_site site_id="<tenant>.sharepoint.com:/sites/<sitename>"
# Drive-Items im Root listen (sollte funktionieren)
m365_list_drive_items site_id="<SITE-ID>" path=""
# Test-Ordner anlegen (sollte HTTP 201 zurueck geben)
POST /sites/<SITE-ID>/drive/root/children
Body: {"name": "_test-grant", "folder": {}, "@microsoft.graph.conflictBehavior": "rename"}Wenn der Test-Ordner angelegt wird: Grant funktioniert. Test-Ordner danach wieder loeschen.
Klassischer Stolperstein — Tenant-Admin ≠ Site-Content-Zugriff
Auch wenn du Tenant-Admin im Kunden-Tenant bist, kommst du als User moeglicherweise NICHT auf den Site-Content (Access Denied bei /sites/<name>/... im Browser). Grund: SharePoint hat eine zweite Permission-Schicht (Site-Collection-Admin) die separat gepflegt wird. Fix:
- SharePoint Admin Center oeffnen:
https://<tenant>-admin.sharepoint.com/ - Active Sites → Suche nach der Site → Klick
- Permissions Tab → „Manage admins”
- Den User-Account als Site-Admin hinzufuegen
Geht in 2 Klicks. Wichtig: die App-Permission (Sites.Selected) und die User-Permission (Site-Collection-Admin) sind vollstaendig getrennt. App-Grant aus Schritt 3 betrifft nur die App, nicht den User.
Wenn der MCP local laeuft vs. hosted
Lokal (~/source/mcps/mcp-m365/ mit .env.local): Grant betrifft die App-Registration mit deren Client-ID. Source-Edits an server.py brauchen nur uvx-Reload, kein Deploy.
Hosted (mcp-vf-hosted auf Fargate): Selbe App-Registration, aber Source-Edits brauchen Fargate-Rebuild + Deploy bevor sie in der Live-Tool-Liste auftauchen. Bei einer Aenderung an der Tool-Liste (z.B. create_folder adden): erst auf Fargate ausrollen, dann ist der neue Tool in Claude Code/Open-WebUI verfuegbar.
Permission widerrufen
Wenn ein Kunde-Setup beendet wird oder die App rotiert:
DELETE https://graph.microsoft.com/v1.0/sites/<SITE-ID>/permissions/<permission-id>
Permission-ID kommt aus dem POST-Response in Schritt 3 oder via GET /sites/<site-id>/permissions.
Workaround wenn der Grant temporaer nicht moeglich
Wenn der Kunde den Grant nicht selber machen kann/will und du keine Tenant-Admin-Permission im Kunden-Tenant hast: direkt mit App-Token + Python gegen Graph API. Snippet siehe ~/source/agentic-ventures/intern/runs/2026-05.md (Eintrag „SharePoint /sites/intern Ordner anlegen via direkt-Graph-API”). Aber: das ist Workaround, das eigentliche Setup ist der Grant.
Related
- m365 — MCP-Setup-Doku mit Entra-App-Registration
- system-prompt-deploys-guardrails — Lessons aus dem v2.7-Vorfall
- kunde-openwebui-onboarding — Master-Pattern, wo dieser Schritt eingebaut ist
- Microsoft Docs — Sites.Selected Permission-Modell
- Microsoft Docs —
POST /sites/{site-id}/permissions