gmail-accounts
Provides multi-account Gmail integration allowing agents to search, read threads, list drafts, create and update drafts, and send emails with human-approved single-use tokens.
Click on "Deploy 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., "@gmail-accountssearch work for the invoice thread"
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
A multi-account Gmail MCP server for AI agents (Claude Code and anything else that speaks MCP), with one design goal above all: the agent can read and draft freely, but a human must approve every send.
Built because the hosted Gmail connectors bind one account at a time and send
without friction. This server binds any number of Gmail accounts behind short
aliases (work, school, ...) and splits capabilities by risk:
Capability | Who can do it |
Search, read threads, list drafts | Agent, freely |
Create and update drafts | Agent, freely |
Send | Only with a single-use approval token a human mints in a terminal |
The server is registered as gmail-accounts (not gmail) on purpose: if you also
run a hosted Gmail connector, near-identical tool names make an agent read the
wrong mailbox and report a confident false negative.
How the send gate works
The agent stages a draft and asks you to approve it.
You run
gmail-approvein your own terminal, review the exact RFC822 payload, and get a one-time token bound to that draft's content hash.The agent calls the send tool with the token. Wrong draft, edited draft, reused token, expired token: all refused.
The send tool also carries anthropic/requiresUserInteraction, so Claude Code
prompts a human even in bypassPermissions mode. The token CLI is a mistake
interlock; the harness prompt is the enforced boundary.
Related MCP server: Gmail Multi-Inbox MCP Server
Setup
Requires Python 3.12+ and uv.
1. Google Cloud OAuth client
Create a project at console.cloud.google.com, enable the Gmail API, create an OAuth client ID of type Desktop app, and download the JSON to:
~/.config/gmail-mcp/client_secret.json2. Declare your accounts
~/.config/gmail-mcp/accounts.json:
{
"accounts": [
{ "alias": "personal", "email": "alice.personal@gmail.com" },
{ "alias": "work", "email": "alice.work@gmail.com" }
]
}Adding an account later is a config edit plus one auth run; the file is re-read on every call, so no restart is needed.
3. Authorize each account
uv sync
scripts/auth-all.sh # runs the OAuth flow once per alias, skips done onesEach grant is verified against its alias: authorizing the wrong Google account in the browser is detected and refused, not silently stored.
4. Register with Claude Code
claude mcp add gmail-accounts -- uv run --directory /path/to/gmail-mcp --frozen --no-sync gmail-mcpEveryday use
Every tool takes an account alias. Ask the agent things like "search work for
the invoice thread" or "draft a reply on personal". When it is time to send:
gmail-approve # lists pending sends, shows the payload, mints a tokenHealth check:
uv run gmail-mcp-healthSecurity notes
Secrets never enter the repo:
client_secret.jsonand per-account tokens live in~/.config/gmail-mcp/(override withGMAIL_MCP_CONFIG).All config writes are atomic (tmp + fsync + rename); a crash mid-write never leaves a torn file.
stdout is the JSON-RPC channel; nothing in the package may
print()(enforced by ruff T201), so diagnostics cannot corrupt the protocol.
Tests
uv run pytestAvailable Tools
12 toolscreate_draftC
(unconfigured) Create a draft. Pass reply_to_message_id to keep it in-thread.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | Yes | ||
| body | Yes | ||
| account | Yes | ||
| subject | Yes | ||
| reply_to_message_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It communicates that creating a draft is the core action and that reply_to_message_id affects threading, but it does not disclose side effects, account requirements, persistence behavior, or whether creation is reversible. For a mutating tool with zero annotation coverage, this is insufficient.
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 short and the core action is front-loaded in the first sentence. However, the '(unconfigured)' prefix is unnecessary and potentially misleading, and the reply_to_message_id guidance could have been integrated more cleanly. It is concise but not optimally structured.
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?
This is a mutating create operation with six parameters, no output schema, and no annotations, so the description needs to supply substantial context. It only explains the primary action and one threading parameter. Missing are typical draft creation details such as recipient handling, draft persistence, response behavior, and relationship to staged-send workflows. The description is not complete enough for reliable tool 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 0%, so the description must compensate, but it only explains reply_to_message_id. The other parameters (account, to, subject, body, cc) are left to their names and titles alone, with no added semantics, format expectations, or interaction notes. The single parameter hint is useful but does not cover the parameter space 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 'Create a draft', naming the primary verb and resource clearly, and adds a meaningful nuance about reply_to_message_id. The name itself already differentiates it from sibling update_draft, so the core purpose is not ambiguous. The 'unconfigured' prefix is confusing but does not obscure the stated purpose.
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 one usage hint: 'Pass reply_to_message_id to keep it in-thread', which tells the agent when to include that parameter. However, it provides no guidance on when to use create_draft versus siblings like stage_send, send, or update_draft, and no exclusions or prerequisites. Usage context is largely left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_attachmentCRead-only
(unconfigured) Download one attachment to a path.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes | ||
| max_bytes | No | ||
| save_path | Yes | ||
| message_id | Yes | ||
| attachment_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers read-safety, and the description adds the useful fact that the operation writes to a local path. However, it does not disclose overwrite behavior, failure modes, or how max_bytes affects the download. The annotation lowers the bar, so a 3 is appropriate.
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 a single short sentence with the core operation front-loaded. It contains no redundant filler, though the '(unconfigured)' prefix adds slight noise. Overall the structure is appropriately lean.
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 tool with five parameters, four required, and no output schema, this description is too thin. It omits practical details like how to identify attachments, what max_bytes controls, and path expectations. It is minimally usable but not complete enough to guide correct 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 0%, and the description only mentions 'attachment' and 'path.' It does not explain account, message_id, attachment_id, save_path, or max_bytes. The description adds little beyond the self-evident parameter names and titles, so it fails to compensate for the lack of schema 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?
The description states a specific verb and object: 'Download one attachment to a path.' It clearly identifies the tool as a file-download operation and distinguishes it from sibling message/thread tools at a high level. It does not explicitly name or contrast with siblings, so it stops short of a 5.
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?
There is no guidance on when to use get_attachment versus alternatives like get_message or get_thread. The description does not mention criteria, prerequisites, or exclusions, so the agent must infer when this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_messageCRead-only
(unconfigured) One message with bodies and attachment stubs.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes | ||
| message_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds minor behavioral context by stating what is returned (bodies and attachment stubs), which supplements the readOnlyHint annotation. It does not contradict annotations, but it does not explain important behavior such as whether a message can be missing attachments, how stubs are represented, or any rate-limit/auth considerations.
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 very short and mostly front-loaded with the core noun phrase, but the leading '(unconfigured)' is placeholder noise and the structure is a fragment rather than a clear directive. It is concise but not well-formed.
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 two-parameter read-only tool, the description provides a minimal sense of the return shape, but it does not cover parameter semantics, output structure beyond 'bodies and attachment stubs', or when to prefer this over sibling retrieval tools. It is a minimally viable definition with clear gaps.
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 0% and the description provides no explanation of what 'account' or 'message_id' mean, what formats they expect, or how they identify the message. The agent must rely entirely on parameter names, which is insufficient for confident invocation.
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 identifies the resource: one message, and distinguishes it from related tools like get_thread and get_attachment by mentioning bodies and attachment stubs. However, it lacks an explicit verb like 'fetches' or 'retrieves' and does not explicitly contrast it with 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?
No guidance is provided on when to use this tool versus alternatives such as get_thread, search, or get_attachment. The phrase '(unconfigured)' gives no contextual usage information, leaving the agent to infer applicability.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_threadBRead-only
(unconfigured) Thread metadata and snippets; bodies via get_message.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes | ||
| thread_id | Yes | ||
| max_messages | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already establishes that this is a safe read operation, so the description does not need to repeat that. It adds useful return-content context by saying the tool returns snippets rather than full bodies, but it does not disclose behavior around max_messages, ordering, or potential absence of results.
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 very short and mostly front-loaded, but the '(unconfigured)' prefix is noise and the sentence lacks a main verb. It earns points for brevity but loses structure and polish.
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 and 0% schema coverage, the description leaves important context unexplained, such as what 'snippets' means, how max_messages affects results, and what the response shape looks like. The pointer to get_message is helpful, but the overall definition is too sparse for an agent to invoke this tool confidently.
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 0%, yet the description does not explain account, thread_id, or max_messages beyond their property names. 'Thread metadata and snippets' only weakly implies what thread_id and max_messages might mean, so the description adds little value for parameter understanding.
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 that this tool returns thread metadata and snippets, and explicitly points to get_message for full bodies, which differentiates it from the most relevant sibling. It lacks a clear main verb and includes the odd '(unconfigured)' prefix, so it is clear but not a perfect 5.
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 phrase 'bodies via get_message' tells the agent when to use get_thread versus get_message, providing a clear alternative for the key ambiguity. It does not discuss other siblings or broader conditions, but the main routing decision is well covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
label_threadC
(unconfigured) Add or remove labels on a thread.
| Name | Required | Description | Default |
|---|---|---|---|
| add | No | ||
| remove | No | ||
| account | Yes | ||
| thread_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full behavioral burden. It only says labels can be added or removed, but does not disclose whether label names or IDs are expected, whether the operation is idempotent, what happens if a label does not exist, or what mutation side effects occur. For a write tool this is a significant gap.
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 very short and readable, with minimal filler. However, the leading '(unconfigured)' marker adds noise, and the brevity comes at the cost of useful behavioral and parameter context. It is concise but not optimally structured for agent decision-making.
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 annotations, no output schema, and 0% schema parameter coverage, the description alone must make the tool safely invokable. It only states the high-level action, omitting return value behavior, prerequisites, error conditions, and parameter semantics. This is insufficient for a 4-parameter mutation 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?
Schema description coverage is 0%, and the schema supplies only titles and types. The description loosely maps to 'add' and 'remove' parameters, but it does not clarify the expected value format, whether these are label IDs or names, or how account and thread_id relate to the operation. The description does not compensate for the schema's lack of parameter documentation.
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 clear verb and resource: 'Add or remove labels on a thread.' This is unambiguous enough to distinguish it from sibling read-only tools like get_thread and list_labels, though it does not explicitly compare itself to any sibling.
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?
There is no guidance about when to use this tool versus alternatives, no mention of prerequisites like needing existing labels or a valid thread, and no exclusionary context. The only usage signal is implied by the tool name and one-line description.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_accountsARead-only
(unconfigured) List configured accounts and local token state. Call this first.
| 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, so the safety profile is known. The description adds value by mentioning 'local token state' and directing the agent to call it first, which goes beyond a bare read-only label. The meaning of '(unconfigured)' is slightly ambiguous, but it does not contradict 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 a single, front-loaded sentence: it states the action and resource, then gives the procedural instruction 'Call this first.' There is no wasted wording or redundant restating of the tool name.
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 no-parameter, read-only discovery tool, the description conveys what the tool lists and when to invoke it. Since there is no output schema, a bit more detail about the exact shape of the returned token state could help, but the summary-level description is likely adequate for call selection.
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 tool has zero parameters and the input schema is empty, so schema coverage is complete by default. The baseline of 4 applies because there is no parameter semantic gap for the description to fill.
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 a specific verb and resource: 'List configured accounts and local token state.' This clearly distinguishes list_accounts from sibling tools, which deal with labels, messages, threads, and drafts rather than account-level state.
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 phrase 'Call this first' gives explicit procedural guidance, telling the agent this is the entry point before other operations. It does not name exclusions or alternatives, but no sibling appears to be a viable substitute for listing accounts, so the guidance is sufficient.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_draftsCRead-only
(unconfigured) List drafts.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation is consistent with the 'List' action, but the description adds no behavioral context beyond that annotation. It does not mention ordering, pagination, empty results, or any side effects, so the agent gets no extra transparency from the text.
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 brief and front-loaded with the core action, so it is technically concise. However, the '(unconfigured)' prefix adds noise, and the terseness reflects under-specification rather than economical completeness.
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 list tool, the description still leaves key gaps: what 'account' refers to, what a draft is in this context, and what the response contains. With no output schema and no parameter coverage, the agent cannot reliably invoke this tool without guessing.
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 0%, and the description entirely omits what 'account' means, what format it should take (ID, email, name), or how it filters the returned drafts. The agent is left without any semantic guidance for the only required parameter.
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 action ('List') and resource ('drafts') are clear, and the sibling tools make it apparent this is the draft-listing tool. However, the description does not define what counts as a draft or what scope the list covers, and the '(unconfigured)' prefix adds ambiguity.
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?
No guidance is given on when to use list_drafts versus siblings like list_labels, list_accounts, search, or create_draft/update_draft. There is no mention of prerequisites, expected account state, or scenarios where another tool would be preferable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_labelsCRead-only
(unconfigured) List labels.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotation readOnlyHint=true already informs the agent that this is a safe read operation, so the description does not need to restate that. The description adds no behavioral context beyond the annotation, but it also does not contradict it. Given the annotation coverage, a baseline 3 is appropriate.
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 extremely short, which is concise, but the '(unconfigured)' prefix is ambiguous noise and adds no useful information. This is under-specification rather than efficient conciseness, leaving the description without essential context.
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 a single required parameter and no output schema, the description should clarify the expected return format, the meaning of 'account', and the relationship to other label-related tools. It does none of this. The placeholder-like nature of the description leaves an agent with too little context to call the tool reliably.
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 0%, and the required 'account' parameter has no description in the schema. The description 'List labels' provides no meaning for the account parameter—whether it is an ID, email address, or scope. The description completely fails to compensate for the lack of parameter documentation.
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: 'List labels.' This clearly distinguishes it from siblings like label_thread (an action) and list_accounts/list_drafts (different resources). The '(unconfigured)' prefix is odd but does not obscure the core purpose.
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 offers no guidance about when to use this tool versus alternatives. It does not mention that this tool is for reading labels, that it should not be used for mutating labels, or that list_accounts/list_drafts serve different resources. The '(unconfigured)' hint is vague and not actionable.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
searchCRead-only
(unconfigured) Search a mailbox with Gmail query syntax.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes | ||
| account | Yes | ||
| page_token | No | ||
| max_results | No | ||
| include_spam_trash | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint annotation already covers the read-only safety profile, and the description adds little behavioral detail beyond that. It does not mention pagination, output format, account requirements, or the ambiguous '(unconfigured)' prefix.
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 core sentence is short and front-loaded with the action. However, the '(unconfigured)' prefix is distracting and unexplained, which prevents this from being a perfectly clean definition.
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 five parameters, no parameter descriptions, and no output schema, the description is too sparse to fully support an agent. It does not describe result shape, pagination behavior, or how account relates to the mailbox, leaving important operational details unspecified.
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 0%, so the description must compensate, but it only clarifies the query parameter (Gmail query syntax) and loosely ties 'mailbox' to the account. The page_token, max_results, and include_spam_trash parameters are left entirely unexplained despite their non-obvious defaults.
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 action ('Search') and the resource ('a mailbox'), and it identifies the key mechanism as Gmail query syntax. It is distinguishable from the sibling get/list tools at a high level, but it does not specify what kind of results are returned or explicitly differentiate itself from related 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?
There is no explicit when-to-use or when-not-to-use guidance, and no alternative tool is mentioned. The intended use is implied by the verb and resource, with the only concrete usage hint being 'Gmail query syntax'.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sendADestructive
(unconfigured) Send a draft that a human already approved via the gmail-approve CLI.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes | ||
| approval_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, so the destructive nature is known. The description adds valuable context beyond annotations: the requirement that a human approved the draft via gmail-approve CLI, which implies a safety gate and irreversible dispatch. It does not contradict 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 a single, well-structured sentence that delivers the core purpose and key precondition without wasted words. The parenthetical '(unconfigured)' adds brief status context without bloating the definition.
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 two required parameters and no schema coverage, the description is not sufficient for an agent to call the tool correctly. It does not explain what 'unconfigured' means operationally, how to find an approval_id, or what account values are valid. The absence of an output schema further increases the need for explanatory context, which 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?
Schema description coverage is 0%, so the description must compensate for explaining the two required parameters, account and approval_id. The description hints that approval_id is tied to the gmail-approve CLI, but it does not explain what account refers to or how either param should be formatted or obtained. This is minimal compensation for a 0% coverage situation.
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 ('Send') with a resource ('a draft') and a clear qualifying condition ('that a human already approved via the gmail-approve CLI'). This distinguishes it from siblings like stage_send, create_draft, and update_draft by emphasizing the final dispatch action after human approval.
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 clearly indicates this tool is for sending drafts that have already received human approval, giving a strong contextual cue about the intended workflow stage. However, it does not explicitly name alternatives or state when not to use the tool, though the approval condition implies it should not be used before approval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
stage_sendA
(unconfigured) Freeze a draft and request human approval to send. Does NOT send.
| Name | Required | Description | Default |
|---|---|---|---|
| account | Yes | ||
| draft_id | Yes | ||
| allow_attachments | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral burden. It discloses the core action: freezing a draft and requesting human approval, and explicitly negates the most important possible side effect: sending. It does not elaborate on post-approval behavior or side effects beyond that, but the critical boundary is clear.
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 very short and front-loaded, with the main behavioral statement first and the clarifying non-sending caveat immediately after. The '(unconfigured)' prefix adds little useful meaning and could confuse, but the overall structure is efficient.
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 tool with no annotations, no output schema, and zero parameter descriptions, the description leaves important invocation details undocumented. It explains the tool's purpose well but does not clarify the account or allow_attachments parameters, nor what requesting human approval implies for the workflow.
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 0%, so the description must compensate, but it only relates to draft_id ('Freeze a draft'). It does not explain what account refers to or the meaning/effect of allow_attachments. With three parameters and no schema descriptions, this is a significant omission.
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 specific verb and resource: 'Freeze a draft and request human approval to send.' It directly differentiates from the sibling 'send' tool with the explicit negative 'Does NOT send,' so an agent can discriminate 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 gives clear workflow context: this tool is for staging a draft for human approval rather than actually sending it. It does not explicitly name alternatives or state when-not-to-use it, but 'Does NOT send' effectively prevents confusion with the sibling send tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_draftC
(unconfigured) Replace a draft's content. Invalidates any staged approval.
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | ||
| to | Yes | ||
| body | Yes | ||
| account | Yes | ||
| subject | Yes | ||
| draft_id | Yes | ||
| reply_to_message_id | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden, and it does disclose a mutation ('Replace') plus a meaningful side effect: 'Invalidates any staged approval.' However, it does not mention reversibility, permission requirements, or what happens to existing draft metadata.
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 short sentences with no fluff, and the key side effect is front-loaded in the second sentence. The '(unconfigured)' prefix is an unnecessary artifact, but it does not substantially harm readability.
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 7-parameter mutation with no annotations and no output schema, this is incomplete. It omits return behavior, failure modes, account handling, and the meaning of 'staged approval,' leaving an agent to guess at operational details.
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 0% and the description adds almost no parameter-level meaning. 'Draft's content' loosely refers to the subject/body fields but gives no guidance on cc, reply_to_message_id, account, or draft_id semantics.
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 action on a specific resource: 'Replace a draft's content.' This distinguishes it from siblings like create_draft, since it modifies an existing draft. The '(unconfigured)' prefix is noise, but the core purpose remains clear.
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?
No guidance on when to use this tool versus create_draft, stage_send, or send. The description implies updating an existing draft, but it does not state prerequisites (e.g., draft must already exist) or scenarios where another sibling is more appropriate.
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.
12 tool updates
v0.1.0- First observed
create_draft - First observed
get_attachment - First observed
get_message - First observed
get_thread - First observed
label_thread - First observed
list_accounts - First observed
list_drafts - First observed
list_labels - First observed
search - First observed
send - First observed
stage_send - First observed
update_draft
TDQS
Scored across 12 tools
Each tool targets a distinct operation: search, thread/message retrieval, attachment download, threading labels, and a clearly separated draft/stage/send pipeline. Even adjacent tools like get_thread and get_message are delineated by thread-level vs message-level detail.
Tool names mostly follow a predictable verb_noun snake_case pattern with list_*, get_*, and create_/update_ prefixes. The bare verbs search and send, plus stage_send, are minor deviations but still readable and consistent in style.
Twelve tools is well-scoped for a Gmail account server covering search, reading, attachments, labels, drafts, and sending. Each tool earns its place with no obvious redundancy.
Core email workflows are covered: search, read, download attachments, label threads, create/update drafts, and send through an approval flow. Minor gaps like creating labels, adding attachments to drafts, or managing read state are plausible but not critical to the server's apparent purpose.
Maintenance
Related MCP Connectors
Stateful email for AI agents — read inboxes, reply in-thread, draft with approval.
Email inboxes and calendars for AI agents: send, receive, search, draft and schedule.
Email inboxes and calendars for AI agents: send, receive, search, draft and schedule.
- PO6 MailboxOAuthcom.po6
Give AI agents secure access to your email via private aliases with dedicated mailbox storage.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to read, search, organize, and draft emails in Gmail inboxes with support for multiple accounts, OAuth authentication, and 26 comprehensive tools for email management.253 npm3MIT
- AlicenseBqualityCmaintenanceEnables AI assistants to manage multiple Gmail accounts simultaneously with built-in OAuth authentication, supporting email reading, sending, drafts, labels, and account management.6051 npm3MIT
- FlicenseAqualityBmaintenanceConnects AI assistants to multiple Gmail accounts simultaneously, enabling search, read, draft, send, and reply operations with per-account permission controls.54-
- FlicenseNot gradedqualityDmaintenanceEnables AI-powered email management through Gmail, including search, send, drafts, labels, and an intelligent agent with human approval workflow and optional customer database integration.-