A reliable, native Gmail MCP server with full mailbox control — search, labels, archive, trash, attachments, and snooze.
mailwarden demonstrates strong tool design with consistent naming conventions, well-documented schemas, and comprehensive error handling. All 18 tools follow verb_noun naming patterns (search, get_, archive, trash, modify_, list_, snooze, unsnooze, create_, delete_, unsubscribe_, bulk_, inspect_, build_). Input schemas are complete and well-typed for all tools. Descriptions are present and actionable (average ~85 chars, baseline 194 chars, shorter but fit for email domain). Error classification system (classifyError, fail pattern) shows mature error handling. However, descriptions for some tools lack specificity about outcomes, preconditions, or when to use them vs similar tools (e.g., archive vs trash distinction not explicit). Output schemas are not formally documented in the visible code, relying instead on structuredContent sanitization, this is a gap for LLM planning. Parameter descriptions are generally good but some lack range/constraint info (e.g., maxResults unbounded). Tool composition is clean: single responsibility per tool, batch variants present (bulk_unsubscribe). Security is well-handled with server-side auth injection and sanitization of untrusted email content.
Archive one or more threads by removing them from the inbox
Build a digest summary of threads matching criteria
Unsubscribe from multiple threads at once
Create an email filter with automated actions
Delete an email filter
Download an attachment from a message
Retrieve the full parsed content of a specific message
Output schemas not formally documented in visible source. Tools return sanitized structuredContent but LLMs cannot see declared return types to plan multi-step chains or validate field availability.
Parameter constraints not fully specified. 'maxResults' and 'maxMessages' lack min/max bounds; 'duration' in snooze lacks format spec (are '1 day', '24h', '1440m' all valid?); 'format' in build_digest lacks enum values.
Descriptions lack preconditions and distinctions. 'archive' and 'trash' both move threads but descriptions do not explain when to use each (is archive reversible? is trash permanent?). 'modify_labels' does not state whether both addLabelIds and removeLabelIds can be empty.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-22 | C | 64 | 2025-06-18+ | v2 |
Inspect the unsubscribe options available for a thread
List all email filters configured in the mailbox
List all labels available in the mailbox
List all currently snoozed threads
List all email subscriptions and newsletters
Add or remove labels on one or more threads
Search for messages and threads matching criteria, with live label re-verification
Snooze a thread to resurface it at a later time
Move one or more threads to trash
Unsnooze a thread, removing it from snooze and returning it to the inbox
Unsubscribe from a thread using the List-Unsubscribe header
create_filter description is generic ('Create an email filter with automated actions'). Does not explain preconditions (must labels exist first?), side effects (does 'applyToExisting' cause delays?), or why 'verify' is optional.
Error recovery guidance embedded in code (explainScopeFailure) but not visible in tool descriptions. LLMs cannot discover that insufficient_scope errors include hints for remediation.