list_emails
Retrieve emails from a Fastmail mailbox with optional filtering by mailbox, result limit, and sort order (newest or oldest first).
Instructions
List emails from a mailbox
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| mailboxId | No | ID of the mailbox to list emails from (optional, defaults to all) | |
| limit | No | Maximum number of emails to return (default: 20) | |
| ascending | No | Sort oldest first instead of newest first (default: false) |
Implementation Reference
- src/index.ts:142-163 (registration)Tool registration: 'list_emails' is declared in the ListToolsRequestSchema handler with input schema (mailboxId, limit, ascending)
{ name: 'list_emails', description: 'List emails from a mailbox', inputSchema: { type: 'object', properties: { mailboxId: { type: 'string', description: 'ID of the mailbox to list emails from (optional, defaults to all)', }, limit: { type: ['number', 'string'], description: 'Maximum number of emails to return (default: 20)', default: 20, }, ascending: { type: 'boolean', description: 'Sort oldest first instead of newest first (default: false)', }, }, }, }, - src/index.ts:1009-1021 (handler)Handler for 'list_emails' tool in the CallToolRequestSchema switch case. Extracts args (mailboxId, limit, ascending), validates limit, and calls client.getEmails()
case 'list_emails': { const { mailboxId, limit, ascending } = args as any; const validLimit = Math.min(Math.max(Number(limit) || 20, 1), 100); const emails = await client.getEmails(mailboxId, validLimit, !!ascending); return { content: [ { type: 'text', text: JSON.stringify(emails, null, 2), }, ], }; } - src/caldav-client.ts:156-180 (helper)JmapClient.getEmails() - the actual JMAP API implementation that queries Email/query then Email/get via the Fastmail API
} const trimmed = value.trim(); // Date-only: 2026-04-18 if (/^\d{4}-\d{2}-\d{2}$/.test(trimmed)) { const d = new Date(trimmed + 'T00:00:00Z'); if (Number.isNaN(d.getTime())) throw new Error(`${fieldName} is not a valid date`); return trimmed.replace(/-/g, ''); } // Datetime forms: floating, UTC (Z), or with offset (+/-HH:MM, +/-HHMM, +/-HH) const dtMatch = /^(\d{4}-\d{2}-\d{2})T(\d{2}:\d{2}:\d{2})(Z|[+-]\d{2}:?\d{0,2})?$/.exec(trimmed); if (!dtMatch) { throw new Error(`${fieldName} must be ISO-8601 date or datetime (got: ${trimmed.slice(0, 60)})`); } const [, datePart, timePart, tz] = dtMatch; const isoForParse = `${datePart}T${timePart}${tz || ''}`; const d = new Date(isoForParse); if (Number.isNaN(d.getTime())) { throw new Error(`${fieldName} is not a valid datetime`); } if (!tz) { // Floating: emit as-is without zone designator return `${datePart.replace(/-/g, '')}T${timePart.replace(/:/g, '')}`; } // UTC or offset: normalize to UTC instant const utc = d.toISOString().replace(/[-:]/g, '').replace(/\.\d{3}/, '');