msexchange-mcp
Version:
MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API
104 lines (101 loc) • 4.77 kB
JavaScript
import { z } from 'zod';
import { MailService } from '../mail/mailService.js';
import accountsConfig from '../config/accountsLoader.js';
export const sendEmailTool = {
name: 'send_email',
description: `Send an email message with optional attachments.
Usage:
- Supports plain text and HTML body formats
- Can include multiple recipients (to, cc, bcc)
- Attachments must be base64 encoded (max 4MB each)
- Automatically saves to Sent Items folder
Examples:
- Simple text email: {"to": ["john@example.com"], "subject": "Hello", "body": "Hi John!"}
- HTML email with CC: {"to": ["john@example.com"], "cc": ["jane@example.com"], "subject": "Meeting", "body": "<h1>Meeting Agenda</h1>", "body_type": "HTML"}
- With attachment: {"to": ["john@example.com"], "subject": "Report", "body": "Please see attached", "attachments": [{"name": "report.pdf", "content": "base64..."}]}
Best practices:
- Always provide meaningful subjects
- Use HTML format for rich formatting
- Check attachment sizes before sending
- Consider using create_draft for complex emails`,
parameters: z.object({
user_id: z.string().describe('The user ID or email address of the sender'),
to: z.array(z.string()).describe('Array of recipient email addresses'),
cc: z.array(z.string()).optional().describe('Array of CC recipient email addresses'),
bcc: z.array(z.string()).optional().describe('Array of BCC recipient email addresses'),
subject: z.string().describe('Email subject'),
body: z.string().describe('Email body content'),
body_type: z.enum(['Text', 'HTML']).default('Text').describe('Body content type'),
save_to_sent: z.boolean().default(true).describe('Save to Sent Items folder'),
attachments: z.array(z.object({
name: z.string().describe('Attachment filename'),
content: z.string().describe('Base64 encoded file content'),
contentType: z.string().optional().describe('MIME type (e.g., "application/pdf", "image/jpeg")')
})).optional().describe('Array of file attachments (max 4MB each)'),
}),
execute: async (params) => {
try {
const account = accountsConfig.accounts.find(acc => acc.id === params.user_id || acc.email === params.user_id);
if (!account) {
throw new Error(`User not found: ${params.user_id}`);
}
const mailService = new MailService(account.email);
const message = {
subject: params.subject,
body: {
contentType: params.body_type || 'Text',
content: params.body,
},
toRecipients: params.to.map(email => ({
emailAddress: { address: email }
})),
ccRecipients: params.cc?.map(email => ({
emailAddress: { address: email }
})),
bccRecipients: params.bcc?.map(email => ({
emailAddress: { address: email }
})),
};
// Add attachments if provided
if (params.attachments && params.attachments.length > 0) {
message.attachments = params.attachments.map(att => ({
'@odata.type': '#microsoft.graph.fileAttachment',
name: att.name,
contentType: att.contentType || 'application/octet-stream',
contentBytes: att.content,
}));
// Check attachment sizes
for (const att of params.attachments) {
const estimatedSize = (att.content.length * 3) / 4;
if (estimatedSize > 4 * 1024 * 1024) {
throw new Error(`Attachment "${att.name}" exceeds 4MB limit`);
}
}
}
await mailService.sendMail(message, params.save_to_sent ?? true);
return {
content: [
{
type: 'text',
text: JSON.stringify({
message: 'Email sent successfully',
recipients: params.to,
attachmentCount: params.attachments?.length || 0,
}, null, 2),
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `Error sending email: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
},
};
//# sourceMappingURL=sendEmail.js.map