email_bulk_delete_messages
Trashes or permanently deletes many messages in one mailbox. This is the most dangerous tool in the server — confirm the exact scope with the user before every call. Select with either message_ids or query, never both and never neither. Query selection needs max_messages, and the server freezes the matching set before deleting anything. One call covers one account only; repeat per account_id from email_accounts_list. mode 'trash' is recoverable; mode 'permanent' is not and also demands confirm_permanent: true plus the account's can_permanently_delete capability. Large operations continue in the background: the result carries operation_id and a status of processing, which you poll with email_bulk_operation_get and can stop with email_bulk_operation_cancel. Always read deleted, failed and skipped — a partial failure is reported as partially_failed, never as success.
Input fields
{
"type": "object",
"properties": {
"account_id": {
"type": "string",
"minLength": 1,
"description": "The connected mailbox to act on, from email_accounts_list. Never guess this value and never reuse one across mailboxes — it selects both the credential and the permission set the call runs under."
},
"message_ids": {
"description": "Explicit message ids to act on. Supply this or query, never both. Prefer explicit ids: you can show the user exactly what will change.",
"anyOf": [
{
"type": "array",
"items": {
"type": "string",
"minLength": 1
}
},
{
"type": "null"
}
]
},
"query": {
"description": "Select messages by search instead of by id, using the same syntax as email_search_messages. The server resolves and freezes the matching set before it deletes, so later mail is never swept in. Requires Read as well as Write. Run the same query through email_search_messages first and show the user the count.",
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"mode": {
"type": "string",
"enum": [
"trash",
"permanent"
],
"description": "'trash' moves messages to trash and stays recoverable. 'permanent' destroys them irreversibly and additionally requires confirm_permanent: true and the account's can_permanently_delete capability. Default to 'trash' unless the user asked for permanent."
},
"max_messages": {
"description": "Hard ceiling on how many messages this call may touch. Also clamped to the server's own maximum.",
"anyOf": [
{
"type": "integer",
"minimum": 1,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"confirm_permanent": {
"description": "Must be exactly true when mode is 'permanent'. Ignored for 'trash'.",
"anyOf": [
{
"type": "boolean"
},
{
"type": "null"
}
]
},
"idempotency_key": {
"type": "string",
"minLength": 1,
"description": "A unique value you generate for this attempt, e.g. a UUID. Retrying with the same key returns the original result instead of acting twice. Reusing a key with different arguments is an IDEMPOTENCY_CONFLICT."
}
},
"required": [
"account_id",
"mode",
"idempotency_key"
]
}Tool behavior
May change provider state. Check the explicit account, required access and provider capabilities before invoking.
Inspect isError and per-account errors. General write tools do not all enforce exact-plan approval. This reference does not certify any current AI client version.

YOUR INBOXES.
UNDER CONTROL.
Get started Start with a free account and one read-only search. Existing accounts keep their connection.