Requirements
- Target platform
- OpenClaw
- Install method
- Manual import
- Extraction
- Extract archive
- Prerequisites
- OpenClaw
- Primary doc
- SKILL.md
Microsoft Excel API integration with managed OAuth. Read and write Excel workbooks, worksheets, ranges, tables, and charts stored in OneDrive. Use this skill when users want to read or modify Excel spreadsheets, manage worksheet data, work with tables, or access cell values. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Microsoft Excel API integration with managed OAuth. Read and write Excel workbooks, worksheets, ranges, tables, and charts stored in OneDrive. Use this skill when users want to read or modify Excel spreadsheets, manage worksheet data, work with tables, or access cell values. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway).
Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.
I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete.
I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run.
Access the Microsoft Excel API (via Microsoft Graph) with managed OAuth authentication. Read and write workbooks, worksheets, ranges, tables, and charts stored in OneDrive or SharePoint.
# List worksheets in a workbook python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/microsoft-excel/{native-api-path} Replace {native-api-path} with the actual Microsoft Graph API endpoint path. The gateway proxies requests to graph.microsoft.com and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header: Authorization: Bearer $MATON_API_KEY Environment Variable: Set your API key as MATON_API_KEY: export MATON_API_KEY="YOUR_API_KEY"
Sign in or create an account at maton.ai Go to maton.ai/settings Copy your API key
Manage your Microsoft Excel OAuth connections at https://ctrl.maton.ai.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=microsoft-excel&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
python <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'microsoft-excel'}).encode() req = urllib.request.Request('https://ctrl.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
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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": "4751ac89-3970-47e1-872c-eacdf4291732", "status": "ACTIVE", "creation_time": "2026-02-07T00:43:18.565932Z", "last_updated_time": "2026-02-07T00:43:29.729782Z", "url": "https://connect.maton.ai/?session_token=...", "app": "microsoft-excel", "metadata": {} } } Open the returned url in a browser to complete OAuth authorization.
python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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 Microsoft Excel connections, specify which one to use with the Maton-Connection header: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/microsoft-excel/v1.0/me/drive') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '4751ac89-3970-47e1-872c-eacdf4291732') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF If omitted, the gateway uses the default (oldest) active connection.
You can access workbooks using either ID-based or path-based patterns: By File ID: /microsoft-excel/v1.0/me/drive/items/{file-id}/workbook/... By File Path: /microsoft-excel/v1.0/me/drive/root:/{path-to-file}:/workbook/...
Get Drive Info GET /microsoft-excel/v1.0/me/drive List Root Files GET /microsoft-excel/v1.0/me/drive/root/children Search for Excel Files GET /microsoft-excel/v1.0/me/drive/root/search(q='.xlsx') Upload Excel File PUT /microsoft-excel/v1.0/me/drive/root:/{filename}.xlsx:/content Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet {binary xlsx content}
Sessions improve performance for multiple operations. Recommended for batch operations. Create Session POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/createSession Content-Type: application/json { "persistChanges": true } Response: { "persistChanges": true, "id": "cluster=PUS7&session=..." } Use the session ID in subsequent requests: workbook-session-id: {session-id} Close Session POST /microsoft-excel/v1.0/me/drive/root:/{path}:/workbook/closeSession workbook-session-id: {session-id}
List Worksheets GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets Response: { "value": [ { "id": "{00000000-0001-0000-0000-000000000000}", "name": "Sheet1", "position": 0, "visibility": "Visible" } ] } Get Worksheet GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1') Create Worksheet POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets Content-Type: application/json { "name": "NewSheet" } Update Worksheet PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1') Content-Type: application/json { "name": "RenamedSheet", "position": 2 } Delete Worksheet DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('{worksheet-id}') Returns 204 No Content on success.
Get Range GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2') Response: { "address": "Sheet1!A1:B2", "values": [ ["Hello", "World"], [1, 2] ], "formulas": [ ["Hello", "World"], [1, 2] ], "text": [ ["Hello", "World"], ["1", "2"] ], "numberFormat": [ ["General", "General"], ["General", "General"] ], "rowCount": 2, "columnCount": 2 } Get Used Range GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/usedRange Update Range PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2') Content-Type: application/json { "values": [ ["Updated", "Values"], [100, 200] ] } Clear Range POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')/clear Content-Type: application/json { "applyTo": "All" } Options: All, Formats, Contents
List Tables GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables Create Table from Range POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/tables/add Content-Type: application/json { "address": "A1:C4", "hasHeaders": true } Response: { "id": "{6D182180-5F5F-448B-9E9C-377A5251CFC5}", "name": "Table1", "showHeaders": true, "showTotals": false, "style": "TableStyleMedium2" } Get Table GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1') Update Table PATCH /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1') Content-Type: application/json { "name": "PeopleTable", "showTotals": true } Get Table Rows GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows Response: { "value": [ { "index": 0, "values": [["Alice", 30, "NYC"]] }, { "index": 1, "values": [["Bob", 25, "LA"]] } ] } Add Table Row POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows Content-Type: application/json { "values": [["Carol", 35, "Chicago"]] } Delete Table Row DELETE /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/rows/itemAt(index=0) Returns 204 No Content on success. Get Table Columns GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns Add Table Column POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/tables('Table1')/columns Content-Type: application/json { "values": [["Email"], ["alice@example.com"], ["bob@example.com"]] }
List Named Items GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/names
List Charts GET /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts Add Chart POST /microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets('Sheet1')/charts/add Content-Type: application/json { "type": "ColumnClustered", "sourceData": "A1:C4", "seriesBy": "Auto" }
// Get range values const response = await fetch( "https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B10')", { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json(); console.log(data.values);
import os import requests # Update range values response = requests.patch( "https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/data.xlsx:/workbook/worksheets('Sheet1')/range(address='A1:B2')", headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, json={'values': [['Name', 'Age'], ['Alice', 30]]} ) print(response.json())
Only .xlsx files are supported (not legacy .xls) Worksheet names with special characters need URL encoding Table and worksheet IDs containing { and } must be URL-encoded (%7B and %7D) Sessions expire after ~5 minutes of inactivity (persistent) or ~7 minutes (non-persistent) Use null in value arrays to skip updating specific cells Blank cells should use "" (empty string) Range addresses use A1 notation (e.g., A1:C10, Sheet1!A1:B5) IMPORTANT: When using curl commands, use curl -g when URLs contain parentheses to disable glob parsing IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments
StatusMeaning400Missing Microsoft Excel connection or invalid request401Invalid or missing Maton API key404Item not found or session expired429Rate limited4xx/5xxPassthrough error from Microsoft Graph API
CodeDescriptionItemNotFoundFile or resource doesn't existItemAlreadyExistsWorksheet or table with that name already existsInvalidArgumentInvalid parameter or missing required fieldSessionNotFoundSession expired or doesn't exist
Check that the MATON_API_KEY environment variable is set: echo $MATON_API_KEY Verify the API key is valid by listing connections: python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.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
Ensure your URL path starts with microsoft-excel. For example: Correct: https://gateway.maton.ai/microsoft-excel/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets Incorrect: https://gateway.maton.ai/v1.0/me/drive/root:/workbook.xlsx:/workbook/worksheets
Microsoft Graph Excel API Overview Working with Excel in Microsoft Graph Excel Workbook Resource Excel Worksheet Resource Excel Range Resource Excel Table Resource Maton Community Maton Support
Workflow acceleration for inboxes, docs, calendars, planning, and execution loops.
Largest current source with strong distribution and engagement signals.