gdrive-access
Access Google Drive via CLI with 1Password OAuth. Use when user wants to list files, download from Drive, sync folders, or.
How do I install this agent skill?
npx skills add https://github.com/terrylica/cc-skills --skill gdrive-accessIs this agent skill safe to install?
- Gen Agent Trust Hubwarn
The skill enables Google Drive access by using 1Password to manage OAuth credentials and compiling a custom CLI tool. It features a self-modification instruction that could be leveraged for persistent prompt injection and requires external dependency downloads from the npm registry.
- Socketwarn
1 alert: gptSecurity
- Snykfail
Risk: CRITICAL · 2 issues
- Runlayerwarn
4/13 files flagged
What does this agent skill do?
Google Drive Access
List, download, and sync files from Google Drive programmatically via Claude Code.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
MANDATORY PREFLIGHT (Execute Before Any Drive Operation)
CRITICAL: You MUST complete this preflight checklist before running any gdrive commands. Do NOT skip steps.
Step 1: Check CLI Binary Exists
ls -la "$HOME/.claude/plugins/marketplaces/cc-skills/plugins/gdrive-tools/skills/gdrive-access/scripts/gdrive" 2>/dev/null || echo "BINARY_NOT_FOUND"
If BINARY_NOT_FOUND: Build it first:
cd ~/.claude/plugins/marketplaces/cc-skills/plugins/gdrive-tools/skills/gdrive-access/scripts && bun install && bun run build
Step 2: Check GDRIVE_OP_UUID Environment Variable
echo "GDRIVE_OP_UUID: ${GDRIVE_OP_UUID:-NOT_SET}"
If NOT_SET: You MUST run the Setup Flow below. Do NOT proceed to gdrive commands.
Step 3: Verify 1Password Authentication
op account list 2>&1 | head -3
If error or not signed in: Inform user to run op signin first.
Setup Flow (When GDRIVE_OP_UUID is NOT_SET)
Follow these steps IN ORDER. Use AskUserQuestion at decision points.
Setup Step 1: Check 1Password CLI
command -v op && echo "OP_CLI_INSTALLED" || echo "OP_CLI_MISSING"
If OP_CLI_MISSING: Stop and inform user:
1Password CLI is required. Install with:
brew install 1password-cli
Setup Step 2: Discover Drive OAuth Items in 1Password
op item list --vault Employee --format json 2>/dev/null | jq -r '.[] | select(.title | test("drive|oauth|google"; "i")) | "\(.id)\t\(.title)"'
Parse the output and proceed based on results:
Setup Step 3: User Selects OAuth Credentials
If items found, use AskUserQuestion with discovered items:
AskUserQuestion({
questions: [{
question: "Which 1Password item contains your Google Drive OAuth credentials?",
header: "Drive OAuth",
options: [
// POPULATE FROM op item list RESULTS - example:
{ label: "Google Drive API (56peh...)", description: "OAuth client in Employee vault" },
{ label: "Gmail API - dental-quizzes (abc12...)", description: "Can also access Drive" },
],
multiSelect: false
}]
})
If NO items found, use AskUserQuestion to guide setup:
AskUserQuestion({
questions: [{
question: "No Google Drive OAuth credentials found in 1Password. How would you like to proceed?",
header: "Setup",
options: [
{ label: "Create new OAuth credentials (Recommended)", description: "I'll guide you through Google Cloud Console setup" },
{ label: "I have credentials elsewhere", description: "Help me add them to 1Password" },
{ label: "Skip for now", description: "I'll set this up later" }
],
multiSelect: false
}]
})
- If "Create new OAuth credentials": Read and present references/gdrive-api-setup.md
- If "I have credentials elsewhere": Guide user to add to 1Password with required fields
- If "Skip for now": Inform user the skill won't work until configured
Setup Step 4: Confirm mise Configuration
After user selects an item (with UUID), use AskUserQuestion:
AskUserQuestion({
questions: [{
question: "Add GDRIVE_OP_UUID to .mise.local.toml in current project?",
header: "Configure",
options: [
{ label: "Yes, add to .mise.local.toml (Recommended)", description: "Creates/updates gitignored config file" },
{ label: "Show me the config only", description: "I'll add it manually" }
],
multiSelect: false
}]
})
If "Yes, add to .mise.local.toml":
- Check if
.mise.local.tomlexists - If exists, append
GDRIVE_OP_UUIDto[env]section - If not exists, create with:
[env]
GDRIVE_OP_UUID = "<selected-uuid>"
- Verify
.mise.local.tomlis in.gitignore
If "Show me the config only": Output the TOML for user to add manually.
Setup Step 5: Reload and Verify
mise trust 2>/dev/null || true
cd . && echo "GDRIVE_OP_UUID after reload: ${GDRIVE_OP_UUID:-NOT_SET}"
If still NOT_SET: Inform user to restart their shell or run source ~/.zshrc.
Setup Step 6: Test Connection
GDRIVE_OP_UUID="${GDRIVE_OP_UUID}" $HOME/.claude/plugins/marketplaces/cc-skills/plugins/gdrive-tools/skills/gdrive-access/scripts/gdrive list 1wqqqvBmeUFYuwOOEQhzoChC7KzAk-mAS
If OAuth prompt appears: This is expected on first run. Browser will open for Google consent.
Drive Commands (Only After Preflight Passes)
GDRIVE_CLI="$HOME/.claude/plugins/marketplaces/cc-skills/plugins/gdrive-tools/skills/gdrive-access/scripts/gdrive"
# List files in a folder
$GDRIVE_CLI list <folder_id>
# List with details (size, modified date)
$GDRIVE_CLI list <folder_id> --verbose
# Search for files
$GDRIVE_CLI search "name contains 'training'"
# Get file info
$GDRIVE_CLI info <file_id>
# Download a single file
$GDRIVE_CLI download <file_id> -o ./output.pdf
# Sync entire folder to local directory
$GDRIVE_CLI sync <folder_id> -o ./output_dir
# Sync with subfolders
$GDRIVE_CLI sync <folder_id> -o ./output_dir -r
# JSON output (for parsing)
$GDRIVE_CLI list <folder_id> --json
Creating a native Google Doc (write)
create-doc uploads a local HTML (or .docx) source and has Drive convert it into a native
Google Doc (application/vnd.google-apps.document) — the team can open + comment on it directly, no
"convert" step. This is the recommended Drive pattern: files.create with the target mimeType in the
metadata and the source bytes as media, sent as a multipart upload (a simple upload silently skips
conversion).
# Markdown is the usual author format → HTML (highest-fidelity import) → native Google Doc
pandoc notes.md -o /tmp/notes.html --standalone
$GDRIVE_CLI create-doc /tmp/notes.html --name "Meeting Notes" --parent <folder_id>
# → prints the new Doc's id, mimeType (application/vnd.google-apps.document), and docs.google.com link
# Overwrite an existing Doc's contents in place (keeps the same id / link / comments):
$GDRIVE_CLI create-doc /tmp/notes.html --update <doc_id>
Why not rclone / .docx? rclone's --drive-import-formats is unreliable for this (name-collision
and sync-confusion gotchas), and a plain .docx in Drive opens in Docs but isn't a native Doc. The Drive
API conversion above is the robust FOSS path.
Write scope (one-time re-auth). create-doc needs the drive.file scope (create/manage files this
app makes — least-privilege, NOT full-drive). It was added alongside the original drive.readonly, so the
first write re-prompts for consent. If it doesn't, force it:
rm ~/.claude/tools/gdrive-tokens/$GDRIVE_OP_UUID.json then re-run. --update only works on Docs this app
created (drive.file limitation); to overwrite externally-created Docs, broaden the scope to auth/drive.
Rate limits & retries (built in)
Drive returns HTTP 403 rateLimitExceeded / userRateLimitExceeded (and sometimes 429) when a
project bursts too many queries — we hit this doing several writes back-to-back. The CLI now wraps every
Drive call in exponential backoff with jitter (withBackoff in lib/drive.ts): wait
min(2^n·1000 + random_ms, 64s), finite retries, per Google's official guidance. Non-rate-limit errors
still fail loud. To stay under the limit proactively: batch / space out bulk operations, avoid
redundant metadata calls, and don't refresh the token on every call.
Extracting Folder ID from URL
Google Drive folder URL:
https://drive.google.com/drive/folders/1wqqqvBmeUFYuwOOEQhzoChC7KzAk-mAS
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
This is the folder ID
Drive Search Syntax
| Query | Description |
|---|---|
name contains 'keyword' | Name contains keyword |
name = 'exact name' | Exact name match |
mimeType = 'application/pdf' | By file type |
modifiedTime > '2026-01-01' | Modified after date |
trashed = false | Not in trash |
'<folderId>' in parents | In specific folder |
Reference: https://developers.google.com/drive/api/guides/search-files
Environment Variables
| Variable | Required | Description |
|---|---|---|
GDRIVE_OP_UUID | Yes | 1Password item UUID for OAuth credentials |
GDRIVE_OP_VAULT | No | 1Password vault (default: Employee) |
Token Storage
OAuth tokens stored at: ~/.claude/tools/gdrive-tokens/<uuid>.json
- Central location (not in plugin, not in project)
- Organized by 1Password UUID (supports multi-account)
- Created with chmod 600
Google Docs Export
Google Docs (Docs, Sheets, Slides) are automatically exported:
| Google Type | Export Format |
|---|---|
| Document | .docx |
| Spreadsheet | .xlsx |
| Presentation | .pptx |
| Drawing | .png |
References
- gdrive-api-setup.md - Google Cloud OAuth setup guide
Post-Change Checklist
- YAML frontmatter valid (no colons in description)
- Trigger keywords current
- Path patterns use $HOME not hardcoded paths
- References exist and are linked
Post-Execution Reflection
After this skill completes, reflect before closing the task:
- Locate yourself. — Find this SKILL.md's canonical path before editing.
- What failed? — Fix the instruction that caused it.
- What worked better than expected? — Promote to recommended practice.
- What drifted? — Fix any script, reference, or dependency that no longer matches reality.
- Log it. — Evolution-log entry with trigger, fix, and evidence.
Do NOT defer. The next invocation inherits whatever you leave behind.
How can the creator link this skill?
Add the canonical catalog link to the repository README so users can inspect current installs and available audits. The publishing guide covers the complete discovery path.
<a href="https://skillzs.dev/skills/terrylica/cc-skills/gdrive-access">View gdrive-access on skillZs</a>