gws-docs is a thin reusable layer on top of gws for AI agents that need to create formatted Google Docs and place them in Google Drive predictably.
If you have zero context, follow these rules exactly:
- Do not handcraft raw Google Docs API indexes or raw
gws docs batchUpdaterequests unless you are explicitly modifying this tool itself. - Write document content as a JSON spec.
- Pass the destination folder at runtime with
--folder-idor--folder-nameunless the task is a fixed automation. - Run
gws-docs render <spec.json> .... - Return the resulting
documentId,folderId, andtitle.
If gws-docs is available, prefer it over custom one-off Docs rendering logic.
This tool takes a simple structured JSON spec and does the low-level work for you:
- Creates a Google Doc through
gws - Inserts the content
- Applies consistent formatting
- Resolves or creates the destination Drive folder
- Moves the Doc into that folder
- It does not authenticate Google Workspace for you
- It does not store or ship credentials
- It does not infer missing required content
- It does not support every possible Google Docs layout yet
If you need unsupported formatting, extend the schema and renderer instead of bypassing the tool silently.
gwsmust already be installed on the local machinegwsmust already be authenticated locally, for example withgws auth login- Google credentials stay local to the machine
- This package does not contain OAuth client secrets, access tokens, or refresh tokens
If the binary is installed globally:
gws-docs render ./spec.json --folder-name "My Documents"If you are running from a cloned repo:
node ./cli.mjs render ./spec.json --folder-name "My Documents"Use a stable Drive folder ID when you already know it:
gws-docs render ./spec.json --folder-id "<DRIVE_FOLDER_ID>"gws-docs render <spec.json> [--folder-id <id>] [--folder-name <name>] [--parent-id <id>]Rules:
- Pass
--folder-idor--folder-name, not both - If both the spec and CLI provide a destination, CLI wins
--parent-idonly matters when the tool needs to create a folder by name- If no destination exists in either the spec or CLI, rendering fails
When you need to create a document, do this:
- Read this README once
- Inspect
examples/ai-workflow-spec.json - Write a new JSON spec
- Prefer runtime destination flags instead of hardcoding Drive-specific values into the spec
- Render the doc
- Return the JSON result from stdout
Successful runs print JSON like this:
{
"documentId": "1abc...",
"folderId": "1def...",
"title": "Project Brief",
"destination": "My Documents"
}Return those values to the user or calling agent.
- Title
- Optional subtitle
- Section headings using
HEADING_1toHEADING_6 - Paragraph blocks
- Bulleted lists
- Numbered lists
- Key/value reference blocks with bold labels
- Destination folder by Drive folder ID
- Destination folder by folder name with auto-create
Top-level fields:
titlerequired stringsubtitleoptional stringdestinationoptional object if the destination will be passed at runtimesectionsrequired non-empty array
Section fields:
headingrequired stringleveloptional integer from1to6blocksrequired non-empty array
Supported block types:
paragraphbullet_listnumbered_listkey_value
{
"title": "Document title",
"sections": [
{
"heading": "Summary",
"level": 1,
"blocks": [
{
"type": "paragraph",
"text": "Write the summary here."
}
]
}
]
}{
"title": "Document title",
"subtitle": "Optional subtitle",
"destination": {
"folderName": "My Documents"
},
"sections": [
{
"heading": "Executive Summary",
"level": 1,
"blocks": [
{
"type": "paragraph",
"text": "Write normal text here."
},
{
"type": "bullet_list",
"items": ["One", "Two"]
},
{
"type": "numbered_list",
"items": ["Step one", "Step two"]
},
{
"type": "key_value",
"items": [
{ "label": "Owner", "value": "AI agent" }
]
}
]
}
]
}Preferred order:
- Use
--folder-idwhen the caller already knows the exact Drive folder - Use
--folder-namewhen the tool should find or create the folder - Put
destinationinside the spec only for fixed workflows or automations
This keeps specs reusable across users, repos, and environments.
A run will fail if:
gwsis not installedgwsis not authenticated- the spec JSON is invalid
- the spec is missing required fields
- no destination is provided
- both
--folder-idand--folder-nameare provided
When it fails, fix the input or environment. Do not fall back to raw Docs API logic unless you are intentionally extending gws-docs.
Render using a folder name:
gws-docs render ./examples/ai-workflow-spec.json --folder-name "Agent Output"Render using a folder ID:
gws-docs render ./examples/ai-workflow-spec.json --folder-id "1abc123..."Render from this repo directly:
node ./cli.mjs render ./examples/ai-workflow-spec.json --folder-name "Agent Output"Use this exact instruction pattern:
Use `gws-docs` to create the Google Doc. Do not handcraft raw Google Docs API requests.
Steps:
1. Read the gws-docs README.
2. Create a JSON spec for the requested document.
3. Pass the destination at runtime with --folder-id or --folder-name.
4. Run gws-docs render.
5. Return documentId, folderId, title, and the spec file path.
This tool exists to separate:
- content generation
- formatting/rendering
- Drive placement
That separation is the main value. It makes agent behavior more reliable, more reusable, and easier to improve later.
The intended deployment model is:
gws-docscode is shared publicly as a normal package or GitHub repo- each machine keeps its own local
gwscredentials - agents call the installed
gws-docsbinary - Drive destination is passed at runtime
That gives you a shared renderer without sharing tokens or hardcoding machine-specific paths.