proton_list_emails
Retrieve emails from a Proton Mail folder with pagination. View sender, subject, date, and read status for organized email management.
Instructions
List emails in a specific folder with pagination. Shows sender, subject, date, and read status. Results are newest first.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | INBOX | |
| limit | No | ||
| offset | No |
Implementation Reference
- src/tools/list.ts:11-75 (registration)Registration of the proton_list_emails tool, which uses the listMessages service to fetch data.
export function registerListEmailsTool(server: McpServer) { server.registerTool( 'proton_list_emails', { title: 'List Emails in Folder', description: 'List emails in a specific folder with pagination. Shows sender, subject, date, and read status. Results are newest first.', inputSchema: ListEmailsSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, async (params: z.infer<typeof ListEmailsSchema>) => { try { const messages = await listMessages(params.folder, params.limit, params.offset); if (messages.length === 0) { return { content: [ { type: 'text', text: 'No messages found in this folder.', }, ], }; } // Format as markdown table let result = `**Folder:** ${params.folder}\n`; result += `**Page:** offset=${params.offset}, limit=${params.limit}\n\n`; result += '| UID | From | Subject | Date | Read |\n'; result += '|-----|------|---------|------|------|\n'; for (const msg of messages) { const fromName = msg.from.name || msg.from.email; const subject = msg.subject.substring(0, 40); const date = msg.date.toISOString().split('T')[0]; const readStatus = msg.seen ? '✓' : '✗'; result += `| ${msg.uid} | ${fromName} | ${subject} | ${date} | ${readStatus} |\n`; } return { content: [ { type: 'text', text: result, }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error listing emails: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); } - src/services/imap.ts:65-124 (handler)The handler logic for listing messages, which fetches and paginates emails via IMAP.
export async function listMessages( folder: string, limit: number, offset: number ): Promise<MessageEnvelope[]> { const client = await getImapClient(); try { const lock = await client.getMailboxLock(folder); try { // Get total message count const mailbox = await client.mailboxOpen(folder); const totalMessages = mailbox.exists || 0; // Calculate range for pagination const start = Math.max(1, totalMessages - offset - limit + 1); const end = Math.max(1, totalMessages - offset); if (start > end) { return []; } const messages: MessageEnvelope[] = []; const fetchQuery = await client.fetch(`${start}:${end}`, { envelope: true, uid: true, flags: true, }); for await (const msg of fetchQuery) { if (msg.envelope) { const from = msg.envelope.from?.[0]; const to = msg.envelope.to; messages.push({ uid: msg.uid as number, from: { name: from?.name || undefined, email: from?.address || '', }, to: to?.map(t => ({ name: t.name || undefined, email: t.address || '', })), subject: msg.envelope.subject || '(no subject)', date: msg.envelope.date || new Date(), flags: Array.from(msg.flags || []).map(f => String(f)), seen: msg.flags.has('\\Seen'), }); } } // Reverse to show newest first return messages.reverse(); } finally { lock.release(); } } finally { await client.logout(); } }