Add configurable INBOX-only search optimisation to mail_move - #1
Open
bartonfriedland wants to merge 9 commits into
Open
Add configurable INBOX-only search optimisation to mail_move#1bartonfriedland wants to merge 9 commits into
bartonfriedland wants to merge 9 commits into
Conversation
Add optional searchInboxOnly parameter to mail_move operation to address performance issues when users have accounts with many mailboxes. Changes: - Add searchInboxOnly parameter (default: false) to moveEmails() function - Update Zod schema and MCP tool handler to support new parameter - Add comprehensive performance documentation to README - When enabled, only searches INBOX mailboxes for 10-20x performance gain Performance impact: Reduces search from 200+ mailboxes to 2-5 INBOX folders when enabled, improving operation time from 10-30s to 1-2s. Backward compatible - default behaviour preserved.
- Add getMailById function to retrieve email by numeric ID or message-ID - Add mail_read tool to MCP server with full content output - Include content field in mail_get_unread and mail_get_latest output - Add ccRecipients field to EmailMessage type Enables agents to read full email bodies for processing and routing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Replace `break outer;` labeled statement with `found` flag pattern - Add missing flagIndex field to search result objects Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Added documentation for: - mail_read (full email content retrieval) - mail_search_inbox (fast inbox-only search) - mail_search_mailbox (specific mailbox search) - mail_search_by_flag (flag color search) Organized tools into sections: Reading & Searching, Composing & Sending, Managing. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Three bugs fixed in the JXA layer: - getUnreadMails() used Mail.mailboxes() (app-level, empty) instead of iterating Mail.accounts() per-account mailboxes - getMailboxHierarchy() counted unread by iterating 100 msgs per mailbox across all mailboxes — now only counts for INBOX/Sent/Drafts - getLatestMails() extracted msg.content() per message triggering IMAP fetch — now returns metadata only New mail_get_inboxes tool provides single-call access to recent INBOX messages across all enabled accounts with per-account message counts. 🤖 Generated with AI assistant support Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…ailboxes The JXA `whose` clause and full message iteration are both O(n) on Apple Mail mailboxes, timing out at 30s+ on large inboxes. Replace with indexed access scanning recent messages newest-first (O(1) per message, up to 500 per mailbox). Add optional accountName/mailboxName hint parameters so callers can direct the lookup to the right mailbox immediately — listing functions already return both fields for every message. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Claude Code's health checker expects servers to declare resources, tools, and prompts capabilities even when not all are used. Declaring only tools caused persistent "Failed to connect" status. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Enables running the server via `npx mcp-apple` in addition to `node dist/index.js`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replaced stdio transport with StreamableHTTPServerTransport on port 8263. Bearer token auth, /health endpoint, session management. start-server.sh for manual server management (launchd deferred due to Node v25 ESM issue on macOS 26). 🤖 Generated with AI assistant support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The
mail_moveoperation searches through ALL mailboxes in ALL accounts to find emails by Message-ID. This creates a cross-account performance penalty:Solution
Added optional
searchInboxOnlyparameter (default:false) tomail_move:true: Only searches INBOX mailboxes (typically 2-5 folders across all accounts)false: Default behaviour, searches all mailboxes (backward compatible)Changes
Modified files:
lib/mail-operations.ts- AddedsearchInboxOnlyparameter tomoveEmails()lib/schemas.ts- Added parameter to Zod schemaindex.ts- Added parameter to tool input schema and handlerREADME.md- Documented parameter and added "Performance Considerations" sectionTesting
Tested with multiple accounts including one with 200+ mailboxes:
searchInboxOnly: true- ✅ Success, ~1-2 secondssearchInboxOnly: false- ✅ Success, ~10-30 seconds (Mail.app unresponsive during search)Backward Compatibility
✅ Default is
false- existing behaviour preserved✅ No breaking changes to API
✅ Optional parameter - existing code continues to work
Future Enhancements
For discussion in a separate PR:
sourceAccountparameter to limit search scope to specific accounts