| name | google-docs-markdown |
| description | Convert markdown files to formatted Google Docs via the API. Handles headings, lists, tables, code blocks, images, folder organization, and sharing. Use when you need to deliver professional documents to stakeholders via Google Drive. Trigger phrases: 'create a google doc', 'upload to google docs', 'share on google drive', 'send as google doc', 'markdown to google docs'. |
Google Docs Markdown
Convert markdown to fully formatted Google Docs -- headings, lists, tables, code blocks, and more -- via the Google Docs and Drive APIs. Organize into folders, add logos, and share with recipients in a single operation.
When to Use
- Delivering professional documents to clients or collaborators via Google Drive
- Batch-uploading markdown files as formatted Google Docs
- Automating document workflows (draft in markdown, publish to Drive)
- Sharing branded documents with logos and organized folder structures
- Any time you need real Google Docs (not exported HTML or PDFs)
What It Does
This skill provides a Python library (gdocs.py) that:
- Creates Google Docs from markdown with proper formatting (H1-H6, bullets, numbered lists, checkboxes, blockquotes, tables, code blocks, horizontal rules, bold)
- Manages Drive folders -- creates, organizes, and shares them
- Handles images -- uploads to Drive and embeds at the top of documents (logos, headers)
- Shares with recipients -- writer or reader access, with notification emails
- Batch uploads -- process an entire directory of
.md files into a shared folder
Setup (One-Time)
1. Google Cloud Project
- Go to Google Cloud Console
- Create a new project (or use an existing one)
- Enable these APIs:
- Google Docs API
- Google Drive API
2. OAuth Credentials
- Go to APIs & Services > Credentials
- Click Create Credentials > OAuth 2.0 Client ID
- Application type: Desktop app
- Download the JSON file
- Save it as
google_credentials.json in the same directory as gdocs.py (or set a custom path)
3. Install Dependencies
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib
4. First Run
The first time you run the library, it opens a browser for Google authorization. After authorizing, a google_token.json file is saved locally for future runs (auto-refreshes).
Usage
Python API
from gdocs import GoogleDocsClient
client = GoogleDocsClient(
credentials_file="path/to/google_credentials.json",
token_file="path/to/google_token.json"
).authenticate()
doc_id, url = client.create_doc("My Document Title", markdown_text)
print(url)
folder_id = client.create_folder("Project Documents")
doc_id, url = client.create_doc("Report", markdown_text, folder_id=folder_id)
client.share(doc_id, "collaborator@email.com", role="writer")
result = client.upload_markdown_folder(
source_dir="./docs/",
folder_name="Project Documents",
share_with="client@email.com",
share_role="writer",
title_prefix="Project Name",
logo_path="./assets/logo.png",
)
print(result["folder_url"])
for title, url in result["docs"]:
print(f" {title}: {url}")
CLI
python gdocs.py upload file1.md file2.md --folder "My Folder" --share user@email.com
python gdocs.py upload *.md --folder "Docs" --prefix "Project" --logo logo.png --share user@email.com
python gdocs.py folder "New Folder" --share user@email.com
python gdocs.py list
Claude Code Integration
To use this as a Claude Code skill:
- Copy
gdocs.py to a stable location (e.g., ~/.local/lib/gdocs.py)
- Place credentials alongside it or set custom paths
- In Claude Code, import and use:
import sys, os
sys.path.insert(0, os.path.expanduser("~/.local/lib"))
from gdocs import GoogleDocsClient
client = GoogleDocsClient().authenticate()
doc_id, url = client.create_doc("Title", markdown_content)
API Reference
| Method | Purpose |
|---|
authenticate() | Auth with Google (browser on first run, then auto-refresh) |
create_doc(title, markdown, folder_id=None) | Create doc from markdown. Returns (doc_id, url) |
create_folder(name, parent_id=None) | Create or find existing folder. Returns folder_id |
share(file_id, email, role="writer", message=None) | Share file/folder with a user |
share_public(file_id, role="reader") | Make publicly accessible via link |
move_to_folder(file_id, folder_id) | Move file into a folder |
delete(file_id) | Delete a file or folder |
list_files(folder_id=None, limit=20) | List files (optionally within a folder) |
upload_image(filepath, folder_id=None, public=True) | Upload image, returns (file_id, uri) |
insert_image(doc_id, uri, width_pt, height_pt, center=True) | Insert image at top of doc |
upload_markdown_folder(source_dir, folder_name, ...) | Batch upload all .md files from a directory |
folder_url(folder_id) | Get the Drive folder URL |
Markdown Features Supported
| Feature | How It Renders |
|---|
# Heading through ###### Heading | Google Docs heading styles (H1-H6) |
- Bullet item | Bulleted list |
1. Numbered item | Numbered list |
- [x] Checkbox | Indented checkbox text |
> Blockquote | Indented + italicized paragraph |
| ` | Table |
```code block``` | Courier New, 9pt monospace |
--- | Horizontal rule (underscores) |
**Bold** | Bold markers are stripped (text preserved) |
Troubleshooting
| Problem | Solution |
|---|
"empty range" error | The library auto-filters these. If still occurs, check for empty code blocks or zero-length text in your markdown. |
| Token expired | Token auto-refreshes. If refresh fails, delete google_token.json and re-run (browser auth). |
| Scope error after changes | Delete the token file to re-authorize with new permissions. |
| Unicode errors on Windows | Run with python -X utf8 to force UTF-8 mode. |
| Batch update limit | The library automatically chunks requests into batches of 100 (Google Docs API limit per call). |
Anti-Patterns
- Don't use for real-time collaboration -- This creates documents, it doesn't sync them. For live editing, just use Google Docs directly.
- Don't hardcode credentials paths -- Use the constructor parameters or environment variables.
- Don't skip the empty-range filter -- The Google Docs API rejects
updateTextStyle requests where startIndex >= endIndex. The library handles this automatically.
- Don't upload massive documents in one shot -- The batch update API has a practical limit. For very large documents (1000+ lines), consider splitting into multiple docs.
Origin
Extracted from a real project: building protocol documents for a multi-week creative gathering in Panama. Three 100+ line markdown documents needed to be delivered as professionally formatted Google Docs with logos, organized in folders, and shared with the event organizer. The initial approach (manual Google Docs creation) was replaced with this automated pipeline that handles the full workflow in seconds.
The library was first built as a one-off upload script, then generalized into a reusable tool after recognizing the pattern would recur across projects.
Part of Claude Code Skills -- reusable skills extracted from real AI-assisted development sessions.