proton_reply_email
Reply to emails in Proton Mail with proper threading headers. Set up replies to all recipients or just the sender using the Proton MCP Server.
Instructions
Send a reply to an existing email. Properly sets In-Reply-To and References headers for threading. Can reply to all or just the sender.
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| folder | No | INBOX | |
| uid | Yes | ||
| body | Yes | ||
| reply_all | No |
Implementation Reference
- src/tools/reply.ts:13-98 (handler)The `registerReplyEmailTool` function registers the `proton_reply_email` tool and contains the main logic handler which fetches the original email, determines recipients based on the `reply_all` parameter, and sends the reply using the `sendMail` service.
export function registerReplyEmailTool(server: McpServer) { server.registerTool( 'proton_reply_email', { title: 'Reply to Email', description: 'Send a reply to an existing email. Properly sets In-Reply-To and References headers for threading. Can reply to all or just the sender.', inputSchema: ReplyEmailSchema, annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false, }, }, async (params: z.infer<typeof ReplyEmailSchema>) => { try { // Fetch the original message to get Message-ID and thread info const original = await fetchMessage(params.folder, params.uid); // Build recipient list let replyTo: string[] = []; if (params.reply_all) { // Reply to all: sender + cc recipients (exclude self) if (original.from.email && original.from.email !== PROTON_USER) { replyTo.push(original.from.email); } if (original.cc && original.cc.length > 0) { for (const cc of original.cc) { if (cc.email && cc.email !== PROTON_USER) { replyTo.push(cc.email); } } } } else { // Reply to just the sender if (original.from.email) { replyTo.push(original.from.email); } } if (replyTo.length === 0) { return { content: [ { type: 'text', text: 'Error: No valid recipients found for reply.', }, ], }; } // Send reply with threading headers const messageId = await sendMail({ from: PROTON_USER, to: replyTo, subject: original.subject.startsWith('Re: ') ? original.subject : `Re: ${original.subject}`, text: params.body, inReplyTo: original.messageId, references: original.references, }); return { content: [ { type: 'text', text: `Reply sent successfully!\nMessage ID: ${messageId}\nTo: ${replyTo.join(', ')}\nOriginal Subject: ${original.subject}`, }, ], }; } catch (error) { return { content: [ { type: 'text', text: `Error sending reply: ${error instanceof Error ? error.message : String(error)}`, }, ], }; } } ); } - src/schemas/index.ts:44-49 (schema)The `ReplyEmailSchema` Zod object defines the expected input parameters for the `proton_reply_email` tool, including `folder`, `uid`, `body`, and `reply_all`.
export const ReplyEmailSchema = z.object({ folder: z.string().default('INBOX'), uid: z.number().int().positive(), body: z.string(), reply_all: z.boolean().default(false), });