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

# Google Drive

The io.b3os/google-drive pack: 5 actions with call snippets, fixture outputs, connection setup and error codes, generated from version 1.0.0.

`io.b3os/google-drive` 1.0.0 · `files`, `documents`, `productivity` · MIT

Find and read files in Google Drive with your own Google OAuth token: search with Drive's query language, get file metadata, export Google Docs, Sheets and Slides as plain text, Markdown or CSV, download text files, and create folders. Includes shared drives. Needs drive.readonly (or drive.file for files the app created, drive for create-folder).

Every call's result carries `upstream_status` and `timing`: `validate_ms`, `inject_ms`, `render_ms`, `upstream_ms`, `map_ms` and `total_ms`. `upstream` is the service's time; the others are B3OS's own ([call actions](/actions/call)). The snippets below show no timing values, because a fixture records none.

## Connection

`google`, type `oauth2`: Google account (Drive).

An OAuth access token for your Google account from your own Google Cloud OAuth client, with the scopes listed here. Store the refresh_token, client_id and client_secret with it so the vault can refresh the token (access tokens last an hour); B3OS never uses a Google client of its own.

How to get one: [developers.google.com](https://developers.google.com/identity/protocols/oauth2/web-server).

Scopes the pack's actions use: `https://www.googleapis.com/auth/drive.readonly`, `https://www.googleapis.com/auth/drive.file`. The manifest names them per connection, not per action.

The credential is sent only to `www.googleapis.com`.

Store the credential once as a [vault connection](/vault) for this pack and key, then name its id in a call's `connections`. Leave the key out and B3OS uses the project's newest connection for the pack and key without a `subject` ([connections](/actions/call#connections)).

Hosts it reaches: `www.googleapis.com`.

## Actions

| Action | Effect | MCP tool | Title |
|---|---|---|---|
| [`search-files`](/actions/catalog/google-drive#google-drive-search-files) | read | `google-drive__search-files` | Search files |
| [`get-file`](/actions/catalog/google-drive#google-drive-get-file) | read | `google-drive__get-file` | Get file metadata |
| [`export-document`](/actions/catalog/google-drive#google-drive-export-document) | read | `google-drive__export-document` | Export Google Doc, Sheet or Slides |
| [`download-text`](/actions/catalog/google-drive#google-drive-download-text) | read | `google-drive__download-text` | Download text file |
| [`create-folder`](/actions/catalog/google-drive#google-drive-create-folder) | write | `google-drive__create-folder` | Create folder |

search-files

**Search files.** Files and folders matching a Drive query, for example name contains 'roadmap' and mimeType = 'application/vnd.google-apps.document' and trashed = false, or 'FOLDER_ID' in parents. Sorted by last modified by default. Page with page_token.

Ref `io.b3os/google-drive/search-files@1.0.0` · effect `read` · connection `google` · MCP tool `google-drive__search-files`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/google-drive/search-files@1",
          "input": {
            "query": "name contains '\''roadmap'\'' and trashed = false",
            "page_size": 2
          },
          "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/google-drive/search-files@1",
      input: {
        query: "name contains 'roadmap' and trashed = false",
        page_size: 2,
      },
      connections: { google: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/google-drive/search-files@1",
        "input": {
            "query": "name contains 'roadmap' and trashed = false",
            "page_size": 2,
        },
        "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "google-drive__search-files",
        "arguments": {
          "query": "name contains 'roadmap' and trashed = false",
          "page_size": 2
        }
      }
    }
    ```

    Expose the pack as tools with `--packs google-drive` on the local server or `?packs=google-drive` on the remote URL, and the agent calls `google-drive__search-files` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Search files (documented response shape, example values). From the bundle's `fixtures/search-files.json`, not a live call.

```json
{
  "files": [
    {
      "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
      "name": "Q4 roadmap",
      "mime_type": "application/vnd.google-apps.document",
      "modified_time": "2026-10-25T21:30:00.000Z",
      "created_time": "2026-09-02T16:00:00.000Z",
      "size": null,
      "web_view_link": "https://docs.google.com/document/d/1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345/edit",
      "parents": ["0AFolderRootExample"],
      "owner": "Mona Example",
      "owner_email": "mona@acme.example",
      "trashed": false,
      "starred": false
    },
    {
      "id": "1zYxWvUtSrQpOnMlKjIhGfEdCbA987654",
      "name": "roadmap-2025.pdf",
      "mime_type": "application/pdf",
      "modified_time": "2026-10-25T21:30:00.000Z",
      "created_time": "2026-09-02T16:00:00.000Z",
      "size": "482113",
      "web_view_link": "https://drive.google.com/file/d/1zYxWvUtSrQpOnMlKjIhGfEdCbA987654/view",
      "parents": ["0AFolderRootExample"],
      "owner": "Mona Example",
      "owner_email": "mona@acme.example",
      "trashed": false,
      "starred": false
    }
  ],
  "next_page_token": "~!!~AI9FV7Q-example"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Google rejected the access token (expired or revoked); refresh or reconnect it. |
| `rate_limited` | 429, 403 | yes | built from the service's response |
| `forbidden` | 403 | no | built from the service's response |
| `invalid_request` | 400 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

get-file

**Get file metadata.** One file's name, type, size, owner, parents, timestamps and web link.

Ref `io.b3os/google-drive/get-file@1.0.0` · effect `read` · connection `google` · MCP tool `google-drive__get-file`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/google-drive/get-file@1",
          "input": {"id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"},
          "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/google-drive/get-file@1",
      input: { id: "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345" },
      connections: { google: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/google-drive/get-file@1",
        "input": {"id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"},
        "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "google-drive__get-file",
        "arguments": {"id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345"}
      }
    }
    ```

    Expose the pack as tools with `--packs google-drive` on the local server or `?packs=google-drive` on the remote URL, and the agent calls `google-drive__get-file` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Get file metadata (documented response shape, example values). From the bundle's `fixtures/get-file.json`, not a live call.

```json
{
  "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
  "name": "Q4 roadmap",
  "mime_type": "application/vnd.google-apps.document",
  "modified_time": "2026-10-25T21:30:00.000Z",
  "created_time": "2026-09-02T16:00:00.000Z",
  "size": null,
  "web_view_link": "https://docs.google.com/document/d/1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345/edit",
  "parents": ["0AFolderRootExample"],
  "owner": "Mona Example",
  "owner_email": "mona@acme.example",
  "trashed": false,
  "starred": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Google rejected the access token (expired or revoked); refresh or reconnect it. |
| `rate_limited` | 429, 403 | yes | built from the service's response |
| `forbidden` | 403 | no | built from the service's response |
| `invalid_request` | 400 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

export-document

**Export Google Doc, Sheet or Slides.** The contents of a Google Doc as plain text or Markdown, of a Sheet's first tab as CSV, or of Slides as plain text. Exports are limited to 10 MB by Google. For other text files use download-text.

Ref `io.b3os/google-drive/export-document@1.0.0` · effect `read` · connection `google` · MCP tool `google-drive__export-document`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/google-drive/export-document@1",
          "input": {
            "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
            "format": "text/markdown"
          },
          "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/google-drive/export-document@1",
      input: { id: "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345", format: "text/markdown" },
      connections: { google: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/google-drive/export-document@1",
        "input": {
            "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
            "format": "text/markdown",
        },
        "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "google-drive__export-document",
        "arguments": {
          "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
          "format": "text/markdown"
        }
      }
    }
    ```

    Expose the pack as tools with `--packs google-drive` on the local server or `?packs=google-drive` on the remote URL, and the agent calls `google-drive__export-document` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Export Google Doc, Sheet or Slides (documented response shape, example values). From the bundle's `fixtures/export-document.json`, not a live call.

```json
{
  "id": "1aBcDeFgHiJkLmNoPqRsTuVwXyZ012345",
  "format": "text/markdown",
  "content": "# Q4 roadmap\n\n## Goals\n\n- Ship checkout v2\n- Cut p50 checkout latency in half\n"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Google rejected the access token (expired or revoked); refresh or reconnect it. |
| `rate_limited` | 429, 403 | yes | built from the service's response |
| `forbidden` | 403 | no | built from the service's response |
| `invalid_request` | 400 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

download-text

**Download text file.** The contents of a regular file stored in Drive (txt, csv, md, json, ...) as text. Binary files come back garbled; Google Docs need export-document. Very large files can exceed the runtime's response size limit.

Ref `io.b3os/google-drive/download-text@1.0.0` · effect `read` · connection `google` · MCP tool `google-drive__download-text`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/google-drive/download-text@1",
          "input": {"id": "1zYxWvUtSrQpOnMlKjIhGfEdCbA987655"},
          "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/google-drive/download-text@1",
      input: { id: "1zYxWvUtSrQpOnMlKjIhGfEdCbA987655" },
      connections: { google: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    });
    console.log(result.output);
    ```
  **Python**

```python
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/google-drive/download-text@1",
        "input": {"id": "1zYxWvUtSrQpOnMlKjIhGfEdCbA987655"},
        "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    })
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "google-drive__download-text",
        "arguments": {"id": "1zYxWvUtSrQpOnMlKjIhGfEdCbA987655"}
      }
    }
    ```

    Expose the pack as tools with `--packs google-drive` on the local server or `?packs=google-drive` on the remote URL, and the agent calls `google-drive__download-text` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Download text file (documented response shape, example values). From the bundle's `fixtures/download-text.json`, not a live call.

```json
{
  "id": "1zYxWvUtSrQpOnMlKjIhGfEdCbA987655",
  "content": "company,stage,amount\nAcme,Proposal,12000\n"
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Google rejected the access token (expired or revoked); refresh or reconnect it. |
| `rate_limited` | 429, 403 | yes | built from the service's response |
| `forbidden` | 403 | no | built from the service's response |
| `invalid_request` | 400 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |

create-folder

**Create folder.** Create a folder, optionally inside another folder (parent_id). Returns its id and link. Not idempotent: Drive allows several folders with the same name.

Ref `io.b3os/google-drive/create-folder@1.0.0` · effect `write` · connection `google` · MCP tool `google-drive__create-folder`

**curl**

```bash
    curl -s https://beta-api.b3os.org/v1/actions/call \
      -H "Authorization: Bearer $B3OS_API_KEY" \
      -H "Idempotency-Key: 7c1e2f6a-1d43-4a8e-b2a5-3f0c9d5e8b11" \
      -H "Content-Type: application/json" \
      -d '{
          "ref": "io.b3os/google-drive/create-folder@1",
          "input": {"name": "Launch assets", "parent_id": "0AFolderRootExample"},
          "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"}
        }'
    ```
  **TypeScript**

```ts
    import { B3OS } from "@b3os/sdk";

    const b3os = new B3OS();
    const result = await b3os.actions.call({
      ref: "io.b3os/google-drive/create-folder@1",
      input: { name: "Launch assets", parent_id: "0AFolderRootExample" },
      connections: { google: "conn_01m5t6cbgdjs1ketgcqwa2sne8" },
    }, { idempotencyKey: crypto.randomUUID() });
    console.log(result.output);
    ```
  **Python**

```python
    import uuid
    from b3os import B3OS

    b3os = B3OS()
    result = b3os.actions.call({
        "ref": "io.b3os/google-drive/create-folder@1",
        "input": {"name": "Launch assets", "parent_id": "0AFolderRootExample"},
        "connections": {"google": "conn_01m5t6cbgdjs1ketgcqwa2sne8"},
    }, idempotency_key=str(uuid.uuid4()))
    print(result["output"])
    ```
  **MCP**

```json
    {
      "method": "tools/call",
      "params": {
        "name": "google-drive__create-folder",
        "arguments": {"name": "Launch assets", "parent_id": "0AFolderRootExample"}
      }
    }
    ```

    Expose the pack as tools with `--packs google-drive` on the local server or `?packs=google-drive` on the remote URL, and the agent calls `google-drive__create-folder` with the action's input. The tool uses your newest connection for each key without a `subject`. Without exposing the pack, `actions_call` takes the same input with `ref`.

Output, labeled `fixture`: Create folder (documented response shape, example values). From the bundle's `fixtures/create-folder.json`, not a live call.

```json
{
  "id": "1FoLdErIdExample0123456789",
  "name": "Launch assets",
  "mime_type": "application/vnd.google-apps.folder",
  "modified_time": "2026-10-25T21:30:00.000Z",
  "created_time": "2026-09-02T16:00:00.000Z",
  "size": null,
  "web_view_link": "https://drive.google.com/drive/folders/1FoLdErIdExample0123456789",
  "parents": ["0AFolderRootExample"],
  "owner": "Mona Example",
  "owner_email": "mona@acme.example",
  "trashed": false,
  "starred": false
}
```

When the service answers with an error, the call fails with [`upstream_error`](/errors#upstream_error) and `pack_error.code` is one of:

| `pack_error.code` | Service status | Retryable | Message |
|---|---|---|---|
| `not_found` | 404 | no | built from the service's response |
| `connection_unauthorized` | 401 | no | Google rejected the access token (expired or revoked); refresh or reconnect it. |
| `rate_limited` | 429, 403 | yes | built from the service's response |
| `forbidden` | 403 | no | built from the service's response |
| `invalid_request` | 400 | no | built from the service's response |
| `conflict` | 409 | no | built from the service's response |