A1 Gmail MCP
A1 Gmail MCP is an MCP server that lets an AI app work with a single Gmail mailbox through 18 tools: search, read, draft, send, organize, trash, and manage labels.
Search and list messages or threads with Gmail query syntax, label filters, pagination, and optional spam/trash inclusion.
Read full messages, conversation threads, and drafts with decoded bodies (truncation limits), headers, and attachment metadata (not attachment content).
Send email immediately via send_message, or safely via create_draft → get_draft → send_draft; replies can be threaded with thread_id, in_reply_to, and subject.
Modify message/thread state: mark read/unread, star/unstar, archive/move to inbox, and add/remove labels.
Manage the trash: trash or untrash individual messages or whole threads (no permanent-delete tool).
Manage drafts: list, read, create, replace/update, send, and permanently delete drafts.
Manage user labels: create, rename, delete, and adjust visibility settings; list labels with per-label counts.
Get the mailbox profile (email address, message/thread totals, historyId).
Make raw Gmail API calls via raw_request for attachment downloads, history sync, settings, and other uncovered endpoints (with caution).
Provides tools for reading and searching Gmail messages and threads, creating and managing drafts, sending emails, managing labels, and trashing or untrashing messages through the Gmail API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@A1 Gmail MCPShow my unread emails from this week about the Acme contract"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Gmail MCP
English | Русский
A1 Gmail MCP lets an AI app work with your Gmail mailbox in plain language. Search and read mail, prepare replies as drafts, send them when you are ready, keep labels tidy and use the trash instead of permanent deletion.
It uses the Gmail API with your Google account. It distinguishes a draft you can still edit from a sent email that cannot be recalled, and makes the limits of the Gmail API explicit instead of implying that every mail task is reversible.
18 tools. Search and read messages and threads, send email directly or through drafts, manage the draft lifecycle, labels and the trash.
Send deliberately. The draft → review → send path is first-class; sending is marked destructive, and the server never re-sends after an ambiguous failure — an email cannot be unsent.
The trash is the safety net. Removing mail goes through the reversible trash (about 30 days); there is deliberately no permanent message delete tool.
Bounded reading. Decoded bodies are truncated at an explicit limit and attachments come back as metadata, so a long newsletter cannot silently flood the conversation.
Minimal Google scope. It uses
gmail.modifyonly — no permanent deletion and no access to Gmail settings.
Start with a read-only question:
Show my unread emails from the last week and tell me which ones need a reply.
Connect the server · Explore use cases · Open technical documentation
See it work in a minute
You: What is unread in my inbox from this week about the Acme contract?
Assistant: Searches with Gmail query syntax and shows senders, subjects, dates and snippets. Nothing changes.
You: Draft a reply to the latest one: we send the signed copy on Friday.
Assistant: Creates a draft in the same thread and shows it for review. Nothing is sent.
You: Send it.
Assistant: Sends the draft. Sending is a separate, explicitly destructive step, so your AI app can ask for confirmation first.
Related MCP server: gmail-mcp
Contents
Quick start
You need Node.js 20+, a Google account and OAuth credentials from a Google Cloud project with the Gmail API enabled.
Add the server to your AI app.
Ask the read-only question above.
In the app: open Settings → MCP servers, select Add server, choose STDIO, enter the command npx -y mcp-google-gmail@latest and environment variables GOOGLE_GMAIL_CLIENT_ID, GOOGLE_GMAIL_CLIENT_SECRET, GOOGLE_GMAIL_REFRESH_TOKEN, then select Save and Restart.
From the command line:
codex mcp add google-gmail \
--env GOOGLE_GMAIL_CLIENT_ID=your_client_id \
--env GOOGLE_GMAIL_CLIENT_SECRET=your_client_secret \
--env GOOGLE_GMAIL_REFRESH_TOKEN=your_refresh_token \
-- npx -y mcp-google-gmail@latestcodex mcp listclaude mcp add \
--env GOOGLE_GMAIL_CLIENT_ID=your_client_id \
--env GOOGLE_GMAIL_CLIENT_SECRET=your_client_secret \
--env GOOGLE_GMAIL_REFRESH_TOKEN=your_refresh_token \
--transport stdio --scope user google-gmail \
-- npx -y mcp-google-gmail@latestclaude mcp listThe current official path is Settings → Extensions. For a custom desktop extension, open Advanced settings → Extension Developer → Install Extension…, select a .mcpb file and follow the prompts.
This repository currently publishes an npm stdio package and does not contain a .mcpb bundle. For Claude Desktop builds that still support local configuration, use the following JSON stdio configuration as a fallback:
{
"mcpServers": {
"google-gmail": {
"command": "npx",
"args": ["-y", "mcp-google-gmail@latest"],
"env": {
"GOOGLE_GMAIL_CLIENT_ID": "your_client_id",
"GOOGLE_GMAIL_CLIENT_SECRET": "your_client_secret",
"GOOGLE_GMAIL_REFRESH_TOKEN": "your_refresh_token"
}
}
}
}In those builds, save it to ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows.
Claude Desktop MCP documentation
Add this to ~/.cursor/mcp.json on macOS/Linux or %USERPROFILE%\.cursor\mcp.json on Windows:
{
"mcpServers": {
"google-gmail": {
"type": "stdio",
"command": "npx",
"args": ["-y", "mcp-google-gmail@latest"],
"env": {
"GOOGLE_GMAIL_CLIENT_ID": "your_client_id",
"GOOGLE_GMAIL_CLIENT_SECRET": "your_client_secret",
"GOOGLE_GMAIL_REFRESH_TOKEN": "your_refresh_token"
}
}
}
}Run MCP: Open User Configuration and add:
{
"servers": {
"google-gmail": {
"type": "stdio",
"command": "npx",
"args": ["-y", "mcp-google-gmail@latest"],
"env": {
"GOOGLE_GMAIL_CLIENT_ID": "${input:gmail_client_id}",
"GOOGLE_GMAIL_CLIENT_SECRET": "${input:gmail_client_secret}",
"GOOGLE_GMAIL_REFRESH_TOKEN": "${input:gmail_refresh_token}"
}
}
},
"inputs": [
{ "type": "promptString", "id": "gmail_client_id", "description": "Google OAuth client ID" },
{ "type": "promptString", "id": "gmail_client_secret", "description": "Google OAuth client secret", "password": true },
{ "type": "promptString", "id": "gmail_refresh_token", "description": "Google OAuth refresh token", "password": true }
]
}Check it with MCP: List Servers.
What you can ask it to do
Triage the inbox
Show unread messages from the last seven days and group them by sender.
Find the conversation with Acme about the contract and summarize it, oldest to newest.
Which messages have attachments waiting for me? Show subjects and file names.
Write and send email
Draft a reply in this thread saying the signed copy goes out on Friday.
Show me the draft, tighten the wording, then send it.
Send a short status email to the team, with the manager in CC.
Keep the mailbox organized
Create a label
Receipts/2026and apply it to the matching messages.Mark this week's newsletters as read and archive them.
Move that thread to the trash — and restore it if I change my mind.
How mail changes
The safe path to sending is a draft:
create_draftprepares the email,get_draftshows it for review,send_draftsends it.send_messageskips the draft and sends immediately.A sent email is externally irreversible. After a timeout or a
5xxerror the server does not re-send; searchin:sentbefore trying again, because a replayed send would be a double-sent email.Removing a message or thread means trashing it.
manage_trashis reversible for about 30 days; there is deliberately no permanent-delete tool.Drafts are the exception:
update_draftreplaces the whole draft (the API has no partial edit) anddelete_draftis permanent, because drafts skip the trash.
Every call works on one mailbox — the account that granted the token. Decoded bodies are truncated at a configurable limit with explicit flags, and attachments come back as metadata only; attachment content is fetched through raw_request deliberately.
What can change
Operation | What happens | Confirmation boundary |
Search and read messages, threads, drafts, labels, the profile | Reads mailbox data | No change |
Create or update a draft | Prepares or replaces an unsent email | Changes the mailbox |
Change read, starred or archived state, apply or strip labels | Changes how mail is organized | Changes the mailbox |
Create or rename a label | Changes the label vocabulary | Changes the mailbox |
Trash or untrash a message or thread | Moves mail to or from the trash; reversible for ~30 days | Destructive |
Send an email or a draft | Delivers mail to real recipients; cannot be unsent | Destructive |
Delete a draft or a label | Removes it permanently, skipping the trash | Destructive |
Raw API request | Can call API methods without a dedicated tool | Potentially destructive |
The AI client controls confirmation prompts. The server marks reads, writes and destructive tools so the client can distinguish an inspection from a live change.
Getting access
Gmail requires OAuth 2.0; an API key is not enough.
Create or select a Google Cloud project and enable the Gmail API.
Configure the OAuth consent screen and create a Desktop app OAuth client.
Authorize the Google account whose mailbox you want to connect — every call works on that one mailbox. The OAuth 2.0 Playground can obtain the refresh token when Use your own OAuth credentials is enabled.
Request the scope:
https://www.googleapis.com/auth/gmail.modifyIt covers search, reading, sending, drafts, labels and the trash — but not permanent deletion and not Gmail settings. Permanent deletion through
raw_requestadditionally requires the fullhttps://mail.google.com/scope.
Testing-mode OAuth refresh tokens can expire after seven days. Publish the OAuth app, or use an Internal app in a Workspace domain, when you need long-lived access. Treat the client secret and refresh token as passwords.
Configuration
Variable | Required | Description |
| Yes* | OAuth client ID. |
| Yes* | OAuth client secret. |
| Yes* | OAuth refresh token. |
| Yes* | Short-lived alternative to the OAuth trio (about 1 hour). |
| No | Gmail API base URL override. |
| No | Per-request timeout; default |
| No | Temporary-error retries; default |
* Provide either the OAuth trio or an access token.
Data, limits and background work
Requests go to Gmail. The local server refreshes Google OAuth tokens and calls the Gmail API. Its anonymous telemetry contains an installation ID, package version, AI client and platform versions, and tool names — never OAuth tokens, mail content, tool arguments or prompts. Set
ASKADS_TELEMETRY=0to opt out.Google meters quota units. Gmail allows roughly 250 quota units per second per user; a send costs 100 units, a typical read 5. Consumer accounts can send about 500 emails a day, Workspace accounts about 2,000. On
429, the server uses backoff; reads also retry after network and5xxerrors, while sends and other writes are never replayed after an uncertain failure.There is no background polling. The server runs only when called. If your AI app supports scheduled tasks, it can check the inbox periodically;
raw_requestcan also reachhistory.listfor incremental sync.
Technical documentation
MCP capability catalog — task-oriented pages for every tool.
Support
Found a bug or need a scenario? Create an issue or write in Telegram.
Available Tools
18 toolscreate_draftCreate a draftA
Creates a draft email in the mailbox without sending anything. All fields are optional — an empty draft is legal — but a useful one carries to[], subject and a body. For a reply draft set thread_id, in_reply_to (headers.messageId of the message being answered, via get_message) and the original subject with "Re: ". Returns the draft id (needed by update_draft/send_draft/delete_draft) and the underlying message id/threadId. Drafting first and sending with send_draft after a human look is the safe path for consequential mail — prefer it over send_message when in doubt.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | Carbon-copy recipients. | |
| to | No | Primary recipients (optional for a draft). | |
| bcc | No | Blind-copy recipients. | |
| subject | No | The subject line. | |
| body_html | No | HTML body (multipart/alternative when body_text is also set). | |
| body_text | No | Plain-text body. | |
| thread_id | No | Make it a reply draft in this thread (pair with in_reply_to and a matching subject). | |
| references | No | Explicit References header chain (defaults to in_reply_to). | |
| in_reply_to | No | RFC Message-ID of the message being replied to (headers.messageId from get_message). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations, the description discloses that nothing is sent, that an empty draft is legal, and that the return value includes the draft id plus underlying message id/threadId. It also explains the safe workflow of draft-then-send. This gives the agent an accurate behavioral model for a write action.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is four sentences, front-loaded with the core purpose and non-sending guarantee, then optionality, reply recipe, return value, and usage routing. Every sentence contributes actionable information without redundancy or fluff. The structure makes it easy for an agent to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a draft-creation tool with nine optional parameters, no output schema, and no destructive/read-only annotations, this description is complete. It covers purpose, side effects, parameter relationships, return value, required follow-up tools, and when to prefer this tool over send_message. An agent can invoke it correctly without needing additional context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already provides 100% parameter coverage with descriptions for every field, so the baseline is 3. The description adds meaningful guidance beyond the schema by clarifying that all fields are optional and by providing the reply-draft pattern for thread_id, in_reply_to, and subject. It does not elaborate on cc/bcc/body fields, but the schema already handles those adequately.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific operation: creates a draft email in the mailbox without sending. It differentiates from related tools by explicit no-send behavior and by naming the draft id consumers (update_draft/send_draft/delete_draft). The purpose is unmistakable even without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly tells the agent when to use this tool over send_message: draft first and send with send_draft after human review, prefer it for consequential mail. It also gives the exact recipe for reply drafts (thread_id, in_reply_to, subject with "Re: ") and points to get_message for the required messageId. This is clear routing guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_draftDelete a draftADestructive
PERMANENTLY deletes a draft — drafts skip the trash, so there is no undo and no manage_trash recovery. Confirm with get_draft before deleting anything the user might still want. Returns empty on success.
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes | The draft id from list_drafts or create_draft output. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Although destructiveHint=true already signals danger, the description adds critical context: deletion is permanent, there is no undo, drafts do not go to trash, and the operation returns empty on success. This goes well beyond the annotation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two highly informative sentences, front-loaded with 'PERMANENTLY' to emphasize the key trait. Every clause earns its place: irreversibility, no-trash behavior, confirmation guidance, and return value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter destructive tool with annotations and no output schema, the description provides everything needed: the action, the risk, the safety precondition, and the success response. No significant information is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema description coverage and a clear draft_id description citing list_drafts or create_draft output, the schema already fully documents the parameter. The description adds no further parameter semantics, but none are needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'PERMANENTLY deletes a draft'. It also distinguishes this tool from siblings like manage_trash by clarifying drafts skip the trash, making the tool's unique purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives an explicit precondition: 'Confirm with get_draft before deleting anything the user might still want.' It also explains why alternatives like manage_trash cannot recover the draft, which helps the agent decide when and how to use the tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_draftRead a draftARead-onlyIdempotent
Fetches one draft with its message decoded like get_message: headers (to, cc, subject, ...), text body, HTML only on request, attachment metadata. Use it to show the user what send_draft would send, or to read the current content before update_draft (updates REPLACE the whole draft).
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes | The draft id from list_drafts or create_draft output. | |
| include_html | No | Return the decoded HTML body even when a text body exists (default false). | |
| max_body_chars | No | Truncate each decoded body at this many characters (default 50000; a truncation flag is set when cut). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, idempotent, openWorld, and non-destructive behavior. The description adds useful behavioral detail beyond that: the draft is decoded like get_message, HTML is returned only on request, and attachment metadata is included. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences with no filler. The first sentence front-loads the core behavior and return contents, and the second sentence delivers actionable usage context and an important warning. Every clause earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only tool with one required parameter, the description covers what the tool returns, how it behaves, when to use it, and why it matters before update_draft. The annotations cover safety and idempotency, so nothing important is missing for an agent to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds some context by noting that include_html controls whether HTML is returned and that text body may exist, but it does not materially explain draft_id or max_body_chars beyond what the schema already states.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb ('Fetches one draft'), a clear resource ('draft'), and enumerates what is returned (headers, text body, HTML on request, attachment metadata). It also distinguishes itself from get_message by explicitly modeling on it while targeting drafts, so an agent can select it without confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides explicit usage guidance: use it to show what send_draft would send, or to read current content before update_draft. It even warns that updates REPLACE the whole draft, giving a concrete reason to call this tool first. This clearly frames when to use it relative to its sibling tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messageRead a messageARead-onlyIdempotent
Fetches one message fully decoded: headers (from, to, cc, subject, date, messageId, inReplyTo, references — RFC 2047 words decoded), the plain-text body (base64/charset decoded), the HTML body when there is no text part or include_html=true, and attachment METADATA (filename, mimeType, sizeBytes, attachmentId — never the content; download bytes via raw_request users/me/messages//attachments/ if truly needed). Bodies are truncated at max_body_chars (default 50000) with textTruncated/htmlTruncated flags. metadata_only=true skips bodies entirely. To reply later, keep headers.messageId (for in_reply_to) and threadId.
| Name | Required | Description | Default |
|---|---|---|---|
| message_id | Yes | The message id from list_messages/get_thread output (not the RFC Message-ID header). | |
| include_html | No | Return the decoded HTML body even when a text body exists (default false). | |
| metadata_only | No | Headers and structure only, no body content. | |
| max_body_chars | No | Truncate each decoded body at this many characters (default 50000; a truncation flag is set when cut). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already declaring readOnlyHint, openWorldHint, idempotentHint, and destructiveHint, the description goes far beyond them. It discloses concrete behavioral details: base64/charset decoding of bodies, truncation at max_body_chars with textTruncated/htmlTruncated flags, conditional HTML-only inclusion, and the fact that attachment content is never returned (only metadata). This transparency is essential for a tool that could otherwise surprise an agent with size limits or missing content. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but well-organized; it front-loads the primary action and then systematically details return components, truncation rules, and alternatives. Every sentence imparts critical information about behavior or edge cases. It is slightly long but justifiably so for a tool with decoding, truncation, and attachment-handling nuances. No filler or redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description must carry the full burden of return-value explanation, and it does: it enumerates decoded headers, plain-text and HTML bodies, attachment metadata (not content), truncation flags, and how to obtain actual bytes via raw_request. It also covers conditional behavior (include_html) and the metadata_only shortcut. An agent has all the information needed to call this tool correctly and interpret its results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, but the description adds meaningful semantics beyond the schema's terse descriptions. It clarifies that message_id is not the RFC Message-ID header, explains the effect of include_html (return HTML even when a text body exists), metadata_only skips bodies entirely, and max_body_chars truncates with a flag. This enriches the parameter meanings, though the schema definitions already cover basic intent, so the value-add is high but not exhaustive.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb-resource pair ('Fetches one message fully decoded') and enumerates exactly what is returned (headers, bodies, attachment metadata). It clearly distinguishes itself from list_messages (listing) and get_thread (thread-level) by focusing on a single message. The level of detail leaves no ambiguity about the tool's scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied by the purpose ('Fetches one message') and the note 'To reply later, keep headers.messageId', but the description does not explicitly state when to use this tool versus siblings like get_thread, list_messages, or get_draft. No exclusions or alternative-routing conditions are given beyond the attachment-bytes mention for raw_request. The guidance is largely implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_profileGet the mailbox profileARead-onlyIdempotent
Returns the authenticated mailbox's profile: emailAddress (the user's own address — useful for send-to-self checks and for recognizing the user's messages in threads), messagesTotal, threadsTotal and historyId. The cheapest way to verify that the OAuth credentials work.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, openWorldHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds what the query returns—profile fields—and characterizes the call as the cheapest verification of OAuth credentials, implying minimal overhead. No contradiction exists.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the primary behavior ('Returns the authenticated mailbox's profile') and enumerates the fields. The parenthetical examples are brief and useful, making every phrase informative without padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no input parameters and a read-only annotation set, there is little an agent needs to know beyond what the tool returns; the description covers the key fields and even adds a practical use case. The absence of an output schema is mitigated by the explicit field list.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so the schema is fully described by its empty object and there is nothing to document. The description's mention of the response fields is not parameter semantics but does give the agent insight into what it gets back.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses the specific verb 'Returns' and identifies the resource as 'the authenticated mailbox's profile', enumerating the exact fields (emailAddress, messagesTotal, threadsTotal, historyId). This clearly differentiates it from sibling tools that operate on messages, threads, drafts, or labels.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states the tool is 'The cheapest way to verify that the OAuth credentials work', which tells an agent when to use it. It also mentions the emailAddress field is useful for send-to-self checks and recognizing the user's messages, providing practical context. It does not name exclusionary alternatives, but the resource is unique among siblings.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threadRead a whole conversationARead-onlyIdempotent
Fetches a conversation with every message decoded like get_message: headers, text bodies (HTML only when a message has no text part or include_html=true), attachment metadata and truncation flags. Messages come oldest-first. To reply to the conversation, take the LAST message's threadId, headers.messageId and subject and pass them to send_message (thread_id, in_reply_to, subject with "Re: "). Long threads can be large — lower max_body_chars (it applies per message) when only the gist is needed.
| Name | Required | Description | Default |
|---|---|---|---|
| thread_id | Yes | The thread id from list_threads or from a message's threadId field. | |
| include_html | No | Return decoded HTML bodies even when a text body exists (default false). | |
| max_body_chars | No | Truncate each decoded body at this many characters (default 50000; a truncation flag is set when cut). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark it read-only and idempotent; the description adds meaningful behavioral detail beyond that: messages are oldest-first, HTML is only returned under certain conditions, attachment metadata and truncation flags are included, and large threads can be resource-heavy. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Every sentence earns its place: core behavior, ordering, reply workflow, and performance guidance. It is dense but well-structured and front-loaded with the most important information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description compensates by specifying what messages contain, the ordering, truncation behavior, and the reply workflow. For a read-only tool with rich annotations, this is complete enough for an agent to select and invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds operational meaning: max_body_chars applies per message and should be lowered when only the gist is needed, and include_html only matters when a text body already exists. This goes beyond the schema's descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource: 'Fetches a conversation with every message' decoded like get_message. The scope (whole conversation vs. individual message) is clear and distinguishes it from the sibling get_message without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear practical usage context, including how to reply using the last message's IDs, and when to lower max_body_chars for large threads. It does not explicitly state when not to use this tool versus alternatives like get_message or list_threads, so it stops short of a 5.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_draftsList draftsARead-onlyIdempotent
Lists the mailbox's drafts: draft id plus the underlying message's id and threadId (no subjects — read one with get_draft). query filters with Gmail query syntax (e.g. subject:invoice); paginate with page_token from nextPageToken.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Gmail query syntax, e.g. "from:amy@example.com is:unread newer_than:7d has:attachment subject:invoice". Same operators as the Gmail search box. | |
| page_size | No | Drafts per page (1..500, API default 100). | |
| page_token | No | nextPageToken from the previous page. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, openWorldHint, and destructiveHint=false, lowering the bar. The description adds valuable behavior beyond annotations: it returns only envelope fields rather than full content, supports Gmail query syntax, and paginates with nextPageToken, which helps the agent know exactly what to expect.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler, front-loading the core purpose and return shape before adding usage details. Every clause contributes: scope, fields returned, exclusions, query syntax, and pagination.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only listing tool, the description is complete: it covers return fields, the notable absence of subjects, the query filter mechanism, and pagination. There is no output schema, but the description supplies the key return information an agent needs, and the annotations already cover safety and idempotency.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema fully documents query, page_size, and page_token. The description mentions query filtering and pagination but does not add meaning beyond what the schema already provides, so the baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States an unambiguous verb+resource ('Lists the mailbox's drafts') and specifies the return shape (draft id, message id, threadId). It explicitly differentiates from the sibling get_draft by noting it returns no subjects and pointing to that tool for full detail, so an agent can distinguish it without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear operational context: query filtering with Gmail syntax and pagination via page_token are described. It gives an exclusion ('no subjects — read one with get_draft'), though it does not systematically contrast with list_messages or list_threads, so it falls just short of fully explicit when/when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_labelsList labelsARead-onlyIdempotent
Without label_id: lists every label in the mailbox — system labels (INBOX, SENT, DRAFT, SPAM, TRASH, UNREAD, STARRED, IMPORTANT, CATEGORY_*) and user labels with their ids — the vocabulary that list_messages label_ids and modify_message add/remove_label_ids speak. With label_id: fetches that one label including its counts (messagesTotal, messagesUnread, threadsTotal, threadsUnread), which the plain list does not carry.
| Name | Required | Description | Default |
|---|---|---|---|
| label_id | No | Fetch one label with counts instead of listing all. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, idempotent, and non-destructive. The description adds behavioral context beyond that: it specifies that system labels are included, and that the plain list does not carry counts, while the single-label fetch does. This is useful supplemental information.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is two sentences, front-loading the default mode and then the optional mode. No wasted words; each sentence earns its place. The structure is logical and easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple tool with one optional parameter and no output schema, the description is complete. It explains both call patterns, what each returns, and its role in the broader API context. There's nothing an agent needs to call it correctly that is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema covers the single parameter at 100%, so baseline is 3. The description adds value by specifying exactly which counts are returned (messagesTotal, messagesUnread, threadsTotal, threadsUnread), which is not in the schema. This elevates the score to 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's function: listing all labels or fetching a specific label with counts, distinguishing between the two modes. It also positions the tool as the vocabulary source for other tools like list_messages and modify_message, which effectively differentiates it from sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when to use each mode: 'Without label_id' for all labels, 'With label_id' for a single label with counts. It also explains that counts are only available with label_id, providing clear, actionable guidance without ambiguity.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_messagesSearch and list messagesARead-onlyIdempotent
Searches the mailbox with Gmail query syntax and returns one summary per message: id, threadId, labelIds, snippet, from, to, subject, date, internalDate. Filter with query (same operators as the Gmail search box: from:, to:, subject:, is:unread, is:starred, has:attachment, label:, newer_than:7d, before:/after:) and/or label_ids (all must match). Spam and trash are excluded unless include_spam_trash=true. Paginate with page_token from nextPageToken; page_size defaults to 25 (max 100 — each summary costs one metadata read, throttled to a few at a time). A message deleted between the search and its metadata read is skipped, so a page can hold slightly fewer summaries than page_size. Set include_metadata=false to get bare ids only (cheapest). resultSizeEstimate is an estimate, not an exact count. Read a full body with get_message; read a whole conversation with get_thread.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Gmail query syntax, e.g. "from:amy@example.com is:unread newer_than:7d has:attachment subject:invoice". Same operators as the Gmail search box. | |
| label_ids | No | Only messages carrying ALL of these label ids (see list_labels). | |
| page_size | No | Messages per page (1..100, default 25). | |
| page_token | No | nextPageToken from the previous page. | |
| include_metadata | No | false = bare ids only, no per-message metadata reads (default true). | |
| include_spam_trash | No | Also search SPAM and TRASH (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations cover readOnly/idempotent/non-destructive, and the description adds substantial behavioral context: pagination via nextPageToken, page_size defaults and throttling, skipped deleted messages causing short pages, resultSizeEstimate being an estimate, and metadata-read costs. This goes far beyond what annotations already provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place, moving from the core search behavior to return shape, filtering, pagination, edge cases, cost options, and alternatives. It is front-loaded with the most important purpose and keeps the reader oriented.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With no output schema, the description needs to explain return values, and it does: summary fields are listed and the bare-id alternative is described. It also covers filtering, exclusion behavior, pagination, incomplete-page edge cases, and alternative tools, making the definition complete for correct selection and invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds important meaning: query uses Gmail search-box operators, label_ids must all match, page_size has cost implications per metadata read, page_token comes from nextPageToken, and include_metadata=false switches to bare ids only. These are practical semantics an agent needs to invoke the tool well.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Searches the mailbox with Gmail query syntax' and returns per-message summaries. It clearly distinguishes itself from related tools by saying a full body should be read with get_message and a whole conversation with get_thread.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit when-to-use guidance: filtering via query/label_ids, excluding spam/trash unless include_spam_trash=true, and the tradeoff between include_metadata=false for cheapest results. It also routes to alternatives for body and thread retrieval, leaving no ambiguity about which sibling to pick.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_threadsSearch and list threadsARead-onlyIdempotent
Searches conversations (threads) with the same Gmail query syntax as list_messages and returns id, snippet (of the latest message) and historyId per thread. Use this instead of list_messages when the unit of work is a conversation — triaging an inbox, finding a discussion to reply into. Filter with query and/or label_ids; paginate with page_token from nextPageToken (page_size max 500). Read the full conversation with get_thread.
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | Gmail query syntax, e.g. "from:amy@example.com is:unread newer_than:7d has:attachment subject:invoice". Same operators as the Gmail search box. | |
| label_ids | No | Only threads carrying ALL of these label ids (see list_labels). | |
| page_size | No | Threads per page (1..500, API default 100). | |
| page_token | No | nextPageToken from the previous page. | |
| include_spam_trash | No | Also search SPAM and TRASH (default false). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already establish read-only, idempotent, and non-destructive behavior, so the description doesn't need to repeat that. It adds value beyond annotations by specifying that the snippet comes from the latest message, how pagination works, and that the same Gmail query syntax applies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three sentences, each with a distinct job: what the tool returns, when to choose it over list_messages, and how to filter/paginate/follow up. No filler or repetition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given there is no output schema, the description names the per-thread return fields and points to get_thread for full content. It doesn't mention include_spam_trash or default ordering, but those are fully covered by the schema and are not essential to tool selection or invocation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so query, label_ids, page_size, page_token, and include_spam_trash are all fully documented in the schema. The description only restates filtering and pagination at a high level and adds no parameter-level meaning beyond what the schema already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb ('Searches'), a clear resource ('conversations (threads)'), and the exact return payload (id, snippet, historyId). It also distinguishes itself from list_messages by naming the different unit of work, so an agent can tell them apart immediately.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly says 'Use this instead of list_messages when the unit of work is a conversation' and gives concrete examples like triaging an inbox or finding a discussion to reply into. It also points to get_thread for full conversation content and describes pagination mechanics.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_labelsCreate, rename or delete a labelADestructive
Manages user labels. action=create needs name (nest with "/", e.g. "Clients/Acme" — the parent must already exist). action=update needs label_id plus at least one of name, label_list_visibility (show | show_if_unread | hide — the label in the sidebar) or message_list_visibility (show | hide — its messages in the list); only the provided fields change. action=delete needs label_id and removes the label from EVERY message it was applied to — the messages survive, the label and its message-associations do not; this cannot be undone. System labels (INBOX, STARRED, ...) cannot be created, renamed or deleted. To apply/remove labels on mail, use modify_message or modify_thread, not this tool.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | create (required) / update: the label name, e.g. "Invoices" or nested "Clients/Acme". | |
| action | Yes | What to do with the label. | |
| label_id | No | update/delete: the user label to target. | |
| label_list_visibility | No | Sidebar visibility of the label itself. | |
| message_list_visibility | No | Whether the label's messages show in the message list. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the annotations (destructiveHint=true, readOnlyHint=false), the description discloses concrete consequences: delete removes the label from every message, messages themselves survive, and the operation cannot be undone. It also states that only provided fields change on update and that system labels are immutable, giving essential behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence earns its place: action rules, nested-name example, visibility semantics, deletion consequences, system-label restrictions, and routing to sibling tools. It front-loads the primary verb and resource before going into conditional details.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With three conditional action modes, five parameters, no output schema, and destructive behavior, the description covers every invocation-relevant concern: prerequisites, field-change semantics, multi-message deletion effects, irreversibility, and excluded label types. A correct call can be constructed from the description alone.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema covers all five parameters, the description adds conditional semantics the schema cannot express: create requires name with optional nesting and an existing parent, update requires label_id plus at least one other field, and delete requires only label_id. It also clarifies what each visibility enum controls in the sidebar versus the message list, materially improving invocation correctness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The title and description name a specific resource—user labels—and three explicit operations: create, rename/update, delete. It immediately separates label management from modifying messages by directing to modify_message/modify_thread, so an agent can distinguish it from sibling tools without inspecting schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly states when not to use the tool ('To apply/remove labels on mail, use modify_message or modify_thread, not this tool') and narrows scope by excluding system labels. It also provides clear action-by-action usage rules, so the agent knows exactly which sibling handles message-level label operations.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
manage_trashTrash or restore mailADestructiveIdempotent
Moves a message or a whole thread to the Gmail trash, or restores it. action=trash is REVERSIBLE: Gmail keeps trashed mail for about 30 days, then deletes it permanently; action=untrash restores it before that happens. target=message (default) uses a message id, target=thread trashes/restores every message in the thread. This server intentionally has no permanent-delete tool — the trash is the safety net. Note: untrash does not re-add INBOX; follow up with modify_message archived=false if it should reappear in the inbox.
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The message id (target=message) or thread id (target=thread). | |
| action | Yes | trash = move to trash (reversible), untrash = restore. | |
| target | No | What the id refers to (default message). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description richly discloses behaviors beyond the annotations: trash is reversible for about 30 days before permanent deletion, target=thread acts on every message in the thread, untrash does not re-add INBOX, and the server deliberately has no permanent-delete tool. These are precisely the behavioral facts an agent needs to avoid irreversible mistakes and to reason about side effects. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, all information-dense and non-redundant. The core action is front-loaded, followed by reversibility, target semantics, server policy, and the INBOX follow-up. Every sentence earns its place with no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a destructive-but-reversible mutation tool with no output schema, the description covers all essential calling considerations: required parameters, target modes, reversibility window, permanent deletion caveat, and the needed follow-up to restore INBOX presence. Combined with the annotations, an agent has enough context to call this tool safely and correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Even though schema coverage is 100%, the description adds meaningful semantics beyond the schema: it explains the 30-day retention meaning of action=trash, the thread-wide effect of target=thread, the default target=message, and the INBOX caveat for untrash. These details transform the enum values into actionable behavior.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states exactly what the tool does: 'Moves a message or a whole thread to the Gmail trash, or restores it.' This is a specific verb+resource statement that clearly distinguishes it from sibling tools like modify_message, manage_labels, and delete_draft. The title and description are aligned and unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit context for when to use this tool: trashing/untrashing mail or threads, with no permanent-delete alternative intentionally available. It also warns that untrash does not re-add INBOX and directs the agent to follow up with modify_message archived=false when inbox restoration is needed. This is clear routing guidance beyond the schema.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modify_messageChange message labels / stateADestructiveIdempotent
Changes a message's state via Gmail labels: read=true/false marks read/unread, starred=true/false stars/unstars, archived=true removes it from the inbox (archived=false moves it back), and add_label_ids/remove_label_ids apply or strip any labels from list_labels (e.g. a user label, or IMPORTANT). At least one change is required; applying the same change twice is harmless. This never deletes anything — use manage_trash for the trash. Returns the message's new id/labelIds.
| Name | Required | Description | Default |
|---|---|---|---|
| read | No | true = mark read, false = mark unread. | |
| starred | No | true = star, false = unstar. | |
| archived | No | true = archive (remove from inbox), false = move back to inbox. | |
| message_id | Yes | The message id from list_messages/get_thread output (not the RFC Message-ID header). | |
| add_label_ids | No | Label ids to add. | |
| remove_label_ids | No | Label ids to remove. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations mark destructiveHint=true, while the description asserts 'This never deletes anything — use manage_trash for the trash.' This categorical non-deletion claim conflicts with the machine-readable destructive hint, creating an inconsistent safety profile. The description adds useful detail (idempotence, return value), but per rubric any contradiction with annotations scores 1.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is front-loaded with the core action and parameter summary, then proceeds to constraints, safety, sibling routing, and return value. Every sentence adds information; there is no filler or duplication of the schema beyond what helps clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 6-parameter mutating tool with no output schema, the description covers what the agent must know: parameter effects, required-change condition, idempotency, safety boundary, and the return shape (new id/labelIds). Minor omissions like explicit error behavior when no change is supplied are acceptable because the constraint is stated.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description adds value beyond the schema by stating the cross-parameter invariant 'At least one change is required,' explaining idempotence, and giving concrete examples of label ids (IMPORTANT, Label_123). This pushes it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The opening line 'Changes a message's state via Gmail labels' names a specific verb and resource, and the body enumerates the exact state transitions (read, starred, archived, add/remove labels). It also distinguishes itself from the sibling manage_trash by explicitly stating 'This never deletes anything — use manage_trash for the trash.'
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear invocation guidance: at least one change is required, duplicate changes are harmless, and trash-related operations should go to manage_trash. It doesn't explicitly contrast with modify_thread or other state-changing siblings, so it isn't a full when-to-use map but is sufficiently clear for most routing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
modify_threadChange thread labels / stateADestructiveIdempotent
Applies the same normalized state changes as modify_message — read/unread, starred, archived, add_label_ids/remove_label_ids — to EVERY message in a conversation at once. Use it to mark a whole conversation read or archive it in one call instead of looping over messages. At least one change is required; repeating the same change is harmless. Returns the thread's new id and message label state.
| Name | Required | Description | Default |
|---|---|---|---|
| read | No | true = mark the whole thread read, false = unread. | |
| starred | No | true = star, false = unstar. | |
| archived | No | true = archive (remove from inbox), false = move back to inbox. | |
| thread_id | Yes | The thread id from list_threads or from a message's threadId field. | |
| add_label_ids | No | Label ids to add to every message. | |
| remove_label_ids | No | Label ids to remove from every message. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already carry the read-only/destructive/idempotent profile. The description adds useful context beyond that: the whole-thread scope, the requirement that at least one change be present, the idempotent behavior that repeated identical changes are harmless, and the return value ('thread's new id and message label state'). No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three compact sentences with no filler. The action and scope are front-loaded, followed by when to use it, the usage constraint, and the return behavior. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite the lack of an output schema, the description states what is returned. Combined with the fully documented parameter schema and annotations covering safety/idempotence/destructiveness, an agent has everything needed to select and invoke the tool correctly. The only minor gap is alternative-selection wording, which is already addressed in usage guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and each parameter already has a detailed description, putting this at baseline 3. The description adds value by enumerating which fields count as 'changes' and by stating the non-schema constraint that at least one change is required. It does not add syntax details, but they are not needed given the schema's completeness.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a precise action — applying the same normalized state changes as modify_message — but scoped to 'EVERY message in a conversation at once'. It lists the exact state dimensions (read/unread, starred, archived, add_label_ids/remove_label_ids), so there is no ambiguity about what the tool operates on.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It explicitly explains when to use the tool: mark a whole conversation read or archive it in one call instead of looping over messages. It references modify_message as the baseline sibling, but stops short of explicitly saying 'use modify_message for a single message', so it lacks a full when-not statement.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
raw_requestRaw Gmail API callADestructive
Escape hatch to call any Gmail API v1 path directly, for requests the typed tools don't cover — e.g. downloading attachment content ("gmail/v1/users/me/messages//attachments/", returns base64url data), history.list for incremental sync ("gmail/v1/users/me/history?startHistoryId=..."), batchModify, or settings endpoints (filters, forwarding, vacation). The path may carry a query string. The Bearer token is added automatically; the method defaults to GET. CAUTION: this bypasses the typed tools' guard rails — users/me/messages/ DELETE is a PERMANENT delete that skips the trash (needs the full https://mail.google.com/ scope); prefer manage_trash.
| Name | Required | Description | Default |
|---|---|---|---|
| body | No | JSON request body (POST/PUT/PATCH). | |
| path | Yes | API path relative to https://gmail.googleapis.com, e.g. "gmail/v1/users/me/history?startHistoryId=123". | |
| method | No | HTTP method. Defaults to GET. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, it discloses that the Bearer token is added automatically, the method defaults to GET, and that DELETE is a PERMANENT delete skipping trash and requiring the full mail.google.com scope. This meaningfully extends the annotation hints without contradicting them.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but each clause serves a purpose: purpose, examples, mechanics, and a prominent safety warning. It is front-loaded with the core escape-hatch meaning and remains scannable despite its length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a raw open-world API tool with no output schema, the description covers the critical invocation details: path, query strings, auth, method default, and destructive risk. It does not describe the general response shape or error behavior, but it does show one concrete return format (base64url data), which is reasonable for an escape-hatch tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 100% schema coverage, the baseline is 3. The description adds value by showing exact path patterns, mentioning query strings are allowed, and clarifying the default GET method. It does not deeply elaborate on the body parameter, but the schema already covers it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: call any Gmail API v1 path directly. It also explicitly positions the tool as an escape hatch for requests the typed tools don't cover, using concrete endpoint examples that distinguish it from the typed sibling tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives clear when-to-use guidance: for attachment downloads, history.list, batchModify, and settings endpoints. It also gives a when-not-to-use warning: prefer manage_trash for deletes, because this bypasses guard rails and can permanently delete messages.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_draftSend a draftADestructive
Sends an existing draft exactly as it is stored, immediately and irreversibly; the draft disappears from the drafts list and becomes a sent message (returned id/threadId). Verify the content with get_draft before calling this. NEVER retried after a timeout or 5xx (a duplicate email cannot be unsent): if the outcome is unclear, check list_drafts (the draft is gone if it was sent) or list_messages in:sent before considering anything else. Daily sending limits apply (~500/day consumer, ~2000/day Workspace).
| Name | Required | Description | Default |
|---|---|---|---|
| draft_id | Yes | The draft id from list_drafts or create_draft output. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Even though annotations already include destructiveHint=true and idempotentHint=false, the description adds meaningful detail: the side effect on the drafts list, the irreversibility of sending, the duplicate-email risk on retry, and rate-limit constraints. This goes well beyond what structured fields convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each with a distinct job: state the effect and output, instruct pre-call verification, explain no-retry and outcome checks, and list rate limits. There is no filler; the length is justified by the destructive, non-idempotent nature of the tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema, this description covers the returned id/threadId, the verification step, ambiguous-outcome handling, and sending limits. An agent has all the information needed to invoke it safely and detect whether it succeeded.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents 'The draft id from list_drafts or create_draft output.' The description's mention of 'existing draft' and 'verify the content with get_draft' is more about behavioral context than parameter semantics, so it meets the baseline without needing to compensate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific action and resource: 'Sends an existing draft exactly as it is stored, immediately and irreversibly.' It also states the concrete outcome (draft disappears, becomes a sent message with returned id/threadId), and the focus on 'existing draft' distinguishes it from send_message, which creates a new message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance: verify with get_draft before calling and never retry after timeout or 5xx because duplicates cannot be unsent. It also names fallback checks, list_drafts and list_messages in:sent, plus daily sending limits, providing clear context for choosing between this tool and alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
send_messageSend an emailADestructive
Sends an email from the authenticated mailbox, immediately and irreversibly. Requires at least one recipient across to/cc/bcc (a bcc-only send is fine — to may be omitted) and at least a subject or a body; body_text and body_html together become multipart/alternative. TO REPLY IN A THREAD: call get_message on the message being answered first, then pass its threadId as thread_id, its headers.messageId as in_reply_to, and the same subject prefixed with "Re: " — Gmail threads the reply only when all three line up. Returns the sent message's id, threadId and labelIds. NEVER retried after a timeout or 5xx (a duplicate email cannot be unsent): if the outcome is unclear, search list_messages with in:sent before considering a re-send. Everyday accounts can send ~500 emails/day (Workspace ~2000); exceeding it disables sending for hours.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | Carbon-copy recipients. | |
| to | No | Primary recipients. Optional when cc or bcc carries at least one recipient (bcc-only send). | |
| bcc | No | Blind-copy recipients. | |
| subject | No | The subject line. For replies use the original subject with "Re: ". | |
| body_html | No | HTML body (sent as multipart/alternative when body_text is also set). | |
| body_text | No | Plain-text body. | |
| thread_id | No | Reply into this thread (pair with in_reply_to and a matching subject). | |
| references | No | Explicit References header chain (defaults to in_reply_to). | |
| in_reply_to | No | RFC Message-ID of the message being replied to (headers.messageId from get_message). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond annotations, the description discloses irreversibility, no-retry semantics, Gmail threading prerequisites, multipart/alternative body handling, return fields, and daily sending limits. This is exactly the behavioral context needed for a destructive, non-idempotent tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is dense but every sentence carries essential information, and the layout front-loads the core send semantics before threading, retry, and rate-limit guidance. The all-caps cues ('TO REPLY IN A THREAD', 'NEVER retried') make the critical instructions easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex send operation with no output schema, the description covers inputs, output fields, failure handling, verification path, and rate limits. An agent has enough to invoke correctly and know what to do when the outcome is unclear.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Although the schema already documents each parameter, the description adds cross-parameter rules: at least one recipient across to/cc/bcc, bcc-only allowed, subject or body required, and how thread_id/in_reply_to/subject must align for threading. It also clarifies references defaults to in_reply_to.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb and resource: it sends an email from the authenticated mailbox, and adds 'immediately and irreversibly' to define the behavior precisely. This clearly distinguishes send_message from sibling draft tools and read-only tools such as list_messages or get_message.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives explicit when-to-use guidance for replies: call get_message first, then pass threadId, in_reply_to, and 'Re: ' subject. It also tells the agent not to retry after timeout or 5xx and to verify via list_messages, but it does not explicitly route users to create_draft/send_draft for non-immediate sends.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_draftUpdate a draftADestructiveIdempotent
REPLACES a draft's entire message — the Gmail API has no partial draft edit, so omitted fields are dropped, not kept. Read the current content with get_draft first, then pass the complete new state (recipients, subject, body, and thread_id/in_reply_to for reply drafts). The draft id stays the same; the underlying message id changes. Returns the updated draft.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | Carbon-copy recipients. | |
| to | No | Primary recipients (optional for a draft). | |
| bcc | No | Blind-copy recipients. | |
| subject | No | The subject line. | |
| draft_id | Yes | The draft id from list_drafts or create_draft output. | |
| body_html | No | HTML body (multipart/alternative when body_text is also set). | |
| body_text | No | Plain-text body. | |
| thread_id | No | Make it a reply draft in this thread (pair with in_reply_to and a matching subject). | |
| references | No | Explicit References header chain (defaults to in_reply_to). | |
| in_reply_to | No | RFC Message-ID of the message being replied to (headers.messageId from get_message). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description discloses critical behavioral traits beyond the annotations: omitted fields are dropped, the draft id remains stable, the underlying message id changes, and the response is the updated draft. The destructiveHint is consistent and the description enriches it by explaining exactly what gets replaced and what side effect occurs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Four sentences, each carrying distinct information: the replacement semantics, the prerequisite, the state behavior, and the return value. The 'REPLACES' warning is front-loaded, and there is no filler or redundant restating of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 10-parameter tool with no output schema, the description is largely complete: it covers prerequisites, full-replacement semantics, reply-draft specifics, id stability, and the return value. It doesn't enumerate every parameter but the schema already does that. A brief note on error conditions or permissions would make it fully complete, but that's a minor gap.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3. The description adds semantic value by explaining that parameters represent the complete new state rather than deltas, and calls out the thread_id/in_reply_to pairing for reply drafts. This goes beyond simple parameter descriptions and prevents common misuse.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with 'REPLACES a draft's entire message', naming the specific verb and resource, and immediately clarifies the key distinguishing trait: this is not a partial edit. It clearly differentiates update_draft from siblings like create_draft and delete_draft by focusing on replacement of an existing draft's full content.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description gives explicit procedural guidance: read current content with get_draft first, then pass the complete new state. It also states when thread_id/in_reply_to are relevant. It doesn't explicitly contrast with alternatives like create_draft or send_draft, but the get_draft prerequisite and full-replacement instruction provide clear usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
18 tool updates
v0.1.0- First observed
create_draft - First observed
delete_draft - First observed
get_draft - First observed
get_message - First observed
get_profile - First observed
get_thread - First observed
list_drafts - First observed
list_labels - First observed
list_messages - First observed
list_threads - First observed
manage_labels - First observed
manage_trash - First observed
modify_message - First observed
modify_thread - First observed
raw_request - First observed
send_draft - First observed
send_message - First observed
update_draft
TDQS
Each tool targets a distinct resource-action pair: message-level and thread-level operations are cleanly separated, direct send vs. draft send are clearly differentiated, and modify_message/manage_trash/list_labels/manage_labels have explicit scopes. The only near-overlap, list_messages vs. list_threads, is resolved by descriptions that tell agents when to use each. No two tools are likely to be confused.
The naming is overwhelmingly verb_noun and snake_case: list_messages, get_thread, create_draft, send_draft, delete_draft, and so on. The minor deviation is raw_request, which is a noun phrase rather than a verb_noun action. Overall the pattern is very predictable.
18 tools is on the heavy side, but the count maps cleanly onto the Gmail domain: message, thread, draft, label, profile, and raw escape-hatch groups. Each tool covers a distinct operation, so the size feels comprehensive rather than bloated. It is slightly above the ideal range but still well-scoped.
The surface covers the full Gmail lifecycle: search/read/send/modify/trash for messages, conversation-level thread operations, draft CRUD plus send, label management, and profile info. The only missing operations, permanent delete and attachment download, are intentionally omitted for safety or covered through raw_request. There are no dead ends for common email workflows.
Maintenance
Related MCP Connectors
Manage Gmail end-to-end: search, read, send, draft, label, and organize threads. Automate workflow…
Manage Gmail messages, threads, labels, drafts, and settings from your workflows. Send and organiz…
Connect any mailbox to Claude, ChatGPT & AI: read, send, reply, schedule & search emails.
Email infrastructure for AI agents — send, receive, search, and reply to email over MCP.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceEnables AI assistants to interact with Gmail through natural language, supporting email sending/reading, searching, draft management, label organization, and batch operations with secure OAuth authentication.-
- AlicenseNot gradedqualityCmaintenanceEnables AI assistants to manage Gmail emails, including sending, searching, and organizing with labels and attachments via OAuth2.531MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Gmail through natural language interactions, including sending, reading, searching emails, and managing labels with auto authentication support.20,6271MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to manage Gmail through natural language, including sending, reading, searching, labeling emails, managing attachments, and performing thread operations.3MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/A1-x-Tech/mcp-google-gmail'
If you have feedback or need assistance with the MCP directory API, please join our Discord server