Search messages
apple_mail_search_messagesSearch Mail.app mailboxes by sender or subject, with filters for unread, flagged, and date range, returning message metadata and handles for reading bodies.
Instructions
Search message HEADERS across one or more Mail.app mailboxes. Returns metadata plus an opaque handle per message; call apple_mail_get_message with that handle to read a body.
Cost model: every filter is pushed down into Mail.app. An unfiltered search over a large mailbox is slow, so since_days defaults to 30 and the tool refuses (rather than hangs) when more than max_scan messages match. If you get TOO_MANY_MATCHES, add filters rather than raising max_scan.
Note: query matches subject and sender only, never body text.
Returns: { total_matched, offset, count, has_more, messages: [{ handle, account, mailbox, subject, sender, date_received (ISO 8601), read, flagged }] } sorted newest first.
Examples:
"unread mail from UNICEF this week" -> { unread_only: true, from: "unicef", since_days: 7 }
"anything about the Quantum tender" -> { query: "Quantum", since_days: 180 }
"what did I send last month" -> { mailbox: "Sent Messages", since_days: 30 }
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| from | No | Substring matched against the sender only, e.g. "unicef.org". | |
| limit | No | Messages per page (default 25). | |
| query | No | Substring matched against BOTH subject and sender. Body text is NOT searched (too slow over Apple Events). | |
| offset | No | Pagination offset. | |
| account | No | Exact account name as shown by apple_mail_list_accounts (e.g. "iCloud", "Work Gmail"). Omit to span every account. | |
| mailbox | No | Mailbox name, e.g. "INBOX", "Sent Messages", "Archive". Defaults to the inbox of each account. | |
| max_scan | No | Refuse the query if more than this many messages match, instead of hanging. Default 400. | |
| since_days | No | Look back this many days. Keep it small — this is the main cost control. Default 30. | |
| unread_only | No | Only unread messages. | |
| flagged_only | No | Only flagged messages. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| count | Yes | ||
| offset | Yes | ||
| has_more | Yes | ||
| messages | Yes | ||
| total_matched | Yes |