> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Google Docs

> Mount Google Docs as JSON-backed files so Python agents can read document structure and content through Mirage.

The Google Docs resource exposes Docs documents as a virtual filesystem
mounted at some prefix such as `/gdocs/`.

For Google OAuth setup, see [Google Workspace Setup](/python/setup/google).

## Config

```python theme={null}
import os

from mirage import MountMode, Workspace
from mirage.resource.gdocs import GDocsConfig, GDocsResource

config = GDocsConfig(
    client_id=os.environ["GOOGLE_CLIENT_ID"],
    client_secret=os.environ["GOOGLE_CLIENT_SECRET"],
    refresh_token=os.environ["GOOGLE_REFRESH_TOKEN"],
)
resource = GDocsResource(config=config)
ws = Workspace({"/gdocs": resource}, mode=MountMode.READ)
```

## Filesystem Layout

```text theme={null}
/gdocs/
  owned/
    <YYYY-MM-DD>_<sanitized-title>__<doc-id>.gdoc.json
    ...
  shared/
    <YYYY-MM-DD>_<sanitized-title>__<doc-id>.gdoc.json
    ...
```

Example:

```text theme={null}
/gdocs/
  owned/
    2026-04-04_Project_Plan__1AbCdEf.gdoc.json
    2026-04-10_Meeting_Notes__2BcDeFg.gdoc.json
  shared/
    2026-04-03_Design_Notes__9XyZ.gdoc.json
```

Documents are split into `owned` (documents you created) and `shared`
(documents shared with you). The filename shape is:

```text theme={null}
<YYYY-MM-DD>_<sanitized-title>__<document-id>.gdoc.json
```

If the modified date is unavailable, the date prefix is omitted.
Reading a document file returns the full Google Docs API JSON for
that document.

## Cache

The Google Docs resource uses `IndexCacheStore`. Index entries store
document IDs and metadata. There is no separate content cache -- file
content caching is handled by the workspace `IOResult` mechanism.

## Example

```python theme={null}
import asyncio
import os

from dotenv import load_dotenv

from mirage import MountMode, Workspace
from mirage.resource.gdocs import GDocsConfig, GDocsResource

load_dotenv(".env.development")

config = GDocsConfig(
    client_id=os.environ["GOOGLE_CLIENT_ID"],
    client_secret=os.environ["GOOGLE_CLIENT_SECRET"],
    refresh_token=os.environ["GOOGLE_REFRESH_TOKEN"],
)
resource = GDocsResource(config=config)


async def main():
    ws = Workspace({"/gdocs": resource}, mode=MountMode.READ)

    # List structure
    r = await ws.execute("ls /gdocs/")
    print(await r.stdout_str())

    # List owned documents
    r = await ws.execute("ls /gdocs/owned/")
    print(await r.stdout_str())

    # Read a document
    r = await ws.execute(
        "cat /gdocs/owned/2026-04-04_Project_Plan__1AbCdEf.gdoc.json")
    print(await r.stdout_str())

    # Extract title with jq
    r = await ws.execute(
        'jq ".title"'
        " /gdocs/owned/2026-04-04_Project_Plan__1AbCdEf.gdoc.json")
    print(await r.stdout_str())

    # Search across all documents
    r = await ws.execute('rg "quarterly" /gdocs/owned/')
    print(await r.stdout_str())

    # Tree view
    r = await ws.execute("tree -L 1 /gdocs/")
    print(await r.stdout_str())

    # Create a new document
    r = await ws.execute(
        'gws-docs-documents-create --json \'{"title":"MIRAGE Example Doc"}\'')
    print(await r.stdout_str())

    # Append text to a document
    r = await ws.execute(
        'gws-docs-write --document 1AbCdEf --text "Appended via MIRAGE."')
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

See `examples/gdocs/gdocs.py` for the full working example.

## Shell Commands

Standard commands available on the mounted Google Docs tree:

| Command                             | Notes                       |
| ----------------------------------- | --------------------------- |
| `ls`                                | List owned/shared documents |
| `cat`                               | Read document JSON          |
| `head` / `tail`                     | First/last N lines          |
| `grep` / `rg`                       | Pattern search              |
| `jq`                                | Query JSON fields           |
| `wc`                                | Line/word/byte counts       |
| `stat`                              | File metadata               |
| `find`                              | Recursive search            |
| `tree`                              | Directory tree view         |
| `basename` / `dirname` / `realpath` | Path utilities              |
| `nl`                                | Number lines                |

Resource-specific commands:

### `gws-docs-documents-create`

Create a new Google Docs document.

```bash theme={null}
gws-docs-documents-create --json '{"title":"MIRAGE Example Doc"}'
```

| Option   | Required | Description                  |
| -------- | -------- | ---------------------------- |
| `--json` | yes      | JSON body with `title` field |

Returns the created document JSON.

### `gws-docs-documents-batchUpdate`

Batch update a document.

```bash theme={null}
gws-docs-documents-batchUpdate --params '{"documentId":"1AbCdEf"}' --json '{"requests":[]}'
```

| Option     | Required | Description                |
| ---------- | -------- | -------------------------- |
| `--params` | yes      | JSON with `documentId`     |
| `--json`   | yes      | JSON with `requests` array |

Returns the batch update response JSON.

### `gws-docs-write`

Append text to a document.

```bash theme={null}
gws-docs-write --document 1AbCdEf --text "Appended via MIRAGE."
```

| Option       | Required | Description        |
| ------------ | -------- | ------------------ |
| `--document` | yes      | Google document ID |
| `--text`     | yes      | Text to append     |

Returns the update response JSON.
