agentleFS
ai-analyst-labai-analyst-lab/ai-analyst/.claude/skills/google-doc-export/SKILL.md

google-doc-export

Skill304 starsChanged 2 months agoMITView on GitHub

Create properly formatted Google Docs via the MCP API. This skill prevents common issues like text/image overlap, broken heading hierarchy, excessive whitespace, and inconsistent formatting. Use this skill automatically whenever you're building a Google Doc, calling any Google Docs MCP tool on the google-workspace server (create_doc, insert_doc_elements, insert_doc_image, batch_update_doc) or the google-docs server (upload_file_to_drive, write_formatted_content), designing a document structure, or when the google-doc-creator or google-doc-reviewer agent is running. This skill is essential for ANY workflow involving Google Docs creation, document formatting, analysis writeups in Google Docs, report generation to Docs, chart embedding in documents, or exporting analysis results to shareable Docs. Make sure to use this skill whenever the user wants to create a Doc, export to Google Docs, share analysis as a Doc, build a formatted document, or mentions Google Docs in any capacity.

The file

Show its rules and text

We split this skill into the rules it gives an agent

15 rules. About 0 are common, 9 are distinctive, and 6 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈9

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 6

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    Create properly formatted Google Docs via the MCP API.

    line 10
  2. Very specific:

    Check helpers/INDEX.md first to verify no helper exists for your use case

    line 93
  3. Distinctive:

    If building from scratch, create the .docx with proper heading hierarchy

    line 94
  4. Very specific:

    Always save to the repo's outputs/ directory

    line 95
  5. Very specific:

    Use descriptive filename with date suffix: report_[title]_[YYYYMMDD].docx

    line 96
  6. Distinctive:

    No risk of index invalidation, no image timing issues, no expiring image URLs.

    line 148
  7. Very specific:

    Critical: Always specify BOTH width_pts and height_pts.

    line 199
  8. Distinctive:

    Use this structure for analysis reports:

    line 207
  9. Distinctive:

    Never insert an image into a paragraph that already contains text.

    line 212
  10. Distinctive:

    If data for a section doesn't exist, omit the heading entirely.

    line 222
  11. Distinctive:

    Always specify both width and height.

    line 314
  12. Distinctive:

    When creating analysis documents with findings, embed provenance data at three levels:

    line 363
  13. Distinctive:

    Every finding paragraph must include a data stamp inline, immediately after the finding title or key claim:

    line 367
  14. Very specific:

    After building the .docx via gdoc_builder.py, the builder automatically creates:

    line 415
  15. Very specific:

    All provenance data comes from helpers/provenance/provenance_assembler.py:

    line 433

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Skill: Google Doc Export

Purpose

Create properly formatted Google Docs via the MCP API. Prevents common issues: text/image overlap, broken heading hierarchy, excessive whitespace, inconsistent formatting.


Section 0: Quick Decision Tree — START HERE

Step 1: What type of document are you creating?

  • Analysis report/writeup → Use .docx → Google Docs workflow (Section A) with helpers/export/gdoc_builder.py
  • Simple text-only doc (meeting notes, memo) → Use direct MCP API (Section B)
  • Non-analysis document (proposal, spec) → Check helpers/INDEX.md for helpers, else use python-docx directly

Step 2: Choose your approach based on document type:

✅ Recommended: .docx → Google Docs Conversion (use for 90% of cases)

When: Any doc with charts, tables, or complex formatting (analysis reports, writeups)

Why: Most reliable. Avoids index calculation errors, handles images/tables automatically, always creates local backup.

How:

# 1. Use helpers/export/gdoc_builder.py to create .docx locally
# 2. Upload with conversion flag
upload_file_to_drive(
    file_path="/path/to/report.docx",
    convert_to_google_doc=True
)
# 3. Done! Returns Google Doc URL

Available MCP function: mcp__google-docs__upload_file_to_drive(file_path, convert_to_google_doc=True)

Alternative: Direct MCP API Calls (simple text-only docs)

When: Quick text-only docs with no images/tables (meeting notes, simple memos)

Which server: This repo's doc agents (google-doc-creator, google-doc-reviewer) target the google-workspace MCP server, whose Docs functions are create_doc, insert_doc_elements, insert_doc_image, inspect_doc_structure, batch_update_doc, update_paragraph_style, and get_doc_as_markdown. Drive uploads (upload_file_to_drive, upload_image_to_drive) come from the google-docs server. auth-preflight detects which servers are installed; call only functions the installed server exposes (Section F lists both).


Section A: Using the .docx → Google Docs Workflow (RECOMMENDED)

This is the easiest and most reliable approach for complex documents.

Step 1: Generate .docx Locally

IMPORTANT: Always check for existing helpers before writing .docx code from scratch.

Option 1A: Use helpers/export/gdoc_builder.py (PREFERRED for analysis documents)

When to use: Creating analysis reports, findings writeups, or any document following the Analysis Readout template (Context → Summary → Analysis → Next Steps → Resources).

Why: Pre-built, tested, handles all formatting automatically. Don't reinvent the wheel.

from helpers.export.gdoc_builder import build_readout

# Build structured analysis document
doc_data = {
    "title": "Q1 Analysis",
    "findings": [...],  # Your analysis content
    "charts": ["/path/to/chart1.png", "/path/to/chart2.png"]
}

docx_path = build_readout(doc_data)  # Returns path to .docx file

The builder automatically applies:

  • Proper heading hierarchy (H1 → H2 → H3 → H4)
  • Bold labels ("The Insight:", "Why this matters for product:")
  • Chart embedding at 6 inches wide with captions
  • Figure numbering
  • Professional spacing
  • Analysis Readout template structure

Option 1B: Use python-docx directly (ONLY if no helper exists)

When to use: Creating non-analysis documents (proposals, specs, design docs) that don't fit the Analysis Readout template.

Requirements:

  • Check helpers/INDEX.md first to verify no helper exists for your use case
  • If building from scratch, create the .docx with proper heading hierarchy
  • Always save to the repo's outputs/ directory
  • Use descriptive filename with date suffix: report_[title]_[YYYYMMDD].docx

Example:

from docx import Document
from docx.shared import Inches, Pt
from docx.enum.text import WD_ALIGN_PARAGRAPH

doc = Document()
# Add title
title = doc.add_heading('Document Title', level=1)
# Add content sections...
# Add charts
doc.add_picture('/path/to/chart.png', width=Inches(6))
# Save
doc.save('outputs/report_title_20260404.docx')

Step 2: Upload with Conversion

CRITICAL: The local .docx file IS your backup. Do not delete it.

result = mcp__google-docs__upload_file_to_drive(
    file_path=docx_path,
    convert_to_google_doc=True
)

# Returns: {"file_id": "...", "url": "https://docs.google.com/document/d/..."}

Step 3: Confirm Deliverables

You now have TWO deliverables (always provide both to the user):

  1. Live Google Doc - result["url"]
    • Editable, shareable, lives in Google Drive
    • Charts embedded permanently (no expiration)
  2. Local backup - docx_path
    • Archival copy in /outputs/ directory
    • Useful for version control, offline access
    • REQUIRED: Always mention both the Google Doc URL AND the local file path in your response to the user

Why This Works Better

Google's .docx converter handles:

  • Image placement (no index calculation needed)
  • Table creation (no manual cell population)
  • Bold/italic/heading styles
  • Spacing and layout

No risk of index invalidation, no image timing issues, no expiring image URLs.


Section B: Direct MCP API Approach (Simple Docs Only)

For simple text-only documents, you can use MCP functions directly.

Create and Populate

# 1. Create blank doc
result = mcp__google-docs__create_document(title="Meeting Notes")
doc_id = result["document_id"]

# 2. Add formatted content
content_blocks = [
    {"type": "heading1", "text": "Meeting Notes\n"},
    {"type": "body", "text": "Attendees: Alice, Bob\n\n"},
    {"type": "heading2", "text": "Discussion Points\n"},
    {"type": "body", "text": "We reviewed the Q1 results...\n"}
]

mcp__google-docs__write_formatted_content(
    document_id=doc_id,
    content_blocks=json.dumps(content_blocks)
)

Insert Images (if needed)

# 1. Upload image to Drive first
image_result = mcp__google-docs__upload_image_to_drive(
    file_path="/path/to/chart.png"
)
image_url = image_result["url"]

# 2. Read doc to find insertion index
doc_content = mcp__google-docs__read_document(document_id=doc_id)
# Find the index where you want the image

# 3. Insert image with BOTH width and height
mcp__google-docs__insert_image(
    document_id=doc_id,
    image_url=image_url,
    width_pts=400,
    height_pts=300  # REQUIRED - calculate from aspect ratio if needed
)

Critical: Always specify BOTH width_pts and height_pts. Omitting height causes API error.


Section C: Document Structure Standards

Standard Analysis Document Template

Use this structure for analysis reports:

  • Text inserted before images — all text content must be in the doc before any image insertion. Images shift all indices.
  • Images in dedicated paragraphs — every image gets its own paragraph. Never insert an image into a paragraph that already contains text.
  • Bottom-to-top image insertion — insert the last section's image first, then work backwards. Prevents index invalidation.
  • Heading hierarchy is clean — exactly one H1, H2 for sections, H3 for subsections. No skipped levels.
  • No more than 2 consecutive empty paragraphs anywhere in the document.
  • Drive file IDs used for images — never public-host URLs (they expire and leak data).
  • Table spacing — every table must have 1 empty paragraph before and after it. Text must never run directly into a table or start immediately after one.
  • No stub headings — never insert a heading without body content beneath it. If data for a section doesn't exist, omit the heading entirely.
  • Both width AND height specified for images — insert_image requires both; omitting height is an API error.

Section B: Document Structure Template

Standard Analysis Document

H1: [Document Title]
    [Subtitle — scope, date, author]

H2: Executive Summary
    [3-5 sentence overview]
    [Numbered key findings — max 3]
    [Bottom line statement]

H2: Section 1: [Topic]
    [Chart image — centered, 400pt wide]
    [The Insight: bold label + finding]
    [Supporting evidence paragraphs]
    [Why this matters for product: bold label + implication]

H2: Section 2: [Topic]
    ... (repeat pattern)

H2: Data Quality and Limitations
    [Outlier investigation]
    [Sample size notes]
    [Methodology caveats]

H2: Recommendations
    [Numbered list of actionable recommendations]
    [Each with a bold title + explanation paragraph]

H2: Appendix
    [Summary statistics tables]

Section Spacing Rules

After H1:          2 empty paragraphs
After H2:          1 empty paragraph
Before chart:      1 empty paragraph
After chart:       1 empty paragraph
Before table:      1 empty paragraph
After table:       1 empty paragraph
Between sections:  2 empty paragraphs (includes the pre-H2 spacing)
Between paragraphs: 0 empty paragraphs (natural paragraph spacing)
After bullet list:  1 empty paragraph

Spacing Rules

After H1:          2 empty paragraphs
After H2:          1 empty paragraph
Before chart:      1 empty paragraph
After chart:       1 empty paragraph
Before table:      1 empty paragraph
After table:       1 empty paragraph
Between sections:  2 empty paragraphs
Between paragraphs: 0 empty paragraphs (natural spacing)
After bullet list:  1 empty paragraph

Bold Labels (Auto-Applied by gdoc_builder)

These phrases should always be bold when they appear at the start of a paragraph:

  • "The Insight:"
  • "Why this matters for product:"
  • "Bottom line:"
  • "Key context:"
  • "Data quality flag:"
  • "Sample size warning:"

Section D: Image Sizing Reference

Standard chart:     width=400, height=300  (4:3 ratio)
Wide chart:         width=500, height=280  (16:9 ratio)
Square chart:       width=350, height=350  (1:1 ratio)
Small inline:       width=250, height=200  (for side notes)

Always specify both width and height. If only one dimension is known, calculate the other from the image's aspect ratio.


Section E: Common Pitfalls

PitfallWhat happensPrevention
Use a public file-host URLExpires quickly and leaks dataUpload to Drive first or use .docx embed
Omit height in insert_imageAPI error: "height must be greater than 0"Always specify both width AND height
Call a function from the other MCP serverTool not found errorSection F lists each server's functions; auth-preflight reports which is installed
No local backupDoc only exists in Google's cloudUse .docx → Google Docs conversion
Complex doc via API callsIndex errors, image placement failuresUse .docx conversion instead
Too many empty paragraphsExcessive whitespace, unprofessionalMax 2 consecutive empty paragraphs
Stub headings with no bodyOrphaned headings confuse readersOnly insert headings that have content beneath

Section F: Quick Reference - Available MCP Functions

Two MCP servers appear in this repo. Use the one that is installed (auth-preflight reports it); do not mix a function from one with a document created on the other.

# google-workspace server — used by google-doc-creator and google-doc-reviewer
mcp__google-workspace__create_doc(title) → {"document_id": str}
mcp__google-workspace__insert_doc_elements(document_id, elements)      # text, headings, tables
mcp__google-workspace__insert_doc_image(document_id, image_url, index, width, height)
mcp__google-workspace__inspect_doc_structure(document_id, detailed=True) # indices for edits
mcp__google-workspace__batch_update_doc(document_id, requests)          # raw Docs API batch
mcp__google-workspace__update_paragraph_style(document_id, ...)
mcp__google-workspace__get_doc_as_markdown(document_id)

# google-docs server — simple text-only docs and Drive uploads
mcp__google-docs__create_document(title) → {"document_id": str}
mcp__google-docs__read_document(document_id) → str
mcp__google-docs__append_text(document_id, text) → status
mcp__google-docs__write_formatted_content(document_id, content_blocks) → status
mcp__google-docs__insert_image(document_id, image_url, width_pts, height_pts) → status
mcp__google-docs__upload_image_to_drive(file_path, file_name) → {"file_id": str, "url": str}
mcp__google-docs__upload_file_to_drive(file_path, convert_to_google_doc) → {"file_id": str, "url": str}

The .docx → Google Docs workflow (Section A) needs only upload_file_to_drive and is the recommended path for any document with tables or images.


Section G: Citation Pattern & Provenance Appendix

When creating analysis documents with findings, embed provenance data at three levels:

Level 1: Data Stamps (Always Present)

Every finding paragraph must include a data stamp inline, immediately after the finding title or key claim:

**Finding 1: Mobile converts at half the rate of desktop**
[50K rows | Jan-Mar 2026 | EVENTS | Confidence: B (82/100)]

Data stamps are built via helpers/provenance/provenance_assembler.py:

from helpers.provenance.provenance_assembler import build_data_stamp, render_data_stamp

stamp = build_data_stamp(
    row_count=50000,
    date_range="Jan-Mar 2026",
    primary_table="EVENTS",
    confidence_grade="B",
    confidence_score=82,
)
# stamp["one_liner"] = "[50K rows | Jan-Mar 2026 | EVENTS | Confidence: B (82/100)]"

In .docx via gdoc_builder.py, data stamps render as a small italic paragraph below each finding heading. In direct MCP mode, insert as body text with 9pt font and muted gray color.

Level 2: Citation Links + Provenance Appendix

For Tier 2+ analyses, add citation markers and a provenance appendix.

Two-pass approach:

Pass 1 — Build content:

  1. For each finding, insert a citation marker [F1] after the data stamp
  2. At the end of the document (before any existing Appendix), add:

    H2: Provenance Appendix
    
    H3: F1: Mobile converts at half the rate
    **Data:** [50K rows | Jan-Mar 2026 | EVENTS | Confidence: B (82/100)]
    **Methodology:** segmented comparison, COUNT by device
    **SQL:**
    ```sql
    SELECT device, COUNT(*) FROM events GROUP BY device

    Cross-verification: Type B: Parts-to-whole — Verified (PASS, diff 0.2%)

    H3: F2: ...

Pass 2 — Link citations (.docx workflow only): After building the .docx via gdoc_builder.py, the builder automatically creates:

  • Bookmark anchors on each H3 in the Provenance Appendix (named F1, F2, etc.)
  • Hyperlinks from [F1] markers in the body to the corresponding bookmark

For direct MCP mode, citation links are not possible (the API doesn't support internal bookmarks). Use the [F1] text markers without hyperlinks — the reader can scroll to the appendix.

Level 3: Full Receipt Link

For Tier 3 analyses, add a link to the analysis receipt at the bottom of the document:

H2: Analysis Receipt
Full audit trail with all queries, methodology, and reproducibility data:
→ outputs/analysis_receipt_{DATASET}_{DATE}.md

Building Provenance Blocks

All provenance data comes from helpers/provenance/provenance_assembler.py:

from helpers.provenance.provenance_assembler import build_provenance_blocks, render_provenance_appendix

blocks = build_provenance_blocks(
    findings=findings_list,          # from narrative parser
    confidence_result=confidence,    # from validation
    cross_verification=cv_data,      # from cross-verification YAML
    connection_type="snowflake",
    database="ANALYTICS",
)

# Render each block as markdown for the appendix
for block in blocks:
    appendix_md = render_provenance_appendix(block)

Checklist for Citation-Enabled Documents

  • Every finding has a data stamp (even without citation links)
  • Citation markers [F1], [F2] appear after each data stamp (Tier 2+)
  • Provenance Appendix section exists with one H3 per finding (Tier 2+)
  • Each appendix entry has: data stamp, methodology, SQL (if available), cross-verification (if available)
  • Bookmark links resolve correctly in .docx output (Tier 2+)
  • Receipt link present at document end (Tier 3 only)

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.