reply_email
Reply to an email with proper threading headers. Automatically fetches the original message to build the reply chain. Optionally save as draft or send immediately.
Instructions
Reply to an existing email with proper threading headers (In-Reply-To, References). Automatically fetches the original email to build the reply chain. By default sends immediately; set send=false to save as a draft instead.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| originalEmailId | Yes | ID of the email to reply to | |
| to | No | Recipient email addresses (optional, defaults to the original sender) | |
| cc | No | CC email addresses (optional) | |
| bcc | No | BCC email addresses (optional) | |
| from | No | Sender email address (optional, defaults to account primary email) | |
| textBody | No | Plain text body (optional) | |
| htmlBody | No | HTML body (optional) | |
| send | No | Whether to send the reply immediately (default: true). Set to false to save as draft instead. | |
| replyTo | No | Reply-To email addresses (replies go here instead of to the sender) |
Implementation Reference
- src/index.ts:243-292 (registration)Tool registration for 'reply_email' in ListToolsRequestSchema handler: defines name, description, and inputSchema (with properties: originalEmailId, to, cc, bcc, from, textBody, htmlBody, send, replyTo)
{ name: 'reply_email', description: 'Reply to an existing email with proper threading headers (In-Reply-To, References). Automatically fetches the original email to build the reply chain. By default sends immediately; set send=false to save as a draft instead.', inputSchema: { type: 'object', properties: { originalEmailId: { type: 'string', description: 'ID of the email to reply to', }, to: { type: 'array', items: { type: 'string' }, description: 'Recipient email addresses (optional, defaults to the original sender)', }, cc: { type: 'array', items: { type: 'string' }, description: 'CC email addresses (optional)', }, bcc: { type: 'array', items: { type: 'string' }, description: 'BCC email addresses (optional)', }, from: { type: 'string', description: 'Sender email address (optional, defaults to account primary email)', }, textBody: { type: 'string', description: 'Plain text body (optional)', }, htmlBody: { type: 'string', description: 'HTML body (optional)', }, send: { type: ['boolean', 'string'], description: 'Whether to send the reply immediately (default: true). Set to false to save as draft instead.', }, replyTo: { type: 'array', items: { type: 'string' }, description: 'Reply-To email addresses (replies go here instead of to the sender)', }, }, required: ['originalEmailId'], }, }, - src/index.ts:1079-1155 (handler)Handler for 'reply_email' in CallToolRequestSchema switch statement: fetches original email, builds threading headers (In-Reply-To, References), prepends 'Re:' to subject, defaults recipients to original sender, then either creates a draft (if send=false) or sends the reply email via JmapClient.
case 'reply_email': { const { originalEmailId, to, cc, bcc, from, textBody, htmlBody, send, replyTo } = args as any; const shouldSend = coerceBool(send) ?? true; if (!originalEmailId) { throw new McpError(ErrorCode.InvalidParams, 'originalEmailId is required'); } if (shouldSend && !textBody && !htmlBody) { throw new McpError(ErrorCode.InvalidParams, 'Either textBody or htmlBody is required'); } // Fetch the original email to get threading headers const originalEmail = await client.getEmailById(originalEmailId); // Build threading headers const originalMessageId = originalEmail.messageId?.[0]; if (!originalMessageId) { throw new McpError(ErrorCode.InternalError, 'Original email does not have a Message-ID; cannot thread reply'); } const inReplyToHeader = [originalMessageId]; const referencesHeader = [ ...(originalEmail.references || []), originalMessageId, ]; // Build subject with Re: prefix let replySubject = originalEmail.subject || ''; if (!/^Re:/i.test(replySubject)) { replySubject = `Re: ${replySubject}`; } // Default recipients to the original sender const toArray = coerceStringArray(to); const replyRecipients = (toArray && toArray.length > 0) ? toArray : (Array.isArray(originalEmail.from) ? originalEmail.from.map((addr: any) => addr.email).filter(Boolean) : []); if (replyRecipients.length === 0) { throw new McpError(ErrorCode.InvalidParams, 'Could not determine reply recipient. Please provide "to" explicitly.'); } const replyParams = { to: replyRecipients, cc, bcc, from, subject: replySubject, textBody, htmlBody, inReplyTo: inReplyToHeader, references: referencesHeader, replyTo, }; if (!shouldSend) { const emailId = await client.createDraft(replyParams); return { content: [ { type: 'text', text: `Reply draft saved successfully (Email ID: ${emailId}). Subject: ${replySubject}`, }, ], }; } const submissionId = await client.sendEmail(replyParams); return { content: [ { type: 'text', text: `Reply sent successfully. Submission ID: ${submissionId}`, }, ], }; } - src/index.ts:248-291 (schema)Input schema for reply_email: defines originalEmailId (required), to, cc, bcc, from, textBody, htmlBody, send (default true), and replyTo fields.
properties: { originalEmailId: { type: 'string', description: 'ID of the email to reply to', }, to: { type: 'array', items: { type: 'string' }, description: 'Recipient email addresses (optional, defaults to the original sender)', }, cc: { type: 'array', items: { type: 'string' }, description: 'CC email addresses (optional)', }, bcc: { type: 'array', items: { type: 'string' }, description: 'BCC email addresses (optional)', }, from: { type: 'string', description: 'Sender email address (optional, defaults to account primary email)', }, textBody: { type: 'string', description: 'Plain text body (optional)', }, htmlBody: { type: 'string', description: 'HTML body (optional)', }, send: { type: ['boolean', 'string'], description: 'Whether to send the reply immediately (default: true). Set to false to save as draft instead.', }, replyTo: { type: 'array', items: { type: 'string' }, description: 'Reply-To email addresses (replies go here instead of to the sender)', }, }, required: ['originalEmailId'], },