msexchange-mcp
Version:
MCP server for Microsoft Exchange/Outlook email operations via Microsoft Graph API
91 lines • 4.93 kB
JavaScript
import { z } from 'zod';
import { SmartQueryBuilder } from '../mail/queryBuilder.js';
import accountsConfig from '../config/accountsLoader.js';
export const queryEmailsSummaryTool = {
name: 'query_emails_summary',
description: 'Get a condensed summary of many emails without full content. Optimized for token efficiency with intelligent query handling.',
parameters: z.object({
user_id: z.string().describe('The user ID or email address'),
search: z.string().optional().describe('Search query (searches subject, body, from)'),
filter: z.string().optional().describe('OData filter expression'),
folder: z.string().optional().describe('Folder name to search in (e.g., Inbox, Sent Items)'),
limit: z.number().max(200).optional().default(50).describe('Maximum number of emails to return (max 200 for summary)'),
skip: z.number().optional().default(0).describe('Number of emails to skip'),
order_by: z.string().optional().default('receivedDateTime DESC').describe('Sort order (not supported when using search parameter)'),
summary_length: z.number().max(200).optional().default(100).describe('Maximum characters for email preview'),
}),
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 safeLimit = Math.min(params.limit || 50, 200);
const summaryLength = params.summary_length || 100;
const queryBuilder = new SmartQueryBuilder(account.email);
// Build query options
const queryOptions = {
search: params.search,
filter: params.filter,
folder: params.folder,
limit: safeLimit,
skip: params.skip,
orderBy: params.order_by,
includeBody: false, // Never include body in summary
};
// Execute query with smart handling
const result = await queryBuilder.executeQuery(queryOptions);
const emails = result.emails;
return {
content: [
{
type: 'text',
text: JSON.stringify({
summary: {
totalRetrieved: emails.length,
hasMore: emails.length === safeLimit,
summaryFormat: true,
maxPreviewLength: summaryLength,
queryStrategy: result.strategy,
},
emails: emails.map(email => ({
id: email.id,
subject: email.subject || 'No Subject',
from: email.from?.emailAddress?.address || 'Unknown',
fromName: email.from?.emailAddress?.name || 'Unknown',
receivedDateTime: email.receivedDateTime,
hasAttachments: email.hasAttachments,
attachmentCount: email.hasAttachments && email.attachments ? email.attachments.length : 0,
attachmentNames: email.hasAttachments && email.attachments
? email.attachments.map((a) => a.name).slice(0, 3).join(', ') +
(email.attachments.length > 3 ? ` +${email.attachments.length - 3} more` : '')
: undefined,
isRead: email.isRead,
importance: email.importance,
preview: email.bodyPreview?.substring(0, summaryLength) +
(email.bodyPreview?.length > summaryLength ? '...' : ''),
categories: email.categories?.slice(0, 3),
})),
paginationInfo: {
currentSkip: params.skip || 0,
nextSkip: (params.skip || 0) + safeLimit,
hasMore: emails.length === safeLimit,
},
}, null, 2),
},
],
};
}
catch (error) {
return {
content: [
{
type: 'text',
text: `Error querying emails summary: ${error instanceof Error ? error.message : 'Unknown error'}`,
},
],
};
}
},
};
//# sourceMappingURL=queryEmailsSummary.js.map