Gmail MCP Server

Search, read, send, and organize Gmail through the Model Context Protocol.

The Gmail service is the largest in Workspace MCP: fifteen tools spanning the full lifecycle of email, from search_gmail_messages with native Gmail query operators through send_gmail_message with reply threading and attachments.

Batch variants (get_gmail_messages_content_batch, batch_modify_gmail_message_labels) keep token usage low when an assistant works across dozens of messages at once, and draft_gmail_message lets you keep a human in the loop before anything is sent.

What you can ask

  • “Find every email from my accountant since March that I never replied to, and draft polite follow-ups”
  • “Search for invoices with attachments from last quarter and label them Finance/2026”
  • “Summarize this morning’s unread messages in three bullets each”

All 15 Gmail MCP tools

Expand any tool for its full parameter list. Tiers control how many tools the server registers: start lean with --tool-tier core and step up to extended or complete when a workflow needs more.

search_gmail_messages Core Search mail using Gmail query operators. 4
ParameterDescription
query requiredThe search query. Supports standard Gmail search operators.
page_size The maximum number of messages to return. Defaults to 10.
page_token Token for retrieving the next page of results.
include_headers If True, also return Subject, From, Date and labels (e.g. DRAFT, SENT) per result, so drafts can be told apart from sent mail. Costs one metadata fetch per result. Defaults to False.
get_gmail_message_content Core Retrieve message content. With `full=True`, returns the complete untruncated message via file/URL (or inline when no file storage is available). 4
ParameterDescription
message_id requiredThe unique ID of the Gmail message to retrieve.
body_format Body output format: 'text' (default), 'html', or 'raw' (decoded MIME).
full If True, return the complete untruncated message.
format 'full' (default) or 'metadata' for headers only, skipping the body fetch.
get_gmail_messages_content_batch Core Batch fetch message content. 2
ParameterDescription
message_ids requiredList of Gmail message IDs to retrieve (max 25 per batch).
format Message format. "full" includes body, "metadata" only headers.
send_gmail_message Core Send email messages (supports replies, forwards, and attachments). When `thread_id` is set, threading headers are derived from the thread automatically. Sends are never retried: a timeout or server error reports that the message may already have been delivered, so check Sent before sending again. 11
ParameterDescription
to Recipient email address. Optional when replying with `reply_all=True`, which derives it from the thread.
subject Email subject. Required for a new message; optional when replying with `thread_id` (inherits the parent subject, adding `Re:` only if missing) or forwarding (defaults to "Fwd: <original subject>").
body Email body content. Required when sending. When forwarding, this is an optional note prepended above the quoted original.
body_format Email body format ('plain' or 'html'). Defaults to 'plain'. With 'html', bare newlines between text become `<br>` line breaks; well-formed block markup is left untouched. A body that starts with an entity-escaped tag (`&lt;div&gt;`) and has no real markup is rejected before sending.
cc Optional CC email address.
bcc Optional BCC email address.
thread_id Thread ID to reply within.
reply_all Derive reply-all recipients from the thread: To is the sender replied to, Cc the other participants, excluding the authenticated account. Requires `thread_id`; explicit `to`/`cc` win. Defaults to False.
quote_original Include the message being replied to as a quoted original. Only has an effect with `thread_id`. Defaults to False.
direction Base text direction of the body: `auto` (default) takes it from the first strong character, `ltr`/`rtl` force it. On a forward it orients the note.
attachments Optional list of attachments (path or base64 content).
get_gmail_thread_content Extended Retrieve full thread content. 1
ParameterDescription
thread_id requiredThe unique ID of the Gmail thread to retrieve.
get_gmail_attachment_content Extended Download Gmail attachments to persistent attachment storage. 4
ParameterDescription
message_id requiredThe ID of the Gmail message containing the attachment.
attachment_id requiredThe ID of the attachment to download.
return_base64 If True, also return the attachment content as base64.
attachment_index Zero-based attachment position from the message-content response. Lets the server re-resolve Gmail's refreshed attachment IDs against current metadata before downloading.
modify_gmail_message_labels Extended Add/remove labels on a message. 3
ParameterDescription
message_id requiredThe ID of the message to modify.
add_label_ids List of label IDs to add to the message.
remove_label_ids List of label IDs to remove from the message.
list_gmail_labels Extended List account labels. 3
ParameterDescription
prefix Return only labels whose name starts with this string (case-sensitive). Useful for fetching a single subtree of a hierarchical label structure.
compact When true, returns minimal JSON with just id and name per label, sorted by name.
include_system When false, excludes Gmail system labels from the results. Defaults to true.
list_gmail_filters Extended List configured Gmail filters. —
manage_gmail_label Extended Create/update/delete labels. 6
ParameterDescription
action requiredAction to perform on the label ('create', 'update', 'delete').
name Label name. Required for create, optional for update.
label_id Label ID. Required for update and delete operations.
background_color Label background color as a hex string, e.g. `#fb4c2f`. Must be set together with text_color. Gmail accepts only its own palette, and an unsupported value is rejected before the request is sent. Applies to user labels, not system labels.
text_color Label text color as a hex string, e.g. `#ffffff`. Must be set together with background_color, from the same palette. On update, omitting both keeps the label's current color.
clear_color On update, remove the label's current color. Cannot be combined with background_color or text_color.
manage_gmail_filter Extended Create, update, and delete Gmail filters, or apply one to existing mail. 6
ParameterDescription
action required"create", "update", "delete", or "apply". Update recreates the filter (new one first, then the old one is deleted), so its ID changes.
criteria Filter criteria object (required for create; optional for update/apply).
filter_action Filter action object (required for create; optional for update/apply).
filter_id ID of the filter (required for delete and update; optional for apply).
dry_run Apply only: count matching messages without changing anything.
max_messages Apply only: safety cap on messages changed. Defaults to 5000.
draft_gmail_message Extended Create Gmail drafts, including a forward of an existing message saved for review. 10
ParameterDescription
subject Email subject. Required for a new draft; optional when replying with `thread_id` (inherits the parent subject) or forwarding (defaults to `Fwd: <original subject>`).
body Email body content. Required unless forwarding, where it becomes an optional note above the quoted original.
body_format Email body format ('plain' or 'html'). Defaults to 'plain'. With 'html', a body that starts with an entity-escaped tag (`&lt;div&gt;`) and has no real markup is rejected.
direction Base text direction of the body: `auto` (default) takes it from the first strong character, `ltr`/`rtl` force it. On a forward it orients the note.
to Optional recipient email address.
cc Optional CC email address.
reply_all Derive reply-all recipients from the thread: To is the sender replied to, Cc the other participants, excluding the authenticated account. Requires `thread_id`; explicit `to`/`cc` win. Defaults to False.
attachments Optional list of attachments.
forward_message_id Gmail message ID to forward. Saves a forward of that message as a draft, carrying over its subject and body.
include_forwarded_attachments When forwarding, whether to carry over the original attachments. Defaults to `true`.
get_gmail_threads_content_batch Complete Batch fetch thread content. 1
ParameterDescription
thread_ids requiredA list of Gmail thread IDs to retrieve.
batch_modify_gmail_message_labels Complete Batch label modifications on messages or whole conversations. 5
ParameterDescription
message_ids A list of message IDs to modify. Can be combined with `thread_ids`; at least one is required.
thread_ids Thread (conversation) IDs to modify. Applies the change to every message in each thread and reports an outcome per thread.
add_label_ids List of label IDs to add to the messages.
remove_label_ids List of label IDs to remove from the messages.
verify Read messages back and report per-ID outcomes. Defaults to `true`; set to `false` to avoid one extra batched read per message when an unverified result is acceptable.
start_google_auth Complete Legacy OAuth 2.0 auth helper (disabled with OAuth 2.1). —

Every service in one reference: full API documentation →

OAuth scopes

The server requests only the scopes for the services you enable. In read-only mode it requests just the readonly variants and skips registering write tools entirely.

  • gmail.readonly search and read messages, threads, and labels
  • gmail.send send mail
  • gmail.compose create drafts
  • gmail.modify label changes (implies the scopes above)
  • gmail.settings.basic manage filters

Gmail MCP questions

Can the assistant read my mail without being able to send anything?
Yes. Read-only mode requests only the gmail.readonly scope and disables every write tool, so send_gmail_message, draft_gmail_message, and label management are never registered. You can also run the core tier and simply not grant send.
Does search support Gmail query operators?
search_gmail_messages passes your query straight to Gmail, so from:, to:, label:, has:attachment, before:/after:, and every other operator you use in the Gmail search bar works unchanged.
How do replies and threading work?
send_gmail_message accepts a thread context so replies land in the existing conversation rather than starting a new one, and get_gmail_thread_content gives the assistant the full back-and-forth before it writes a response.
Can I keep a human in the loop before email goes out?
Use draft_gmail_message: the assistant composes the draft, and it sits in your Drafts folder until you review and hit send yourself.