JMAP MCP server has clear, verb-based tool names and reasonable parameter schemas with type definitions. However, descriptions are consistently brief (10-50 chars), lacking the depth needed for LLM reasoning about WHEN to use each tool and any prerequisites. Parameter descriptions are minimal or absent in several tools. Output schemas are not explicitly documented in the source. Error handling is basic (returns errorContent with text) but does not provide recovery guidance. Overall solid foundations but insufficient detail for production agent use.
Tools (10)
archive-threadswriteauthsource verified67/100
Move all emails in one or more threads to the Archive mailbox
Descriptions are uniformly brief (10 - 50 chars) and lack WHEN/WHY context. LLMs cannot infer when to choose 'list-threads' vs 'search-threads' or whether 'mark-threads-read' is idempotent and safe to retry. Baseline for A+ tools is 50 - 200 chars with explicit context about prerequisites and use cases.
Output schemas are not documented in tool registration. Agents cannot determine what fields are returned (e.g., does list-threads return emailIds, subject, threadId?). This forces agents to guess or construct responses blindly.
Expand ALL tool descriptions to 50 - 150 characters, stating WHAT the tool does, WHEN to use it, and any prerequisites. Example: 'List email threads in a mailbox (or all). Returns thread summaries with latest subject and sender. Call this first to discover threads before operating on them.' (vs current 'List the email threads in a mailbox, or all threads from all mailboxes')
Document output schemas for each tool. Specify the response structure as a comment or separate schema definition. Example: 'Returns { threads: [{ threadId, emailIds, summary: { subject, from, receivedAt } }], position, limit, total, hasMore }'.
Add tool annotations to all registrations. Mark read-only tools with { readOnlyHint: true }, destructive tools with { destructiveHint: true }, and idempotent writes with { idempotentHint: true }. Example: server.tool('delete-threads', ..., { threadIds: ... }, handler, { destructiveHint: true }).
Implement confirmation-request pattern for destructive operations. Split delete-threads into (1) preview_delete_threads returning a summary of what will be deleted, and (2) confirm_delete_threads requiring a confirmation token from the preview step. This prevents accidental bulk deletion.
Enhance error messages with recovery guidance. Instead of 'No archive mailbox found', return: 'Archive mailbox not found. User may not have archive enabled. Available mailboxes: Inbox, Sent, Drafts, Trash. Try move_threads_to_mailbox instead.' This enables the agent to self-correct.
Add parameter descriptions to all tools. Example for search-threads, add descriptions for 'text' (search in subject, sender, recipients, body), 'from' (exact sender email), 'to' (exact recipient email), etc. Currently 'from' and 'to' lack inline descriptions.
Score history
Overall score trend
↓ 1 points across a rubric change (v1 → v2)
50/100
Scored
Grade
Overall
Spec posture
Rubric
2026-09-22
D
50
2026-07-28+
v2
2026-03-09
D
51
-
v1
70/100
Mark emails in a thread as unread (all or just the last)
Error handling returns plain text via errorContent() with no guidance on what to do next. 'No archive mailbox found' tells agent nothing about how to proceed. Errors should be categorized (retryable vs user-fixable) and include recovery hints.
Destructive operations (delete-threads, move-threads-to-mailbox, archive-threads) have no confirmation or dry-run mode. A single hallucinated call could delete 10 threads with no opportunity to confirm. LLMs should not have one-shot destructive access.
Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are missing from all tool registrations. The agent cannot determine which tools are safe to retry or which modify state. Spec 2026-07-28 requires these for safety-critical operations.
STDIO transport only. Server is not remotely accessible and cannot be used by hosted MCP clients (e.g., Claude web, hosted agent platforms). This is a hard cap on protocol readiness.
Document which operations are idempotent. mark-threads-read called twice with the same threadIds should produce the same result (idempotent). Document this so agents can safely retry.
Consider adding a batch-preview mode for destructive operations. Before executing, return a summary showing how many emails will be affected, which mailbox(es) they are in, date range, etc. This gives the agent visibility to avoid unintended cascades.
Return chainable IDs in all responses. If list-threads returns threads, ensure each thread includes threadId (for get-email-details) and emailIds (for list-thread-messages). Avoid responses that omit downstream-necessary IDs.
Add pagination context to descriptions. E.g., 'Returns paginated results (default limit=10, max=50). Use position and limit to iterate through threads.'
Document any rate limits or concurrency constraints (e.g., 'Max 10 threadIds per batch operation').