Search and Move
email_search_and_moveSearch your inbox with structured criteria (sender, subject, dates) and move every matching message to a chosen folder in one server-side operation. Filter results securely to avoid moving the wrong mail.
Instructions
Move every message matching a search into a destination folder, in one server-side operation, so no message ID is ever stale by the time it is used. Search uses structured, provider-agnostic fields (from, to, cc, subject, body, text, unread, has_attachment, flagged, since, before) that the server translates into the inbox's native search syntax, so you never need provider query syntax; query is a raw escape hatch. SEPARATE from email_organize, and flagged destructive to your MCP client, because it acts on everything the filter matches rather than on ids you chose: one wrong filter relocates a whole inbox. To move messages you have already listed, use email_organize (action 'move' or 'move_batch') instead. Bounded by limit, maximum and default 500: check has_more before reporting a mailbox fully swept, and finish any remainder with email_organize (action 'move_batch'). On Gmail, moving adds the destination label and removes the INBOX label. Returns succeeded/failed counts and per-message results. Needs manage:folders.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| cc | No | Cc recipient to match: address, name, or fragment. | |
| to | No | To recipient to match: address, name, or fragment. | |
| body | No | Text to find in the body. On Gmail this matches the whole message. | |
| from | No | Sender to match: address, name, or fragment. | |
| text | No | Text to match anywhere, headers included. | |
| inbox | No | Inbox email address, an alternative to inbox_id. | |
| limit | No | Cap on messages moved. Default 500. | |
| query | No | Provider-native raw query (escape hatch); prefer the structured fields. Ignored on Fastmail. | |
| since | No | Received on or after this date or datetime (no timezone = UTC). | |
| before | No | Received strictly before this date or datetime (no timezone = UTC). | |
| unread | No | true = unread only; false = read only; omit for both. | |
| flagged | No | true = only flagged/starred messages. Ignored on Outlook. | |
| subject | No | Text to match in the subject; phrases match as-is. | |
| inbox_id | No | Inbox UUID from inbox_list. Optional when the key has one inbox; pass this or `inbox`, not both. | |
| has_attachment | No | true = only messages with an attachment. Ignored on generic IMAP. | |
| idempotency_key | No | Reuse only when retrying the identical request within 24 hours; the retry is collapsed, not repeated. Reuse with different arguments is rejected. | |
| include_folders | No | Folder names to search. IMAP covers INBOX only when omitted. | |
| destination_folder_id | Yes | Target folder: an alias (inbox, sent, drafts, trash, archive, spam), a folder name, or a folder id. Names and aliases resolve for you. |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | The limit that bounded the search. | |
| notes | No | Server notes about how this call was handled — for example an argument that was not applied because the selected action does not accept it. Written by MCP Emails, not taken from any message, and absent when there is nothing to report. | |
| failed | Yes | ||
| partial | No | True when the operation did NOT process every message it was given. succeeded/failed describe only what was attempted; remaining_message_ids lists what was left untouched. | |
| results | Yes | ||
| has_more | No | True when messages matching the query were left UNTOUCHED because of the limit. Check this before reporting the sweep complete: re-run until it is false. | |
| inbox_id | Yes | ||
| operation | Yes | ||
| remaining | No | ||
| succeeded | Yes | ||
| match_count | No | How many messages the search returned, i.e. the most this call could act on. | |
| continuation | No | ||
| limit_notice | No | Present only when has_more: plain-language statement of what was left behind. | |
| limit_reached | No | True when the search filled its window and stopped counting. On its own it does not prove more mail exists; has_more is that claim. | |
| total_matches | No | Provider's total match count when it supplies one. | |
| partial_notice | No | ||
| stopped_reason | No | 'cancelled' — a person stopped the run from the dashboard. 'time_budget' — the server stopped on its own wall-clock limit so the result could be returned before the client timed out. Neither is an error. | |
| total_requested | No | ||
| remaining_message_ids | No | Messages that were NOT processed and are unchanged. These exact ids, not a repeat of the original search, are what a follow-up call should use. | |
| total_matches_is_estimate | No | True when total_matches is a provider estimate (Gmail) rather than a count. |