From document-skills
Manages Google Workspace APIs (Docs, Drive, Sheets, Calendar, Gmail) including OAuth authentication, document operations, file management, spreadsheet manipulation, calendar events, email handling. Use when working with any Google Workspace API, document automation, email operations, calendar management, or spreadsheet data.
npx claudepluginhub andercore-labs/claudes-kitchen --plugin document-skillsThis skill uses the workspace's default tool permissions.
**CLI Tool:** `gw <api> <command> [args...]`
api-reference/README.mdapi-reference/authentication.mdapi-reference/batch-update/images.mdapi-reference/batch-update/paragraph.mdapi-reference/batch-update/structure.mdapi-reference/batch-update/table.mdapi-reference/batch-update/text.mdapi-reference/calendar/calendars.mdapi-reference/calendar/events-core.mdapi-reference/calendar/events-features.mdapi-reference/calendar/freebusy.mdapi-reference/calendar/recurrence.mdapi-reference/calendar/sharing.mdapi-reference/docs-batchupdate.mdapi-reference/docs-get.mdapi-reference/drive/about.mdapi-reference/drive/changes.mdapi-reference/drive/comments.mdapi-reference/drive/drives.mdapi-reference/drive/file-schema-content.mdGuides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
CLI Tool: gw <api> <command> [args...]
Google Docs:
gw docs get <doc_id> --tabs
gw docs insert <doc_id> <tab_id> <index> "text"
gw docs delete <doc_id> <tab_id> <start> <end>
Google Drive:
gw drive list "mimeType='application/vnd.google-apps.document'"
gw drive download <file_id> output.txt
gw drive share <file_id> user@example.com reader
Google Sheets:
gw sheets get <sheet_id> "Sheet1!A1:B10"
gw sheets update <sheet_id> "A1:B2" '[[1,2],[3,4]]'
gw sheets create "My Spreadsheet"
Google Calendar:
gw calendar list-events primary
gw calendar freebusy '["primary"]' 2025-01-15T00:00:00Z 2025-01-15T23:59:59Z
gw calendar find-slots user1@company.com user2@company.com --duration 30 --working-hours
gw calendar insert-event primary '{"summary":"Meeting","start":{"dateTime":"2025-01-15T10:00:00Z"},"end":{"dateTime":"2025-01-15T11:00:00Z"}}'
Gmail:
gw gmail list "is:unread"
gw gmail send user@example.com "Subject" "Body text"
gw gmail get <message_id>
Setup: See setup.md for installation
| Trigger | Action |
|---|---|
| Google Workspace API mentioned | Invoke skill |
| Docs/Drive/Sheets/Calendar/Gmail operations | Invoke skill |
| Document/spreadsheet automation | Invoke skill |
| Email operations | Invoke skill |
| Calendar management | Invoke skill |
| Finding meeting times | Invoke skill |
Plugin location: Scripts included with google-workspace-recipe skill
See setup.md for complete installation and OAuth setup instructions
Quick start:
PLUGIN_DIR=~/.claude/plugins/marketplaces/claudes-kitchen/plugins/document-skills/skills/google-workspace-recipe
chmod +x $PLUGIN_DIR/scripts/*.py
echo "alias gw='python3 $PLUGIN_DIR/scripts/gw.py'" >> ~/.zshrc
source ~/.zshrc
python3 $PLUGIN_DIR/scripts/oauth_init.py # Requests all 9 scopes
See setup.md for complete file layout.
Automatic: CLI handles OAuth token refresh automatically
Initial setup: Run oauth_init.py (see Installation section)
Manual refresh:
rm ~/token.json
python3 $PLUGIN_DIR/scripts/oauth_init.py # Re-authorize with all scopes
401 → CLI auto-refreshes token
400 → Check command syntax: gw <api> help
404 → Verify resource ID
timeout → Retry operation
CRITICAL: Always use --tabs flag
gw docs get <doc_id> --tabs
Output: JSON with full document structure including all tabs
doc['tabs'][i]
├─ ['tabProperties']['tabId'] # Stable ID: t.b2646bt2v2o0
├─ ['tabProperties']['title'] # Tab name
└─ ['documentTab']['body']['content'] # Array of elements
└─ [j]['paragraph']['elements']
└─ [k]['textRun']['content'] # Actual text
gw docs insert-text <doc_id> <tab_id> <index> "text content"
gw docs delete-range <doc_id> <tab_id> <start_index> <end_index>
gw docs replace-all <doc_id> "find" "replace" [--match-case]
Parse output with jq:
gw docs get <doc_id> --tabs | jq -r '.tabs[] | .tabProperties.tabId as $tab | .documentTab.body.content[]? | select(.paragraph) | .paragraph.elements[]? | select(.textRun.content | contains("search_term")) | "Tab: \($tab) Index: \(.startIndex)"'
| Issue | Fix |
|---|---|
| Timeout | Retry command |
| No tabs | Add --tabs flag: gw docs get <doc_id> --tabs |
| 401 | CLI auto-refreshes token |
| Content missing | Verify tab_id, refresh browser, re-fetch with --tabs |
| Can't find insertion point | Parse JSON output to get endIndex |
| Command not found | Run gw <api> (no args) to see help |
| Property | Details |
|---|---|
| Tab IDs | Stable (e.g., t.b2646bt2v2o0), extract with jq -r '.tabs[0].tabProperties.tabId' |
| Default behavior | Only first tab without --tabs flag |
| Index | Character position (starts at 1) |
| Batch updates | Atomic (all succeed or fail), use gw docs batch |
Fetch → Always use --tabs flag
Batch → Use gw docs batch for atomic multi-operation updates
Tab IDs → Stable across updates (parse from get output)
Verify → Re-fetch after modifications to confirm changes
Complex operations → Use batch command with JSON requests
Workflow: Get document → Insert text → Verify
# Get document with all tabs
DOC_ID="1ZO1GicwaubhS9bxCWtyM2_eJZjd-bDM6P9iPsVmTnLY"
gw docs get $DOC_ID --tabs > doc.json
# Extract tab ID and title
TAB_ID=$(jq -r '.tabs[0].tabProperties.tabId' doc.json)
TITLE=$(jq -r '.title' doc.json)
echo "Document: $TITLE"
# Insert text at index 1
gw docs insert-text $DOC_ID $TAB_ID 1 "Hello from CLI"
# Verify insertion
gw docs get $DOC_ID --tabs | jq -r '.tabs[0].documentTab.body.content[0].paragraph.elements[0].textRun.content'
Multiple operations in batch:
# Atomic batch update - insert text + make it bold
gw docs batch $DOC_ID '[
{"insertText": {"location": {"tabId": "'$TAB_ID'", "index": 1}, "text": "Bold text"}},
{"updateTextStyle": {"range": {"tabId": "'$TAB_ID'", "startIndex": 1, "endIndex": 10}, "textStyle": {"bold": true}, "fields": "bold"}}
]'
Organized by usage frequency - load common operations first, advanced on-demand.
Total: 49 files, all < 17 KB |
Workspace docs: https://developers.google.com/workspace
MANDATORY: Run after Google Workspace operations.
| Phase | Action |
|---|---|
| 1. Execute | Perform Google Workspace API operations |
| 2. Validate | Gather evidence from conversation context, confirm operations occurred |
| 3. Report | ✓ Pass → Done | ✗ Fail → List violations with evidence |
| 4. Fix | Violations found → Fix → Re-validate |
| 5. Store Metrics | After ALL validation passes, call mcp__agent-orchestrator__store-skill-metrics |
Validation principle:
Validation = Evidence gathering from conversation context
NOT re-running API operations
Validation method:
Review conversation context (tool calls, outputs)
→ Search for API function calls in tool outputs
→ Verify temporal order (operation → verification)
→ Cite tool call evidence with line numbers/timestamps
→ Confirm operation success from returned data
Check conversation context for required sequence:
| API | Operation | Required Evidence | Violation |
|---|---|---|---|
| Docs | Fetch doc | Write/Bash output shows get_document() called | No evidence of API call = FAIL |
| Docs | Insert text | insert_text() called → get_document() called after | No insert call or no verification = FAIL |
| Docs | Delete text | delete_range() called → get_document() called after | No delete call or no verification = FAIL |
| Drive | List files | files.list() called | No evidence of API call = FAIL |
| Drive | Share file | permissions.create() called | No evidence of API call = FAIL |
| Sheets | Get values | values.get() called | No evidence of API call = FAIL |
| Sheets | Update values | values.update() called → values.get() called after | No update or no verification = FAIL |
| Calendar | Find free time | freebusy.query() called | No evidence of API call = FAIL |
| Calendar | Create event | events.insert() called | No evidence of API call = FAIL |
| Gmail | List messages | messages.list() called | No evidence of API call = FAIL |
| Gmail | Send email | messages.send() called | No evidence of API call = FAIL |
| All | Token refresh | refresh_token() called before retry on 401 | 401 error without refresh attempt = FAIL |
Check conversation outputs for data validation:
| API | Operation | Evidence Required |
|---|---|---|
| Docs | Fetch | Output shows doc['title'], tabs array, content present |
| Docs | Insert | Re-fetch output shows text at expected index in correct tab |
| Docs | Delete | Re-fetch output shows range removed, indices adjusted |
| Drive | List files | Output shows files array matching query criteria |
| Drive | Create file | Output shows file ID, subsequent list shows new file |
| Drive | Share | Output shows permission created with correct role/type |
| Sheets | Get values | Output shows values array matching requested range |
| Sheets | Update values | Re-fetch output shows updated values in correct range |
| Sheets | Create sheet | Output shows sheet ID, spreadsheet structure updated |
| Calendar | Find free time | Output shows busy times parsed, free slots calculated |
| Calendar | Create event | Output shows event ID, event appears in list |
| Gmail | List messages | Output shows message IDs matching query |
| Gmail | Send email | Output shows message ID, message appears in sent folder |
| Gmail | Modify labels | Re-fetch output shows updated labels array |
| All | Token refresh | Output shows new access_token ≠ old, updated expiry |
Pattern:
Execute → Cite tool output → Verify data present → Report evidence
NOT: Assume success, re-execute, or trust status codes alone
Output format (with evidence):
VALIDATION REPORT:
✓ Docs insert: [Evidence] Tool output shows insert_text() at line 45
✓ Verification: [Evidence] get_document() called at line 52, text present at index 100
✓ Calendar query: [Evidence] freebusy.query() output at line 78 shows 3 busy periods
✓ Free slots: [Evidence] Calculated 5 free slots from busy periods
✗ FAIL: Sheets update not verified
[Evidence] values.update() called at line 103, but no subsequent get_values()
VIOLATIONS (1):
1. Add get_values() call after update to verify changes persisted
Evidence: Conversation shows update call but no verification fetch
ACTION: Fix violations and re-validate
Re-validation required after fixes. Repeat until ALL checks pass.
Metrics storage (Phase 5):
ALL validation checks pass → Store effectiveness metrics
mcp__agent-orchestrator__store-skill-metrics({
sessionId: "[from conversation context]",
skill: "managing-google-workspace-recipe",
initialViolations: 1,
iterations: 1,
fixesApplied: 1,
finalViolations: 0,
validationPassed: true,
durationSeconds: 45,
metadata: {
api: "docs",
operation: "insert_text",
verified: true,
doc_id: "abc123"
}
})
✓ Metrics stored → Skill effectiveness tracked