get_storage_report
Analyze iCloud Mail storage usage by categorizing emails into size groups and identifying top senders contributing to storage consumption.
Instructions
Estimate storage usage by size bucket and identify top senders by email size. Uses SEARCH LARGER queries for bucketing and samples large emails for sender analysis.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mailbox | No | Mailbox to analyze (default INBOX) | |
| sampleSize | No | Max number of large emails to sample for sender analysis (default 100) |
Implementation Reference
- lib/imap.js:1079-1133 (handler)Implementation of the get_storage_report tool logic.
export async function getStorageReport(mailbox = 'INBOX', sampleSize = 100, creds = null) { const client = createRateLimitedClient(creds); await client.connect(); await client.mailboxOpen(mailbox); // Count emails by size bucket using 4x SEARCH LARGER const thresholds = [10 * 1024, 100 * 1024, 1024 * 1024, 10 * 1024 * 1024]; const counts = []; for (const thresh of thresholds) { const r = await client.search({ larger: thresh }, { uid: true }).catch(() => []); counts.push(Array.isArray(r) ? r.length : 0); } const buckets = [ { range: '10KB–100KB', count: counts[0] - counts[1] }, { range: '100KB–1MB', count: counts[1] - counts[2] }, { range: '1MB–10MB', count: counts[2] - counts[3] }, { range: '10MB+', count: counts[3] } ]; // Sample top senders among large emails (> 100 KB) const largeRaw = await client.search({ larger: 100 * 1024 }, { uid: true }).catch(() => []); const largeUids = Array.isArray(largeRaw) ? largeRaw : []; const sampleUids = largeUids.slice(-sampleSize); const senderSizes = {}; if (sampleUids.length > 0) { for await (const msg of client.fetch(sampleUids, { envelope: true, bodyStructure: true }, { uid: true })) { const address = msg.envelope?.from?.[0]?.address; if (address && msg.bodyStructure) { senderSizes[address] = (senderSizes[address] || 0) + estimateEmailSize(msg.bodyStructure); } } } await client.logout(); const topSendersBySize = Object.entries(senderSizes) .sort((a, b) => b[1] - a[1]) .slice(0, 10) .map(([address, estimateBytes]) => ({ address, estimateKB: Math.round(estimateBytes / 1024) })); const midpoints = [50, 512, 5120, 15360]; // rough KB midpoint for each bucket const estimatedTotalKB = buckets.reduce((sum, b, i) => sum + b.count * midpoints[i], 0); return { mailbox, buckets, estimatedTotalKB, topSendersBySize, ...(sampleUids.length < largeUids.length && { note: `Sender analysis sampled ${sampleUids.length} of ${largeUids.length} large emails (>100 KB)` }) }; }