Install
openclaw skills install one-driveOneDrive API integration with managed OAuth via Microsoft Graph. Manage files, folders, and sharing. Use this skill when users want to upload, download, organize, or share files in OneDrive. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
openclaw skills install one-driveAccess the OneDrive API with managed OAuth authentication via Microsoft Graph. Manage files, folders, drives, and sharing with full CRUD operations.
CLI:
maton one-drive item list
maton api '/one-drive/v1.0/me/drive/root/children'
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/one-drive/v1.0/me/drive/root/children')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/one-drive/v1.0/{resource}
Maton proxies requests to graph.microsoft.com and automatically injects your OAuth token.
NPM:
npm install -g @maton-ai/cli
Homebrew:
brew install maton-ai/cli/maton
CLI:
maton login # Opens browser for API key
maton login --interactive # Skip browser, paste API key directly
maton whoami # Show current auth state
Manual:
MATON_API_KEY:export MATON_API_KEY="YOUR_API_KEY"
Manage your OneDrive OAuth connections at https://api.maton.ai.
CLI:
maton connection list one-drive --status ACTIVE
maton api -X GET /connections -f app=one-drive -f status=ACTIVE
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=one-drive&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection create one-drive
maton api /connections -f app=one-drive
Python:
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'one-drive'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
CLI:
maton connection view {connection_id}
maton api /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-07T08:23:30.317909Z",
"last_updated_time": "2026-02-07T08:24:04.925298Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "one-drive",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
CLI:
maton connection delete {connection_id}
maton api -X DELETE /connections/{connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple OneDrive connections, specify which one to use:
CLI:
maton one-drive item list --connection {connection_id}
maton api /one-drive/v1.0/me/drive/root/children --connection {connection_id}
Python:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/one-drive/v1.0/me/drive')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always specify the connection to ensure requests go to the intended account.
GET /one-drive/v1.0/me/drive
Example:
maton one-drive whoami
GET /one-drive/v1.0/me/drives
Example:
maton one-drive drive list
GET /one-drive/v1.0/drives/{drive-id}
Example:
maton one-drive drive view {drive-id}
GET /one-drive/v1.0/me/drive/root
Example:
maton one-drive item view root
GET /one-drive/v1.0/me/drive/root/children
Example:
maton one-drive item list
GET /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item view {item-id}
Use colon (:) syntax to access items by path:
GET /one-drive/v1.0/me/drive/root:/Documents/report.pdf
Example:
maton one-drive item view-by-path Documents/report.pdf
GET /one-drive/v1.0/me/drive/root:/Documents:/children
Example:
maton one-drive item list Documents
GET /one-drive/v1.0/me/drive/items/{item-id}/children
Example:
maton one-drive item view {item-id} --expand children
Access known folders by name:
GET /one-drive/v1.0/me/drive/special/documents
GET /one-drive/v1.0/me/drive/special/photos
GET /one-drive/v1.0/me/drive/special/music
GET /one-drive/v1.0/me/drive/special/approot
Example:
maton one-drive item view --special documents
GET /one-drive/v1.0/me/drive/recent
Example:
maton one-drive drive recent
GET /one-drive/v1.0/me/drive/sharedWithMe
Example:
maton one-drive drive shared
GET /one-drive/v1.0/me/drive/root/search(q='budget')
Example:
maton one-drive drive search 'budget'
POST /one-drive/v1.0/me/drive/root:/Documents:/children
Content-Type: application/json
{
"name": "Reports",
"folder": {},
"@microsoft.graph.conflictBehavior": "rename"
}
Example:
maton one-drive item create-folder Reports --path Documents
Create folder inside another folder by parent ID:
POST /one-drive/v1.0/me/drive/items/{parent-id}/children
Content-Type: application/json
{
"name": "Reports",
"folder": {}
}
Example:
maton one-drive item create-folder Reports --parent-id {parent-id}
PUT /one-drive/v1.0/me/drive/root:/Documents/report.pdf:/content
Content-Type: application/pdf
{report.pdf binary content}
Example:
maton one-drive item upload ./report.pdf --path Documents/report.pdf
For files over 4MB, use resumable upload:
Step 1: Create upload session
POST /one-drive/v1.0/me/drive/root:/large-report.pdf:/createUploadSession
Content-Type: application/json
{
"item": {
"@microsoft.graph.conflictBehavior": "rename"
}
}
Example:
maton one-drive item upload ./large-report.pdf --path large-report.pdf --conflict rename
Files larger than 4 MiB automatically use a resumable upload session.
Response:
{
"uploadUrl": "https://sn3302.up.1drv.com/up/...",
"expirationDateTime": "2024-02-08T10:00:00Z"
}
Step 2: Upload bytes to the uploadUrl
Get the file metadata to retrieve the download URL:
GET /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item view {item-id}
The response includes @microsoft.graph.downloadUrl - a pre-authenticated URL valid for a short time:
{
"id": "...",
"name": "document.pdf",
"@microsoft.graph.downloadUrl": "https://public-sn3302.files.1drv.com/..."
}
Use this URL directly to download the file content (no auth header needed).
PATCH /one-drive/v1.0/me/drive/items/{item-id}
Content-Type: application/json
{
"name": "new-name.txt"
}
Example:
maton one-drive item update {item-id} --name new-name.txt
Move to different folder:
PATCH /one-drive/v1.0/me/drive/items/{item-id}
Content-Type: application/json
{
"parentReference": {
"id": "{new-parent-id}"
}
}
Example:
maton one-drive item move {item-id} --dest-id {new-parent-id}
POST /one-drive/v1.0/me/drive/items/{item-id}/copy
Content-Type: application/json
{
"parentReference": {
"id": "{destination-folder-id}"
},
"name": "copied-file.txt"
}
Example:
maton one-drive item copy {item-id} --dest-id {destination-folder-id} --name copied-file.txt
Returns 202 Accepted with a Location header to monitor the copy operation.
DELETE /one-drive/v1.0/me/drive/items/{item-id}
Example:
maton one-drive item delete {item-id}
Returns 204 No Content on success.
POST /one-drive/v1.0/me/drive/items/01ABCDEF/createLink
Content-Type: application/json
{
"type": "view",
"scope": "anonymous"
}
Link types:
view - Read-only accessedit - Read-write accessembed - Embeddable linkScopes:
anonymous - Anyone with the linkorganization - Anyone in your organizationExample:
maton one-drive item share 01ABCDEF --type view --scope anonymous
POST /one-drive/v1.0/me/drive/items/{item-id}/invite
Content-Type: application/json
{
"recipients": [
{"email": "user@example.com"}
],
"roles": ["read"],
"sendInvitation": true,
"message": "Check out this file!"
}
Example:
maton one-drive item invite {item-id} --emails user@example.com --roles read --message 'Check out this file!'
Customize responses with OData query parameters:
$select - Choose specific properties: ?$select=id,name,size$expand - Include related resources: ?$expand=children$filter - Filter results: ?$filter=file ne null (files only)$orderby - Sort results: ?$orderby=name asc$top - Limit results: ?$top=10Example:
GET /one-drive/v1.0/me/drive/root/children?$select=id,name,size&$top=20&$orderby=name%20asc
maton one-drive item list --select id,name,size --top 20 --orderby 'name asc'
OneDrive uses cursor-based pagination. The CLI automatically paginates with '--paginate'.
Example:
maton one-drive item list --paginate
# Search for files
maton one-drive drive search 'budget'
# Share a file
maton one-drive item share 01ABCDEF --type view --scope anonymous
# Extract specific fields with --jq (requires --json)
maton one-drive item view root --json --jq '.name'
// List files in root
const response = await fetch(
'https://api.maton.ai/one-drive/v1.0/me/drive/root/children',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
// Upload a file
const uploadResponse = await fetch(
'https://api.maton.ai/one-drive/v1.0/me/drive/root:/myfile.txt:/content',
{
method: 'PUT',
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
'Content-Type': 'text/plain'
},
body: 'Hello, OneDrive!'
}
);
import os
import requests
# List files in root
response = requests.get(
'https://api.maton.ai/one-drive/v1.0/me/drive/root/children',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
files = response.json()
# Upload a file
upload_response = requests.put(
'https://api.maton.ai/one-drive/v1.0/me/drive/root:/myfile.txt:/content',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'text/plain'
},
data='Hello, OneDrive!'
)
graph.microsoft.com):) syntax for path-based addressing: /root:/path/to/file@microsoft.graph.downloadUrl are pre-authenticated and temporaryfail, replace, renamewhoami) is directly addressable. The additional b!...-prefixed IDs that appear in drive list return HTTP 400 from Microsoft Graph when fetched this way. Use me/drive instead.curl -g when URLs contain brackets to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments| Status | Meaning |
|---|---|
| 400 | Missing OneDrive connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Insufficient permissions |
| 404 | Item not found |
| 409 | Conflict (e.g., item already exists) |
| 429 | Rate limited (check Retry-After header) |
| 4xx/5xx | Passthrough error from Microsoft Graph API |
{
"error": {
"code": "itemNotFound",
"message": "The resource could not be found."
}
}
CLI:
maton whoami
maton connection list
Manual:
MATON_API_KEY environment variable is set:echo $MATON_API_KEY
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
one-drive. For example:https://api.maton.ai/one-drive/v1.0/me/drive/root/childrenhttps://api.maton.ai/v1.0/me/drive/root/children