Skip to main content
Glama
flt-sudo

gmail-mcp-server

by flt-sudo

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
GMAIL_MCP_CLIENT_IDNoGoogle OAuth client ID. Can also be provided via ~/.config/gmail-mcp/client.json.
GMAIL_MCP_HTTP_HOSTNoInterface to bind for HTTP mode (default 127.0.0.1).127.0.0.1
GMAIL_MCP_HTTP_PORTNoPort for HTTP mode (default 3333).3333
GMAIL_MCP_HTTP_TOKENNoBearer token for HTTP mode (required when running with --http). Must be at least 32 characters.
GMAIL_MCP_CLIENT_SECRETNoGoogle OAuth client secret. Can also be provided via ~/.config/gmail-mcp/client.json.

Instructions

Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.

This server publishes no instructions, or was last inspected before Glama recorded them.

Capabilities

Features and capabilities supported by this server

Protocol revision2025-11-25

CapabilityDetails
tools
{
  "listChanged": true
}

Tools

Functions exposed to the LLM to take actions

NameDescription
gmail_add_accountA

Add (or re-authenticate) a Gmail account via a browser OAuth consent flow on this machine.

Args:

  • access ("readonly" | "modify" | "send", default "modify"): readonly = search and read only; modify = read plus labels, trash, drafts; send = modify plus send and reply.

  • allow_send (boolean, legacy): same as access "send"; ignored when access is set.

  • alias (string, optional): short name usable anywhere an 'account' parameter is accepted.

  • set_default (boolean, default false): make this the default account. The first account added is always the default.

Returns: the authenticated email address and granted scopes. A browser window opens for consent; if it does not, the consent URL is included in the response for manual opening. Re-adding an existing email overwrites its stored credentials (this is the re-auth path).

Examples:

  • {"access": "readonly"} — add a read-only account

  • {} — add an account that can read, label, trash, and draft, but not send

  • {"access": "send", "alias": "work", "set_default": true}

Error Handling: returns an actionable error if OAuth client credentials are missing (see README setup), if the user denies consent, or if the flow times out (5 minutes).

gmail_list_accountsA

List every stored Gmail account: email, alias, access level (read-only, read+modify, or read+modify+send), whether it is the default, and when it was added. Tokens are never exposed.

Args: none.

Returns: one line per account, or a note that no accounts are configured.

Examples:

  • {} — list all accounts

Error Handling: returns an error only if the local accounts file is unreadable or corrupt.

gmail_remove_accountA

Remove a stored Gmail account by email or alias. Best-effort revokes the refresh token with Google, then deletes the local entry. If the removed account was the default, another stored account becomes the default (or the default is cleared).

Args:

  • account (string, required): email or alias to remove.

Returns: confirmation, including whether remote revocation succeeded and the new default account, if any.

Examples:

Error Handling: removing an unknown account returns an error listing available accounts. Revocation failures are ignored (the local entry is still deleted), making this safe to repeat.

gmail_search_threadsA

Search threads with full Gmail search syntax, in one account or across all stored accounts.

Args:

  • query (string, required): Gmail search syntax. Examples: 'from:alice@example.com is:unread', 'newer_than:7d', 'has:attachment subject:"invoice"', 'to:me label:starred'.

  • account (string, optional): email or alias to search; the literal 'all' fans out to every stored account concurrently, merges results by date (newest first), and tags each thread with its account. Omit for the default account.

  • max_results (1–50, default 10): per-account cap.

  • page_token (optional): continue a previous single-account search. NOT supported with account:'all' — in that mode each account instead reports has_more; narrow the query or search one account to paginate.

  • response_format: 'markdown' (default) or 'json'.

Returns: thread-level summaries only (thread_id, account, participants, date, subject, snippet, message_count) — never full bodies. Use gmail_get_thread with the thread_id AND the same account to read a thread.

Examples:

  • {"query": "is:unread newer_than:2d"}

  • {"query": "subject:"invoice" has:attachment", "account": "all", "max_results": 20}

Error Handling: in 'all' mode, per-account failures are reported inline without failing the whole call. Expired credentials return a re-auth instruction naming the affected account.

gmail_get_threadA

Fetch a full thread — every message with normalized headers and body text.

Args:

  • thread_id (string, required): from gmail_search_threads. Thread ids are ACCOUNT-SPECIFIC — pass the same 'account' the id came from.

  • account (string, optional): email or alias. Omit for the default account.

  • response_format: 'markdown' (default) or 'json'.

Returns: all messages in the thread (from/to/cc, date, subject, labels, body text, attachment metadata). Long threads are truncated to fit the response limit, with a note saying how many messages were shown; use gmail_get_message for a specific message's full content.

Examples:

  • {"thread_id": "18c2f5a7b3d9e1f0"}

  • {"thread_id": "18c2f5a7b3d9e1f0", "account": "work", "response_format": "json"}

Error Handling: a 404 usually means the id belongs to a DIFFERENT account — check the 'account' field on the search result that produced the id.

gmail_get_messageA

Fetch a single message with full body text and attachment metadata.

Args:

  • message_id (string, required): Gmail message id. Message ids are ACCOUNT-SPECIFIC — pass the same 'account' the id came from.

  • account (string, optional): email or alias. Omit for the default account.

  • response_format: 'markdown' (default) or 'json'.

Returns: normalized message (from/to/cc, date, subject, labels, body text) plus attachment metadata (filename, mimeType, size, attachment_id). Attachment CONTENT download is not supported in v1.

Examples:

  • {"message_id": "18c2f5a7b3d9e1f0"}

  • {"message_id": "18c2f5a7b3d9e1f0", "account": "personal", "response_format": "json"}

Error Handling: a 404 usually means the id belongs to a different account.

gmail_list_labelsA

List every label in an account — system labels (INBOX, UNREAD, STARRED, SPAM, TRASH, ...) and user labels — with their ids. gmail_modify_labels operates on label IDS, so call this first to translate names to ids.

Args:

  • account (string, optional): email or alias. Omit for the default account.

  • response_format: 'markdown' (default) or 'json'.

Returns: label name, id, and type (system/user) for every label.

Examples:

  • {}

  • {"account": "work", "response_format": "json"}

Error Handling: expired credentials return a re-auth instruction naming the account.

gmail_send_messageA

Send a new plain-text email from one of the stored accounts. REQUIRES the account to have been added with access: "send".

Args:

  • to (string[], required), cc (string[], optional), bcc (string[], optional): recipient addresses.

  • subject (string, required), body (string, required): plain text (v1 — no HTML, no attachments).

  • account (string, optional): email or alias to send FROM. Omit for the default account.

Returns: confirmation echoing the sending account, recipients, and the new message and thread ids.

Examples:

  • {"to": ["alice@example.com"], "subject": "Meeting notes", "body": "Attached below..."}

  • {"to": ["a@x.com"], "cc": ["b@x.com"], "subject": "Hi", "body": "...", "account": "work"}

Error Handling: if the account was added read-only, this returns an instruction to re-add it with access: "send" (use gmail_create_draft instead if the account should not send).

gmail_reply_to_threadA

Reply to an existing thread from the account that owns it, with correct In-Reply-To/References threading headers. REQUIRES the account to have been added with access: "send".

Args:

  • thread_id (string, required): the thread to reply within (account-specific — use the same account the id came from).

  • body (string, required): plain-text reply body.

  • reply_all (boolean, default false): false replies only to the last message's sender (or Reply-To); true also includes everyone on that message's To/Cc lines (minus this account).

  • account (string, optional): email or alias. Omit for the default account.

Returns: confirmation echoing the sending account, recipients, and the new message id + thread id.

Examples:

  • {"thread_id": "18c2f5a7b3d9e1f0", "body": "Sounds good — Thursday works."}

  • {"thread_id": "18c2f5a7b3d9e1f0", "body": "Looping everyone in.", "reply_all": true, "account": "work"}

Error Handling: accounts without send access get a re-add instruction. A 404 usually means the thread id belongs to a different account.

gmail_create_draftA

Create a plain-text draft (saved to the account's Drafts folder; nothing is sent). Works without the send scope; needs access "modify" or "send" (gmail.modify).

Args:

  • to (string[], required), cc (string[], optional), bcc (string[], optional): recipient addresses.

  • subject (string, required), body (string, required): plain text.

  • account (string, optional): email or alias. Omit for the default account.

Returns: the draft id, its message id, and the account it was created in.

Examples:

  • {"to": ["alice@example.com"], "subject": "Draft: proposal", "body": "First pass..."}

  • {"to": ["b@x.com"], "subject": "Hi", "body": "...", "account": "personal"}

Error Handling: expired credentials return a re-auth instruction naming the account.

gmail_modify_labelsA

Add and/or remove labels on one message or one whole thread. This is also how you archive and mark read/unread:

  • Archive: remove_label_ids: ["INBOX"]

  • Mark read: remove_label_ids: ["UNREAD"] · Mark unread: add_label_ids: ["UNREAD"]

  • Star: add_label_ids: ["STARRED"]

Args:

  • message_id OR thread_id (exactly one, required): target. Ids are account-specific.

  • add_label_ids (string[], optional), remove_label_ids (string[], optional): label IDS, not names — call gmail_list_labels to translate. At least one of the two is required.

  • account (string, optional): email or alias. Omit for the default account.

Returns: confirmation with the resulting label set (message) or affected thread id.

Examples:

  • {"message_id": "18c2...", "remove_label_ids": ["UNREAD"]}

  • {"thread_id": "18c2...", "add_label_ids": ["STARRED"], "remove_label_ids": ["INBOX"], "account": "work"}

Error Handling: unknown label ids return a Gmail error — list labels first. A 404 usually means the id belongs to a different account.

gmail_trash_messageA

Move one message or one whole thread to Trash. RECOVERABLE — Gmail keeps trashed mail for ~30 days and it can be restored from the Trash folder; nothing is permanently deleted by this tool.

Args:

  • message_id OR thread_id (exactly one, required): target. Ids are account-specific.

  • account (string, optional): email or alias. Omit for the default account.

Returns: confirmation of what was trashed and in which account.

Examples:

  • {"message_id": "18c2f5a7b3d9e1f0"}

  • {"thread_id": "18c2f5a7b3d9e1f0", "account": "personal"}

Error Handling: a 404 usually means the id belongs to a different account — check the 'account' field on the search result that produced the id.

Prompts

Interactive templates invoked by user choice

NameDescription

No prompts

Resources

Contextual data attached and managed by the client

NameDescription

No resources

TDQS

A4.6/5.0

Scored across 12 tools

Disambiguation5/5

Every tool targets a distinct action-resource pair: account management, search/read, send/reply/draft, labels, and trash are cleanly separated. Even similar tools like get_message and get_thread are clearly scoped by resource type, and list_labels explicitly feeds modify_labels without overlap.

Naming Consistency5/5

All tools use the consistent gmail_verb_noun pattern with snake_case, making the action and target predictable. Minor variation like reply_to_thread instead of reply_thread does not break the overall convention.

Tool Count5/5

Twelve tools is well-scoped for a Gmail server: account lifecycle, search/read, send/reply/draft, labels, and trash each get focused coverage without redundancy. The count is solidly within the ideal range.

Completeness4/5

Core Gmail workflows are well covered: search, read, send, reply, draft, label modification, trash, and multi-account management. Minor gaps exist—no attachment content download, no draft editing/deletion, and no label create/delete—but these are workable and do not leave the main workflows dead-ended.

Maintenance

ActivityMaintained
ResponsivenessNo issues