mail
cmdhub adapter

Gmail CLI
for cmdhub.

Messages, threads, drafts, labels, and attachments with command-level schema.

lock Auth: OAuth2
Quick Install cmdhub get gmail

data_object Agent Contract

Agents should start with auth/status and discovery commands, inspect schemas before composition, and treat commands marked as mutating as state-changing operations.

Output

Use human output for normal reads, `--json` for scripting or complete structured fields, and `--jsonl` for upstream pipe inputs.

Auth

Google OAuth. Used for Gmail messages, threads, drafts, labels, and attachments.

Refs

Prefer list/search, then short refs or piped JSONL. Use `resolve` to inspect cached refs.

Schemas

Use `gmail schema` and `catalog.json` to inspect fields, flags, examples, and side effects.

Auth scopes

openidemailhttps://www.googleapis.com/auth/gmail.modify

terminal Command Reference

Generated from source. Global flags apply to all commands.

Global Flags

--json bool Emit JSON machine output
--jsonl bool Emit JSONL records for piping
--output, -o string Compatibility output mode: json|jsonl. Prefer --json or --jsonl
--view string = summary View mode: summary|full
--profile string = default Config/auth profile
--config string Config path override
--quiet, -q bool Suppress non-essential diagnostics
--debug bool Enable debug diagnostics
--limit int = 50 Maximum items to emit
--page-size int = 50 Requested upstream page size
--cursor string Continuation cursor
--no-paginate bool Fetch only one page
--version, -v bool Print version information
gmail attachment Work with Gmail attachments
#cmd-gmail-attachment discovery safe
$ gmail attachment --help
gmail attachment get Download a Gmail attachment
#cmd-gmail-attachment-get discovery safe

Download one Gmail attachment to a local file or emit its contents.

Pass –message-id and –attachment-id directly, or pipe one full message item that contains exactly one attachment. If the message contains multiple attachments, pass –attachment-id explicitly. With –message-id, a local attachment ref such as a1 is resolved within that message if it is not already cached. Use –emit-content to include a UTF-8 text preview and base64 payload in the command output for agent-visible verification.

--attachment-id string Gmail attachment id
--emit-content bool Include text/base64 content in the response
--message-id string Gmail message id
--output-file string Path to save the attachment
$ gmail attachment get
$ gmail attachment get --message-id m1 --attachment-id a1 --emit-content --json
$ gmail attachment get --message-id m1 --attachment-id a1 --output-file ./invoice.pdf
$ gmail message get m1
$ gmail message list --query 'has:attachment' --limit 1 --jsonl | gmail message get
gmail attachment list List attachments for a message
#cmd-gmail-attachment-list discovery safe

List Gmail message attachments without downloading payload bytes.

Pass a message local ref such as m1 or a canonical Gmail message id.

--message string Message ref or id
$ gmail attachment list
$ gmail attachment list --message m1
$ gmail message list --query 'has:attachment' --limit 1 --jsonl | gmail message get
gmail auth Manage Gmail authentication
#cmd-gmail-auth discovery safe
$ gmail auth --help
gmail auth login Start Gmail OAuth login
#cmd-gmail-auth-login mutates state
--delegate string Workspace user email to impersonate
--key-file string Google service account JSON key file
--service-account bool Use Google Workspace service-account domain-wide delegation
$ gmail --profile work auth login
$ gmail auth login
$ gmail auth login --help
$ gmail auth login --service-account --delegate user@example.com --key-file service-account.json
gmail auth logout Clear auth state
#cmd-gmail-auth-logout mutates state
$ gmail --profile work auth logout
$ gmail auth logout
$ gmail auth logout --help
gmail auth refresh Refresh stored token
#cmd-gmail-auth-refresh mutates state
$ gmail auth refresh
$ gmail auth refresh --help
$ gmail auth refresh --json
gmail auth status Show auth status
#cmd-gmail-auth-status discovery safe
$ gmail auth status
$ gmail auth status --help
$ gmail auth status --json
gmail auth whoami Return the authenticated Gmail address
#cmd-gmail-auth-whoami discovery safe
$ gmail auth whoami
$ gmail auth whoami --help
$ gmail auth whoami --json
gmail capabilities Describe capabilities
#cmd-gmail-capabilities discovery safe
--section string Show one capability section: scopes, schemas, or commands
$ gmail capabilities --help
gmail config Inspect local configuration
#cmd-gmail-config discovery safe
$ gmail config --help
gmail config explain Explain resolved configuration
#cmd-gmail-config-explain discovery safe
$ gmail config explain --help
gmail doctor Run Gmail adapter diagnostics
#cmd-gmail-doctor discovery safe
$ gmail doctor
$ gmail doctor --help
$ gmail doctor --json
gmail draft Work with Gmail drafts
#cmd-gmail-draft discovery safe
$ gmail draft --help
gmail draft create Create a Gmail draft
#cmd-gmail-draft-create mutates state

Create a new Gmail draft.

Pass recipients with –to, then provide –subject and –body. Use repeated –attach flags to include local files.

--attach stringSlice = [] File path(s) to attach
--bcc string Comma-separated bcc recipients
--body string Plain text body
--body-file string Read plain text body from file
--cc string Comma-separated cc recipients
--html-body string HTML body
--html-body-file string Read HTML body from file
--subject string Message subject
--to string Comma-separated recipients
$ gmail draft create --help
$ gmail draft create --to alice@example.com --subject 'Status' --body 'Draft text'
$ gmail draft create --to alice@example.com,bob@example.com --subject 'Agenda' --body 'Attached.' --attach ./agenda.pdf
gmail draft delete Delete a draft
#cmd-gmail-draft-delete mutates state dry-run

Delete one Gmail draft.

The target may be a canonical draft id, a short ref such as d1, or one piped draft item. Draft deletion is immediate and permanent, so –yes is required. Use –dry-run to preview the selected draft without deleting it.

--dry-run bool Preview selected draft without deleting it
--id string Draft id
--yes bool Confirm permanent draft deletion
$ gmail draft delete --help
$ gmail draft delete d1 --dry-run
$ gmail draft delete d1 --yes
$ gmail draft list --limit 1 --jsonl | gmail draft delete --yes
gmail draft get Get a draft
#cmd-gmail-draft-get discovery safe

Get one Gmail draft.

The target may be a canonical draft id, a short ref such as d1, a shortened canonical id, or one piped draft item.

--id string Draft id
$ gmail draft get
$ gmail draft get d1
$ gmail draft list --limit 1 --jsonl | gmail draft get
gmail draft list List drafts
#cmd-gmail-draft-list discovery safe

List Gmail drafts and cache local draft references such as d1.

Use –query with Gmail search syntax to narrow drafts by subject, recipient, or tokens. Use –jsonl when the next step is another draft command such as get, send, or delete.

--query string Raw Gmail search query for drafts
$ gmail draft list
$ gmail draft list --limit 1 --jsonl | gmail draft get
$ gmail draft list --limit 1 --jsonl | gmail draft send
$ gmail draft list --limit 10
$ gmail draft list --limit 20 --json
$ gmail draft list --query 'subject:"Quarterly review"' --limit 1 --jsonl | gmail draft get
gmail draft send Send a draft
#cmd-gmail-draft-send mutates state

Send one Gmail draft.

The target may be a canonical draft id, a short ref such as d1, or one piped draft item from stdin.

--id string Draft id
$ gmail draft list --limit 1 --jsonl | gmail draft send
$ gmail draft send --help
$ gmail draft send d1
gmail draft update Update a draft
#cmd-gmail-draft-update mutates state

Update one Gmail draft.

The target may be a canonical draft id, a short ref such as d1, or one piped draft item. Omitted fields are preserved from the current draft.

--attach stringSlice = [] File path(s) to attach
--bcc string Comma-separated bcc recipients
--body string Plain text body
--body-file string Read plain text body from file
--cc string Comma-separated cc recipients
--html-body string HTML body
--html-body-file string Read HTML body from file
--id string Draft id
--subject string Message subject
--to string Comma-separated recipients
$ gmail draft list --limit 1 --jsonl | gmail draft update --subject 'Status'
$ gmail draft update --help
$ gmail draft update d1 --body 'Updated text'
$ gmail draft update d1 --subject 'Status' --body 'Updated text'
gmail history Inspect Gmail mailbox history
#cmd-gmail-history discovery safe
$ gmail history --help
gmail history list List Gmail history records from a known historyId
#cmd-gmail-history-list discovery safe
--history-type stringSlice = [] History type filter; repeat or comma-separate
--start-history-id string Gmail historyId from message/thread metadata
$ gmail history list
$ gmail history list --start-history-id 123456 --history-type messageAdded
gmail label Work with Gmail labels
#cmd-gmail-label mutates state

List Gmail labels and cache local label refs such as l1.

Use this before label add or label remove if you need to inspect available labels for the current mailbox.

$ gmail label --help
gmail label create Create a user Gmail label
#cmd-gmail-label-create mutates state
--name string New user label name
$ gmail label create --help
$ gmail label create --name cmdhub-demo
gmail label delete Delete a user Gmail label
#cmd-gmail-label-delete mutates state dry-run

Delete a user Gmail label.

The command resolves the label first so system labels are protected. Use –dry-run to preview the exact label and message/thread counts before deleting.

--dry-run bool Preview the label deletion without deleting it
--id string Gmail label id, name, or local ref
--yes bool Confirm destructive label deletion
$ gmail label delete --help
$ gmail label delete l1 --dry-run
$ gmail label delete l1 --yes
gmail label get Get a Gmail label
#cmd-gmail-label-get discovery safe
--id string Gmail label id, name, or local ref
$ gmail label get
$ gmail label get INBOX
$ gmail label get l1
gmail label list List Gmail labels
#cmd-gmail-label-list discovery safe
List Gmail labels for the active profile and cache local refs such as l1.
--query string Filter labels locally by name or id
$ gmail label list
$ gmail label list --json
$ gmail label search --query cmdhub
gmail label update Rename a user Gmail label
#cmd-gmail-label-update mutates state
--id string Gmail label id, name, or local ref
--name string Updated user label name
$ gmail label update --help
$ gmail label update l1 --name cmdhub-demo-done
gmail mcp Run the MCP server
#cmd-gmail-mcp discovery safe

Run a stdio Model Context Protocol server for this adapter.

The server exposes read-only resource commands by default. Mutating commands are listed only when explicitly allowed with –allow and remain gated by the command contract safety class.

--allow stringArray = [] Allow mutating command keys such as gmail.message.archive or gmail.message.label.*
--allow-dangerous bool Allow --allow wildcards to include destructive or sends_external commands
--concurrency int Maximum concurrent MCP subprocesses
--max-output int64 = 0 Maximum stdout/stderr bytes captured per MCP command
--print-config bool Print MCP tool configuration and exit
--timeout duration = 0s Per-command MCP subprocess timeout, for example 45s or 2m
$ mcp
$ mcp --print-config
gmail message Work with Gmail messages
#cmd-gmail-message discovery safe

Work with Gmail messages.

Use explicit subcommands such as list, get, reply, or archive. As a convenience, gmail message <message-id> is treated as gmail message get <message-id>.

$ gmail message list --query 'subject:"Quarterly review"' --limit 1 --jsonl
$ gmail message get m1
$ gmail message 19d8712e0a4159b7 --jsonl
gmail message archive Archive a message by removing INBOX
#cmd-gmail-message-archive mutates state

Archive one Gmail message.

The target may come from an explicit id, a short ref such as m1, or piped message items. Batch archive requires –all.

--all bool Confirm batch archive
--id string Gmail message id
$ gmail message archive --all m1 m2
$ gmail message archive --help
$ gmail message archive m1
$ gmail message list --unread --jsonl | gmail message archive --all
gmail message create Create a new Gmail message or draft
#cmd-gmail-message-create mutates state

Create a new Gmail message.

Pass –draft to save the message as a draft. Without –draft this command sends immediately.

--attach stringSlice = [] File path(s) to attach
--bcc string Comma-separated bcc recipients
--body string Plain text body
--body-file string Read plain text body from file
--cc string Comma-separated cc recipients
--draft bool Save as draft instead of sending
--html-body string HTML body
--html-body-file string Read HTML body from file
--subject string Message subject
--to string Comma-separated recipients
--yes bool Confirm send/reply when confirmation is required
$ gmail message create --draft --to alice@example.com --subject 'Status' --body 'Save first'
$ gmail message create --help
$ gmail message create --to alice@example.com --subject 'Status' --body 'Send now'
gmail message forward Create a forward draft
#cmd-gmail-message-forward mutates state

Create a Gmail forward draft for one message.

The target may come from an explicit id, a short ref such as m1, or one piped message item. This command creates a draft rather than sending immediately.

--body string Forward body text
--id string Gmail message id
--to string Comma-separated recipients
$ gmail message forward --help
$ gmail message forward m1 --to bob@example.com --body 'Please review.'
$ gmail message list --query 'has:attachment' --limit 1 --jsonl | gmail message forward --to bob@example.com --body 'Please review.'
gmail message get Get a full message with parsed MIME content
#cmd-gmail-message-get discovery safe

Get one Gmail message in full detail.

The target may be:

  • a full Gmail message id
  • a stored short id such as 19d…9b7
  • a cached marker such as m1
  • one piped message item from stdin

If you already listed messages, prefer a short ref or piped jsonl instead of copying the full id. Use message get when you need the subject, parsed body, headers, or attachments for a message you just found with message list.

--id string Gmail message id
$ gmail message get
$ gmail message get 19d…9b7
$ gmail message get m1
$ gmail message list --query 'subject:"Quarterly review"' --limit 1 --jsonl | gmail message get
$ gmail message list --unread --limit 1 --jsonl | gmail message get
gmail message important Mark a message as important
#cmd-gmail-message-important discovery safe
--all bool Confirm batch important
--id string Gmail message id
$ gmail message important --help
$ gmail message important m1
gmail message label Modify Gmail labels
#cmd-gmail-message-label mutates state

Add or remove Gmail labels on one message.

List labels first if you need valid label refs, then pass the message target directly or via stdin.

$ gmail message label --help
gmail message label add Add labels to a message
#cmd-gmail-message-label-add mutates state

Add one or more Gmail labels to one message.

Pass –label with one or more Gmail label ids, names, or local refs such as l1. The target message may come from an explicit id, a short ref such as m1, or piped message items. Batch label changes require –all.

--all bool Confirm batch label add
--id string Gmail message id
--label string Comma-separated label IDs, names, or local refs to add
$ gmail label list
$ gmail message label add --all m1 m2 --label STARRED
$ gmail message label add --help
$ gmail message label add m1 --label l1
gmail message label remove Remove labels from a message
#cmd-gmail-message-label-remove mutates state

Remove one or more Gmail labels from one message.

Pass –label with one or more Gmail label ids, names, or local refs such as l1. The target message may come from an explicit id, a short ref such as m1, or piped message items. Batch label changes require –all.

--all bool Confirm batch label remove
--id string Gmail message id
--label string Comma-separated label IDs, names, or local refs to remove
$ gmail message label remove --all m1 m2 --label STARRED
$ gmail message label remove --help
$ gmail message label remove m1 --label l1
gmail message list List messages
#cmd-gmail-message-list discovery safe

List Gmail messages and cache local follow-up references.

Human output shows local markers such as m1 and shortened canonical ids. Use –jsonl when you want the results to feed directly into another gmail command. If you need message bodies, headers, or attachments, follow up with gmail message get rather than stopping at list output.

The most common next steps are:

  • gmail message get
  • gmail message reply
  • gmail message archive
  • gmail attachment get
--after string Gmail after date filter, e.g. 2026/06/01 or epoch seconds
--before string Gmail before date filter, e.g. 2026/06/30 or epoch seconds
--from string Filter by sender
--has-attachment bool Filter to messages with attachments
--in string Mailbox/search bucket, e.g. inbox, sent, trash
--inbox bool List inbox messages only
--include-spam-trash bool Include spam and trash in search results
--label stringSlice = [] Gmail label ID, name, or local ref; repeat or comma-separate
--newer-than string Gmail relative time filter, e.g. 7d
--older-than string Gmail relative time filter, e.g. 30d
--query string Raw Gmail search query
--subject string Filter by subject terms
--to string Filter by recipient
--unread bool List unread messages only
$ gmail message list
$ gmail message list --from alice@example.com --limit 10
$ gmail message list --query 'has:attachment newer_than:7d' --limit 10
$ gmail message list --query 'subject:"Quarterly review"' --limit 1 --jsonl | gmail message get
$ gmail message list --unread --limit 1 --jsonl | gmail message get
$ gmail message list --unread --limit 10
gmail message not-important Remove important marker from a message
#cmd-gmail-message-not-important discovery safe
--all bool Confirm batch not-important
--id string Gmail message id
$ gmail message not-important --help
$ gmail message not-important m1
gmail message read Mark a message as read
#cmd-gmail-message-read mutates state

Mark one Gmail message as read.

The target may come from an explicit id, a short ref such as m1, or piped message items. Batch read marking requires –all.

--all bool Confirm batch read marking
--id string Gmail message id
$ gmail message list --unread --jsonl | gmail message read --all
$ gmail message read --all m1 m2
$ gmail message read --help
$ gmail message read m1
gmail message reply Send or draft a reply
#cmd-gmail-message-reply mutates state

Send or draft a Gmail reply for one message.

The target may come from an explicit id, a short ref such as m1, or one piped message item. Pass –draft to save the reply as a draft. Without –draft this command sends immediately.

--all bool Reply to all recipients
--attach stringSlice = [] File path(s) to attach
--body string Plain text body
--body-file string Read plain text body from file
--draft bool Save as draft instead of sending
--html-body string HTML body
--html-body-file string Read HTML body from file
--id string Gmail message id
--yes bool Confirm send/reply when confirmation is required
$ gmail message list --query 'from:alice@example.com' --limit 1 --jsonl | gmail message reply --body 'Received.'
$ gmail message reply --help
$ gmail message reply m1 --body 'Looping everyone in.' --all
$ gmail message reply m1 --body 'Thanks' --draft
$ gmail message reply m1 --body 'Thanks, I will review this.'
$ gmail message reply m1 --draft --body 'Holding this for review.'
gmail message star Star a message
#cmd-gmail-message-star discovery safe
--all bool Confirm batch star
--id string Gmail message id
$ gmail message list --query cmdhub-demo --jsonl | gmail message star --all
$ gmail message star --help
$ gmail message star m1
gmail message trash Move a message to trash
#cmd-gmail-message-trash mutates state dry-run

Move one Gmail message to trash.

The target may come from an explicit id, a short ref such as m1, or piped message items. Batch trash requires –all –yes. Use –dry-run to preview selected targets without moving them.

--all bool Confirm batch trash
--dry-run bool Preview selected messages without trashing them
--id string Gmail message id
--yes bool Confirm destructive batch trash
$ gmail message list --query cmdhub-demo --jsonl | gmail message trash --all --dry-run
$ gmail message trash --all --yes m1 m2
$ gmail message trash --help
$ gmail message trash m1
gmail message unread Mark a message as unread
#cmd-gmail-message-unread mutates state

Mark one Gmail message as unread.

The target may come from an explicit id, a short ref such as m1, or piped message items. Batch unread marking requires –all.

--all bool Confirm batch unread marking
--id string Gmail message id
$ gmail message unread --all m1 m2
$ gmail message unread --help
$ gmail message unread m1
gmail message unstar Remove star from a message
#cmd-gmail-message-unstar discovery safe
--all bool Confirm batch unstar
--id string Gmail message id
$ gmail message unstar --help
$ gmail message unstar m1
gmail message untrash Restore a message from trash
#cmd-gmail-message-untrash mutates state

Restore one Gmail message from trash.

The target may come from an explicit id, a short ref such as m1, or piped message items. Batch restore requires –all.

--all bool Confirm batch untrash
--id string Gmail message id
$ gmail message untrash --all m1 m2
$ gmail message untrash --help
$ gmail message untrash m1
gmail profile Manage provider profiles
#cmd-gmail-profile discovery safe
$ gmail profile --help
gmail profile create Create an unauthenticated provider profile
#cmd-gmail-profile-create mutates state
$ gmail profile create --help
gmail profile delete Delete a local provider profile
#cmd-gmail-profile-delete mutates state
$ gmail profile delete --help
gmail profile list List provider profiles
#cmd-gmail-profile-list discovery safe
$ gmail profile list --help
gmail profile rename Rename a local provider profile
#cmd-gmail-profile-rename discovery safe
$ gmail profile rename --help
gmail profile use Set the default provider profile
#cmd-gmail-profile-use mutates state
$ gmail profile use --help
gmail resolve Resolve a local marker or stored short reference
#cmd-gmail-resolve discovery safe

Resolve a Gmail short reference into its canonical payload.

Use this when you have a marker such as m1, t1, d1, l1, or u1, or a stored short id such as 19d…9b7, and want to inspect what it refers to.

Resolution is profile-scoped. If a marker does not resolve, verify –profile and rerun the relevant list command.

$ gmail resolve --help
$ gmail resolve 19d…9b7
$ gmail resolve m1
$ gmail resolve t1
$ gmail resolve u1
gmail schema Emit Gmail adapter schema hints
#cmd-gmail-schema discovery safe

Show schema hints for the Gmail resource payloads emitted or accepted by this CLI.

Use this when you need to understand the shape of structured output for follow-up automation or parsing.

--in bool Show input schema
--input bool Show input schema
--out bool Show output schema
$ gmail schema
$ gmail schema --help
$ gmail schema draft.create --input --json
$ gmail schema message.get --out --json
gmail thread Work with Gmail threads
#cmd-gmail-thread discovery safe
$ gmail thread --help
gmail thread archive Archive a thread by removing INBOX from existing messages
#cmd-gmail-thread-archive mutates state
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread archive --help
$ gmail thread archive t1
gmail thread get Get a full thread
#cmd-gmail-thread-get discovery safe

Get one Gmail thread in full detail.

The target may be a canonical thread id, a short ref such as t1, a shortened canonical id, or one piped thread item.

--id string Gmail thread id
$ gmail thread get
$ gmail thread get t1
$ gmail thread list --limit 1 --jsonl | gmail thread get
gmail thread important Mark existing messages in a thread as important
#cmd-gmail-thread-important discovery safe
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread important --help
$ gmail thread important t1
gmail thread label Apply or remove labels on existing messages in a thread
#cmd-gmail-thread-label mutates state
$ gmail thread label --help
gmail thread label add Add labels to existing messages in a thread
#cmd-gmail-thread-label-add mutates state
--all bool Confirm batch thread label add
--id string Gmail thread id
--label string Comma-separated label IDs, names, or local refs to add
$ gmail thread label add --help
$ gmail thread label add t1 --label l1
gmail thread label remove Remove labels from existing messages in a thread
#cmd-gmail-thread-label-remove mutates state
--all bool Confirm batch thread label remove
--id string Gmail thread id
--label string Comma-separated label IDs, names, or local refs to remove
$ gmail thread label remove --help
$ gmail thread label remove t1 --label l1
gmail thread list List threads
#cmd-gmail-thread-list discovery safe

List Gmail threads and cache local thread references such as t1.

Use this when you want to act on conversation-level results rather than individual messages. Use –jsonl when the next step should consume one thread item from stdin.

--after string Gmail after date filter, e.g. 2026/06/01 or epoch seconds
--before string Gmail before date filter, e.g. 2026/06/30 or epoch seconds
--from string Filter by sender
--has-attachment bool Filter to threads with attachments
--in string Mailbox/search bucket, e.g. inbox, sent, trash
--include-spam-trash bool Include spam and trash in search results
--label stringSlice = [] Gmail label ID, name, or local ref; repeat or comma-separate
--newer-than string Gmail relative time filter, e.g. 7d
--older-than string Gmail relative time filter, e.g. 30d
--query string Raw Gmail search query
--subject string Filter by subject terms
--to string Filter by recipient
--unread bool List unread threads only
$ gmail thread list
$ gmail thread list --query 'label:IMPORTANT' --limit 1 --jsonl | gmail thread get
$ gmail thread list --query 'label:IMPORTANT' --limit 1 --jsonl | gmail thread reply --body 'Following up here.'
$ gmail thread list --subject invoice --limit 10
gmail thread not-important Remove important from existing messages in a thread
#cmd-gmail-thread-not-important discovery safe
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread not-important --help
$ gmail thread not-important t1
gmail thread read Mark a thread as read
#cmd-gmail-thread-read mutates state
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread read --help
$ gmail thread read t1
gmail thread reply Send or draft a reply to the latest message in a thread
#cmd-gmail-thread-reply mutates state

Send or draft a Gmail reply using the latest message in a thread.

This is useful when your workflow is organized around conversation results from thread list rather than message list. Pass –draft to save the reply as a draft. Without –draft this command sends immediately.

--all bool Reply to all recipients
--attach stringSlice = [] File path(s) to attach
--body string Plain text body
--body-file string Read plain text body from file
--draft bool Save as draft instead of sending
--html-body string HTML body
--html-body-file string Read HTML body from file
--id string Gmail thread id
--yes bool Confirm send/reply when confirmation is required
$ gmail thread list --query 'label:IMPORTANT' --limit 1 --jsonl | gmail thread reply --body 'Following up here.'
$ gmail thread reply --help
$ gmail thread reply t1 --body 'Following up here.'
$ gmail thread reply t1 --draft --body 'Holding this for review.'
gmail thread star Star existing messages in a thread
#cmd-gmail-thread-star discovery safe
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread star --help
$ gmail thread star t1
gmail thread trash Move a thread to trash
#cmd-gmail-thread-trash mutates state dry-run
--all bool Confirm batch thread trash
--dry-run bool Preview selected threads without trashing them
--id string Gmail thread id
--yes bool Confirm destructive batch thread trash
$ gmail thread search --query cmdhub-demo --jsonl | gmail thread trash --all --dry-run
$ gmail thread search --query cmdhub-demo --jsonl | gmail thread trash --all --yes
$ gmail thread trash --help
$ gmail thread trash t1
gmail thread unread Mark a thread as unread
#cmd-gmail-thread-unread mutates state
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread unread --help
$ gmail thread unread t1
gmail thread unstar Unstar existing messages in a thread
#cmd-gmail-thread-unstar discovery safe
--all bool Confirm batch thread mutation
--id string Gmail thread id
$ gmail thread unstar --help
$ gmail thread unstar t1
gmail thread untrash Restore a thread from trash
#cmd-gmail-thread-untrash mutates state
--all bool Confirm batch thread restore
--id string Gmail thread id
$ gmail thread untrash --help
$ gmail thread untrash t1
gmail version Show gmail version information
#cmd-gmail-version discovery safe
$ gmail version --help

play_circle Live Examples

Output captured from a real workspace. Regenerate with scripts/gen-docs.sh --update.

auth

Check Gmail readiness
$ gmail auth status
Authenticated as kestrelphilip@gmail.com
Profile: cmdhub-{token}

Next steps:
- Run: gmail message list --inbox --limit 10
Check current identity
$ gmail auth whoami
Authenticated as kestrelphilip@gmail.com

Next steps:
- Run: gmail message list --inbox --limit 10
Recover when a Gmail profile is not ready
$ gmail auth status --profile cmdhub-docshot-missing-scope
Not logged in.
Profile: {id}

Other profiles:
- cmdhub-{token} kestrelphilip@gmail.com            ready

Next steps:
- Login: gmail auth login

schemas

Message create input schema
$ gmail schema message.create --input --json
{
  "schema_id": "gmail.message.create.input.v1",
  "version": "v1",
  "tool": "gmail",
  "resource": "message",
  "action": "create",
  "direction": "input",
  "kind": "provider-native",
  "json_schema": {
    "{id}": true,
    "properties": {
      "attach": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "bcc": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "body": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "body_file": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "cc": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "draft": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "html_body": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "html_body_file": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "subject": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "to": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      },
      "yes": {
        "type": [
          "string",
          "number",
          "integer",
          "boolean",
          "array",
          "object",
          "null"
        ]
      }
    },
    "required": [
      "to",
      "subject"
    ],
    "type": "object"
  },
  "required": [
    "to",
    "subject"
  ],
  "optional": [
    "cc",
    "bcc",
    "body",
    "body_file",
    "html_body",
    "html_body_file",
    "attach",
    "draft",
    "yes"
  ],
  "sensitive_paths": [
    "$.text_body",
    "$.html_body",
    "$.from",
    "$.to",
    "$.content_text",
    "$.content_base64"
  ]
}

messages

List inbox messages
$ gmail message list --inbox --limit 5
Messages (5 shown, more available)
REF  TITLE                                                                            STATUS  WHEN                            OWNER
m1   {id} {id}       sent    Mon, 6 Jul 2026 08:50:30 +0000  Philip Kestrel <kestrelphilip@gmail.com>
m2   Consent requirements for email tracking are changing                             unread  Fri, 3 Jul 2026 14:52:35 +0200  HubSpot <noreply@notifications.hubspot.com>
m3   You have been made the Deal owner of the deal "{id} Deal"  unread  Fri, 3 Jul 2026 13:48:35 +0200  HubSpot <noreply@notifications.hubspot.com>
m4   You have been made the Deal owner of the deal "{id} Deal"  unread  Fri, 3 Jul 2026 10:05:21 +0200  HubSpot <noreply@notifications.hubspot.com>
m5   Security alert                                                                   unread  3d ago                          Google <no-reply@accounts.google.com>

Next steps:
- More:         gmail message list --query in:inbox --limit 5 --cursor c1
- Open:         gmail message get m1
- Drafts:       gmail draft list --limit 10
- Capabilities: gmail capabilities
Empty message search recovery
$ gmail message list --query cmdhub-eval-docshot-empty-token --inbox --limit 5
Empty state
No message found.

Next steps:
- List:         gmail message list --limit 10
- Status:       gmail auth status
- Drafts:       gmail draft list --limit 10
- Capabilities: gmail capabilities
Get a message in full view
$ gmail message get 19f369f3082a9a9f --view full
m1  {id} {id}
Local ref:   m1
Provider ID: 19f369f3082a9a9f
Thread:      t1
From:        Philip Kestrel <kestrelphilip@gmail.com>
To:          kestrelphilip@gmail.com
Date:        Mon, 6 Jul 2026 08:50:30 +0000
Labels:      UNREAD, SENT, INBOX
Attachments: a1 {id}.txt (text/plain, 71 bytes)

Body:
{id} docshot message body


Next steps:
- Draft reply: gmail message reply m1 --body "Reviewed, thanks." --draft
- Open thread: gmail thread get t1 --view full
- Download:    gmail attachment get --message-id m1 --attachment-id a1 --output-file {id}.txt
- Resolve ID:  gmail resolve m1
Mark a disposable message read
$ gmail message read 19f369f3082a9a9f
Message Read message m1: {id} {id}
Local ref:   m1
Provider ID: 19f369f3082a9a9f
Thread:      19f369
Subject:     {id} {id}
Status:      read


Next steps:
- Inspect: gmail message get m1 --view full
- Thread:  gmail thread get 19f369 --view full
Preview bounded trash recovery
$ gmail message trash --all --dry-run
INVALID_ARGUMENT: missing message reference

Next steps:
- Help:    gmail message trash --help
- List:    gmail message list --limit 10
- Inspect: gmail message get m1
exit status 2

threads

List recent threads
$ gmail thread list --limit 3
Threads (3 shown, more available)
REF  TITLE                                                                       STATUS      WHEN                            OWNER
t2   {id} {id}    1 messages  Mon, 6 Jul 2026 08:50:31 +0000  Philip Kestrel <kestrelphilip@gmail.com>
t1   {id} {id}  2 messages  Mon, 6 Jul 2026 04:50:33 -0400  Philip Kestrel <kestrelphilip@gmail.com>
t3   Consent requirements for email tracking are changing                        1 messages  Fri, 3 Jul 2026 14:52:35 +0200  HubSpot <noreply@notifications.hubspot.com>

Next steps:
- More:         gmail thread list --limit 3 --cursor c1
- Open:         gmail thread get t2
- Drafts:       gmail draft list --limit 10
- Capabilities: gmail capabilities
Get a thread in full view
$ gmail thread get 19f369f2b331ee20 --view full
t1  {id} {id}
Local ref:   t1
Provider ID: 19f369f2b331ee20
Messages: 2
Participants: Philip Kestrel <kestrelphilip@gmail.com>, kestrelphilip@gmail.com
Latest: Philip Kestrel <kestrelphilip@gmail.com>, Mon, 6 Jul 2026 04:50:33 -0400
Labels: SENT, INBOX, DRAFT

m1  Philip Kestrel <kestrelphilip@gmail.com> -> kestrelphilip@gmail.com, Mon, 6 Jul 2026 08:50:30 +0000
Labels: SENT, INBOX
Body: {id} docshot message body
Attachments: a2 {id}.txt (text/plain, 71 bytes)

m6  Philip Kestrel <kestrelphilip@gmail.com> -> Philip Kestrel <kestrelphilip@gmail.com>, Mon, 6 Jul 2026 04:50:33 -0400
Labels: DRAFT
Body: {id} reply draft body


Next steps:
- Draft reply: gmail thread reply t1 --body "Reviewed, thanks." --draft
- Resolve ID:  gmail resolve t1
- Reply to m6: gmail message reply m6 --body "Reviewed, thanks." --draft
- Download:    gmail attachment get --message-id m1 --attachment-id a2 --output-file {id}.txt
Create a reply draft in a disposable thread
$ gmail thread reply 19f369f2b331ee20 --body 'cmdhub-eval-gmail-docshot-20260706t085027z-59aa4bc5 docshot reply draft' --draft
Reply Draft Created draft d11: Re: {id} {id}
Thread:   t1
Target:   latest message in thread
To:       Philip Kestrel <kestrelphilip@gmail.com>
Sender:   cmdhub-{token}
Subject:  Re: {id} {id}
Body:     {id} docshot reply draft
Status:   saved, not sent


Next steps:
- Inspect draft: gmail draft get d11 --view full
- Send draft:    gmail draft send d11
- Delete draft:  gmail draft delete d11 --yes
- Verify thread: gmail thread get t1 --view full

labels

List mailbox labels
$ gmail label list --limit 20
Labels (14 total)
REF  TITLE                STATUS
l1   CHAT                 system
l2   SENT                 system
l3   INBOX                system
l4   IMPORTANT            system
l5   TRASH                system
l6   DRAFT                system
l7   SPAM                 system
l8   CATEGORY_FORUMS      system
l9   CATEGORY_UPDATES     system
l10  CATEGORY_PERSONAL    system
l11  {id}  system
l12  CATEGORY_SOCIAL      system
l13  STARRED              system
l14  UNREAD               system

Next steps:
- Open:         gmail label get l1
- Drafts:       gmail draft list --limit 10
- Capabilities: gmail capabilities
- Inbox:        gmail message list --inbox --limit 10

drafts

List drafts
$ gmail draft list --limit 10
Drafts (9 total)
REF  TITLE                                                                           STATUS  WHEN                            OWNER
d1   Re: {id} {id}  draft   Mon, 6 Jul 2026 04:50:33 -0400  Philip Kestrel <kestrelphilip@gmail.com>
d2   {id} {id}        draft   Mon, 6 Jul 2026 08:50:31 +0000  kestrelphilip@gmail.com
d3   {id}                                                    draft   25d ago                         cmdhub-{token}@cmdhub.dev
d4   {id}                                                     draft   25d ago                         cmdhub-{token}@example.com
d5   {id}                                                    draft   25d ago                         cmdhub-{token}@example.com
d6   draft                                                                           draft   Tue, 2 Jun 2026 08:16:00 -0700  kestrelphilip@gmail.com
d7   cmdhub-{token}                                                               draft   1mo ago                         test@example.com
d8   {id}                                                          draft   1mo ago                         kestrelphilip@gmail.com
d9   Re: Join your team on Notion                                                    draft   2mo ago                         Notion Team <notify@updates.notion.so>

Next steps:
- Open:         gmail draft get d1
- Drafts:       gmail draft list --limit 10
- Capabilities: gmail capabilities
- Inbox:        gmail message list --inbox --limit 10
Recover from incomplete draft creation
$ gmail draft create --subject cmdhub-docshot-draft-create
INVALID_ARGUMENT: missing --to

Next steps:
- Help:    gmail draft create --help
- List:    gmail draft list --limit 10
- Inspect: gmail draft get d1
exit status 2
Create a disposable draft
$ gmail draft create --to kestrelphilip@gmail.com --subject 'cmdhub-docshot-draft cmdhub-eval-gmail-docshot-20260706t085027z-59aa4bc5' --body 'cmdhub-eval-gmail-docshot-20260706t085027z-59aa4bc5 disposable draft body'
Draft Created draft d10: {id} {id}
Local ref:   d10
Provider ID: {id}
Thread:      19f369
To:          kestrelphilip@gmail.com
Subject:     {id} {id}
Status:      saved, not sent


Next steps:
- Inspect: gmail draft get d10 --view full
- Update:  gmail draft update d10 --body "Updated text"
- Send:    gmail draft send d10
- Delete:  gmail draft delete d10 --yes

alt_route Composition Patterns

Bridge your ecosystem with zero middleware.

# Inspect one message and then hand it to an agent transform
gmail message list --label INBOX --limit 1 --jsonl \
  | agent adapt --to "gcal event create"