UNPKG

msexchange-mcp

Version:

MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API

154 lines 5.11 kB
/** * Format an email message for MCP output */ export function formatEmailForMCP(email, options = {}) { const { includeBody = false, includeHeaders = false, maxBodyLength = 500, includeAttachments = true, } = options; let output = ''; // Subject and metadata output += `📧 **${email.subject || '(No Subject)'}**\n`; output += `From: ${formatEmailAddress(email.from)}\n`; if (email.toRecipients && email.toRecipients.length > 0) { output += `To: ${email.toRecipients.map(r => formatEmailAddress(r)).join(', ')}\n`; } if (email.ccRecipients && email.ccRecipients.length > 0) { output += `Cc: ${email.ccRecipients.map(r => formatEmailAddress(r)).join(', ')}\n`; } output += `Date: ${formatDate(email.receivedDateTime)}\n`; // Status indicators const indicators = []; if (!email.isRead) indicators.push('🔵 Unread'); if (email.hasAttachments) indicators.push('📎 Has Attachments'); if (email.importance === 'high') indicators.push('❗ High Priority'); if (email.flag?.flagStatus === 'flagged') indicators.push('🚩 Flagged'); if (indicators.length > 0) { output += `Status: ${indicators.join(' | ')}\n`; } // Categories/Labels if (email.categories && email.categories.length > 0) { output += `Labels: ${email.categories.map(c => `🏷️ ${c}`).join(', ')}\n`; } // ID for reference output += `ID: ${email.id}\n`; // Headers if requested if (includeHeaders && email.internetMessageHeaders) { output += '\n**Headers:**\n'; const importantHeaders = ['Message-ID', 'In-Reply-To', 'References']; email.internetMessageHeaders .filter(h => importantHeaders.includes(h.name)) .forEach(h => { output += `${h.name}: ${h.value}\n`; }); } // Body preview or full body if (includeBody && email.body) { output += '\n**Content:**\n'; const bodyText = email.body.contentType === 'text' ? email.body.content : stripHtml(email.body.content); if (maxBodyLength && bodyText.length > maxBodyLength) { output += bodyText.substring(0, maxBodyLength) + '...\n'; output += `(Truncated - ${bodyText.length} total characters)\n`; } else { output += bodyText + '\n'; } } else if (email.bodyPreview) { output += `\nPreview: ${email.bodyPreview}\n`; } // Attachments if (includeAttachments && email.hasAttachments && email.attachments) { output += '\n**Attachments:**\n'; email.attachments.forEach(att => { output += `• ${att.name} (${formatFileSize(att.size)})\n`; }); } return output; } /** * Format email address for display */ function formatEmailAddress(recipient) { if (!recipient) return '(Unknown)'; const { address, name } = recipient.emailAddress; return name ? `${name} <${address}>` : address; } /** * Format date for display */ function formatDate(dateString) { if (!dateString) return '(Unknown date)'; const date = new Date(dateString); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffDays = Math.floor(diffMs / (1000 * 60 * 60 * 24)); // Today if (diffDays === 0) { return `Today at ${date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true })}`; } // Yesterday if (diffDays === 1) { return `Yesterday at ${date.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true })}`; } // This week if (diffDays < 7) { return date.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true }); } // Older return date.toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric', hour: 'numeric', minute: '2-digit', hour12: true }); } /** * Format file size for display */ function formatFileSize(bytes) { if (bytes === 0) return '0 Bytes'; const k = 1024; const sizes = ['Bytes', 'KB', 'MB', 'GB']; const i = Math.floor(Math.log(bytes) / Math.log(k)); return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]; } /** * Basic HTML stripping */ function stripHtml(html) { return html .replace(/<[^>]*>/g, '') // Remove HTML tags .replace(/&nbsp;/g, ' ') // Replace &nbsp; .replace(/&amp;/g, '&') // Replace &amp; .replace(/&lt;/g, '<') // Replace &lt; .replace(/&gt;/g, '>') // Replace &gt; .replace(/&quot;/g, '"') // Replace &quot; .replace(/&#39;/g, "'") // Replace &#39; .replace(/\s+/g, ' ') // Collapse whitespace .trim(); } //# sourceMappingURL=formatters.js.map