Static source inference · medium confidence · detected: Logging
Deprecated protocol patterns detected
Summary
The server provides 21 tools with schemas and descriptions present for most. Naming conventions are strong and action-oriented (list_, read_, search_, create_, update_, delete_). However, there are significant gaps: (1) Output schemas are largely undocumented, the code shows tool registration but return types are not formally declared in the visible schema artifacts; (2) Parameter descriptions exist but lack constraint detail (enums, ranges, format patterns); (3) Error handling is minimal, functions return generic exception strings rather than structured recovery guidance; (4) Some tool descriptions lack dependency hints and prerequisites (e.g., download_attachment requires calling get_email_attachments first, not stated); (5) No tool annotations (readOnlyHint, destructiveHint, idempotentHint) despite mixed risk profiles; (6) Tools mixing concerns: send_email could benefit from a dry_run parameter for safety; (7) Tools accepting environment-sourced defaults (folder='INBOX') but not documenting valid folder values as enums. The server is functional but lacks the polish expected of a production tool.
Output schemas not formally documented. Code shows tool registration but return type structures (fields, types) are not visible in the provided schema artifacts. Callers cannot predict response structure.
Parameter descriptions lack constraint details (enums, ranges, patterns). E.g., 'folder' accepts arbitrary strings but valid values (INBOX, INBOX.Trash, etc.) are not enumerated. 'limit' lacks explicit min/max bounds in descriptions. LLMs cannot infer valid values.
Recommendations
Add formal output schemas to all tools. Document return type as JSON Schema with field names, types, and descriptions. Example: 'Returns: {type: object, properties: {emails: {type: array, items: {type: object, properties: {id: {type: string}, from: {type: string}, subject: {type: string}, date: {type: string}, preview: {type: string}}}}}}}'
Convert free-form parameter descriptions to formal constraints. Add enums for 'folder' (INBOX, INBOX.Trash, INBOX.Archive, etc.), 'signature_name' (list valid names in description or return from list_email_signatures). Add bounds to 'limit' and 'attachment_index': 'limit: integer, 1 - 50', 'attachment_index: integer >= 0'.
Implement structured error responses. Replace generic try/except with typed errors: '{"error": "not_found", "message": "Email not found.", "recovery": "Try search_emails() to locate the message."}' or '{"error": "invalid_folder", "message": "Folder INBOX.BadName not found.", "available_folders": ["INBOX", "INBOX.Trash", "INBOX.Archive"]}'.
Add tool annotations via fastmcp decorator parameters (if supported) or inline. Mark destructive tools: @mcp.tool(hints={"destructive": true}). Mark read-only: @mcp.tool(hints={"readOnly": true}). Ensures clients can gate dangerous operations.
Implement confirmation flow for irreversible operations. Add optional 'confirm=true' parameter to delete_email, delete_email_signature, delete_calendar_event. Return {"status": "confirmation_required", "message": "Delete email from John (2024-01-15)?", "action_token": "..."} and require token in retry. Or adopt Multi Round-Trip Requests pattern (result: "input_required").
Spec posture evidence
Inferred effective spec: <=2025-11-25.
Relies on Logging (deprecated) - log to stderr or use OpenTelemetry
Score history
Overall score trend
↑ 71 points across a rubric change (v1 → v2)
71/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
B
71
<=2025-11-25
v2
2026-03-09
F
0
1.2.0+
v1
read onlyauthsource verified71/100
Get raw email content in RFC822 format for .eml export.
Download an email attachment and save it directly to disk. This is the PREFERRED tool for attachments — saves the file and returns the local path so the user can open it immediately.
Sensitive operations (send_email, reply_to_email, delete_email with permanent=true) lack confirmation or dry-run support. No mechanism to prevent agent mistakes, irreversible actions execute immediately without user checkpoint.
Tool composition issues: download_attachment returns binary content but save_attachment is the 'preferred' tool. However, LLMs have no way to know which to call first. Descriptions should guide sequencing: 'Call get_email_attachments to list, then download_attachment or save_attachment to retrieve.'
list_folders and list_email_signatures have minimal descriptions (50 chars). Descriptions lack context on when to call them or what structure they return. LLMs cannot infer discovery intent.
Credentials exposed as environment variables without server-side secret injection pattern. IMAP_USERNAME, IMAP_PASSWORD, CALDAV_USERNAME, CALDAV_PASSWORD read directly from os.getenv(). If agent traces are logged, credentials could leak.
No audit logging of tool calls. Tools log to INFO level but do not capture who called, parameters (scrubbed), or outcomes in a compliance-auditable format. Agent actions are not traceable.
Pagination not implemented. list_emails, search_emails, list_calendar_events accept 'limit' but have no offset/cursor or next_token. If result sets exceed limits, no way to fetch remaining items without re-querying with different filters.
list_emailssearch_emailslist_calendar_events
Enhance tool descriptions with dependency hints. Example: 'download_attachment requires a valid email_id from list_emails or search_emails. Call get_email_attachments(email_id) first to list available attachments and their indices.'
Expand list_folders and list_email_signatures descriptions to 100+ characters. Explain what structure they return and when to call them. Example for list_folders: 'Returns all available mailbox folders (INBOX, Trash, Archive, etc.). Call this first if you need to list emails from folders other than INBOX, or to verify folder names for move_email operations.'
Implement pagination for list_* and search_* tools. Add 'offset' and 'total_count' to responses. Example: 'list_emails(folder="INBOX", limit=10, offset=0) returns {emails: [...], total_count: 47, has_more: true}'. Enable agents to iterate through large result sets.
Add idempotency keys or checksums to state-modifying operations. send_email should accept optional 'idempotency_key' parameter to prevent duplicate sends on retries. mark_email_as_read should be naturally idempotent (document it).
Implement server-side secret injection. Move credential handling out of tool parameters. Use a configuration file (encrypted at rest) or environment variables loaded at startup, not per-request. Never return credentials in responses.
Add structured audit logging. Log each tool call with {timestamp, agent_id, tool_name, parameters (sanitized), result_status, error_details}. Write to a tamper-evident log (file or service) for compliance tracing.
Consider adding a 'dry_run' parameter to send_email, reply_to_email, create_calendar_event. Allows agents to preview actions: dry_run=true returns what would be sent without actually sending. Reduces risk of accidental messages.
Document date format expectations explicitly. search_emails uses 'DD-MMM-YYYY' but list_calendar_events uses ISO format. Add format constraints to every date parameter: 'date in ISO 8601 format (YYYY-MM-DD) or natural language ("today", "tomorrow", "next Monday")'.
Add rate limiting documentation or implement exponential backoff in error responses. Prevent agents in retry loops from overwhelming the IMAP/SMTP/CalDAV servers. Return {"error": "rate_limited", "retry_after_seconds": 60} and guide retries.