From bedrock
Fetches Google Docs and Sheets content via MCP (preferred), API/public export (fallback), or browser DOM extraction, converting to Markdown. Internal module for /bedrock:learn and /bedrock:sync.
npx claudepluginhub iurykrieger/claude-bedrock --plugin bedrockThis skill is limited to using the following tools:
Internal module — invoked by `/bedrock:learn` Phase 1 and `/bedrock:sync` Phase 2, not user-invocable.
Converts Google Docs, Slides, or Sheets URLs to Markdown or CSV using gcloud CLI and Python scripts. Useful for reading or importing Google Drive documents.
Exports Google Docs, Sheets, Slides from URLs or files to DOCX/XLSX/PPTX via browser for local reading, summarization, and analysis.
Fetches Confluence page content via Atlassian MCP (preferred), REST API fallback, or browser DOM extraction and converts to Markdown. Internal module for Bedrock skills.
Share bugs, ideas, or general feedback.
Internal module — invoked by /bedrock:learn Phase 1 and /bedrock:sync Phase 2, not user-invocable.
Fetches a Google Docs document or Google Sheets spreadsheet and converts it to a local Markdown file. Supports both document types with automatic detection. Three layers in fallback order: MCP (preferred) → API / Public Export → Browser DOM extraction.
Dependency: Browser fallback (Layer 3) requires scripts/extract.js (relative to this skill directory).
Parse the URL. Accept these formats:
Google Docs:
https://docs.google.com/document/d/{docId}/edithttps://docs.google.com/document/d/{docId}/edit#heading=...https://docs.google.com/document/d/{docId}/edit?tab=t.0https://docs.google.com/document/d/{docId}Google Sheets:
https://docs.google.com/spreadsheets/d/{docId}/edithttps://docs.google.com/spreadsheets/d/{docId}/edit#gid=0https://docs.google.com/spreadsheets/d/{docId}Detect type:
/spreadsheets/d/ → Sheet/document/d/ → DocExtract the {docId} — the string between /d/ and the next / or end of path.
The preferred layer. Checks if a Google Docs/Drive MCP server is installed and authenticated.
Use ToolSearch to check if any Google Docs or Google Drive MCP tools are available:
ToolSearch(query: "google docs drive document", max_results: 5)
Evaluate the result:
MCP not available: No Google Docs/Drive MCP server installed. When a Google Docs MCP becomes available, install it for direct document access. Falling back to API (Layer 2).
Use the Google Docs MCP tools to fetch the document content. The specific tool depends on what the MCP exposes.
MCP fetch failed: {error message}. Falling back to API (Layer 2).
If an MCP is installed but not authenticated, guide the user:
MCP not authenticated: A Google Docs MCP server is installed but requires authentication. Complete the authentication flow as prompted by the MCP server. After authentication, Google documents can be fetched directly via MCP.
Ask the user: "Would you like to authenticate the Google Docs MCP now, or skip to API fallback (Layer 2)?"
Uses the Google Drive/Sheets API with a bearer token or public URL export.
GOOGLE_ACCESS_TOKEN env var exists → use Strategy A (API with token)GOOGLE_ACCESS_TOKEN is NOT set → use Strategy B (Public Export)API not available: This document requires authentication and no
GOOGLE_ACCESS_TOKENis set. Generate a token at https://developers.google.com/oauthplayground/ with thehttps://www.googleapis.com/auth/drive.readonlyscope. Export:export GOOGLE_ACCESS_TOKEN="your-token". Falling back to Browser extraction (Layer 3).
Inform the caller which strategy is being used and whether the document is a Doc or Sheet.
Use WebFetch:
WebFetch(
url: "https://www.googleapis.com/drive/v3/files/{docId}/export?mimeType=text/markdown",
headers: { "Authorization": "Bearer {GOOGLE_ACCESS_TOKEN}" },
prompt: "Return the COMPLETE raw content exactly as-is. Do not summarize or truncate."
)
If WebFetch cannot send the Authorization header, fall back to Bash:
curl -sL -H "Authorization: Bearer ${GOOGLE_ACCESS_TOKEN}" \
"https://www.googleapis.com/drive/v3/files/{docId}/export?mimeType=text/markdown"
API authentication failed: Google API returned 401. The token may be expired or invalid. Refresh your token at https://developers.google.com/oauthplayground/. Falling back to Browser extraction (Layer 3).
API access denied: Google API returned 403. You do not have access to this document. Verify document sharing permissions in Google Docs.
Document not found: Google API returned 404. The document ID may be incorrect. Verify the URL or document ID.
API returned empty: The document appears to be empty or the export failed. Falling back to Browser extraction (Layer 3).
Do not post-process the Markdown — return Google's native output as-is.
curl -sL "https://docs.google.com/document/d/{docId}/export?format=md"
The -L flag follows the 307 redirect to *.googleusercontent.com.
Public export not available: Document is private and requires authentication. Set
GOOGLE_ACCESS_TOKENfor API access, or ensure you are logged into Google in Chrome. Falling back to Browser extraction (Layer 3).
Public export returned empty: The document appears to be empty or inaccessible. Falling back to Browser extraction (Layer 3).
curl -sL -H "Authorization: Bearer ${GOOGLE_ACCESS_TOKEN}" \
"https://sheets.googleapis.com/v4/spreadsheets/{docId}?fields=sheets.properties"
Returns JSON with sheets[].properties.title (sheet name) and sheets[].properties.sheetId (gid).
For each tab:
curl -sL -H "Authorization: Bearer ${GOOGLE_ACCESS_TOKEN}" \
"https://docs.google.com/spreadsheets/d/{docId}/export?format=csv&gid={sheetGid}"
If the export endpoint fails for a specific tab, fall back to the Sheets API values endpoint:
curl -sL -H "Authorization: Bearer ${GOOGLE_ACCESS_TOKEN}" \
"https://sheets.googleapis.com/v4/spreadsheets/{docId}/values/{sheetName}!A:ZZ"
Convert the JSON values array rows to comma-separated values to produce CSV.
For each tab's CSV:
"..." are a single field)| col1 | col2 | ... || --- | --- | ... || val1 | val2 | ... || within cell values as \|For each tab, prepend: ## {sheet_name} followed by a blank line, then the Markdown table, then a blank line. Tabs appear in the same order as returned by the Sheets API metadata.
API authentication failed: Sheets API returned 401. The token may be expired or invalid. Refresh your token at https://developers.google.com/oauthplayground/. Falling back to Browser extraction (Layer 3).
API access denied: Sheets API returned 403. You do not have access to this spreadsheet. Verify spreadsheet sharing permissions or ensure token has
drive.readonlyscope.
Spreadsheet not found: Sheets API returned 404. The spreadsheet ID may be incorrect. Verify the URL.
API returned empty: The spreadsheet appears to be empty. Falling back to Browser extraction (Layer 3).
curl -sL "https://docs.google.com/spreadsheets/d/{docId}/gviz/tq?tqx=out:csv&gid=0"
Public export not available: Spreadsheet is private and requires authentication. Set
GOOGLE_ACCESS_TOKENfor API access, or ensure you are logged into Google in Chrome. Falling back to Browser extraction (Layer 3).
Public export returned empty: The spreadsheet appears to be empty or inaccessible. Falling back to Browser extraction (Layer 3).
Inform the caller: "Public export can only retrieve the first sheet tab. To export all tabs, set GOOGLE_ACCESS_TOKEN."
Format the single tab with heading ## Sheet1 followed by the Markdown table.
Last resort. Opens the document in Chrome and extracts content via DOM scraping.
Via ToolSearch:
select:mcp__claude-in-chrome__tabs_context_mcp,mcp__claude-in-chrome__tabs_create_mcp
select:mcp__claude-in-chrome__navigate
select:mcp__claude-in-chrome__javascript_tool
If Chrome MCP tools are not available, abort:
Browser not available: Claude in Chrome MCP is not installed or not running. Install the Claude in Chrome extension and ensure it is connected. No further fallback layers available — cannot fetch this document.
mcp__claude-in-chrome__tabs_context_mcp(createIfEmpty: true)
mcp__claude-in-chrome__tabs_create_mcp()
mcp__claude-in-chrome__navigate(url: "<full document URL>", tabId: <id>)
Read scripts/extract.js from this skill's directory using the Read tool. Then execute it:
mcp__claude-in-chrome__javascript_tool(
action: "javascript_exec",
text: <contents of extract.js>,
tabId: <id>
)
The script returns JSON:
{
"status": "ready",
"totalLength": 31450,
"totalChunks": 4,
"chunkSize": 10000,
"title": "Document Title",
"docType": "doc",
"instructions": "Run window.__gdoc.chunk(0), window.__gdoc.chunk(1), etc."
}
If the script returns an error field: handle accordingly (login page, empty content, wrong page).
For each chunk from 0 to totalChunks - 1:
mcp__claude-in-chrome__javascript_tool(
action: "javascript_exec",
text: "window.__gdoc.chunk(N)",
tabId: <id>
)
Concatenate all chunks into a single Markdown string.
Check that the result is not empty and not a login page. If validation fails:
Browser extraction failed: Could not extract content from the document. Ensure you are logged into Google in Chrome and the document has loaded. No further fallback layers available — cannot fetch this document.
/tmp/gdoc_{docId}.md/tmp/gsheet_{docId}.mdWrite the Markdown content using the Write tool. Verify the file was written by reading the first few lines.
Return to /bedrock:learn or /bedrock:sync:
/tmp/gdoc_{docId}.md or /tmp/gsheet_{docId}.mdThe caller copies the file to $TEACH_TMP/<slug>.md.
| Rule | Detail |
|---|---|
| Read-only | Never write back to Google Docs or Sheets. |
| No OAuth interactive flows | Use only existing MCP auth, static token from GOOGLE_ACCESS_TOKEN, or browser session. |
| Validate before saving | Do not save empty files, HTML error pages, or Google login pages. |
| Layer order is sacred | Always try MCP → API → Browser, in that order. Never skip ahead unless a layer is unavailable or user declines. |
| Guide before falling through | If a layer exists but is misconfigured, guide the user before moving to the next layer. |
| No Markdown post-processing for Docs | Return Google's native Markdown export as-is (API layer). |
| Export all sheet tabs (API) | Do not skip tabs or allow selective export. |
| Respect CSV quoting rules | Quoted fields are single fields, even with commas or newlines inside. |
| Best-effort | If a layer fails, try the next. If all fail, report and abort — do not retry indefinitely. |
| 403 is terminal | Permission denied cannot be resolved by falling to another layer — abort immediately. |
| Problem | Solution |
|---|---|
| No Google Docs MCP available | Expected today — skip to API layer automatically |
| API returns 401 | Token expired — refresh at https://developers.google.com/oauthplayground/ |
| API returns 403 | User lacks access to the document/spreadsheet |
| API returns 404 | Document ID is wrong — verify URL |
| Public export returns HTML login page | Document is private — set GOOGLE_ACCESS_TOKEN or use browser |
| Content is truncated | Google Drive API limits exports to 10 MB — document may be too large |
| WebFetch fails to send Authorization header | Fall back to curl -H "Authorization: Bearer {token}" -sL "<url>" via Bash |
| Sheets 403 for metadata | Token may lack drive.readonly or spreadsheets.readonly scope |
| Sheets CSV export returns HTML | Export endpoint blocked — fall back to Sheets API values endpoint |
| Public Sheets export returns only first tab | Expected limitation — multi-sheet export requires GOOGLE_ACCESS_TOKEN |
| Chrome extension disconnected | Refresh extension, call tabs_context_mcp(createIfEmpty: true) |
| Browser redirects to Google login | User not authenticated — log into Google in Chrome, retry |
extract.js returns empty | Document may not have loaded — wait and retry, or check if document is empty |