# Gmail connector

When a user connects their Gmail, your agent gets tools to list, search and read their messages, download attachments — and to DRAFT replies for the user to review and send. Read is separate from write, gated by distinct scopes.

## Overview

The Gmail connector lets your agent work with a user's own inbox. The user authorizes ONBF **once** with Google's Gmail scopes; ONBF vaults and refreshes the OAuth token and exposes the tools on the run's session token. You never register a Google app, request scopes or handle a callback — see **[Connectors](/docs/connectors)** for the zero-setup model.

> **Reads and drafts — never sends:** Gmail uses the `gmail.readonly` scope (list/search/read) and `gmail.compose` (create drafts). `gmail.compose` physically cannot send mail, so the connector can only prepare a draft in the user's Drafts folder — the user reviews and sends it themselves. Sending is intentionally not supported.

## Tools

These tools are exposed when the builder selects Gmail under Required connectors. Read calls require `connectors:use`; drafting also requires `connectors:write`. User connection status is checked when a tool runs.

| Tool | Access | What it does | Key arguments |
| --- | --- | --- | --- |
| `gmail_list_messages` | Read | List the user's most recent messages. Returns `id`, `threadId`, `from`, `to`, `subject`, `snippet` and `date`. | `maxResults` (optional), `pageToken` (optional). |
| `gmail_search_messages` | Read | Search with Gmail query syntax (`from:`, `subject:`, `has:attachment`, `newer_than:7d`, …). Returns matches newest-first. | `query`, `maxResults` (optional), `pageToken` (optional cursor). |
| `gmail_read_message` | Read | Read one message by id: parsed headers (from/to/cc/subject/date), the decoded plain-text body (truncated if large) and an attachment list (filename, mimeType, sizeBytes, attachmentId). | `messageId` — an id from list/search. |
| `gmail_download_attachment` | Read | Download one attachment so the agent can process it **locally** (PDF, image, spreadsheet, …). Returns a short-lived `downloadUrl` — NOT the bytes. | `messageId`, `attachmentId`; also pass returned `filename` and `mimeType` when available so the download keeps its real name and content type. |
| `gmail_create_draft` | Write | Create a DRAFT (never sends). Returns the `draftId`; the draft lands in the user's Drafts for them to review and send. | `to`, `subject`, `body`; `cc` (optional). |

## Attachments

Working with attachments is a two-step flow. `gmail_read_message` returns attachment **metadata** (filename, MIME type, size and an `attachmentId`) — not the bytes. To get the file, pass that `messageId` and `attachmentId` to `gmail_download_attachment`, which hands back a short-lived `downloadUrl` you fetch over HTTPS. The message body you get from `read_message` is the decoded `text/plain` part; HTML-only messages return an empty body with the snippet still available.

> **download_attachment returns a URL, not bytes:** File bytes never ride through an ONBF Tool call. `gmail_download_attachment` returns a short-lived, purpose-bound `downloadUrl`; fetch it with a plain HTTPS GET and no auth header. Pass `filename` and `mimeType` from `gmail_read_message` when available. The user's Google token stays server-side.

> **There's a size limit:** Attachment downloads are capped at 25 MB. Larger attachments return a clear error instead of a link, and the metadata's `sizeBytes` lets your agent check before it tries.

## Access & consent

- **Read vs write are separate** — reading requires `connectors:use`; drafting requires `connectors:write`. An agent granted read-only can never draft.
- **Never sends** — the `gmail.compose` scope can't send mail; the connector only creates drafts.
- **Per-user & revocable** — each user connects their own account and can disconnect it anytime from their ONBF dashboard under **Connectors**.
- **Allowlisted by the builder** — tools appear when Gmail is selected under Required connectors and the credential has the needed scope. If this user has not connected Gmail, calls return `{ connected: false, message }` — prompt them to connect, then retry.

> **Google verification:** `gmail.readonly` and `gmail.compose` are Google 'restricted' scopes. Test users work immediately; a public launch requires Google app verification for these scopes.
