| name | drive |
| description | Google Drive integration via AtrisOS API. Full file management (upload, copy, share, move, delete), Google Docs (create, edit, format, templates), Google Sheets (read, write, format, charts). Use when user asks about Drive, files, docs, sheets, or spreadsheets. |
| version | 2.0.0 |
| tags | ["drive","backend","google-drive","sheets"] |
Drive Agent
Drop this in ~/.claude/skills/drive/SKILL.md and Claude Code becomes your Google Drive assistant.
Bootstrap (ALWAYS Run First)
Before any Drive operation, run this bootstrap to ensure everything is set up:
#!/bin/bash
set -e
if ! command -v atris &> /dev/null; then
echo "Installing atris CLI..."
npm install -g atris
fi
if [ ! -f ~/.atris/credentials.json ]; then
echo "Not logged in to AtrisOS."
echo ""
echo "Option 1 (interactive): Run 'atris login' and follow prompts"
echo "Option 2 (non-interactive): Get token from https://atris.ai/auth/cli"
echo " Then run: atris login --token YOUR_TOKEN"
echo ""
exit 1
fi
if command -v node &> /dev/null; then
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
elif command -v python3 &> /dev/null; then
TOKEN=$(python3 -c "import json,os; print(json.load(open(os.path.expanduser('~/.atris/credentials.json')))['token'])")
elif command -v jq &> /dev/null; then
TOKEN=$(jq -r '.token' ~/.atris/credentials.json)
else
echo "Error: Need node, python3, or jq to read credentials"
exit 1
fi
STATUS=$(curl -s "https://api.atris.ai/api/integrations/google-drive/status" \
-H "Authorization: Bearer $TOKEN")
if echo "$STATUS" | grep -q "Token expired\|Not authenticated"; then
echo "Token expired. Please re-authenticate:"
echo " Run: atris login --force"
exit 1
fi
if command -v node &> /dev/null; then
CONNECTED=$(node -e "try{console.log(JSON.parse('$STATUS').connected||false)}catch(e){console.log(false)}")
elif command -v python3 &> /dev/null; then
CONNECTED=$(echo "$STATUS" | python3 -c "import sys,json; print(json.load(sys.stdin).get('connected', False))")
else
CONNECTED=$(echo "$STATUS" | jq -r '.connected // false')
fi
if [ "$CONNECTED" != "true" ] && [ "$CONNECTED" != "True" ]; then
echo "Google Drive not connected. Getting authorization URL..."
AUTH=$(curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/start" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{}')
if command -v node &> /dev/null; then
URL=$(node -e "try{console.log(JSON.parse('$AUTH').auth_url||'')}catch(e){console.log('')}")
elif command -v python3 &> /dev/null; then
URL=$(echo "$AUTH" | python3 -c "import sys,json; print(json.load(sys.stdin).get('auth_url', ''))")
else
URL=$(echo "$AUTH" | jq -r '.auth_url // empty')
fi
echo ""
echo "Open this URL to connect your Google Drive:"
echo "$URL"
echo ""
echo "After authorizing, run your command again."
exit 0
fi
echo "Ready. Google Drive is connected."
export ATRIS_TOKEN="$TOKEN"
API Reference
Base: https://api.atris.ai/api/integrations
All requests require: -H "Authorization: Bearer $TOKEN"
Get Token (after bootstrap)
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
List Shared Drives
curl -s "https://api.atris.ai/api/integrations/google-drive/shared-drives" \
-H "Authorization: Bearer $TOKEN"
Returns all shared/team drives the user has access to with id and name.
List Files
curl -s "https://api.atris.ai/api/integrations/google-drive/files?page_size=20" \
-H "Authorization: Bearer $TOKEN"
List files in a folder:
curl -s "https://api.atris.ai/api/integrations/google-drive/files?folder_id=FOLDER_ID&page_size=20" \
-H "Authorization: Bearer $TOKEN"
List files in a shared drive:
curl -s "https://api.atris.ai/api/integrations/google-drive/files?shared_drive_id=DRIVE_ID&page_size=20" \
-H "Authorization: Bearer $TOKEN"
NOTE: All file operations (list, search, get, download, export) automatically include shared drive files. Use shared_drive_id only to scope results to a specific shared drive.
Search Files
curl -s "https://api.atris.ai/api/integrations/google-drive/search?q=quarterly+report&page_size=20" \
-H "Authorization: Bearer $TOKEN"
Simple queries search by file name. For advanced queries, use Drive query syntax:
name contains 'budget' — name search
mimeType = 'application/vnd.google-apps.spreadsheet' — only sheets
mimeType = 'application/vnd.google-apps.document' — only docs
modifiedTime > '2026-01-01' — recently modified
Get File Metadata
curl -s "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
-H "Authorization: Bearer $TOKEN"
Download File
curl -s "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/download" \
-H "Authorization: Bearer $TOKEN"
Returns base64-encoded content. For Google Docs/Sheets/Slides, use export instead.
Export Google Docs/Sheets/Slides
curl -s "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/export?mime_type=text/plain" \
-H "Authorization: Bearer $TOKEN"
Export formats:
text/plain — plain text (default, good for Docs)
text/html — HTML
application/pdf — PDF
text/csv — CSV (for Sheets)
Upload File
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "notes.txt",
"content": "File content here",
"mime_type": "text/plain"
}'
Upload to a specific folder:
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "report.txt",
"content": "File content here",
"mime_type": "text/plain",
"folder_id": "FOLDER_ID"
}'
Update Existing File
curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "Updated file content here",
"mime_type": "text/plain"
}'
Update content and rename:
curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "New content",
"mime_type": "text/plain",
"name": "renamed-file.txt"
}'
Delete / Trash File
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}?trash=true" \
-H "Authorization: Bearer $TOKEN"
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
-H "Authorization: Bearer $TOKEN"
Copy File
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/copy" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Copy of Document", "folder_id": "OPTIONAL_FOLDER_ID"}'
Works with Docs, Sheets, Slides — creates a full copy.
Share File
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"email": "user@example.com", "role": "writer", "notify": true}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"anyone": true, "role": "reader"}'
Roles: reader, writer, commenter
Create Folder
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/folders" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "Project Files", "parent_id": "OPTIONAL_PARENT_FOLDER_ID"}'
Move File
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/move" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"new_parent_id": "TARGET_FOLDER_ID"}'
Pagination
List and search endpoints return next_page_token when there are more results. Pass it to get the next page:
curl -s "https://api.atris.ai/api/integrations/google-drive/files?page_size=20&page_token=NEXT_PAGE_TOKEN" \
-H "Authorization: Bearer $TOKEN"
Works on: /files, /search, /shared-drives
Google Docs
Native Google Docs creation and editing. Uses the same Drive OAuth connection.
List Google Docs
curl -s "https://api.atris.ai/api/integrations/google-docs/documents?page_size=20" \
-H "Authorization: Bearer $TOKEN"
Create a New Google Doc
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Q1 2026 Report"}'
Returns documentId and url (direct link to edit in browser).
Read a Google Doc
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}" \
-H "Authorization: Bearer $TOKEN"
Returns full document structure (body, paragraphs, text runs, styles).
Insert Text into a Doc
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"insertText": {
"location": {"index": 1},
"text": "Hello, this is the first paragraph.\n\nSecond paragraph here.\n"
}
}
]
}'
Text is inserted at a character index. Index 1 = start of document body. Newlines create paragraphs.
Replace Placeholders in a Doc Template
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"replaceAllText": {
"containsText": {"text": "{{client_name}}", "matchCase": true},
"replaceText": "Acme Corp"
}
},
{
"replaceAllText": {
"containsText": {"text": "{{date}}", "matchCase": true},
"replaceText": "March 5, 2026"
}
}
]
}'
Format Text (Bold, Italic, Font Size, Color)
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"updateTextStyle": {
"range": {"startIndex": 1, "endIndex": 20},
"textStyle": {"bold": true, "fontSize": {"magnitude": 18, "unit": "PT"}},
"fields": "bold,fontSize"
}
}
]
}'
Insert a Table
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/batch-update" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"insertTable": {
"rows": 3,
"columns": 2,
"location": {"index": 1}
}
}
]
}'
Export Doc as PDF
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/export" \
-H "Authorization: Bearer $TOKEN"
Returns base64-encoded PDF.
Export Doc as Plain Text
curl -s "https://api.atris.ai/api/integrations/google-docs/documents/{document_id}/text" \
-H "Authorization: Bearer $TOKEN"
Google Sheets
Full read/write access to Google Sheets.
Create a Spreadsheet
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"title": "Q1 Revenue Tracker"}'
Returns spreadsheetId and url (direct link to edit in browser).
Get Spreadsheet Info
curl -s "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}" \
-H "Authorization: Bearer $TOKEN"
Returns sheet names, title, and metadata.
Read Cells
curl -s "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}/values?range=Sheet1" \
-H "Authorization: Bearer $TOKEN"
Range uses A1 notation:
Sheet1 — entire sheet
Sheet1!A1:D10 — specific range
Sheet1!A:A — entire column A
Sheet1!1:1 — entire row 1
Update Cells
curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}/values" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"range": "Sheet1!A1:B2",
"values": [
["Name", "Score"],
["Alice", 95]
]
}'
Append Rows
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}/append" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"range": "Sheet1",
"values": [
["Bob", 88],
["Carol", 92]
]
}'
Format Cells (batchUpdate)
Apply formatting, merges, conditional formatting, charts, and other structural changes.
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{spreadsheet_id}/batchUpdate" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"requests": [
{
"repeatCell": {
"range": {"sheetId": 0, "startRowIndex": 0, "endRowIndex": 1},
"cell": {
"userEnteredFormat": {
"textFormat": {"bold": true},
"backgroundColor": {"red": 0.9, "green": 0.9, "blue": 0.9}
}
},
"fields": "userEnteredFormat(textFormat,backgroundColor)"
}
}
]
}'
Common request types:
repeatCell — format a range (bold, colors, font size, alignment)
mergeCells — merge a range into one cell
updateBorders — add borders to cells
autoResizeDimensions — auto-fit column widths
addConditionalFormatRule — highlight cells based on rules
addChart — embed a chart
addSheet / deleteSheet — manage sheets/tabs
sortRange — sort rows by a column
Range format: {"sheetId": 0, "startRowIndex": 0, "endRowIndex": 1, "startColumnIndex": 0, "endColumnIndex": 3} — sheetId 0 = first tab, indices are 0-based.
Color format: RGB floats 0-1, e.g. {"red": 0.2, "green": 0.6, "blue": 1.0}
You can send multiple requests in one call — they execute in order.
Workflows
"Create a Google Doc with content"
- Run bootstrap
- Create doc:
POST /google-docs/documents with {"title": "..."}
- Insert text:
POST /google-docs/documents/{id}/batch-update with insertText requests
- Return the edit URL to user
"Fill a doc template"
- Run bootstrap
- Copy template:
POST /files/{template_id}/copy with {"name": "Client Proposal"}
- Replace placeholders:
POST /google-docs/documents/{new_id}/batch-update with replaceAllText requests
- Share if needed:
POST /files/{id}/share
- Return URL
"Find a file in my Drive"
- Run bootstrap
- Search:
GET /google-drive/search?q=QUERY
- Display: name, type, modified date for each result
"Read a Google Doc"
- Run bootstrap
- Search for the doc:
GET /google-drive/search?q=DOC_NAME
- Export as text:
GET /google-drive/files/{id}/export?mime_type=text/plain
- Display content
"Read a spreadsheet"
- Run bootstrap
- Search for the sheet:
GET /google-drive/search?q=SHEET_NAME
- Get sheet info:
GET /google-drive/sheets/{id} (to see sheet names)
- Read values:
GET /google-drive/sheets/{id}/values?range=Sheet1
- Display as a table
"Add rows to a spreadsheet"
- Run bootstrap
- Find the sheet
- Read current data to understand the columns:
GET /google-drive/sheets/{id}/values?range=Sheet1!1:1
- Show user what will be appended, get approval
- Append:
POST /google-drive/sheets/{id}/append
"Browse a shared drive"
- Run bootstrap
- List shared drives:
GET /google-drive/shared-drives
- Display drive names and IDs
- List files in chosen drive:
GET /google-drive/files?shared_drive_id=DRIVE_ID
"Find a file across all drives"
- Run bootstrap
- Search:
GET /google-drive/search?q=QUERY (automatically searches My Drive + all shared drives)
- Display results
"Format a spreadsheet"
- Run bootstrap
- Find the sheet, get its
spreadsheetId
- Build requests array — bold headers, colors, borders, auto-resize, etc.
- Show user what formatting will be applied, get approval
- Apply:
POST /google-drive/sheets/{id}/batchUpdate with {"requests": [...]}
"Create a spreadsheet with data"
- Run bootstrap
- Create:
POST /google-drive/sheets with {"title": "..."}
- Write headers + data:
PUT /google-drive/sheets/{id}/values with range + values
- Format headers:
POST /google-drive/sheets/{id}/batchUpdate (bold, background color)
- Return the URL
"Share a file"
- Run bootstrap
- Find the file
- Ask user: share with specific email or anyone with link?
- Share:
POST /google-drive/files/{id}/share
"Organize files into folders"
- Run bootstrap
- Create folder:
POST /google-drive/folders with {"name": "..."}
- Move files:
POST /google-drive/files/{id}/move with {"new_parent_id": "FOLDER_ID"}
"Copy a template"
- Run bootstrap
- Find the template file
- Copy:
POST /google-drive/files/{id}/copy with {"name": "New Name"}
- If it's a Doc, replace placeholders via
/google-docs/documents/{new_id}/batch-update
- Share if needed
"Delete files"
- Run bootstrap
- Find the files
- Confirm with user — show file names
- Trash (recoverable):
DELETE /google-drive/files/{id}?trash=true
- Or permanent delete:
DELETE /google-drive/files/{id}
"Upload a file to Drive"
- Run bootstrap
- Read the local file content
- Confirm with user: "Upload {filename} to Drive?"
- Upload:
POST /google-drive/files with {name, content, mime_type}
"Edit a file on Drive"
- Run bootstrap
- Find the file:
GET /google-drive/search?q=FILENAME
- Read current content:
GET /google-drive/files/{id}/export?mime_type=text/plain
- Make edits
- Show user the changes for approval
- Update:
PUT /google-drive/files/{id} with {content, mime_type}
Error Handling
| Error | Meaning | Solution |
|---|
Token expired | AtrisOS session expired | Run atris login |
Google Drive not connected | OAuth not completed | Re-run bootstrap |
401 Unauthorized | Invalid/expired token | Run atris login |
400 Drive not connected | No Drive credentials | Complete OAuth via bootstrap |
429 Rate limited | Too many requests | Wait 60s, retry |
Invalid grant | Google revoked access | Re-connect via bootstrap |
Security Model
- Local token (
~/.atris/credentials.json): Your AtrisOS auth token, stored locally with 600 permissions.
- Drive credentials: Google Drive refresh token is stored server-side in AtrisOS encrypted vault.
- Access control: AtrisOS API enforces that you can only access your own Drive.
- OAuth scopes: Only requests necessary Drive permissions (read, write files).
- HTTPS only: All API communication encrypted in transit.
Quick Reference
npm install -g atris && atris login
TOKEN=$(node -e "console.log(require('$HOME/.atris/credentials.json').token)")
curl -s "https://api.atris.ai/api/integrations/google-drive/status" -H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/google-drive/shared-drives" -H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/google-drive/files" -H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/google-drive/search?q=budget" -H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/export?mime_type=text/plain" -H "Authorization: Bearer $TOKEN"
curl -s "https://api.atris.ai/api/integrations/google-drive/sheets/{id}/values?range=Sheet1" -H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{id}/append" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"range":"Sheet1","values":[["Alice",95]]}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"notes.txt","content":"Hello world","mime_type":"text/plain"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/folders" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Project Files"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/copy" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Copy of Doc"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/share" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"email":"user@example.com","role":"writer"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/files/{file_id}/move" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"new_parent_id":"FOLDER_ID"}'
curl -s -X DELETE "https://api.atris.ai/api/integrations/google-drive/files/{file_id}?trash=true" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"title":"New Sheet"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-drive/sheets/{id}/batchUpdate" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"requests":[{"repeatCell":{"range":{"sheetId":0,"startRowIndex":0,"endRowIndex":1},"cell":{"userEnteredFormat":{"textFormat":{"bold":true}}},"fields":"userEnteredFormat.textFormat.bold"}}]}'
curl -s -X PUT "https://api.atris.ai/api/integrations/google-drive/files/{file_id}" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"content":"Updated content","mime_type":"text/plain"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"title":"New Doc"}'
curl -s -X POST "https://api.atris.ai/api/integrations/google-docs/documents/DOC_ID/batch-update" \
-H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
-d '{"requests":[{"insertText":{"location":{"index":1},"text":"Hello world\n"}}]}'