Gmail MCP server for Claude Code — multi-account email management
gmail-mcp presents a solid set of 14 well-organized tools with generally clear naming and consistent parameter structures. Strengths: all tools have descriptions (100+ chars), most parameter descriptions are present, input schemas are properly defined with types, and the tool set is well-composed (single responsibility per tool, good chaining potential). Weaknesses: output schemas are not documented in the source code provided (pattern:tool requirement), error handling guidance is absent (no recovery hints or error categorization), parameter descriptions lack constraint detail (format, ranges, dependencies), and there is no documentation of what fields are returned by each tool. The descriptions are adequate (100-250 chars typical) but could be more prescriptive about when to use which tool (vs. similar tools) and how they differ. Email/account resolution is good (natural identifiers supported), but drafting tools lack explicit confirmation/dry-run patterns for safety.
Archive an email by removing the INBOX label. Returns success status and message ID.
Batch modify multiple emails: archive, trash, or add/remove labels. Returns success status, modified count, and message IDs.
Create a draft email. Returns the draft ID and message info.
Create a draft reply to an existing email. Fetches original message for proper threading (In-Reply-To, References, threadId). Draft appears in Gmail for review before sending — use send_draft to send after review.
List all Gmail labels for an account. Returns label id, name, type, and message counts (total and unread).
Get a conversation thread by thread ID. Returns all messages in the thread with full headers and body text.
No output schemas documented for any tool. LLMs cannot plan downstream tool calls or extract required fields (e.g., what structure does send_email return? Is thread_id always present?). Violates pattern:tool requirement to document return type.
Missing error handling guidance across all write/modify tools (send_email, draft_email, reply_email, send_draft, label_email, batch_modify). No indication of what errors are retryable (network timeout) vs. user-fixable (invalid recipient) vs. fatal (account not authenticated). Violates pattern:recovery-guide.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | D | 57 | 2026-07-28+ | v2 |
| 2026-03-09 | D | 50 | - | v1 |
Add or remove labels on an email. Returns success status, message ID, and current labels.
List emails from an account inbox or label. Returns summaries with id, from, subject, date, snippet, and unread status.
Read a single email by message ID. Returns full content including body, headers, labels, and attachment metadata.
Reply to an existing email. Fetches original message for proper threading (In-Reply-To, References, threadId). Supports reply-all.
Search emails using Gmail query syntax. Returns summaries with id, from, subject, date, snippet, and unread status.
Send an existing draft by its draft ID. Use after reviewing a draft created by draft_email or draft_reply.
Send an email. Returns the sent message ID, thread ID, and labels.
Move an email to trash by adding the TRASH label. Returns success status and message ID.
Hardcoded account alias examples ('vyg', 'indigo', 'personal', 'abacus') embedded in parameter descriptions for draft_reply and send_draft. LLMs will treat these as the only valid options and attempt to pass them literally in real calls. Violates pattern:tool-description (do not embed example values).
No dry-run or confirmation step for irreversible write operations (send_email, reply_email). Agents make mistakes, draft-then-send pattern is correct for draft_email, but send_email should support a confirm_before_execute variant or at minimum require explicit 'confirm' param. Violates pattern:confirmation-request.
Parameter constraints under-specified. max_results documented as 'max: 1000' but no minimum or guidance on performance (does 1000 items cause timeouts?). query param in search_emails accepts arbitrary Gmail syntax but no validation rules or error guidance if malformed. is_html and reply_all booleans have no default documented (docs say 'default: false' but this is implicit, not explicit in code).
batch_modify does not return per-item success/failure. Description says 'Returns success status, modified count, message IDs' but if 50 messages are submitted and 1 fails (e.g., permission denied), the LLM has no way to know which one. Violates pattern:response-shaper for multi-item operations.
Tool naming does not clearly distinguish all similar operations. label_email is somewhat generic, does it add, remove, or both? Better names: add_labels + remove_labels (explicit), or clarify via description. Similarly, archive_email vs. trash_email are close in function but names do not hint at the difference.
No guidance on when to use similar tools. list_emails + search_emails are both in the codebase. When should an LLM choose one over the other? Description should clarify: 'Use list_emails to browse a label; use search_emails for complex queries.' Missing pattern:tool-description context.