| name | msgraph-files |
| description | How to upload, download, and manage files in SharePoint document libraries and OneDrive via the Microsoft Graph CLI (mgc). Use this skill whenever the user wants to upload files to SharePoint, download files, list folder contents, or navigate SharePoint drive structures. |
Microsoft Graph CLI — Files & SharePoint
Binary
./mgc-cli/mgc
Required scope
SharePoint drive access requires Sites.ReadWrite.All. Without it, drive endpoints return 403 accessDenied.
./mgc-cli/mgc login --scopes Sites.ReadWrite.All --strategy InteractiveBrowser
Key concepts
- Site — a SharePoint site, e.g.
https://tenant.sharepoint.com/backoffice
- Drive — a document library within a site. Each site has a default drive (
Shared Documents).
- Drive item — a file or folder identified by a
drive-item-id
- mgc does not support path-based addressing — you must resolve IDs by navigating the tree or using the two-step upload script
Resolve IDs
Get site ID
./mgc-cli/mgc sites get --site-id "tenant.sharepoint.com:/site-relative-path"
./mgc-cli/mgc sites get --site-id "softwarearchitects1com.sharepoint.com:/backoffice"
Get default drive (Shared Documents)
./mgc-cli/mgc sites drive get --site-id "<site-id>"
List a folder's children
./mgc-cli/mgc drives items children list \
--drive-id "<drive-id>" \
--drive-item-id "<folder-item-id>" \
--select "id,name"
Use root item ID from mgc drives root get --drive-id <drive-id> as the starting point.
Upload a file (one-step script)
Use the bundled script — it handles ID resolution, file entry creation, and content upload automatically:
python3 .claude/skills/msgraph-files/scripts/upload_file.py \
--site "softwarearchitects1com.sharepoint.com:/backoffice" \
--folder "Buchhaltung/Belege-Rainer/oebb" \
/path/to/file.pdf
python3 .claude/skills/msgraph-files/scripts/upload_file.py \
--drive-id "<drive-id>" \
--folder "Buchhaltung/Belege-Rainer/oebb" \
/path/to/file.pdf
python3 .claude/skills/msgraph-files/scripts/upload_file.py \
--site "softwarearchitects1com.sharepoint.com:/backoffice" \
--folder "Buchhaltung/Belege-Rainer/oebb" \
--overwrite \
/path/to/file.pdf
What the script does internally (two-step process)
mgc does not have a single-command upload-to-path. The process is:
Step 1 — create an empty file entry in the target folder:
./mgc-cli/mgc drives items children create \
--drive-id "<drive-id>" \
--drive-item-id "<folder-item-id>" \
--body '{"name":"filename.pdf","file":{}}'
Step 2 — upload the content:
./mgc-cli/mgc drives items content put \
--drive-id "<drive-id>" \
--drive-item-id "<new-file-item-id>" \
--input-file "/path/to/file.pdf"
Download a file (script)
Use the bundled script — it resolves sharing URLs, navigates paths, and downloads in one step:
python3 .claude/skills/msgraph-files/scripts/download_file.py \
--share-url "https://tenant.sharepoint.com/:b:/g/site/ITEM?e=TOKEN"
python3 .claude/skills/msgraph-files/scripts/download_file.py \
--site "softwarearchitects1com.sharepoint.com:/backoffice" \
--path "Buchhaltung/Belege-Rainer/ticket.pdf"
python3 .claude/skills/msgraph-files/scripts/download_file.py \
--drive-id "<drive-id>" \
--path "Buchhaltung/Belege-Rainer/ticket.pdf"
python3 .claude/skills/msgraph-files/scripts/download_file.py \
--drive-id "<drive-id>" \
--item-id "<item-id>" \
--output /tmp/downloaded.pdf
Default output path is ./<filename> (current directory, original filename).
Use --output <path> to override.
How sharing URL resolution works
SharePoint sharing URLs are encoded for the Graph /shares endpoint:
import base64
share_id = "u!" + base64.urlsafe_b64encode(url.encode()).decode().rstrip("=")
Raw mgc command (when IDs are already known)
./mgc-cli/mgc drives items content get \
--drive-id "<drive-id>" \
--drive-item-id "<file-item-id>" \
--output-file /tmp/downloaded.pdf
Get a drive item by navigating the path manually
When you need the item ID of a folder deep in the tree:
./mgc-cli/mgc drives root get --drive-id "<drive-id>" --select "id,name"
./mgc-cli/mgc drives items children list \
--drive-id "<drive-id>" --drive-item-id "<root-id>" --select "id,name"
The upload script automates this navigation given a slash-delimited folder path.
Known SharePoint IDs (softwarearchitects1com)
These are stable and can be reused to skip resolution steps:
| Resource | ID |
|---|
Site (/backoffice) | softwarearchitects1com.sharepoint.com,1ad35ca4-c33c-4f39-b879-66989de76ac9,b58e40ac-8840-4c8b-805b-6e4e661e6072 |
| Drive (Shared Documents) | b!pFzTGjzDOU-4eWaYnedqyaxAjrVAiItMgFtuTmYeYHL6X5UxYPEpRK3qBk-NBEEl |
| Root item | 015KPENK56Y2GOVW7725BZO354PWSELRRZ |
Buchhaltung | 015KPENKYDQQBET2SUDVA3CQ57JPSRJ3V4 |
Buchhaltung/Belege-Rainer | 015KPENK6R2YDBPRVOL5GLUU55YKMYXKIR |
Buchhaltung/Belege-Rainer/oebb | 015KPENK36CG3JBFNGS5ELARYB2CUML5QT |
Troubleshooting
403 accessDenied on drive endpoints → re-login with Sites.ReadWrite.All
- File created with size 0 → step 1 (create) succeeded but step 2 (content put) was not run
- File already exists error → use
--overwrite flag on the upload script, or delete first with mgc drives items delete
--input-file path must be absolute or relative to cwd where mgc is invoked
shares drive-item get fails with 403 → the sharing URL may require the ?e=TOKEN query parameter; ensure the full URL including the token is passed