proton_search_emails
Search Proton Mail emails by sender, recipient, subject, date range, body content, or unread status using multiple criteria with AND logic.
Instructions
Search emails by sender, recipient, subject, date range, body content, or unread status. Multiple criteria are combined with AND logic.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | INBOX | |
| from | No | ||
| to | No | ||
| subject | No | ||
| since | No | ||
| before | No | ||
| body | No | ||
| unseen_only | No | ||
| limit | No | ||
| offset | No |
Implementation Reference
- src/tools/search.ts:26-100 (handler)The handler for 'proton_search_emails' processes the search criteria, calls the IMAP service to fetch messages, and formats the results into a markdown table.
async (params: z.infer<typeof SearchEmailsSchema>) => { try { const criteria: SearchCriteria = { from: params.from, to: params.to, subject: params.subject, body: params.body, unseen: params.unseen_only, }; // Parse ISO date strings to Date objects if (params.since) { criteria.since = new Date(params.since); } if (params.before) { criteria.before = new Date(params.before); } const messages = await searchMessages(params.folder, criteria, params.limit, params.offset); if (messages.length === 0) { return { content: [ { type: 'text', text: 'No messages found matching the search criteria.', }, ], }; } // Format as markdown table let result = `**Folder:** ${params.folder}\n`; result += '**Search Criteria:**\n'; if (params.from) result += `- From: ${params.from}\n`; if (params.to) result += `- To: ${params.to}\n`; if (params.subject) result += `- Subject: ${params.subject}\n`; if (params.body) result += `- Body contains: ${params.body}\n`; if (params.since) result += `- Since: ${params.since}\n`; if (params.before) result += `- Before: ${params.before}\n`; if (params.unseen_only) result += `- Unread only: yes\n`; result += `\n**Results:** ${messages.length} message(s)\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 searching emails: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); - src/tools/search.ts:14-25 (registration)Registration of the 'proton_search_emails' tool with its schema and metadata.
'proton_search_emails', { title: 'Search Emails', description: 'Search emails by sender, recipient, subject, date range, body content, or unread status. Multiple criteria are combined with AND logic.', inputSchema: SearchEmailsSchema, annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false, }, }, - src/schemas/index.ts:17-28 (schema)Input validation schema for 'proton_search_emails'.
export const SearchEmailsSchema = z.object({ folder: z.string().default('INBOX'), from: z.string().optional(), to: z.string().optional(), subject: z.string().optional(), since: z.string().datetime().optional(), before: z.string().datetime().optional(), body: z.string().optional(), unseen_only: z.boolean().default(false), limit: z.number().int().min(1).max(100).default(20), offset: z.number().int().min(0).default(0), });