bulk_modify
Apply label changes to many emails at once using a Gmail search query, processing up to 1,000 messages per request. Add or remove labels in bulk, with a dry-run option to preview matched messages and counts before any change is made.
Instructions
Bulk-apply label changes to every message matching a Gmail query, batched at 1000 messages per API request. Labels may be given by name or by id: an unknown name in add is created automatically (use '/' for nested labels), an unknown name in remove is ignored. Returns matched/modified counts, matched and modified thread IDs (both lists capped at 500 — matchedThreadCount/modifiedThreadCount hold the true totals), and per-chunk failures (partial success is reported, not hidden). If more messages match than maxMessages, only the first maxMessages are processed and 'capped' is true — raise maxMessages or re-run to finish the rest. NOTE: the query hits Gmail's search index as-is, WITHOUT the live re-verification search performs. The staleness that makes search re-verify was measured on threads.list (132 threads returned, 114 carrying no unread message at all); the same query through the message index this tool uses returned 19 hits, none stale — same mailbox, same minute. So the known drift does not reach this path, but that is one measurement, not a guarantee: unverifiedPredicates in the result names the conditions taken on the index's word, and when the outcome must be read-state-precise, resolve the set with search (which verifies against live labels) and act on those thread ids instead. Set dryRun:true to rehearse: the same query resolution, matched counts/threads and the labels that would be created — and no message or label is touched. A dry run reads the SAME unverified index, so it confirms the size of the set, never its correctness. USE WHEN: mass operations — 'archive all newsletters older than 30 days' (query + remove INBOX), bulk labeling, bulk mark-read; dryRun first when the query is broad or the user should see the set before it changes. DO NOT USE: for a single thread (use modify_labels or the dedicated tools), or with neither add nor remove. SIDE EFFECTS: modifies up to maxMessages messages in one call (none with dryRun); label changes are reversible by the inverse call.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| add | No | ||
| query | Yes | ||
| dryRun | No | ||
| remove | No | ||
| maxMessages | No |
Output Schema
| Name | Required | Description | Default |
|---|---|---|---|
| capped | Yes | ||
| dryRun | Yes | ||
| failed | Yes | ||
| labelsToCreate | No | ||
| matchedThreads | Yes | ||
| matchedMessages | Yes | ||
| modifiedThreads | Yes | ||
| modifiedMessages | Yes | ||
| matchedThreadCount | Yes | ||
| modifiedThreadCount | Yes | ||
| unverifiedPredicates | Yes |