---
name: gsk-gmail
version: 1.0.0
description: 'Gmail operations. Actions: search, read, send, draft, reply, forward,
  delete, archive, move, mark_as_read, add_label, remove_label, create_label, create_filter,
  list_filters, delete_filter, get_attachment, list_send_as, get_vacation, update_vacation,
  get_signature, update_signature.'
metadata:
  category: general
  requires:
    bins:
    - gsk
  cliHelp: gsk gmail --help
---

# gsk-gmail

**PREREQUISITE:** Read `../gsk-shared/SKILL.md` for auth, global flags, and security rules.

> **Note:** a unified `gsk connector` flow is rolling out (see `../gsk-connector/SKILL.md`: `gsk connector tools <id>` / `gsk connector call <id> -t <tool>`) and may not be enabled for every account yet. THIS command remains fully supported — use it directly, and it stays the fallback whenever `gsk connector` is unavailable.

Gmail operations. Actions: search, read, send, draft, reply, forward, delete, archive, move, mark_as_read, add_label, remove_label, create_label, create_filter, list_filters, delete_filter, get_attachment, list_send_as, get_vacation, update_vacation, get_signature, update_signature.

## Usage

```bash
gsk gmail [options]
```

## Flags

| Flag | Required | Description |
|------|----------|-------------|
| `<action>` (positional) | Yes | Action to perform. 'search': Search emails by query; 'read': Read a specific email by ID; 'send': Compose and send an email. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'draft': Save an email to the Drafts folder without sending; 'reply': Reply to an existing email. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'forward': Forward an email to new recipients. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'delete': Delete an email. Auto-approved: executes on the FIRST call — no [y/N] prompt and no pending_confirmation step. Do NOT re-run the command; a second call performs the operation again (e.g. sends a duplicate message).; 'archive': Archive one or more emails (pass message_ids to archive a whole set in one call); 'move': Move an email to a different label/folder. Auto-approved: executes on the FIRST call — no [y/N] prompt and no pending_confirmation step. Do NOT re-run the command; a second call performs the operation again (e.g. sends a duplicate message).; 'mark_as_read': Mark an email as read or unread; 'add_label': Add a label to an email; 'remove_label': Remove a label from an email; 'create_label': Create a new Gmail label; 'create_filter': Create a persistent Gmail filter. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'list_filters': List persistent Gmail filters; 'delete_filter': Delete a persistent Gmail filter. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'get_attachment': Download an email attachment; 'list_send_as': List available send-as aliases; 'get_vacation': Get the vacation (out-of-office) auto-reply settings; 'update_vacation': Enable, disable, or update the vacation (out-of-office) auto-reply. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes).; 'get_signature': Get the signature of a send-as address; 'update_signature': Set or clear the signature of a send-as address. Confirmation-gated: on a CLI with client-side confirmation the command runs as a single call after the [y/N] prompt (or --yes). (string, one of: search, read, send, draft, reply, forward, delete, archive, move, mark_as_read, add_label, remove_label, create_label, create_filter, list_filters, delete_filter, get_attachment, list_send_as, get_vacation, update_vacation, get_signature, update_signature) |
| `--query` | No | [search] Query to filter emails using Gmail search syntax. Examples: - Simple: 'meeting' - From Sender: 'from:boss@example.com' - Subject: 'subject:report' - In Folder: 'in:spam', 'in:inbox', 'in:trash', 'in:sent' - Label: 'label:important' - Unread: 'is:unread' - Unread in Spam: 'in:spam is:unread' - Has Attachment: 'has:attachment' - Date Range: 'after:2024/01/01 before:2024/01/31' - Newer Than: 'newer_than:7d' (7 days) - Older Than: 'older_than:1m' (1 month) Note: Some queries like 'is:recent' are invalid. (string) |
| `--after_date` | No | [search] Filter emails received after this date (inclusive). Format: YYYY/MM/DD (e.g., '2024/01/01'). This is equivalent to adding 'after:YYYY/MM/DD' to the query. (string) |
| `--before_date` | No | [search] Filter emails received before this date (exclusive). Format: YYYY/MM/DD (e.g., '2024/01/31'). This is equivalent to adding 'before:YYYY/MM/DD' to the query. (string) |
| `--next_page_token` | No | [search] Next page token to retrieve more emails (optional). (string) |
| `--auto_paginate` | No | [search] If true, automatically fetches multiple pages until reaching max_total_results (default: 500). Returns ALL emails matching the query. (boolean) |
| `--max_total_results` | No | [search] Maximum total results to fetch when auto_paginate is true. Default: 500, Maximum: 500. (integer) |
| `--from_account` | No | [search] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [read] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [send] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [draft] Sender email account to use. \| [reply] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [forward] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [delete] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [archive] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [move] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [mark_as_read] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [add_label] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [remove_label] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [create_label] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [create_filter] Optional email address of the Gmail account to use when multiple accounts are connected. Defaults to the primary connected account. \| [list_filters] Optional email address of the Gmail account to use when multiple accounts are connected. Defaults to the primary connected account. \| [delete_filter] Optional email address of the Gmail account to use when multiple accounts are connected. Defaults to the primary connected account. \| [get_attachment] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [list_send_as] Optional: Email address of the Gmail account to use. Use this when the user has multiple Gmail accounts connected. If not specified, uses the default Gmail account. \| [get_vacation] Optional: email address of the Gmail account to use when the user has multiple Gmail accounts connected. Defaults to the primary connected account. \| [update_vacation] Optional: email address of the Gmail account to use when the user has multiple Gmail accounts connected. Defaults to the primary connected account. \| [get_signature] Optional: email address of the Gmail account to use when the user has multiple Gmail accounts connected. Defaults to the primary connected account. \| [update_signature] Optional: email address of the Gmail account to use when the user has multiple Gmail accounts connected. Defaults to the primary connected account. (string) |
| `--id` | No | [read] The ID of a single Gmail message to retrieve. Mutually exclusive with 'thread_id'. (string) |
| `--thread_id` | No | [read] The Gmail thread (conversation) ID to retrieve. Returns every message in the thread. Mutually exclusive with 'id'. Each Gmail message exposes its parent thread via the 'threadId' field — the same value returned by 'gmail_search'. (string) |
| `--max_messages` | No | [read] Optional cap on how many messages to return when reading by 'thread_id'. Returns the most-recent N messages (chronological order preserved within the slice). Use this for long threads to keep the LLM context bounded — e.g. max_messages=5 for the tail of a long newsletter chain. Ignored when reading by single 'id'. (integer) |
| `--title` | No | [read] The title of the email to retrieve and read (string) |
| `--question` | No | [read] Question to answer guiding how to process the email content (string) |
| `--download_attachments` | No | [read] Whether need to download attachments from the email to analysis (boolean) |
| `--aidrive_path` | No | [read] Path in AIDrive where attachments should be saved. Default is /gmail_attachments/ \| [get_attachment] The path in AIDrive to save the attachment. Default: /gmail_attachments/ (string) |
| `--to` | No | [send] Optional: primary recipient email address(es). For multiple recipients, separate with commas. At least one address across to, cc, or bcc is required. \| [draft] Recipient email address(es), comma-separated. \| [forward] Optional: primary recipient email address(es). For multiple recipients, separate with commas. (string) |
| `--subject` | No | [send] Optional: The email subject line. Defaults to empty. \| [draft] Email subject line. (string) |
| `--body` | No | [send] The email body content. **IMPORTANT**: The format of this field MUST match the content_type parameter: - If content_type='text/plain': Use plain text - If content_type='text/html': Use HTML format with tags like <h1>, <p>, <ul>, <li>, etc. **Note**: Email clients DO NOT support Markdown rendering. If you have Markdown content and want formatted display, you must convert it to HTML and set content_type='text/html'. \| [draft] Email body content (plain text or HTML). \| [reply] The reply message body. **IMPORTANT**: The format of this field MUST match the content_type parameter: - If content_type='text/plain': Use plain text - If content_type='text/html': Use HTML format with tags like <h1>, <p>, <ul>, <li>, etc. **Note**: Email clients DO NOT support Markdown rendering. If you have Markdown content and want formatted display, you must convert it to HTML and set content_type='text/html'. \| [forward] Optional: Additional message to include above the forwarded content. This is your personal note to the recipients. (string) |
| `--cc` | No | [send] Optional: CC email address(es). For multiple recipients, separate with commas. \| [draft] CC recipient(s), comma-separated. \| [forward] Optional: CC email address(es). For multiple recipients, separate with commas. (string) |
| `--bcc` | No | [send] Optional: BCC email address(es). For multiple recipients, separate with commas. \| [draft] BCC recipient(s), comma-separated. \| [forward] Optional: BCC email address(es). For multiple recipients, separate with commas. (string) |
| `--content_type` | No | [send] Content type of the email body. Default: text/html (recommended) **CRITICAL**: This parameter defines the format of the 'body' field: - 'text/plain': body should be plain text only - 'text/html': body MUST be valid HTML (e.g., '<h1>Title</h1><p>Content</p>') **Common mistake**: Setting content_type='text/html' but providing Markdown text (# Title, **bold**). This will display raw Markdown symbols in the email. Always convert Markdown to HTML before passing to this tool. \| [reply] Content type of the reply body. Default: text/html (recommended) **CRITICAL**: This parameter defines the format of the 'body' field: - 'text/plain': body should be plain text only - 'text/html': body MUST be valid HTML (e.g., '<h1>Title</h1><p>Content</p>') **Common mistake**: Setting content_type='text/html' but providing Markdown text. This will display raw Markdown symbols. Always convert Markdown to HTML first. \| [forward] Content type of the body. Default: text/html (recommended) **CRITICAL**: This parameter defines the format of the 'body' field: - 'text/plain': body should be plain text only - 'text/html': body MUST be valid HTML (e.g., '<h1>Title</h1><p>Content</p>') **Common mistake**: Setting content_type='text/html' but providing Markdown text. This will display raw Markdown symbols. Always convert Markdown to HTML first. (string, one of: text/plain, text/html) |
| `--from_address` | No | [send] Send-as email address to use as the sender. Use this to send as a group/alias address (e.g., 'feedback@company.com'). Must be configured in Gmail's 'Send mail as' settings. \| [draft] Optional 'From:' identity to send AS — Gmail verified alias, Outlook proxyAddress / mail-enabled group, or a granted SendAs / on-behalf address. Must be an address the from-account is authorized to send as (see 'send_as' on /api/ai-inbox/mailbox/accounts). For Gmail this becomes the draft's MIME 'From:' header; for Outlook the saved draft stays as the from-account and the alias is applied by the eventual send call. \| [reply] Send-as email address to use as the sender. Use this to reply as a group/alias address (e.g., 'feedback@company.com'). Must be configured in Gmail's 'Send mail as' settings. \| [forward] Send-as email address to use as the sender. Use this to forward as a group/alias address. Must be configured in Gmail's 'Send mail as' settings. (string) |
| `--client_send_id` | No | [send] Optional stable idempotency key. When provided, stored in X-Genspark-Client-Send-Id and mirrored into a provider-safe Message-ID digest. Scheduled agent retries use it for internal deduplication. Usually auto-resolved from the active scheduled-action context — the LLM only needs to pass this when it wants to derive its own key (e.g. plan fan-out). (string) |
| `--force_resend` | No | [send] Set true only when the user explicitly wants another copy of an otherwise identical email. This bypasses the 10-minute interactive-send deduplication window. (boolean, default: `False`) |
| `--attachments` | No | [send] Optional file attachments. Each item is either a local file path (read inline by the gsk CLI — the bytes ride in the request body as base64 and are not persisted to blob storage) or an already-hosted URL (file-wrapper URL or other public https). Files are delivered as real email attachments (not links): inline base64 for items ≤3 MB, Microsoft Graph upload session for larger Outlook attachments. CLI alias: --attach / --attachment (repeatable). CLI inline cap: 5 MiB per local file — larger files must be uploaded via 'gsk upload' first and passed as a URL. Per-message raw-payload cap: 18 MiB for Gmail (Gmail's 25 MB send cap is on the base64-encoded RFC 822 message; 18 MiB raw leaves headroom for ~33% encoding overhead) and 150 MB for Outlook (via Graph upload session). \| [draft] Optional file attachments. Each item is either a local file path (read inline by the gsk CLI — the bytes ride in the request body as base64 and are not persisted to blob storage) or an already-hosted URL (file-wrapper URL or other public https). Files are delivered as real email attachments (not links): inline base64 for items ≤3 MB, Microsoft Graph upload session for larger Outlook attachments. CLI alias: --attach / --attachment (repeatable). CLI inline cap: 5 MiB per local file — larger files must be uploaded via 'gsk upload' first and passed as a URL. Per-message raw-payload cap: 18 MiB for Gmail (Gmail's 25 MB send cap is on the base64-encoded RFC 822 message; 18 MiB raw leaves headroom for ~33% encoding overhead) and 150 MB for Outlook (via Graph upload session). \| [reply] Optional file attachments. Each item is either a local file path (read inline by the gsk CLI — the bytes ride in the request body as base64 and are not persisted to blob storage) or an already-hosted URL (file-wrapper URL or other public https). Files are delivered as real email attachments (not links): inline base64 for items ≤3 MB, Microsoft Graph upload session for larger Outlook attachments. CLI alias: --attach / --attachment (repeatable). CLI inline cap: 5 MiB per local file — larger files must be uploaded via 'gsk upload' first and passed as a URL. Per-message raw-payload cap: 18 MiB for Gmail (Gmail's 25 MB send cap is on the base64-encoded RFC 822 message; 18 MiB raw leaves headroom for ~33% encoding overhead) and 150 MB for Outlook (via Graph upload session). \| [forward] Optional file attachments. Each item is either a local file path (read inline by the gsk CLI — the bytes ride in the request body as base64 and are not persisted to blob storage) or an already-hosted URL (file-wrapper URL or other public https). Files are delivered as real email attachments (not links): inline base64 for items ≤3 MB, Microsoft Graph upload session for larger Outlook attachments. CLI alias: --attach / --attachment (repeatable). CLI inline cap: 5 MiB per local file — larger files must be uploaded via 'gsk upload' first and passed as a URL. Per-message raw-payload cap: 18 MiB for Gmail (Gmail's 25 MB send cap is on the base64-encoded RFC 822 message; 18 MiB raw leaves headroom for ~33% encoding overhead) and 150 MB for Outlook (via Graph upload session). (array) |
| `--body_type` | No | [draft] Body format: 'html' (default) or 'text'. (string) |
| `--prompt` | No | [draft] Optional instruction describing the email to write, in the sender's own voice using their Email Brain (persona plus their handling and writing rules) — e.g. 'ask Ana to move the review to Friday, apologize for the short notice'. Use INSTEAD of 'body' to have the body written for you, or TOGETHER WITH 'body' to revise that text per the instruction (everything the instruction does not ask to change is preserved). Recipients and attachments are never inferred from the instruction — pass them explicitly. Omit to commit 'body' exactly as given. (string) |
| `--message_id` | No | [reply] The Gmail message ID to reply to \| [forward] The Gmail message ID to forward \| [delete] The Gmail message ID to delete \| [archive] (Deprecated, use message_ids) A single Gmail message ID to archive \| [move] The Gmail message ID to move \| [mark_as_read] (Deprecated, use message_ids) A single Gmail message ID to mark \| [add_label] The Gmail message ID to add label to \| [remove_label] The Gmail message ID to remove label from \| [get_attachment] The Gmail message ID containing the attachment (string) |
| `--reply_all` | No | [reply] Whether to reply to all recipients (TO and CC). Default: true (reply to all recipients including CC) (boolean) |
| `--include_original` | No | [reply] Whether to append the original message as a Gmail-style quoted block under the reply body so the recipient sees the thread context standard mail clients attach automatically. Default: true. Set to false only when the caller already embedded their own quoted block in `body` (the helper detects the canonical `gmail_quote_container` markup and short-circuits anyway, but this flag lets the caller opt out unconditionally — useful for terse one-line replies where the quote is noise). \| [forward] Whether to append the original message as a Gmail-style '---------- Forwarded message ----------' quoted block under the forwarder's note so the recipient sees the original verbatim — same shape as native Gmail forwards. Default: true. Set to false only when the caller already embedded their own forwarded block in `body` (e.g. the `.genmail` editor send path). (boolean, default: `True`) |
| `--include_attachments` | No | [forward] Whether to include original email attachments in the forward. Default: true (boolean, default: `True`) |
| `--message_ids` | No | [archive] The Gmail message ID(s) to archive. Can be a single ID string or an array of IDs. \| [mark_as_read] The Gmail message ID(s) to mark. Can be a single ID string or an array of IDs. |
| `--label_name` | No | [move] The target label name. Use '/' for nested labels (e.g., 'Work/Projects'). The label will be created if it doesn't exist. \| [add_label] The label name to add. Can be a new label or an existing one. \| [remove_label] The label name to remove \| [create_label] The name of the label to create. Use '/' for nested labels (e.g., 'Parent/Child'). (string) |
| `--remove_from_inbox` | No | [move] Whether to remove the email from INBOX. Default: true (standard 'move' behavior). Set to false to just add the label without removing from inbox. (boolean) |
| `--create_if_not_exists` | No | [move] Whether to create the label if it doesn't exist. Default: true (boolean) |
| `--is_read` | No | [mark_as_read] Set to true to mark as read, false to mark as unread. Default: true (boolean) |
| `--label_list_visibility` | No | [create_label] The visibility of the label in the label list. Default: labelShow (string, one of: labelShow, labelShowIfUnread, labelHide) |
| `--message_list_visibility` | No | [create_label] The visibility of messages with this label. Default: show (string, one of: show, hide) |
| `--background_color` | No | [create_label] The background color of the label in hex format (e.g., '#16a765'). Optional. (string) |
| `--text_color` | No | [create_label] The text color of the label in hex format (e.g., '#ffffff'). Optional. (string) |
| `--criteria` | No | [create_filter] Gmail filter criteria, such as from, to, subject, query, negatedQuery, hasAttachment, excludeChats, size, and sizeComparison. (object) |
| `--filter_action` | No | [create_filter] Gmail filter action containing addLabelIds, removeLabelIds, and/or forward. (object) |
| `--filter_id` | No | [delete_filter] ID of the Gmail filter to delete. (string) |
| `--filename` | No | [get_attachment] The filename of the attachment to retrieve. Use '*' to get all attachments. (string) |
| `--save_to_aidrive` | No | [get_attachment] Whether to save the attachment to AIDrive. Default: true (boolean) |
| `--enable_auto_reply` | No | [update_vacation] Turn the vacation auto-reply on (true) or off (false). (boolean) |
| `--response_subject` | No | [update_vacation] Subject line of the auto-reply. (string) |
| `--response_body_plain` | No | [update_vacation] Plain-text auto-reply body. Provide this or response_body_html when enabling. (string) |
| `--response_body_html` | No | [update_vacation] HTML auto-reply body (takes precedence over the plain-text body in Gmail). (string) |
| `--restrict_to_contacts` | No | [update_vacation] Only auto-reply to people in the user's contacts. (boolean) |
| `--restrict_to_domain` | No | [update_vacation] Only auto-reply to people in the user's domain (Workspace accounts). (boolean) |
| `--start_time` | No | [update_vacation] When the auto-reply starts: ISO 8601 (e.g. '2026-08-01T00:00:00Z') or epoch milliseconds. Pass an empty string to clear the window. (string) |
| `--end_time` | No | [update_vacation] When the auto-reply ends: ISO 8601 or epoch milliseconds. Pass an empty string to clear the window. (string) |
| `--send_as_email` | No | [get_signature] Send-as address whose signature to read. Defaults to the primary address. \| [update_signature] Send-as address whose signature to set. Defaults to the primary address. (string) |
| `--signature` | No | [update_signature] New signature as HTML (plain text works too). An empty string removes the signature. (string) |

## Write Confirmation

Confirmation-gated actions: `send`, `reply`, `forward`, `create_filter`, `delete_filter`, `update_vacation`, `update_signature`. The CLI shows a preview and asks `[y/N]` on stderr before the single server call; pass `--yes` (`-y`) for unattended runs. `--no-input` (or `--args-file -`, which consumes stdin) makes a gated call exit 2 with no server call instead of hanging. Never re-run a command to 'confirm' it — every call is a real execution. `--skip_confirmation true` / `--auto_skip_confirmation` are deprecated on this CLI (still accepted, warn on stderr): use `--yes`.

Interactive-only actions: `create_filter`, `delete_filter`, `update_vacation`, `update_signature` (the action excludes the skip params, e.g. Marketplace policy on Slack) — `--yes` is ignored and a real `[y/N]` answer is required.

Auto-approved actions: `delete`, `move` — the server skips the confirmation gate, so the operation executes on the FIRST call with no `[y/N]` prompt and no confirmation step. Do NOT re-run the command expecting a confirmation arc: a second call performs the operation again (e.g. sends a duplicate message).

## See Also

- [gsk-shared](../gsk-shared/SKILL.md) — Authentication and global flags
