get_messages
Retrieve email messages from your iCloud mailbox, with options to filter by unread status and limit results for focused email management.
Instructions
Get email messages from specified mailbox
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of messages to retrieve | |
| mailbox | No | Mailbox name (default: INBOX) | INBOX |
| unreadOnly | No | Retrieve only unread messages |
Implementation Reference
- src/index.ts:57-80 (registration)Registration of the 'get_messages' tool in the MCP server's listTools handler, including name, description, and input schema.{ name: 'get_messages', description: 'Get email messages from specified mailbox', inputSchema: { type: 'object', properties: { mailbox: { type: 'string', description: 'Mailbox name (default: INBOX)', default: 'INBOX', }, limit: { type: 'number', description: 'Maximum number of messages to retrieve', default: 10, }, unreadOnly: { type: 'boolean', description: 'Retrieve only unread messages', default: false, }, }, }, },
- src/index.ts:391-417 (handler)MCP tool handler for 'get_messages': validates connection, extracts parameters (mailbox, limit, unreadOnly), calls iCloudMailClient.getMessages, and returns JSON stringified messages.case 'get_messages': { if (!mailClient) { throw new McpError( ErrorCode.InvalidRequest, 'iCloud Mail not configured. Please set ICLOUD_EMAIL and ICLOUD_APP_PASSWORD environment variables.' ); } const mailbox = (args?.mailbox as string) || 'INBOX'; const limit = (args?.limit as number) || 10; const unreadOnly = (args?.unreadOnly as boolean) || false; const messages = await mailClient.getMessages( mailbox, limit, unreadOnly ); return { content: [ { type: 'text', text: JSON.stringify(messages, null, 2), }, ], }; }
- Core helper method getMessages in iCloudMailClient class: opens IMAP mailbox, searches for recent messages (optionally unread), fetches bodies, parses with mailparser, extracts metadata/attachments/flags, returns EmailMessage array.async getMessages( mailbox: string = 'INBOX', limit: number = 10, unreadOnly: boolean = false ): Promise<EmailMessage[]> { return new Promise((resolve, reject) => { this.imap.openBox(mailbox, true, (err: Error) => { if (err) { reject(err); return; } const searchCriteria = unreadOnly ? ['UNSEEN'] : ['ALL']; this.imap.search(searchCriteria, (err: Error, results: number[]) => { if (err) { reject(err); return; } if (!results || results.length === 0) { resolve([]); return; } const messageIds = results.slice(-limit); const fetch = this.imap.fetch(messageIds, { bodies: '', struct: true, }); const messages: EmailMessage[] = []; fetch.on('message', (msg: ImapMessage, seqno: number) => { let emailData = ''; msg.on('body', (stream: NodeJS.ReadableStream) => { stream.on('data', (chunk: Buffer) => { emailData += chunk.toString('utf8'); }); stream.once('end', async () => { try { const parsed: ParsedMail = await simpleParser(emailData); const attachments: Attachment[] = []; if (parsed.attachments) { parsed.attachments.forEach((att: MailparserAttachment) => { attachments.push({ filename: att.filename || 'unknown', contentType: att.contentType || 'application/octet-stream', size: att.size || 0, data: att.content, }); }); } const getEmailText = ( addr: | MailparserAddressObject | MailparserAddressObject[] | undefined ) => { if (!addr) return ''; if (Array.isArray(addr)) return addr.map((a) => a.text).join(', '); return addr.text; }; const emailMessage: EmailMessage = { id: parsed.messageId || `${seqno}`, from: getEmailText(parsed.from), to: parsed.to ? Array.isArray(parsed.to) ? parsed.to.map((t) => getEmailText(t)) : [getEmailText(parsed.to)] : [], subject: parsed.subject || '', body: parsed.text || parsed.html || '', date: parsed.date || new Date(), flags: [], attachments: attachments.length > 0 ? attachments : undefined, }; messages.push(emailMessage); } catch (parseError) { console.error('Error parsing email:', parseError); } }); }); msg.once('attributes', (attrs: ImapMessageAttributes) => { if (attrs.flags) { const lastMessage = messages[messages.length - 1]; if (lastMessage) { lastMessage.flags = attrs.flags; } } }); }); fetch.once('error', (fetchErr: Error) => { reject(fetchErr); }); fetch.once('end', () => { resolve(messages); }); }); }); }); }